Guia de Mods para Skyrim: Garantindo a Compatibilidade de Mods Durante o Jogo

Tornando Seu Mod de Skyrim Compatível com Saves Existentes

A Importância da Compatibilidade com Saves Existentes

Jogadores de Skyrim são conhecidos por sua dedicação, muitas vezes investindo centenas, até milhares de horas em um único jogo. Exigir que esses jogadores iniciem um novo jogo para experimentar seu mod, ou mesmo para uma atualização, pode ser um grande impedimento. Da perspectiva do usuário, reiniciar significa perder incontáveis horas de progresso e potencialmente perder seu mod completamente.

Este guia foi elaborado para criadores de mods, particularmente aqueles familiarizados com o Creation Kit e os conceitos básicos de modding. Exploraremos como implementar técnicas que permitem que seu mod seja instalado ou atualizado em saves existentes, garantindo uma experiência mais suave e agradável para seus usuários.

Lidando com Atualizações e Instalações

A chave para a compatibilidade com saves existentes está em entender como gerenciar scripts, missões e referências de objetos durante uma atualização de mod ou instalação inicial. Como esses cenários compartilham os mesmos princípios, vamos abordá-los juntos.

Tempo é Tudo: Executando Sua Lógica

  • Evento OnInit: Uma abordagem direta é utilizar a função OnInit dentro de uma nova missão especificamente projetada para atualizações/instalações. Esta missão deve ser marcada como "Start Game Enabled" na Guia de Dados da Missão do Creation Kit. Anexe um script a esta missão através da Guia de Scripts e coloque seu código de atualização/instalação dentro da função OnInit.

  • Evento OnPlayerLoadGame: Para atualizações, o evento OnPlayerLoadGame oferece uma alternativa. Crie um alias na Guia Alias, force-o a referenciar o jogador e anexe um script (estendendo o script ReferenceAlias) a este alias. Implemente sua lógica de atualização dentro da função OnPlayerLoadGame. Lembre-se de que este evento é acionado apenas ao carregar um save, não na inicialização de uma nova missão. No entanto, OnInit ainda será executado para este script de alias quando a missão começar.

  • Evento OnCellAttach: Algumas funções, como GetDistance ou FindClosestReferenceOfAnyTypeInListFromRef, exigem ObjectReferences carregadas. Se sua lógica de atualização/instalação depender delas, use a função OnCellAttach.

Desmistificando Scripts

Os scripts são frequentemente uma fonte de ansiedade para os criadores de mods preocupados com a compatibilidade com saves existentes. No entanto, a menos que um script esteja sendo executado ativamente durante o processo de salvamento (o que é raro), seu código e estado de execução não são salvos. Os scripts normalmente são executados rapidamente, especialmente se você estiver usando RegisterForSingleUpdate e OnUpdate para atrasos mais longos em vez de Utility.Wait.

A principal preocupação reside nas propriedades e variáveis de instância do script, que são salvas. Felizmente, estas são gerenciáveis:

  • Propriedades: Defina diretamente seus valores para o estado desejado usando Papyrus.

  • Variáveis de Instância: Como estas são privadas ao seu script, crie funções setter para atualizá-las:

    int myInstanceVar = 5
    
    Function SetMyInstanceVar(int newValue)
      myInstanceVar = newValue
    EndFunction
    

Importantemente, as propriedades adicionadas recentemente a um script já inicializado serão automaticamente padronizadas para o valor especificado em seu plugin, portanto, você só precisa ajustar as propriedades existentes.

Trabalhando com Missões

Uma vez que uma missão está em andamento (não apenas visível no diário), suas etapas, propriedades de script e aliases se tornam fixos. Veja como lidar com isso:

  • Aliases: Facilmente atualizados usando a função ForceRefTo. Adicione a nova referência como uma propriedade de script em sua lógica de atualização/instalação e use ForceRefTo para apontar seu alias para ela.

  • Etapas da Missão:

    1. Evite Mudanças Desnecessárias: Idealmente, mantenha sua sequência de índice de estágio original. Projete sua missão com IDs de estágio suficientes para acomodar adições futuras.
    2. Considere a Substituição da Missão: Para revisões importantes, finalize a missão original usando Stop e introduza uma nova missão completamente.
    3. Reconstrução da Missão: Se você precisar reconstruir uma missão existente usando o mesmo formulário, use Stop, Reset e SetStage para guiar o jogador ao estado desejado após a atualização.

Gerenciando Referências de Objetos

Mods que alteram o mundo do jogo podem causar conflitos de posicionamento de objetos, frequentemente levando os autores a exigir um novo save. Isso ocorre porque as referências persistentes têm suas posições salvas.

Lembre-se de que apenas as referências de objetos persistentes são uma preocupação. Objetos temporários serão atualizados automaticamente para suas novas posições, pois não são salvos.

  • Objetos Móveis: A maioria dos objetos persistentes como Ativadores, Contêineres, MovableStatics e Marcadores podem ser movidos usando scripts. A função MoveToMyEditorLocation é particularmente útil para isso.

  • Objetos Imóveis: Árvores, Flora, Statics e Móveis não podem ser movidos via script. Aqui estão algumas soluções:

    1. Desabilitar e Substituir: Se o objeto não for usado por outros mods, desabilite o antigo e adicione um novo no local desejado. Certifique-se de que quaisquer aliases de missão ou propriedades de script que referenciem esses objetos sejam atualizados de acordo.
    2. Requisito do Save Unbaker: Adicione o mod Save Unbaker como um requisito. Esta ferramenta move automaticamente esses objetos para suas novas posições.

Outros Registros Persistentes

Lembre-se destes registros adicionais que persistem nos saves:

Exemplo: Script de Atualização Retroativa

ScriptName RetroactiveFixAlias Extends ReferenceAlias

MyQuestScript Property myQuest Auto
ObjectReference Property myQuestProperty1Ref Auto
ObjectReference Property myQuestProperty2Ref Auto

ReferenceAlias Property myAlias1 Auto
ReferenceAlias Property myAlias2 Auto
ObjectReference Property myAlias1Ref Auto
ObjectReference Property myAlias2Ref Auto

ObjectReference Property myRef1 Auto
ObjectReference Property myRef2 Auto

ObjectReference Property myActor1 Auto
Outfit Property myActor1Outfit Auto

int currentVersion = -1

Event OnInit()
  HandleInstallOrUpdates()
EndEvent

Event OnPlayerLoadGame()
  HandleInstallOrUpdates()
EndEvent

Function HandleInstallOrUpdates()
  If currentVersion != 2
    myQuest.myQuestProperty1 = myQuestProperty1Ref
    myQuest.myQuestProperty2 = myQuestProperty2Ref

    myAlias1.ForceRefTo(myAlias1Ref)
    myAlias2.ForceRefTo(myAlias2Ref)

    myRef1.MoveToMyEditorLocation()
    myRef2.MoveToMyEditorLocation()

    myActor1.SetOutfit(myActor1Outfit)

    currentVersion = 2
  EndIf
EndFunction

Exemplo: Corrigindo uma ObjectReference Após o Carregamento da Célula

ScriptName RetroactiveFixObjectReference extends ObjectReference

int currentVersion = -1
ObjectReference Property myRef Auto
FormList Property myRefTypes Auto

Event OnInit()
  ; Inicializado na versão 2, nenhuma correção necessária
  currentVersion = 2
EndEvent

Event OnCellAttach()
  If currentVersion != 2
    myRef = Game.FindClosestReferenceOfAnyTypeInListFromRef(myRefTypes, self, 100.0)
    currentVersion = 2
  EndIf
EndEvent

Conclusão

Embora este guia não cubra todos os cenários, ele fornece uma base sólida para tornar seu mod de Skyrim mais acessível e amigável. Lembre-se de que, embora alcançar a compatibilidade perfeita com saves existentes possa ser desafiador, mesmo pequenos passos nessa direção podem melhorar significativamente a experiência para seus usuários.

Analytics