Adding private variables

Adding private variables to an existing Raft class is sometimes very necessary. There're many ways to add new variables. In this article we will consider the method provided by Whitebrim. (Discord Whitebrim#4444)

We will store variables in the newly created class and add an extension for original Raft class. You can read how C# extensions work here.

We need to create new ConditionalWeakTable<TKey, TValue>. It will store our data classes and link them to original classes. This class is specifically created for our case, if you're interested you can read more about it here.

In this example we will add new private bool isLocked variable to SteeringWheel class:

First, we need to create data class to store all data we need to add:

[Serializable]
public class SteeringWheelAdditionalData
{
    public bool isLocked;

    public SteeringWheelAdditionalData()
    {
        isLocked = false;
    }
}

You must add [Serializable] attribute that our class could be saved. Also you need to create default constructor with no parameters to initialize class with default values.

Second, we need to create an extension class to store and handle data:

public static class SteeringWheelExtension
{
    private static readonly ConditionalWeakTable<SteeringWheel, SteeringWheelAdditionalData> data = 
        new ConditionalWeakTable<SteeringWheel, SteeringWheelAdditionalData>();

    public static SteeringWheelAdditionalData GetAdditionalData(this SteeringWheel steeringWheel)
    {
        return data.GetOrCreateValue(steeringWheel);
    }

    public static void AddData(this SteeringWheel steeringWheel, SteeringWheelAdditionalData value)
    {
        try
        {
            data.Add(steeringWheel, value);
        }
        catch (Exception) { }
    }
}

Then you need to patch original class. In our case we need to change displaying text depending on IsLocked state. We will patch OnIsRayed() method inside SteeringWheel class:

You can read more about Harmony patching here.

Also you need to apply patch:

You can access new data using class instance. SteeringWheel.GetAdditionalData().

Example for float and string:

Saving private variables

To save private variables you need to patch RDG_%RaftClassName% class and method that is invoked inside switch in SaveAndLoad class in RestoreRGDGame(RGD_Game game) method.

In this example we will use SteeringWheel class and save data from Adding private variables section.

First, we have to add new link RGD Class -> our additional data class (ConditionalWeakTable):

Second, we need to patch RGD_SteeringWheel class. There're two constructors (one for saving, another for loading) and GetObjectData method (to control flow of Serialization).

Lastly, we need to find method that loads saved block data and patch it. This method is invoked inside switch in SaveAndLoad class in RestoreRGDGame(RGD_Game game) method:

Our case:

In our case method is called RestoreWheel(RGD_SteeringWheel rgdWheel). This method contains instructions on how to deserialize RGD class to retrieve saved data. We will add our custom instructions:

Congratulations, our custom data for Steering Wheel is saving and loading successfully.

Full code you can find downloading Better Steering Wheel mod.

Last updated

Was this helpful?