All Projects → OwlcatOpenSource → WrathModificationTemplate

OwlcatOpenSource / WrathModificationTemplate

Licence: Apache-2.0 License
Internal development repository for Wrath of the Righteous mod template

Programming Languages

HLSL
714 projects
ShaderLab
938 projects
C#
18002 projects
GLSL
2045 projects

Getting started

  1. Open the project using Unity 2019.4.26f1

    • Unity console will show many compiler errors, but don't panic!
    • Click Modification Tools -> Setup project menu entry and choose Pathfinder: Wrath of the Righteous installation folder in the dialog that will appear
    • If Unity shows you API Update Required dialog click No Thanks
    • Close and reopen project
    • Click Modification Tools -> Setup render pipeline menu entry
    • Project is now ready
  2. Setup your modification (take a look at Assets/Modifications/ExampleModification for examples)

    • Create a folder for your modification in Assets/Modifications
    • Create Modification scriptable object in this folder (right click on folder -> Create -> Modification)
      • Specify Unique Name in Modification scriptable object
    • Create Scripts folder and your-modification-name.Scripts.asmdef file inside it (right click on folder -> Create -> Assembly Definition)
    • Create Content, Blueprints and Localization folders as needed
  3. Create your modification

  4. Build your modification (use Modification Tools -> Build menu entry)

  5. Test your modification

    • Copy Build/your-modification-name folder to user-folder/AppData/LocalLow/Owlcat Games/Pathfinder Wrath Of The Righteous/Modifications
    • Add your modification to user-folder/AppData/LocalLow/Owlcat Games/Pathfinder Wrath Of The Righteous/OwlcatModificationManagerSettings.json
      {
          "EnabledModifications": ["your-modification-name"] // use name from the manifest(!), not folder name
      }
    • Before patch 1.1.1 there was a typo in filename used to store settings: OwlcatModificationManangerSettings.json. This is now corrected, please use the correct filename (the game will still find file under the old name).
    • Run Pathfinder: Wrath of the Righteous
  6. Publish build results from Build folder

    • TODO

Features

All content of your modification must be placed in folder with Modification scriptable object or it's subfolders.

Scripts

All of your scripts must be placed in assemblies (in folder with *.asmdef files or it's subfolders). Never put your scripts (except Editor scripts) in other places.

Content

All of your content (assets, prefabs, scenes, sprites, etc) must be placed in your-modification-name/Content folder.

Blueprints

Blueprints are JSON files which represent serialized version of static game data (classes inherited from SimpleBlueprint).

  • Blueprints must have file extension *.jbp and must be situated in your-modification-name/Blueprints folder.

    • example: Examples/Basics/Blueprints/TestBuff.jbp
    // *.jbp file format
    {
        "AssetId": "unity-file-guid-from-meta", // "42ea8fe3618449a5b09561d8207c50ab" for example
        "Data": {
            "$type": "type-id, type-name", // "618a7e0d54149064ab3ffa5d9057362c, BlueprintBuff" for example
            
            // type-specific data
        }
    }
    • if you specify AssetId of an existing blueprint (built-in or from another modification) then the existing blueprint will be replaced
  • For access to metadata of all built-in blueprints use this method

    // read data from <WotR-installation-path>/Bundles/cheatdata.json
    // returns object {Entries: [{Name, Guid, TypeFullName}]}
    BlueprintList Kingmaker.Cheats.Utilities.GetAllBlueprints();
  • You can write patches for existing blueprints: to do so, create a *.patch JSON file in your-modification-name/Blueprints folder. Instead of creating a new blueprint, these files will modify existing ones by changing only fields that are specified in the patch and retaining everything else as-is.

    • Example 1: Examples/Basics/Blueprints/ChargeAbility.patch

    • Example 2: Examples/Basics/Blueprints/InvisibilityBuff.patch

    • Connection between the existing blueprint and the patch must be specified in BlueprintPatches scriptable object (right click in folder -> Create -> Blueprints' Patches)

      • example: Examples/Basics/BlueprintPatches.asset
    • OLD: Newtonsoft.Json's Populate is used for patching (_#ArrayMergeSettings and _#Entries isn't supported)

    • NEW (game version 1.1.1): Newtonsoft.Json's Merge is used for patching

    // *.patch file format: change icon in BlueprintBuff and disable first component
    {
      "_#ArrayMergeSettings": "Merge", // "Union"/"Concat"/"Replace"
      "m_Icon": {"guid": "b937cb64288636b4c8fd4ba7bea337ea", "fileid": 21300000},
      "Components": [
        {
          "m_Flags": 1
        }
      ]
    }

    OR

    {
      "_#Entries": [
        {
          "_#ArrayMergeSettings": "Merge", // "Union"/"Concat"/"Replace"
          "m_Icon": {"guid": "b937cb64288636b4c8fd4ba7bea337ea", "fileid": 21300000},
          "Components": [
            {
              "m_Flags": 1
            }
          ]
        }
      ]
    }

Localization

You can add localized strings to the game or replace existing strings. Create enGB|ruRU|deDE|frFR|zhCN|esES.json file(s) in your-modification-name/Localization folder.

  • example: Examples/Basics/Localizations/enGB.json

  • You shouldn't copy enGB locale with different names if creating only enGB strings: enGB locale will be used if modification doesn't contains required locale.

  • The files should be in UTF-8 format (no fancy regional encodings, please!)

// localization file fromat
{
    "strings": [
        {
            "Key": "guid", // "15edb451-dc5b-4def-807c-a451743eb3a6" for example
            "Value": "whatever-you-want"
        }
    ]
}

Assembly entry point

You can mark static method with OwlcatModificationEnterPoint attribute and the game will invoke this method with corresponding OwlcatModification parameter once on game start. Only one entry point per assembly is allowed.

  • example: Examples/Basics/Scripts/ModificationRoot.cs (ModificationRoot.Initialize method)
[OwlcatModificationEnterPoint]
public static void EnterPoint(OwlcatModification modification)
{
    ...
}

GUI

Use OwlcatModification.OnGUI for inserting GUI to the game. It will be accessible from modifications' window (ctrl+M to open). GUI should be implemented with IMGUI (root layout is vertical).

  • example: Examples/Basics/Scripts/ModificationRoot.cs (ModificationRoot.Initialize method)

Harmony Patching

Harmony lib is included in the game and you can use it for patching code at runtime.

  • example: Examples/Basics/Scripts/ModificationRoot.cs (ModificationRoot.Initialize method) and Examples/Basics/Scripts/Tests/HarmonyPatch.cs

  • Harmony Documentation

OwlcatModification modification = ...;
modification.OnGUI = () => GUILayout.Label("Hello world!");

Storing data

  • You can save/load global modification's data or settings with methods OwlcatModification.LoadData and OwlcatModification.SaveData. Unity Serializer will be used for saving this data.

    • Example: Examples/Basics/Scripts/ModificationRoot.cs (ModificationRoot.TestData method)
    [Serialzable]
    public class ModificationData
    {
        public int IntValue;
    }
    ...
    OwlcatModification modification = ...;
    var data = modification.LoadData<ModificationData>();
    data.IntValue = 42;
    modification.SaveData(data);
  • You can save/load per-save modification's data or settings by adding EntityPartKeyValueStorage to Game.Instance.Player.

    • Example: Examples/Basics/Scripts/Tests/PerSaveDataTest.cs
    var data = Game.Instance.Player.Ensure<EntityPartKeyValueStorage>().GetStorage("storage-name");
    data["IntValue"] = 42.ToString();

EventBus

You can subscribe to game events with EventBus.Subscribe or raise your own event using EventBus.RaiseEvent.

  • Example (subscribe): Examples/Basics/Scripts/ModificationRoot.cs (ModificationRoot.Initialize method)

  • Raise your own event:

    interface IModificationEvent : IGlobalSubscriber
    {
        void HandleModificationEvent(int intValue);
    }
    ...
    EventBus.RaiseEvent<IModificationEvent>(h => h.HandleModificationEvent(42))

Rulebook Events

  • IBeforeRulebookEventTriggerHandler and IAfterRulebookEventTriggerHandler exists specifically for modifications. These events are raised before OnEventAboutToTrigger and OnEventDidTigger correspondingly.
  • Use RulebookEvent.SetCustomData and RulebookEvent.TryGetCustomData to store and read your custom RulebookEvent data.

Resources

OwlcatModification.LoadResourceCallbacks is invoked every time when a resource (asset, prefab or blueprint) is loaded.

Game Modes and Controllers

A Controller is a class that implements a particular set of game mechanics. It must implementi IController interface.

Game Modes (objects of class GameMode) are logical groupings of Controllers which all must be active at the same time. Only one Game Mode can be active at any moment. Each frame the game calls Tick method for every Controller in active Game Mode. You can add your own logic to Pathfinder's main loop or extend/replace existing logic using OwlcatModificationGameModeHelper.

  • Example (subscribe): Examples/Basics/Scripts/Tests/ControllersTest.cs

Using Pathfinder shaders

Default Unity shaders doesn't work in Pathfinder. Use shaders from Owlcat namespace in your materials. If you don't know what you need it's probably Owlcat/Lit shader.

Scenes

You can create scenes for modifications but there is a couple limitations:

  • if you want to use Owlcat's MonoBehaviours (i.e. UnitSpawner) you must inherit from it and use child class defined in your assembly

  • place an object with component OwlcatModificationMaterialsInSceneFixer in every scene which contains Renderers

Helpers

  • Copy guid and file id as json string: right-click-on-asset -> Modification Tools -> Copy guid and file id

  • Copy blueprint's guid: right-click-on-blueprint -> Modification Tools -> Copy blueprint's guid

  • Create blueprint: right-click-in-folder -> Modification Tools -> Create Blueprint

  • Find blueprint's type: Modification Tools -> Blueprints' Types

Interactions and dependencies between modifications

Work in progress. Please note that users will be able to change order of mods in the manager. We're planning to provide the ability to specify a list of dependencies for your modification, but it will only work as a hint: the user will be responsible for arranging a correct order of mods in the end.

Testing

  • Command line argument -start_from=area-name/area-preset-name allows you to start game from the specified area without loading main menu.
  • Cheat reload_modifications_data allows you to reload content, blueprints and localizations. All instantiated objects (prefab instances, for example) stays unchanged.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].