# Conteúdo custom — nossa camada "Season 6 Custom"
> "Custom 31" aqui é referência de **estilo** (muito conteúdo extra sobre o S6), não a Season 31 da Webzen,
> e nenhum código/asset de servidores comerciais é usado.
## Princípios
1. **Fundação antes de conteúdo** — nada de Custom 1+ antes do MVP v0.1 (Custom 0) estar validado.
2. **Ordem de implementação:** configuração → plugin → módulo custom → extensão → core (último recurso,
com justificativa em [decisions.md](decisions.md), patch mínimo e teste).
3. **Regra Servidor + Web (D15):** todo conteúdo novo tem estado `Server / Web` na
[matriz](compatibility-matrix.md). Só está pronto com os três ✅.
4. **Nada de assets proprietários no Git** ([assets.md](assets.md)).
## Onde cada tipo de customização vive
| Tipo | Mecanismo no OpenMU | Onde no nosso repo |
|---|---|---|
| Rates (EXP, drop, zen), spots, horários de eventos | Configuração do jogo (Admin Panel → Game configuration / Maps / Drops) | export/scripts em `custom/configuration/` |
| Comandos de chat, regras (reset, ranking), QoL | Plugins `IChatCommandPlugIn`, `I*PlugIn` | `custom/server/src/MuCustom.Gameplay` |
| Eventos periódicos | `IPeriodicTaskPlugIn` / `PeriodicTaskBasePlugIn` | `MuCustom.Events` |
| Itens/sets/wings novos (dados) | `ItemDefinition` + `IConfigurationUpdatePlugIn` (atualização versionada de dados) | `MuCustom.Items` + `custom/items/` |
| Monstros/bosses (dados) | `MonsterDefinition`, `MonsterSpawnArea`, drop groups | `MuCustom.Monsters` + `custom/monsters/` |
| IA de boss com fases | plugins de eventos de dano/morte + `IPeriodicTaskPlugIn` | `MuCustom.Monsters` |
| Mapas | `GameMapDefinition` (+ arquivos de terreno nos **clientes**) | `custom/maps/` |
| Pacotes novos | XML em `Network/Packets` (**upstream**) | contribuição upstream |
Dados de jogo novos devem entrar como **`IConfigurationUpdatePlugIn`** (padrão do upstream para atualizar
bancos existentes sem reinstalar) — assim servidores já em produção recebem o conteúdo pelo Admin Panel →
*Configuration updates*.
## Fases
### Custom 0 — Season 6 vanilla operacional (MVP v0.1)
OpenMU + PostgreSQL + Admin + cliente web (protocolo estendido, D16): login, personagem, mapa,
movimento, combate, loot, inventário, persistência. **Estado:** ver [STATUS.md](../STATUS.md).
### Custom 1 — Qualidade de vida
- ✅ Rates de EXP, master, zen e drop pelo `.env` (`scripts/apply-game-config.sh`, D22).
- ✅ Reset (`/reset`, `/resetinfo`): plugin do próprio OpenMU, configurado pelo mesmo script.
- ✅ Ranking público em `/ranking` (D21).
- ✅ Comandos: `/serverinfo` (nosso), `/online`, `/pkclear`, `/post`, `/add*` (do OpenMU) — todos aparecem no
autocompletar do chat.
- 🚧 Grand reset, auto pickup, balanceamento, spots.
✅ Dano/HP 32-bit no web desde o protocolo estendido (D16).
### Custom 2 — Itens
Novas armas, sets, shields, acessórios, pets; modelos/texturas/ícones; stats, excellent/ancient options.
Requisitos por item:
- **Server:** `ItemDefinition` (grupo/número, tamanho, requisitos, opções) via configuration update.
- **Web:** modelo convertido em `public/game-assets`, entrada em `src/common/items.json`/`itemsDatabase.ts`.
- **Limites de ID:** serialização estendida → grupo 0–15 e número 0–4095 (12 bits).
### Custom 3 — Wings
Investigação feita:
- **Inventário/trade/drop:** itens de wing usam a serialização de item normal (grupo 12, número até 511) — custom cabe.
- **Aparência para outros jogadores (o ponto crítico):** a appearance **clássica** (`AppearanceSerializer.AddWing`,
usada pelo cliente web até a D16, 44405) codifica wings por um `switch` sobre números **fixos** (1ª/2ª/2,5/3ª/pequenas)
em poucos bits. Uma wing com número novo cai no `default` → **outros jogadores web não a veem**.
- A appearance **estendida** (`AddCharacterToScopeExtended`/`AppearanceChangedExtended`, hoje usada pelo web)
envia grupo/número do item explicitamente → wings custom são transmitidas sem hack.
- **Web:** `src/common/deserializeAppearance.ts` entende a variante estendida.
**Resolvido em 2026-10-03 (D16):** o cliente web passou a operar no modo estendido (patch 0003). A aparência
de 27 bytes leva grupo + número reais da wing, e o item usa número de 12 bits (até 4095 por grupo).
Para uma wing custom ficar pronta faltam só o **conteúdo**: definição no servidor (`ItemDefinition` via
`IConfigurationUpdatePlugIn`) e o modelo/ícone no cliente web (`game-assets` + `items.json`).
### Custom 4 — Monstros e bosses
Monstros novos (modelos, texturas, IA, skills, loot, respawn), bosses e world bosses.
Bosses com fases (planejado, **não implementar antes da fundação**):
```
100% ──▶ 75%: invoca adds ──▶ 50%: skill nova ──▶ 25%: enrage (dano/velocidade)
```
Desenho: plugin que observa dano recebido (ponto de extensão de "attackable got hit"/HP), mantém estado por
instância e dispara ações (spawn de monstros na área, troca de skill set, buff). Modelos novos exigem trabalho no cliente web.
### Custom 5 — Mapas
Terreno (`EncTerrain*.att/map/obj`), objetos, iluminação, spawns, gates, NPCs, safe zones, minimapa, drops.
Servidor: `GameMapDefinition` + atributos de terreno (o servidor precisa do mapa de atributos para pathfinding/safezone).
Web: conversão para `game-assets` (pipeline `tools/` do Babylon; 0.97d mostra
que conversão de mundos ainda é trabalho manual upstream).
### Custom 6 — Sistemas modernos (arquitetura, não implementação)
Daily/weekly quests, achievements, daily login, progressão de conta, world boss, dungeons, raids, crafting,
coleções, temporadas, battle pass, cosméticos, marketplace, ranking web, eventos.
**Já implementados** (ver `STATUS.md` e `docs/compatibility-matrix.md`): quests diárias e registro de caça, Gremory Case, banco de joias, Ruud + loja (D25); fotos de perfil e de guilda (D28); brincos (D29); login diário (D32); dungeons com bots (D33, `docs/dungeons.md`); quests de NPC (D35, `docs/quests-npc.md`); chefe mundial com fases (D36, `docs/boss-fases.md`); mapa detalhado (D37, `docs/mapa-detalhado.md`); ranking web (D21).
**Ainda por fazer:** conquistas, raids, crafting novo, coleções, temporadas, battle pass, cosméticos, marketplace.
Comandos de GM dos sistemas: `/ruud `, `/gremory [nível] [qtd]`, `/worldboss [0|1|2|stop|hp N]`, `/botparty [n] [nível] [grupo número]`.
Base técnica prevista:
- estado novo em **tabelas próprias** (schema `mucustom` no mesmo Postgres) — não alterar o DataModel do upstream;
- regras em plugins `MuCustom.*` reagindo a eventos do GameLogic;
- UI: inicialmente por mensagens/NPC (sem mudança de cliente); UIs novas exigem trabalho no cliente web;
- portal web consumindo a API `/api` do OpenMU + uma API nossa (futuro `api.DOMAIN`).
## Checklist de nova feature custom
- [ ] issue/descrição com fase (Custom N)
- [ ] implementação na camada certa (config → plugin → …)
- [ ] GUIDs novos e fixos; dados via `IConfigurationUpdatePlugIn`
- [ ] testado no servidor (smoke + teste manual/automatizado)
- [ ] testado no web
- [ ] linha na [matriz de compatibilidade](compatibility-matrix.md)
- [ ] assets registrados em [assets.md](assets.md)
- [ ] CHANGELOG