-
Notifications
You must be signed in to change notification settings - Fork 1
Modder guide : Call replication
The entire mod networking is built around feature that enforces certain methods to be invoked at every client no matter what. Lets call this 'call replication' and call that a day. It's done via Harmony patching shenanigans (yes, mod patches itself). Here's an example of such patch :
ParrotWrapper.ParrotPatchExpressiontarget<Action<Bill_Production, int>>((Bill_Production bill, int count) => BillRepeatModeUtilityPatch.SetBillTargetCount(bill, count));
BillRepeatModeUtilityPatch.SetBillTargetCount
is a static method, that does very simple thing - assigns a value to variable :
[MethodImpl(MethodImplOptions.NoInlining)]
public static void SetBillRepeatType(Bill_Production bill, BillRepeatModeDef repeatMode)
{
bill.repeatMode = repeatMode;
}
If you leave this method untouched, it would work as specified : it would just move repeatMode
to a specified field. Nothing exciting, huh? But IF you ParrotPatch
it, things gonna change drastically. After patch, calling that method would serialize it's arguments and it's body would be magically called at every client in session, once it's time will come. A little notes, tho :
-
You have to make sure that very small methods, like that one, won't be inlined. This is why
[MethodImpl(MethodImplOptions.NoInlining)]
is applied. -
You have to make sure that complex objects, like pawns, items, etc, specified in method arguments, already exists at other clients too, including
Def
s. Stuff like numbers, vectors, strings, etc, straigly serialized as their values. More info about that you will find in Serialization section(WIP). -
If method is non-static, you should specify
__instance
argument and patch should look like that :
ParrotWrapper.ParrotPatchExpressiontarget<Action<ExampleClass>>((ExampleClass __instance) => __instance.Do());
In this case, callingDo
on any instance ofExampleClass
, will callExampleClass.Do
method on all clients by serializingExampleClass
and sending method index to call. -
ALL clients have to call
ParrotPatchExpressionTarget
during initialization to entirely the same set of methods, in exact same order. Shouldn't be a big deal, tho. -
ThingFilter
s are very special beasts. Refer to their own section in this wiki (WIP)