Como começar a criar um MOD no DayZ

53815587674_1c825da8aa_o.png

Bom, acredito que a melhor forma de você começar no desenvolvimento de mods, é começar com coisas pequenas. Foque em uma funcionalidade específica que você gostaria de modificar no jogo.

Por onde começar?

Gostaria de começar, explicando para você sobre a tecnologia que o DayZ usa para o desenvolvimento de MODs.
O DayZ utiliza de uma abstração da linguagem C, com o nome de Enforce Script, assim escrevo esse artigo presumindo que você já tenha conhecimento com desenvolvimento de software, e com criação de servidores de DayZ, se você não tem esses conhecimentos, oriento você entender melhor sobre isso, dessa forma vai facilitar o entendimento desse conteúdo.

Podemos utilizar as ferramentas que a propria Bohemia disponibilizada para nós, também podemos usar o Visual Studio Code para facilitar em alguns momentos, mais a baixo falaremos sobre isso.

Vamos começar a pensar em uma funcionalidade para ser criada. Pensei em começarmos com um exemplo simples, vamos criar a funcionalidade de "autorun", é algo relativamente simples e com um exemplo prático, acredito que vai te ajudar a entender como funciona a criação mais facilmente.

Primeiros Passos

Beleza, agora que já sabemos o que vamos fazer, vamos entender melhor as ferramentas disponíveis, na Steam, em sua biblioteca assim que você instalar o jogo, procure por "DayZ Tools", nesse aplicativo, você tem tudo o que é necessário para o desenvolvimento do MOD:

dayz-tools.png

Antes de colocarmos a mão na massa, precisamos extrair o jogo para o seu computador, clique no menu "Tools" -> "Extract Game Data", assim todo código do DayZ ficara disponível, essa execução vai levar um tempo, dependendo da configuração do seu computador, pode demorar bastante.

Assim que finalizar, vamos monta a unidade P, clique no menu "Tools" -> "Mount Drive P", isso é necessário para usarmos o "Workbench" que é a ferramenta de desenvolvimento nativa do jogo.

Criar a Estrutura Base

Agora, podemos começar a criar o nosso MOD, vamos abrir o "Workbench":

workbench1.png

Dentro da pasta "SourceData", está todo código do jogo que podemos alterador, porem, não podemos alterar os arquivos diretamente nessa pasta do jogo, primeiro precisamos criar o nosso MOD, vamos começar criando a estrutura básica de um MOD.

Clique com o Botão direto do mouse na pasta "SourceData" va em "New" -> "New Folder", agora coloque o nome do seu MOD, vamos colocar "AutorunTuto":

workbench2.png

Beleza, com o botão direito do mouse na pasta do nosso MOD, e click em "Open File Location", isso ira abrir o explorer diretamente na pasta que criamos.

Dentro dessa pasta agora vamos criar o arquivo de configuração do nosso MOD, esse arquivo precisa ter o nome config.cpp, e também precisa ter a extensão ".cpp", caso contrario seu MOD não irá funcionar, recomendo utilizar algum editor de texto, ou IDE para fazer isso, não vou entrar em detalhes sobre o que é cada parte desse código nesse artigo, se for necessário podemos falar sobre isso em outro artigo.

Copie o código a baixo e cole no arquivo que acabamos de criar:

class CfgPatches
{
    class AutoRunTuto
    {
        units[]={};
        weapons[]={};
        shoulder[]={};
        melee[]={};
        requiredVersion=0.1;
        requiredAddons[]=
        {
        };
    };
};
class CfgMods
{
    class AutoRunTuto
    {
        dir="AutoRunTuto";
        name="AutoRunTuto";
        // inputs="AutoRunTuto/data/Inputs.xml";
        credits="";
        author="Fernando Oliveira";
        authorID=0;
        version="1.0";
        extra=0;
        type="mod";
        dependencies[]=
        {
            "Game",
            "Mission",
            "World"
        };
        class defs
        {
            class gameScriptModule
            {
                value="";
                files[]=
                {
                    "AutoRunTuto/Scripts/3_Game"
                };
            };
            class worldScriptModule
            {
                value="";
                files[]=
                {
                    "AutoRunTuto/Scripts/4_World"
                };
            };
            class missionScriptModule
            {
                value="";
                files[]=
                {
                    "AutoRunTuto/Scripts/5_Mission"
                };
            };
        };
    };
};
class CfgVehicles
{
};
class CfgSlots
{
};

Agora, vamos criar 4 pastas, para nosso MOD, Scripts, 3_Game, 4_World, 5_Mission. A estrutura ficara dessa forma:

AutoRunTuto
└── Scripts
    ├── 3_Game
    ├── 4_World
    └── 5_Mission

Pronto, já temos a estrutura base para o nosso MOD, a partir de agora vamos começar a criar as nossas modificações no jogo, para mais detalhes sobre os scripts acesse aqui.

Mão na Massa - Escrever o Código

A partir de agora, vamos criar e procurar os arquivos que precisamos alterar, vamos voltar para o Workbench.

O primeiro arquivo que vamos alterar é o PlayerBase.c, vamos colocar algumas coisas nesse arquivo, mas antes, vamos criar esse mesmo arquivo dentro do nosso MOD, crie na mesma estrutura do jogo, para facilitar no futuro, o arquivo ficara nessa pasta Scripts/4_World/Entities/Manbase/PlayerBase.c

Com base no arquivo original, vamos criar o aquivo em nosso MOD:

modded class PlayerBase extends ManBase
{
    const int TUTO_RPC_AUTORUN = 98600;
    int tuto_AutoRunning;

    override void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx)
    {
        super.OnRPC(sender, rpc_type, ctx);

        if (rpc_type == TUTO_RPC_AUTORUN)
        {
            TutoRpcAutorun(ctx);
        }
    }

    private void TutoRpcAutorun(ParamsReadContext ctx)
    {
        Param3<int, int, bool> data;

        if (ctx.Read(data))
        {
            this.GetInputController().OverrideMovementSpeed(data.param3, data.param1);
            this.GetInputController().OverrideMovementAngle(data.param3, data.param2);
        }
    }
}

Repare, eu coloquei "modded" antes de class, para informar ao jogo que estamos modificando essa classe, no método "OnRPC" eu coloquei override na frente, informando que estamos sobrescrevendo o método com nossa funcionalidade, é importante sempre chamarmos a função original usando "super", para não interferirmos em outras funcionalidades.

Agora vamos criar a nossa funcionalidade, vamos criar um arquivo chamado AutoRun.c, esse é de fato a nossa funcionalidade de autorun, o foco desse artigo não explicar de fato cada detalhe da lógica do código, mas sim te dar o caminho das pedras, por onde começar a fazer suas modificações.

Vamos criar em uma pasta separada, para ficar mais organizado: Scripts\4_World\Classes\AutoRun.c

class AutoRun
{
    const int TUTO_RPC_AUTORUN = 98600;
    ref array<int> inputs = new array<int>;

    void AutoRun(PlayerBase player, int key)
    {
        if (GetGame().GetUIManager().GetMenu() != NULL)
            return;

        if (!player.IsAlive() || player.IsUnconscious())
        {
            if (player.tuto_AutoRunning == 1)
                InitAutoRun(player, DayZPlayerConstants.MOVEMENTIDX_IDLE, 0, 0);

            return;
        }

        if (player.tuto_AutoRunning == 1)
        {
            SetCheckStopKeys();

            CheckStopKeyPress(player, key);

            return;
        }

        if (player.tuto_AutoRunning == 0 && CheckKeyPress(key))
        {
            int speed = DayZPlayerConstants.MOVEMENTIDX_RUN;

            if (CheckKeyHold("UATurbo"))
                speed = DayZPlayerConstants.MOVEMENTIDX_SPRINT;
            else if (CheckKeyHold("UAWalkRunTemp"))
                speed = DayZPlayerConstants.MOVEMENTIDX_WALK;

            InitAutoRun(player, speed, 1, 1);
        }
    }

    void InitAutoRun(PlayerBase player, int speed, int angle, int run)
    {
        player.tuto_AutoRunning = run;
        player.GetInputController().OverrideMovementSpeed(run, speed);
        player.GetInputController().OverrideMovementAngle(run, angle);

        GetGame().RPCSingleParam(player, TUTO_RPC_AUTORUN, new Param3<int, int, bool>(speed, angle, run), true);
    }

    bool CheckKeyPress(int key)
    {
        if (key == KeyCode.KC_ADD)
            return true;

        return false;
    }

    void CheckStopKeyPress(PlayerBase player, int key)
    {
        foreach(int keypress : inputs)
        {
            if (keypress == key)
                InitAutoRun(player, DayZPlayerConstants.MOVEMENTIDX_IDLE, 0, 0);
        }
    }

    bool CheckKeyHold(string keyCheck)
    {
        UAInput input = GetUApi().GetInputByName(keyCheck);

        if (input && input.LocalHold())
            return true;

        return false;
    }

    void SetCheckStopKeys()
    {
        inputs.Insert(KeyCode.KC_ADD);
        inputs.Insert(KeyCode.KC_W);
        inputs.Insert(KeyCode.KC_S);
        inputs.Insert(KeyCode.KC_A);
        inputs.Insert(KeyCode.KC_D);
        inputs.Insert(KeyCode.KC_ESCAPE);
    }
}

Agora precisamos capturar a ação do teclado com o método "OnKeyPress", para isso iremos modificar outro arquivo, vamos modificar o arquivo MissionGameplay.c, sempre que o player fizer uma ação no teclado, nós iremos verificar se ativou o autorun.

Crie o arquivo na pasta: Scripts\5_Mission\MissionGameplay.c

modded class MissionGameplay extends MissionBase
{
    override void OnKeyPress(int key) 
    {
        super.OnKeyPress(key);

        PlayerBase player = PlayerBase.Cast(GetGame().GetPlayer());

        if (player) {
            AutoRun(player, key);
        }
    }
}

Desenvolvimento concluído, agora que já temos nosso código, vamos para a próxima etapa, chegou a hora de fazermos a build do nosso MOD.

Fazer a Build e Assinar

Vamos fazer a build do nosso MOD, vamos usar a ferramenta "Addon Builder":

addonbuild.png

Em "Addon source directory" coloque a pasta que criamos na unidade "P:", e para o "Destination directory" vamos criar uma nova pasta chamada @TutoAutoRun, pode ser em um local de sua escolha, e dentro dessa pasta criamos mais uma chamada addons, e deixe as configurações marcadas como acima, depois clique em "PACK".

Agora dentro vemos que dentro da pasta addons, temos nossa build, agora vamos assinar a nossa build. A assinatura é necessária para garantir a integridade do nosso MOD, é uma etapa obrigatória.

Vamos usar a ferramenta "DS Utils":

dsutils.png

Primeiro vamos criar nossa primeira chave, em "Private Key" clique no botão N, coloque o nome da sua chave, e selecione o destino, não armazene dentro da pasta com @, pois essa é sua chave privada, só você pode ter ela.

dsutils2.png

Agora vamos assinar nossa build clique em "Add a source directory", se selecione o arquivo ".pbo" que criamos, depois clique em "Process files".

dsutils3.png

Dentro da pasta onde armazenamos nossa chave privada, também vamos ter um chave publica (tudo_key.bikey), a chave publica você precisa copiar para dentro da pasta @ do seu MOD, de preferência crie uma pasta chamada key, essa chave é usada para habilitar o mod no servidor, lembrando que eu presumo que você já saiba fazer isso.

key.png

Deploy do MOD

Agora vamos usar a ferramenta "Publisher" para publicar nosso MOD:

publisher.png

Preencha as informações como no exemplo acima, seu MOD está pronto para ser testado e usado na Steam.

OBS: Caso seu MOD não funcione de primeira, faça o deploy novamente, às vezes, ocorre um bug na Steam.

Em breve vou trazer mais artigos de como fazer o debug do seu código e assuntos relacionados.

Espero que esse artigo tenha te ajudado, entre em nossa comunidade do Discord.

Até logo.