修改数据表及相关数据

Update 26 (11th of May 2017) introduces 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

Create a new blueprint in your mods folder that inherits from the ModController class.

ModController Info
* This blueprint will be found by the game as long as it exists in your mod folder, and the server will automatically create an instance of it and spawn it during startup.
* It will always be available from anywhere, so it's a great place to put global data for your mod.
* It will also be saved to the DataBase. So if you create new variables on it, and tag them with the "SaveGame" flag, it will be saved and loaded when the server restarts. So persistent data can also be stored here for your mod.
* **All ModControllers will be Spawned/Loaded in the mod load order!** That primarily means their BeginPlay will be ran in that order as well, but it is also relevant in **Step Two.**
* ModControllers get Spawned/lLoaded before any other saved actor in the DataBase.
* It is always relevant to all players, and can replicate properties to them. So any variable marked as Replicated will be updated on all clients. So client side modifications you have made can get global information from your mod from here.

### 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 of 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.

I also show you how to use the "Remove Data Table Rows" function to simply delete rows, and the "Clear Data Table" to show how to completely remove all entries from a DataTable. You should obviously not completely clear out the RecipesTable, unless perhaps if you are making a complete total conversion mod.

ModDataTableOperations Info
* Gets run as early as possible during game startup
* Is run on the Default Object of the class. Not the ModController object you get during normal play as mentioned in Step One.
* They are executed in Mod Load Order. Which means that if multiple mods modify the same DataTable row, the last one in the mod load order will be the winner. But it will still be compatible with those mods, but one will lose some of its changes to the other mod overriding it.
* You are only allowed to use specifically approved functions here. Since it runs on the default object, I don't want you to mess anything up. The new DataTable functions here are also not available outside of ModDataTableOperations.

### 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.

### Step Two - Add your component to your ModController's AdditionalClassComponents list

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 playercontroller blueprints!