Chapter 2.5: File Organization Best Practices
Home | << Previous: Minimum Viable Mod | File Organization | Next: Server vs Client Architecture >>
Indice
- A Estrutura de Diretorio Canonica
- Convencoes de Nomenclatura
- Tres Tipos de Mods
- Mods com Divisao Cliente-Servidor
- O Que Vai Onde
- Nomenclatura de PBO e Pasta @mod
- Exemplos Reais de Mods Profissionais
- Anti-Padroes
A Estrutura de Diretorio Canonica
Este e o layout padrao usado por mods profissionais de DayZ. Nem toda pasta e obrigatoria -- crie apenas o que precisar.
MyMod/ <-- Raiz do projeto (desenvolvimento)
mod.cpp <-- Metadados do launcher
stringtable.csv <-- Localizacao (na raiz do mod, NAO em Scripts/)
Scripts/ <-- Raiz do PBO de scripts
config.cpp <-- CfgPatches + CfgMods + definicoes de script modules
Inputs.xml <-- Keybindings customizados (opcional)
Data/
Credits.json <-- Creditos do autor
Version.hpp <-- String de versao (opcional)
1_Core/ <-- engineScriptModule (raro)
MyMod/
Constants.c
3_Game/ <-- gameScriptModule
MyMod/
MyModConfig.c <-- Classe de configuracao
MyModRPCs.c <-- Identificadores / registro de RPC
Data/
SomeDataClass.c <-- Estruturas de dados puras
4_World/ <-- worldScriptModule
MyMod/
Entities/
MyCustomItem.c <-- Itens customizados
MyCustomVehicle.c
Managers/
MyModManager.c <-- Managers com consciencia do mundo
Actions/
ActionMyCustom.c <-- Acoes customizadas do jogador
5_Mission/ <-- missionScriptModule
MyMod/
MyModRegister.c <-- Registro do mod (hook de startup)
GUI/
MyModPanel.c <-- Scripts de paineis de UI
MyModHUD.c <-- Scripts de overlay de HUD
GUI/ <-- Raiz do PBO de GUI (separado de Scripts)
config.cpp <-- Config especifico de GUI (imageSets, estilos)
layouts/ <-- Arquivos .layout
mymod_panel.layout
mymod_hud.layout
imagesets/ <-- Arquivos .imageset + atlas de texturas
mymod_icons.imageset
mymod_icons.edds
looknfeel/ <-- Arquivos .styles
mymod.styles
Data/ <-- Raiz do PBO de dados (modelos, texturas, itens)
config.cpp <-- CfgVehicles, CfgWeapons, etc.
Models/
my_item.p3d <-- Modelos 3D
Textures/
my_item_co.paa <-- Texturas de cor
my_item_nohq.paa <-- Normal maps
Materials/
my_item.rvmat <-- Definicoes de material
Sounds/ <-- Arquivos de som
alert.ogg <-- Arquivos de audio (sempre .ogg)
ambient.ogg
ServerFiles/ <-- Arquivos para admins de servidor copiarem
types.xml <-- Definicoes de spawn da Central Economy
cfgspawnabletypes.xml <-- Presets de acessorios
README.md <-- Guia de instalacao
Keys/ <-- Chaves de assinatura
MyMod.bikey <-- Chave publica para verificacao do servidorConvencoes de Nomenclatura
Nomes de Mod/Projeto
Use PascalCase com um prefixo claro:
MyFramework <-- Framework, prefixo: MyMod_
MyMissions <-- Mod de funcionalidade
MyWeapons <-- Mod de conteudo
VPPAdminTools <-- Alguns mods pulam underscores
DabsFramework <-- PascalCase sem separadorNomes de Classe
Use um prefixo curto unico para seu mod, seguido de um underscore e o proposito da classe:
// Padrao MyMod: My[Subsistema]_[Nome]
class MyLog // Logging do core
class MyRPC // RPC do core
class MyW_Config // Config de armas
class MyM_MissionBase // Base de missoes
// Padrao CF: CF_[Nome]
class CF_ModuleWorld
class CF_EventArgs
// Padrao COT: JM_COT_[Nome]
class JM_COT_Menu
// Padrao VPP: [Nome] (sem prefixo)
class ChatCommandBase
class WebhookManagerRegras:
- Prefixo previne colisoes com outros mods
- Mantenha curto (2-4 caracteres)
- Seja consistente dentro do seu mod
Nomes de Arquivo
Nomeie cada arquivo com a classe principal que ele contem:
MyLog.c <-- Contem class MyLog
MyRPC.c <-- Contem class MyRPC
MyModConfig.c <-- Contem class MyModConfig
ActionMyCustom.c <-- Contem class ActionMyCustomUm classe por arquivo e o ideal. Multiplas classes auxiliares pequenas em um arquivo e aceitavel quando sao fortemente acopladas.
Arquivos de Layout
Use minusculas com o prefixo do seu mod:
my_admin_panel.layout
my_killfeed_overlay.layout
mymod_settings_dialog.layoutNomes de Variaveis
// Variaveis membro: prefixo m_
protected int m_Count;
protected ref array<string> m_Items;
protected ref MyConfig m_Config;
// Variaveis estaticas: prefixo s_
static int s_InstanceCount;
static ref MyLog s_Logger;
// Constantes: MAIUSCULAS_COMPLETAS
const int MAX_PLAYERS = 60;
const float UPDATE_INTERVAL = 0.5;
const string MOD_NAME = "MyMod";
// Variaveis locais: camelCase (sem prefixo)
int count = 0;
string playerName = identity.GetName();
float deltaTime = timeArgs.DeltaTime;
// Parametros: camelCase (sem prefixo)
void SetConfig(MyConfig config, bool forceReload)Tres Tipos de Mods
Mods de DayZ se dividem em tres categorias. Cada uma tem uma enfase de estrutura diferente.
1. Mod de Conteudo
Adiciona itens, armas, veiculos, construcoes -- principalmente assets 3D com scripting minimo.
MyWeaponPack/
mod.cpp
Data/
config.cpp <-- CfgVehicles, CfgWeapons, CfgMagazines, CfgAmmo
Weapons/
MyRifle/
MyRifle.p3d
MyRifle_co.paa
MyRifle_nohq.paa
MyRifle.rvmat
Ammo/
MyAmmo/
MyAmmo.p3d
Scripts/ <-- Minimo (pode nem existir)
config.cpp
4_World/
MyWeaponPack/
MyRifle.c <-- Apenas se a arma precisa de comportamento customizado
ServerFiles/
types.xmlCaracteristicas:
- Pesado em
Data/(modelos, texturas, materiais) - Pesado em
Data/config.cpp(definicoes CfgVehicles, CfgWeapons) - Scripting minimo ou nenhum
- Scripts apenas quando itens precisam de comportamento customizado alem do que o config define
2. Mod de Script
Adiciona funcionalidades de gameplay, ferramentas de admin, sistemas -- principalmente codigo com assets minimos.
MyAdminTools/
mod.cpp
stringtable.csv
Scripts/
config.cpp
3_Game/
MyAdminTools/
Config.c
RPCHandler.c
Permissions.c
4_World/
MyAdminTools/
PlayerManager.c
VehicleManager.c
5_Mission/
MyAdminTools/
AdminMenu.c
AdminHUD.c
GUI/
layouts/
admin_menu.layout
admin_hud.layout
imagesets/
admin_icons.imagesetCaracteristicas:
- Pesado em
Scripts/(maior parte do codigo em 3_Game, 4_World, 5_Mission) - Layouts de GUI e imagesets para UI
- Pouco ou nenhum
Data/(sem modelos 3D) - Geralmente depende de um framework (CF, DabsFramework, MyFramework)
3. Mod de Framework
Fornece infraestrutura compartilhada para outros mods -- logging, RPC, configuracao, sistemas de UI.
MyFramework/
mod.cpp
stringtable.csv
Scripts/
config.cpp
Data/
Credits.json
1_Core/ <-- Frameworks frequentemente usam 1_Core
MyFramework/
Constants.c
LogLevel.c
3_Game/
MyFramework/
Config/
ConfigManager.c
ConfigBase.c
RPC/
RPCManager.c
Events/
EventBus.c
Logging/
Logger.c
Permissions/
PermissionManager.c
UI/
ViewBase.c
DialogBase.c
4_World/
MyFramework/
Module/
ModuleManager.c
ModuleBase.c
Player/
PlayerData.c
5_Mission/
MyFramework/
MissionHooks.c
ModRegistration.c
GUI/
config.cpp
layouts/
imagesets/
icons/
looknfeel/Caracteristicas:
- Usa todas as camadas de script (1_Core ate 5_Mission)
- Hierarquia de subdiretorios profunda em cada camada
- Define
defines[]para deteccao de funcionalidades - Outros mods dependem dele via
requiredAddons - Fornece classes base que outros mods estendem
Mods com Divisao Cliente-Servidor
Quando um mod tem tanto comportamento visivel ao cliente (UI, renderizacao de entidades) quanto logica apenas de servidor (spawning, cerebros de IA, estado seguro), ele deve ser dividido em dois pacotes.
Estrutura de Diretorio
MyMod/ <-- Raiz do projeto (repositorio de desenvolvimento)
MyMod_MyMod/ <-- Pacote do cliente (carregado via -mod=)
mod.cpp
stringtable.csv
Scripts/
config.cpp <-- type = "mod"
3_Game/MyMod/ <-- Classes de dados compartilhadas, RPCs
4_World/MyMod/ <-- Renderizacao de entidades do lado do cliente
5_Mission/MyMod/ <-- UI do cliente, HUD
GUI/
layouts/
Sounds/
MyMod_MyModServer/ <-- Pacote do servidor (carregado via -servermod=)
mod.cpp
Scripts/
config.cpp <-- type = "servermod"
3_Game/MyModServer/ <-- Classes de dados do lado do servidor
4_World/MyModServer/ <-- Spawning, logica de IA, gerenciamento de estado
5_Mission/MyModServer/ <-- Hooks de startup/shutdown do servidorRegras Principais para Mods Divididos
- O pacote do cliente e carregado por todos (servidor e todos os clientes via
-mod=) - O pacote do servidor e carregado apenas pelo servidor (via
-servermod=) - O pacote do servidor depende do pacote do cliente (via
requiredAddons) - Nunca coloque codigo de UI no pacote do servidor -- clientes nao o receberao
- Mantenha logica segura/privada no pacote do servidor -- nunca e enviado aos clientes
Cadeia de Dependencias
// config.cpp do pacote do cliente
class CfgPatches
{
class MyMyMod_Scripts
{
requiredAddons[] = { "DZ_Scripts", "MyCore_Scripts" };
};
};
// config.cpp do pacote do servidor
class CfgPatches
{
class MyMyModServer_Scripts
{
requiredAddons[] = { "DZ_Scripts", "MyMyMod_Scripts", "MyCore_Scripts" };
// ^^^ depende do pacote do cliente
};
};Exemplo Real: MyMissions Mod
MyMissions/
MyMissions/ <-- Cliente (-mod=)
mod.cpp type = "mod"
Scripts/
config.cpp requiredAddons: MyCore_Scripts
3_Game/MyMissions/ Enums compartilhados, config, RPC IDs
4_World/MyMissions/ Marcadores de missao (renderizacao do cliente)
5_Mission/MyMissions/ UI de missao, HUD de radio
GUI/layouts/ Layouts de painel de missao
Sounds/ Sons de bip de radio
MyMissions_Server/ <-- Servidor (-servermod=)
mod.cpp type = "servermod"
Scripts/
config.cpp requiredAddons: MyScripts, MyCore_Scripts
3_Game/MyMissionsServer/ Extensoes de config do servidor
4_World/MyMissionsServer/ Spawner de missao, gerenciador de loot
5_Mission/MyMissionsServer/ Ciclo de vida de missao do servidorO Que Vai Onde
Diretorio Data/
Assets fisicos e definicoes de itens:
Data/
config.cpp <-- CfgVehicles, CfgWeapons, CfgMagazines, CfgAmmo
Models/ <-- Arquivos de modelo 3D .p3d
Textures/ <-- Arquivos de textura .paa, .edds
Materials/ <-- Definicoes de material .rvmat
Animations/ <-- Arquivos de animacao .anim (raro)Diretorio Scripts/
Todo codigo Enforce Script:
Scripts/
config.cpp <-- CfgPatches, CfgMods, definicoes de script modules
Inputs.xml <-- Definicoes de keybinding
Data/
Credits.json <-- Creditos do autor
Version.hpp <-- String de versao
1_Core/ <-- Constantes fundamentais e utilitarios
3_Game/ <-- Configs, RPCs, classes de dados
4_World/ <-- Entidades, managers, logica de gameplay
5_Mission/ <-- UI, HUD, ciclo de vida da missaoDiretorio GUI/
Recursos de interface do usuario:
GUI/
config.cpp <-- CfgPatches especifico de GUI (para registro de imageset/style)
layouts/ <-- Arquivos .layout (arvores de widgets)
imagesets/ <-- XML .imageset + atlas de texturas .edds
icons/ <-- Imagesets de icones (podem ser separados dos imagesets gerais)
looknfeel/ <-- Arquivos .styles (propriedades visuais de widgets)
fonts/ <-- Arquivos de fontes customizadas (raro)
sounds/ <-- Arquivos de som de UI (click, hover, etc.)Diretorio Sounds/
Arquivos de audio:
Sounds/
alert.ogg <-- Sempre formato .ogg
ambient.ogg
click.oggConfig de som (CfgSoundSets, CfgSoundShaders) vai em Scripts/config.cpp, nao em um config separado de Sounds.
Diretorio ServerFiles/
Arquivos que administradores de servidor copiam para a pasta de missao do servidor:
ServerFiles/
types.xml <-- Definicoes de spawn de itens para Central Economy
cfgspawnabletypes.xml <-- Presets de acessorios/cargo
cfgeventspawns.xml <-- Posicoes de spawn de eventos (raro)
README.md <-- Instrucoes de instalacaoNomenclatura de PBO e Pasta @mod
Nomes de PBO
Cada PBO recebe um nome descritivo com o prefixo do mod:
@MyMod/
Addons/
MyMod_Scripts.pbo <-- Codigo de script
MyMod_Data.pbo <-- Modelos, texturas, itens
MyMod_GUI.pbo <-- Layouts, imagesets, estilos
MyMod_Sounds.pbo <-- Audio (as vezes agrupado com Data)O nome do PBO nao precisa corresponder ao nome da classe CfgPatches, mas mante-los alinhados previne confusao.
Nome da Pasta @mod
O prefixo @ e uma convencao do Steam Workshop. Durante o desenvolvimento, voce pode omiti-lo:
Desenvolvimento: MyMod/ <-- Sem prefixo @
Workshop: @MyMod/ <-- Com prefixo @O @ nao tem significado tecnico para o motor. E puramente convencao organizacional.
Multiplos PBOs por Mod
Mods grandes se dividem em multiplos PBOs por varias razoes:
- Ciclos de atualizacao separados -- atualizar scripts sem re-baixar modelos 3D
- Componentes opcionais -- PBO de GUI e opcional se o mod funciona headless
- Pipeline de build -- PBOs diferentes construidos por ferramentas diferentes
@MyWeapons/
Addons/
MyWeapons_Scripts.pbo <-- Comportamento de script
MyWeapons_Data.pbo <-- 268 modelos de armas, texturas, configsCada PBO tem seu proprio config.cpp com sua propria entrada CfgPatches. O requiredAddons entre eles controla a ordem de carregamento:
// Scripts/config.cpp
class CfgPatches
{
class MyWeapons_Scripts
{
requiredAddons[] = { "DZ_Scripts", "DZ_Weapons_Firearms" };
};
};
// Data/config.cpp
class CfgPatches
{
class MyWeapons_Data
{
requiredAddons[] = { "DZ_Data", "DZ_Weapons_Firearms" };
};
};Exemplos Reais de Mods Profissionais
MyFramework -- Mod de Framework
MyFramework/
MyFramework/ <-- Pacote do cliente
mod.cpp
stringtable.csv
GUI/
config.cpp
fonts/
icons/ <-- 5 imagesets de peso de icones
imagesets/
layouts/
dialogs/
options/
prefabs/
MyMod/loading/hints/
MyFramework/AdminPanel/
MyFramework/Dialogs/
MyFramework/Modules/
MyFramework/Options/
MyFramework/Prefabs/
MyFramework/Tooltip/
looknfeel/
sounds/
Scripts/
config.cpp
Inputs.xml
1_Core/MyMod/ <-- Niveis de log, constantes
2_GameLib/MyMod/UI/ <-- Sistema de atributos MVC
3_Game/MyMod/ <-- 15+ pastas de subsistemas
Animation/
Branding/
Chat/
Collections/
Config/
Core/
Events/
Hints/
Killfeed/
Logging/
Module/
MVC/
Notifications/
Permissions/
PlayerData/
RPC/
Settings/
Theme/
Timer/
UI/
4_World/MyMod/ <-- Dados de jogador, managers do mundo
5_Mission/MyMod/ <-- Painel de admin, registro de mods
MyFramework_Server/ <-- Pacote do servidor
mod.cpp
Scripts/
config.cpp
...Community Online Tools (COT) -- Ferramenta de Admin
JM/COT/
mod.cpp
GUI/
config.cpp
layouts/
cursors/
uiactions/
vehicles/
textures/
Objects/Debug/
config.cpp <-- Definicoes de entidades de debug
Scripts/
config.cpp
Data/
Credits.json
Version.hpp
Inputs.xml
Common/ <-- Compartilhado entre todas as camadas
1_Core/
3_Game/
4_World/
5_Mission/
languagecore/
config.cpp <-- Config de string tableNote o padrao da pasta Common/: incluida em todo script module via files[], permitindo tipos compartilhados entre todas as camadas.
MyWeapons Mod -- Mod de Conteudo
MyWeapons/
MyWeapons/
mod.cpp
Data/
config.cpp <-- Config mesclado: 268 definicoes de armas
Ammo/ <-- Organizado por fonte/calibre
BC/12.7x55/
BC/338/
BC/50Cal/
GCGN/3006/
GCGN/300AAC/
Attachments/ <-- Miras, supressores, grips
Magazines/
Weapons/ <-- Modelos de armas organizados por fonte
Scripts/
config.cpp <-- Definicoes de script modules
3_Game/ <-- Config de armas, sistema de stats
4_World/ <-- Overrides de comportamento de armas
5_Mission/ <-- Registro, UIMods de conteudo tem um diretorio Data/ massivo e Scripts/ relativamente pequeno.
DabsFramework -- Framework de UI
DabsFramework/
mod.cpp
gui/
config.cpp
imagesets/
icons/
brands.imageset
light.imageset
regular.imageset
solid.imageset
thin.imageset
looknfeel/
scripts/
config.cpp
Credits.json
Version.hpp
1_core/
2_GameLib/ <-- Um dos poucos mods usando camada 2
3_Game/
4_World/
5_Mission/Nota: DabsFramework usa nomes de pasta em minusculas (scripts/, gui/). Isso funciona porque o Windows nao diferencia maiusculas, mas pode causar problemas no Linux. A convencao e usar a capitalizacao canonica (Scripts/, GUI/).
Anti-Padroes
1. Despejo Plano de Scripts
Scripts/
3_Game/
AllMyStuff.c <-- 2000 linhas, 15 classes
MoreStuff.c <-- 1500 linhas, 12 classesCorrecao: Um arquivo por classe, organizado em subdiretorios por subsistema.
2. Posicionamento de Camada Errado
Scripts/
3_Game/
MyMod/
PlayerManager.c <-- Referencia PlayerBase (definido em 4_World)
MyPanel.c <-- Codigo de UI (pertence a 5_Mission)
MyItem.c <-- Estende ItemBase (pertence a 4_World)Correcao: Siga as regras de camada do Capitulo 2.1. Mova codigo de entidades para 4_World e codigo de UI para 5_Mission.
3. Sem Subdiretorio do Mod nas Camadas de Script
Scripts/
3_Game/
Config.c <-- Risco de colisao de nome com outros mods!
RPCs.cCorrecao: Sempre use namespace com um subdiretorio:
Scripts/
3_Game/
MyMod/
Config.c
RPCs.c4. stringtable.csv Dentro de Scripts/
Scripts/
stringtable.csv <-- LOCALIZACAO ERRADA
config.cppCorrecao: stringtable.csv vai na raiz do mod (ao lado de mod.cpp):
MyMod/
mod.cpp
stringtable.csv <-- Correto
Scripts/
config.cpp5. Assets e Scripts Misturados em Um PBO
MyMod/
config.cpp
Scripts/3_Game/...
Models/weapon.p3d
Textures/weapon_co.paaCorrecao: Separe em multiplos PBOs:
MyMod/
Scripts/
config.cpp
3_Game/...
Data/
config.cpp
Models/weapon.p3d
Textures/weapon_co.paa6. Subdiretorios Profundamente Aninhados
Scripts/3_Game/MyMod/Systems/Core/Config/Managers/Settings/PlayerSettings.cCorrecao: Mantenha aninhamento em 2-3 niveis no maximo. Achate quando possivel:
Scripts/3_Game/MyMod/Config/PlayerSettings.c7. Nomenclatura Inconsistente
mymod_Config.c
MyMod_rpc.c
MYMOD_Manager.c
my_mod_panel.cCorrecao: Escolha uma convencao e mantenha-a:
MyModConfig.c
MyModRPC.c
MyModManager.c
MyModPanel.cChecklist de Resumo
Antes de publicar seu mod, verifique:
- [ ]
mod.cppesta na raiz do mod (ao lado deAddons/ouScripts/) - [ ]
stringtable.csvesta na raiz do mod (NAO dentro deScripts/) - [ ]
config.cppexiste na raiz de cada PBO - [ ]
requiredAddons[]lista TODAS as dependencias - [ ] Caminhos
files[]dos script modules correspondem a estrutura de diretorio real - [ ] Todo arquivo
.cesta dentro de um subdiretorio com namespace do mod (ex:3_Game/MyMod/) - [ ] Nomes de classe tem um prefixo unico para evitar colisoes
- [ ] Classes de entidade estao em
4_World, classes de UI estao em5_Mission, classes de dados estao em3_Game - [ ] Sem segredos ou codigo de debug nos PBOs publicados
- [ ] Logica apenas de servidor esta em um pacote
-servermodseparado (se aplicavel)
Anterior: Capitulo 2.4: Seu Primeiro Mod -- Minimo ViavelProximo: Parte 3: Sistema de GUI e Layout
