Update 26 (11th of May 2017) introduced a few new tools to the modders to primarily help with compatibility issues between mods and official patches.
Modding DataTables (e.g. ItemTable)[]
The old way of modding a DataTable would be to edit the DataTable directly and applying the changes you wanted directly to the asset. Modifying an existing asset is the recipe for having incompatible mods. So unless you are specifically replacing something that already exists, you should always strive to not modify existing assets directly.
For DataTables the new method involves using a set of tools you unlock through a new class called a ModController.
Step One - The ModController[]
Step Two - Make your DataTable[]
In this example I'm creating a new table that uses the ItemTable struct. You do that by right-clicking in your mod folder -> Miscellaneous -> DataTable. And selecting "ItemTableRow". If you are targeting different DataTables, select the appropriate struct for your target DataTable. I'm creating a completely new item with a new ID. Stone2, ID 1337. Other than the name and description it's the same as normal Stone. And I'm altering an existing item, by overriding the row in the DataTable. This is Steel Bar, ID 11502. Which I am changing the name of and the descriptions. Other than that I copied the values completely from the normal Steel Bar entry in the ItemTable. The goal here is to merge my own mod specific ItemTable (MOC_ItemTable) into the games ItemTable. NOTICE: The row ID needs to be unique for new items between mods, otherwise they will override each other! We are considering some ideas, so you don't have to worry about this anymore, but for now you need to be careful to pick unique IDs for your new entries. |
Step Three - ModDataTableOperations[]
Every blueprint that is created that inherits from ModController will automatically get a function added called "ModDataTableOperations", which is very similar in concept to the ConstructionScript.
It will automatically be executed on game startup. And only allows certain functions to be executed inside it. This is because it needs to run very early to make sure all the DataTables are altered before they get accessed by any game logic. And to do that, it runs these functions on the Default Object for the class. So doing anything other than the approved actions here does not make sense.
Conclusion DataTables[]
You now have a mod that modifies a DataTable without actually touching that DataTable's asset! This means that it will not always break whenever we touch that DataTable in an official patch. And it means that other mods that follow the same method can all dynamically merge and remove things to any DataTable as well! This should make life easier for modders, giving them less work to maintain their mods. And gives players who use mods more options to mix and match their favorite combinations of mods.
We plan to expand on this feature of modifying DataTables to allow individual columns to be edited and not just entire rows.
Dynamically added Components[]
The second problem the patch tries to alleviate is when mods require new RPCs (Remote Procedure Calls). Most importantly for our game the RunOnServer call. (You can learn more about owning connections here https://docs.unrealengine.com/latest/INT/Gameplay/Networking/Actors/OwningConnections/).
In our game the actors that will have an owning connection is the PlayerController and the controlled Pawn/Character actor. Our PlayerController class is the "Funcombat_PlayerController". Our controlled Pawn for players is the "BasePlayerChar". You can add RPCs that will work with owning connection to any of these Actors, in any of the blueprints they inherit from. Which for BasePlayerChar means that you can add RPCs in the parent blueprints as well (BaseSurvivalChar, BaseBPCombat, BaseBPChar). This is how many modders have been dealing with compatibility issues, introducing a new inheritance level between one of these layers, getting their own blueprint to add stuff in. But this method still requires edits to one of the mentioned blueprints, to change the parent of one of them. So it will break if we update that asset, or if any other modder is touching the same one.
Another important layer to the owning connections is that it extends to owned objects such as Components. So you can do RPCs through Replicated Components as well, which you can find many examples of us doing in our blueprints as well. This is what the new system takes advantage of. You can now create a new replicated component that you can attach to any Actor without having to touch that asset.
Step One - Create your Replicated Component[]
Create a component that fits your need, does not matter which type it is. But if you want to use this for RPCs, you have to enable the "Component Replicates" option under Class Defaults.
IMPORTANT: the name of your actor component has to be unique. Mod controller added actor components with the same name will overwrite each other and it is very likely that the result is a client and/or server crash! Good practice: add you suffix/prefix to every single actor / actor component of your project (e.g. your nickname, the modname, ...).
Step Two - Add your component to your ModController's AdditionalClassComponents list[]
With this setup, any BasePlayerChar that gets spawned will get a MOC_Component added to it.
You can add a ComponentTag to it if you wish, so you can do GetComponentsByTag to find it later, or in case you need multiple of the same type and need to distinguish them. |
Step Three - Make all the new RPCs you need[]
As an example I have added a new radial menu button to the "Wooden Box", that adds a Give Wood option. But as mentioned before, touching an existing file is asking for incompatibility issues. So this is just as an example, you should do this by making a completely new placeable.
Inside the MOC_Component:
Inside the BP_PL_Medium_Chest (Which is the Wooden Box):
Conclusion Components[]
The wooden box now has a new RPC call to the server that will give the player one wood item. And we did it without having to touch any of the player or the player controller blueprints!