Modifying Bills.

Started by Skraps, October 31, 2015, 09:57:28 AM

Previous topic - Next topic

Skraps

Hey all. I'm new to modding but not programming. Sorry if this is a too noob question for the forum, but I had trouble finding helpful and complete information on the topic. I have an idea for a mod that extends users control over bill creation. I've been reading the decompiled code on how bills work. However I'm not sure how I could extend the capabilities of the bills without modifying the core code or overriding it and having everything that pointed to it changed and so on until the whole game is changed. I assume this is a common problem in modding so I assume there's a known solution, but I can't seem to think of it. The main part of the mod would involve adding additional Bill repeat modes (e.g. do until X) but to actually add new functionality I would need to modify the Bill_Production class. How would I do this? Is there another way?

Fluffy (l2032)

I'm afraid it's going to have to be overwrite the class and everything that points to it.

On a side note, my manager mod does some extension things with bills by automatically adding/updating/deleting bills, which theoretically allows all kinds of start/stop triggers. (right now there's just a thingfilter trigger, which means you can do things like 'up to x of >50% hp and > normal quality', or 'down to 0' for smelting/burning jobs.)


Skraps

Really? That's the only way? Well I think its only a few classes I need to modify. Still, how would I override core classes them with a mod? Also using CCL looks like it would help reduce the number of classes I need to modify and improve comparability with other mods? I not sure how relevant it is to what I plan though.

I've been meaning to try colony manager. My friend I'm working on this with likes it. Sounds like you can do everything we were planning with bills with it though.

Fluffy (l2032)

As far as I know there's no way to 'detour' method calls, so you need to overwrite everything that calls the method you want to change. Then overwrite everything that calls to that, etc. In the case of 'core' functions such as the bill system, this will end up in overwriting significant portions of the game, starting with a custom worktree to call a new workgiver_work, and potentially going as far as changing all workstation buildings to change their ITab_Bills to your custom one.

CCL allows you to easily add things (Comps, usually) to core or other mod's assets, but overriding core code is a massive pain in the arse in most cases, because most things are highly interlinked.

Skraps

#4
Okay so say I change the ShouldDoNow method in the Bill_Production class, would I need to change the WorkGiver_DoBill.JobOnThing method that uses it? To me it would seem to be used in the same way as before (i.e. if ShouldDoNow returns true, do job). Did you have to modify the Bill classes and all that call it for your colony manager. I'll have to have a look at how you did it.

Fluffy (l2032)

Quote from: Skraps on November 02, 2015, 12:38:49 AM
Okay so say I change the ShouldDoNow method in the Bill_Production class, would I need to change the WorkGiver_DoBill.JobOnThing method that uses it? To me it would seem to be used in the same way as before (i.e. if ShouldDoNow returns true, do job).
Yeah, the method signature doesn't change, but the internal logic did. You can't actually overwrite the core method (let's call it method A), it still exists. So in order to make sure your implementation (method B) gets used, you need to change all methods that call method A to now call method B. Just using the same name and signature isn't enough - method B lives in a different assembly (and namespace), and needs to be explicitly called.

Quote from: Skraps on November 02, 2015, 12:38:49 AM
Did you have to modify the Bill classes and all that call it for your colony manager. I'll have to have a look at how you did it.
I circumvent all of this by not actually messing with the Bill classes, but instead having an extra layer on top. The manager just uses the same methods that players use to add/remove/reorder bills.

Skraps

I haven't had much experiences with namespaces so I didn't think of that. I had a look at the source code for your colony manager. So you've just made your own tab and such and not messed with the core too much. I probably wont work on this any more, since your manager seems to do almost everything I was thinking. Still thanks for the help. Just curious, what are the methods that the player's use to add/remove/reorder bills that you talk about? I'm guessing the ability to set thresholds and item condition requirements isn't a part of that.

Fluffy (l2032)

Basically I add/remove bills to the billstack of a workstation, this is the same process as the standard bill window.

Where I deviate is in when to add/remove these bills, by implementing a custom count function that works with a thingfilter (this is the same filter used when setting allowed ingredients for bills), which allows for setting quality and hp thresholds, as well as counting multiple things/categories (e.g. you could produce simple meals while the number of all meals is < 50, to only produce simple meals as a last resort.)

The core 'do until x' method simply counts the number of output products of the recipe that you have (in storage buildings/zones for things that count as resources; also the default in the manager).
This has a few problems;
- Outputs can't always be determined from the recipe (e.g. smelting weapons).
- Doesn't allow 'custom' thresholds, i.e. you can't count down to x for destructive bills (smelting, cremation), you can't set a different thing/category as the threshold, you can't use quality/hp thresholds.

Skraps

Hey, I've been trying out your colony manager and its pretty neat so far. There's a few ideas we had that it seems you haven't done yet. Setting start and stop thresholds (i.e. start crafting when <50 but stop when >60) and a max level restriction, for when you want to raise skill of lower level pawns. Do you think this would be possible in your mod?

Fluffy (l2032)

hey skraps, bit late, but here goes;

I thought about having lower/upper thresholds (thats how it works in Dwarf Fortress, which is the inspiration), but decided against it because I didn't really see the point, it's just more complicated. The switch is now a simple if x < y, with two thresholds you have to start remembering what the last state was and everything. Certainly possible, but I just didn't want to go there at that point. Also, there's some added UI stuff that would be needed, and I already think the UI is cluttered and clumsy (improvements coming for that soon).

As to maximum skill, nope, not without overriding how the vanilla game works. There simply is no check for that in the AI - implementing it might be nice for a Manager 2.0 - if one of three things happens; 
- I (or someone else, open to pull requests!) take on the monumental task of rewriting the whole bill system.
- Tynan adds a max skill field and logic to the bill system.
- Someone figures out how to detour methods (see https://ludeon.com/forums/index.php?topic=16774.0)

The first is unlikely, the second might be. The third is a hard job of coding for which I don't have the skill (looked into it, but this is not something I feel like I can pick up over a weekend (or even week or month). However, if someone ever figures it out it'll seriously change RimWorld modding and make a huge amount of new mods possible (as well as a huge amount of possible bugs and conflicts - with great power comes great responsibility :P )

Skraps

That makes sense. I was thinking thresholds might be good to avoid pawns walking somewhere far away to only do the job once, but it's a rare case and its probably better to make the interface simpler. Still wish you could have max skill though. Hopefully Tynan will add it. Shouldn't be too hard.