Skip to content

Instantly share code, notes, and snippets.

@Zetrith
Zetrith / Multifaction.md
Created October 21, 2023 10:54
Multiplayer multifaction

The faction system is well integrated into the game and multifaction makes good use of it. Most of the work needs to be done in places where vanilla expects only one (player) faction.

Basically, RimWorld keeps a global variable Faction.OfPlayer storing the single player faction. Multiplayer creates additional player factions and then changes the value of this variable when necessary. The value of OfPlayer then depends on the context in which code is executing (you could say it's a form of dynamic scoping).

This "faction context" is set, for example, to the a colonist's faction when it begins executing its logic and then restored. In code:

void Pawn.Tick() {
@Zetrith
Zetrith / MpMethodUtil.cs
Last active September 4, 2021 20:38
A utility for reflecting on compiler generated methods
// From Multiplayer.Client.Util
public static class MpMethodUtil
{
const string DisplayClassPrefix = "<>c__DisplayClass";
const string SharedDisplayClass = "<>c";
const string LambdaMethodInfix = "b__";
const string LocalFunctionInfix = "g__";
const string EnumerableStateMachineInfix = "d__";
public static MethodInfo GetLambda(Type parentType, string parentMethod = null, MethodType parentMethodType = MethodType.Normal, Type[] parentArgs = null, int lambdaOrdinal = 0)
private static void RewriteAssembly(string assemblyPath)
{
ModuleDef assembly = ModuleDefMD.Load(assemblyPath);
foreach (TypeDef type in assembly.Types.SelectMany(t => t.NestedTypes.Concat(t)))
{
type.Attributes &= ~TypeAttributes.VisibilityMask;
if (type.IsNested)
{