Can I add new variables to base classes like Pawn or NeedsTracker?

Started by thenextguy, December 21, 2017, 12:03:22 PM

Previous topic - Next topic

thenextguy

I am attempting to add a new type of need to all pawns in the game. My concern is that if I create my own MyMod.Pawn that uses my own MyMod.NeedsTracker that has a MyMod.MyNewNeed I would have to overwrite every existing NeedsTracker and Pawn with my own version.

HugsLib and Harmony seem to be only concerned with extending existing functions, but not adding new variables to the classes themselves, so I don't believe they are the solution.

I believe I am coming at this problem from the wrong angle. Do I not need to replace the base classes in order to add data to them? Could a child class of Pawn called PawnWithMyNeed be passed around without its WithMyNeed part being sliced off?

Thanks for your time and consideration of my question! :D

Nightinggale

I'm very interested in the answer to this one as well. I did add BoneStatDef : StatDef to Bone Mod to add one string and it seems to work fine, but I'm less certain with pawns. Also even if it works, what about two mods adding a variable to pawns?
ModCheck - boost your patch loading times and include patchmods in your main mod.

CannibarRechter

Well, you don't really have to do what you are asking. Instead, you can do something like create a Dictionary, indexed by pawn id, that has your values. Only trick is every few thousand ticks you should probably make sure there aren't dead pawns (stale references) in there.
CR All Mods and Tools Download Link
CR Total Texture Overhaul : Gives RimWorld a Natural Feel
CR Moddable: make RimWorld more moddable.
CR CompFX: display dynamic effects over RimWorld objects

Fluffy (l2032)

Good question. The answer is a bit complicated.

You can inherit the base class, `class MyPawn : Pawn`
This lets you add your custom fields, properties, methods, and so forth. Generally speaking, this is the preferred solution. You will, however, need to make sure Pawns are actually created as `MyPawn` class. That is a rather tricky proposition, because you'd need to significantly alter many core defs to use your new class, and would create many mod conflicts. An alternative is to dynamically change the class on game start, which would make your mod more compatible, but it's still quite fragile, and only one mod can do this. What's more, this will store data in the colonists, meaning the save game won't load anymore without your mod.

Mods that (used to) do this; Psychology (PsychologyPawn: Pawn), Better workbench management (MyBill: Bill).

Subclassing is good for adding new races/animals, but not for changing existing functionality.

You could keep additional information in a separate gamecomponent. Personally, I think a more elegant solution to the problem of adding extra functions to a core class is to use extension methods. You can use a game or mapcomponent to store a `Dictionary<Pawn, MyClass>`, and use a static extension method to make calls like `somePawn.MyClass()` point to your class' instance for a specific pawn. This allows any number of mods to work together, and keeps your mods savegame information self-contained. Making sure everything stays correctly synced is a bit more work, but not all that hard.

Mods that do this; Work Tab (Pawn.workSettings()), Better workbench management (I think).


==============================================================

That said, from what you're describing you really don't need to do any of this. If all you want to do is add a need, that's all completely moddable with defs. See the vanilla needs, and for example the drug-related needs on how to add more.

Fluffy (l2032)

Quote from: CannibarRechter on December 21, 2017, 04:24:34 PM
Well, you don't really have to do what you are asking. Instead, you can do something like create a Dictionary, indexed by pawn id, that has your values. Only trick is every few thousand ticks you should probably make sure there aren't dead pawns (stale references) in there.
True. Personally, I purge them before saving and let autosaving handle the timing. Nice and simple.

thenextguy

Quote from: Fluffy (l2032) on December 21, 2017, 04:37:33 PM
Good question. The answer is a bit complicated.

You can inherit the base class, `class MyPawn : Pawn`
This lets you add your custom fields, properties, methods, and so forth. Generally speaking, this is the preferred solution. You will, however, need to make sure Pawns are actually created as `MyPawn` class. That is a rather tricky proposition, because you'd need to significantly alter many core defs to use your new class, and would create many mod conflicts. An alternative is to dynamically change the class on game start, which would make your mod more compatible, but it's still quite fragile, and only one mod can do this. What's more, this will store data in the colonists, meaning the save game won't load anymore without your mod.

Mods that (used to) do this; Psychology (PsychologyPawn: Pawn), Better workbench management (MyBill: Bill).

Subclassing is good for adding new races/animals, but not for changing existing functionality.

You could keep additional information in a separate gamecomponent. Personally, I think a more elegant solution to the problem of adding extra functions to a core class is to use extension methods. You can use a game or mapcomponent to store a `Dictionary<Pawn, MyClass>`, and use a static extension method to make calls like `somePawn.MyClass()` point to your class' instance for a specific pawn. This allows any number of mods to work together, and keeps your mods savegame information self-contained. Making sure everything stays correctly synced is a bit more work, but not all that hard.

Mods that do this; Work Tab (Pawn.workSettings()), Better workbench management (I think).

==============================================================

That said, from what you're describing you really don't need to do any of this. If all you want to do is add a need, that's all completely moddable with defs. See the vanilla needs, and for example the drug-related needs on how to add more.

Thanks for the well thought out answer with many avenues for me to explore. I think I'll look to see how Psychology does it, though I dislike the idea of making my users have to pick between psychology and my mod.