[1.0] Rim of Madness - Bones V2.0

Started by SihvMan, May 18, 2017, 04:39:38 AM

Previous topic - Next topic

SihvMan

Quote from: Canute on June 29, 2017, 12:50:45 PM
Hi SihvMan
i am geting this error.
[Bone Mod] Patch operation Verse.PatchOperationAdd(*/ThingDef[defName = "ElectricCrematorium"]/recipes) failed
Verse.Log:Error(String)
Verse.PatchOperation:Complete(String)
Verse.LoadedModManager:LoadAllActiveMods()
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.Root:<Start>m__84E()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__84C()


Yeah, this frustrated me for a bit. Turns out, xpath is much more case sensitive than most RW Def files. [defName] needs to be [DefName] in the xpath, because the Crematorium uses <DefName> instead of <defName> I'll upload the fix shortly.

Flimflamshabam

Nice mod, saved my ass in an Ice Sheet biome run. like 90% of the base is made of bone right now about 40% of that thrumbo, 50% human, and the last 10% assorted polar animals and cargo pods. Shame modded creatures apparently have no bones, heh.

DiamondBorne

Does this mod allows me to broke down those desiccated corpse into bones?

Canute

No,
because you can't butcher them.

Nightinggale

I love this mod, but it sort of breaks when being used with mods, which adds animals. It's not really useful when the majority of animals fail to provide bones. I decided to quickly write my own little mod to add bones to more animals. Before I even started, I realized that would take forever.

Plan B was to write a script to do it for me. I did so and sure enough it generates patch xml files. I wanted to share that, but it turned out to be completely useless for distribution because it causes errors if the animals aren't there. This means it would require one mod for adding bones to each animal mod. That would get messy in no time.

Studying the features usable in patches, I started experimenting with PatchOperationSequence. I managed to get it to a state where it inserts bones if the animal has no bones already. Even more importantly, if the animal is missing, it will fail silently. This means Bone Mod can have one patch xml file for each animal mod and it will just work if Bone Mod is loaded last.

Using this script is really easy. Just copy it into ThingDefs_Races and double click it. It will then generate a new xml file, which you move to Patches and rename. There are more details in the top of the script (it's plain text, just like xml files) and there are some settings, which can be tweaked. Most importantly the amount of bones. I have set it to 50 * body size (rounded down), which seems to be ok from a balance point of view. Remember this just generates the files. The actual numbers can be adjusted by hand afterwards if needed. The script has no way of knowing if the animal is an octopus (no bones at all) or something with a thick exoskeleton.

Since the script is written in perl, you may have to install perl. For windows I recommend strawberry perl. For none-windows, it's usually installed by default.

I also added the generated patch files for AnimalCollabProj and Beasts of the Rim. You should be able to generate them yourself, but since I already got them, I might as well add them.

Technically this would be my first Rimworld mod and it's my first post on the forum, not bad considering I made it in just one evening  :)

Also for the next release, do update the link in About.xml to link to this thread. Right now it goes to the forum frontpage if you click the link, which is supposed to go to this thread.

[attachment deleted by admin: too old]
ModCheck - boost your patch loading times and include patchmods in your main mod.

SihvMan

Ahhh.... I'm finally back to RW. Now to check my mod, surely nothing has -
Quote from: Nightinggale on October 09, 2017, 09:17:28 PM
-SNIP-

Studying the features usable in patches, I started experimenting with PatchOperationSequence. I managed to get it to a state where it inserts bones if the animal has no bones already. Even more importantly, if the animal is missing, it will fail silently. This means Bone Mod can have one patch xml file for each animal mod and it will just work if Bone Mod is loaded last.

Using this script is really easy. Just copy it into ThingDefs_Races and double click it. It will then generate a new xml file, which you move to Patches and rename. There are more details in the top of the script (it's plain text, just like xml files) and there are some settings, which can be tweaked. Most importantly the amount of bones. I have set it to 50 * body size (rounded down), which seems to be ok from a balance point of view. Remember this just generates the files. The actual numbers can be adjusted by hand afterwards if needed. The script has no way of knowing if the animal is an octopus (no bones at all) or something with a thick exoskeleton.

Since the script is written in perl, you may have to install perl. For windows I recommend strawberry perl. For none-windows, it's usually installed by default.

-SNIP-

HELLO! You just became my new favorite person on this forum. A script to autogen patches? That just made compatibility real easy.

QuoteI also added the generated patch files for AnimalCollabProj and Beasts of the Rim. You should be able to generate them yourself, but since I already got them, I might as well add them.

Thanks. I've since made some for TiberiumRim, Megafauna, and Cosmic Horrors. Those should cover the majority of the big creature patches.

Quote
Technically this would be my first Rimworld mod and it's my first post on the forum, not bad considering I made it in just one evening  :)

And what a mod to make! This is excellent.

Quote
Also for the next release, do update the link in About.xml to link to this thread. Right now it goes to the forum frontpage if you click the link, which is supposed to go to this thread.

Aaaanndd... fixed.

-------------------------------

Version 1.3 now up. Couple of XML tweaks, added the patches, and this AMAZING BIT OF CODE.


SihvMan


Nightinggale

Maybe it would be a good idea to list the supported mods both in steam and in the ingame mod menu. It would also be a good idea to mention mod load order. However they shouldn't be listed as requirements on steam. That is unless steam supports optional requirements.

Looking at steam, it's not updated yet. The comments request support for Rainbeaus Basic Bridges Fishing Addon. It shouldn't be too difficult to add, though remember that not all sea creatures have lots of bones. Most noteworthy is octopusses, which have none at all. They do however have 3 hearts and 9 brains (one central and one at the base of each arm).

It also mentions Shear Those Corpses ACP. I would love to see that and if I'm not mistaken it's just one more line for each creature in the patch files. The question is what to add. Presumably it's some data in xml, which needs to be copied.
ModCheck - boost your patch loading times and include patchmods in your main mod.

Nightinggale

#69
As you most likely all know, when butchering, the bones are taken to the stockpile while the meat is left behind. I took a look at the C# code to see if it can be fixed and I think I figured it out, though I'm not 100% sure.

The interesting code is in Source\Verse\Thing\Corpse.cs
public override IEnumerable<Thing> ButcherProducts( Pawn butcher, float efficiency )
{
foreach( var t in InnerPawn.ButcherProducts(butcher, efficiency) )
{
yield return t;
}
// some code to make colonists unhappy when butchering humans

It's actually fairly simple. It just loops ButcherProducts and then returns the yields. My guess is that each time it returns something, it is put into the hands of the butcher, which will cause the item already held in the hands to be dropped. Vanilla then has leather, meat in that array and since meat is last, that is what the butcher will end up with. However now we mod it to become "leather, meat, bone".

The next question is how do we get it to become "leather, bone, meat"? I would say copy the concept from MinifyEverything. Simply put, it has a function, which executes once all mods have been loaded and updates the minify bool and it does so in a single 60 line C# file. The interesting function is just 25 lines.

Say we have a function, which is called once at startup. What it should do would be to find all things with ButcherProducts. Loop it and store the meat in a temp variable. Then remove it from the list and append the temp variable to the end.

If there is such a function, which executes anyway, we might as well use it to add the bones automatically. Ge the number of bones like this:

  • 50 * body size
  • if defined, multiply with BoneModifier
  • if defined, add BoneAppend
  • append bones to ButcherProducts if the number is > 0
BoneModifier and BoneAppend are then a double and an int from xml, which can be used to modify each creature (human or animal). For instance setting BoneModifier = 0 for robots and androids would be the right approach. This can be done either by the original mod or as patches.

Likewise we can shear animals while butchering like I mentioned in the previous post.
  <ThingDef ParentName="AnimalThingBase">
    <defName>Muffalo</defName>
    ....
    <comps>
      <li Class="CompProperties_Milkable">
        <milkDef>Milk</milkDef>
        <milkIntervalDays>2</milkIntervalDays>
        <milkAmount>12</milkAmount>
      </li>
      <li Class="CompProperties_Shearable">
        <woolDef>WoolMuffalo</woolDef>
        <shearIntervalDays>25</shearIntervalDays>
        <woolAmount>100</woolAmount>
      </li>
    </comps>

It doesn't look like it's hard to read if the animal can be sheared, just look for CompProperties_Shearable. Just read the data there and add the item and amount. We could argue that maybe you only get half because it would be pure luck to get it when the wool is just right, but that's a detail unrelated to the main question: how to implement it.

It should be noted that this implementation requires a lot less maintenance as mods will just default to 50 * body size unless specified otherwise. This means the next animal addon mod will just work without updating Bone Mod.

Since I haven't done anything to even open Rimworld files in an IDE, I will have to say that it's completely untested. However I have a pretty good feeling about this approach and I think it should be with minimal mod conflicts. The only thing I can think of is what I already mentioned: robots. However they will just have to be patched and luckily there are a whole lot less of those than there are of animals with bones.

EDIT: one simple solution to avoiding giving bones to robots would be to skip anything, which doesn't provide any meat when butchering.
ModCheck - boost your patch loading times and include patchmods in your main mod.

Nightinggale

I coded a small mod and attached it here and the plan is that it should be merged into BoneMod itself.

What it does is:

  • Adds a default to bone amount (currently 50)
  • Patches butcher code to provide BoneAmount*body size*missing body parts modifier
  • Patches stats info window for both living and corpse (see attached screenshot)
  • Gives bones lower priority than meat when butchers haul when finished, meaning they will haul meat and leave bones
  • Added ability to patch individual ThingDefs to have a non-default 50 base (currently giving mechanoids a base of 0)
  • Uses Harmony for max mod compatibility
On top of the modifiers for amount of bones written here, it will also multiply with the butcher's efficiency. This means if you have a butcher with lower manipulation or consciousness, he will provide fewer bones, just like he will provide less meat and leather.

This can be used as a standalone mod as well, in which case BoneMod will have to be loaded too. For both merging and using both mods, the patches to add bones in BoneMod should be removed or bones will be provided double. In other words open Patches and remove files. I think the two files, which should remain are BoneRefinePatch.xml and NeolithicBonePatch.xml.

I think I have done what I can/want for this mod. Now it's a question of figuring out if 50 is the right default value for game balance and make patches for modded creatures, which shouldn't provide bones. This is all xml, the layout is already in place in the mod and modding it shouldn't require C# skills or setting up the compiler. I will naturally still be around for bugfixing if that should be needed.

[attachment deleted by admin: too old]
ModCheck - boost your patch loading times and include patchmods in your main mod.

SihvMan

Quote from: Nightinggale on October 23, 2017, 12:58:56 PM
I coded a small mod and attached it here and the plan is that it should be merged into BoneMod itself.

-SNIP-
On top of the modifiers for amount of bones written here, it will also multiply with the butcher's efficiency. This means if you have a butcher with lower manipulation or consciousness, he will provide fewer bones, just like he will provide less meat and leather.

Oh goody! You once again improved this mod four-fold. As far as I'm concerned, you're just as much the author of this as I am.

Quote from: Nightinggale on October 23, 2017, 12:58:56 PM
I think I have done what I can/want for this mod. Now it's a question of figuring out if 50 is the right default value for game balance and make patches for modded creatures, which shouldn't provide bones. This is all xml, the layout is already in place in the mod and modding it shouldn't require C# skills or setting up the compiler. I will naturally still be around for bugfixing if that should be needed.

A little playtesting shows that your changes seem to add bones to even mod added creatures. No patches required except for mechanoids.

Nightinggale

Quote from: SihvMan on October 24, 2017, 07:51:48 PMOh goody! You once again improved this mod four-fold. As far as I'm concerned, you're just as much the author of this as I am.
Heh, conquering RimWorld, one mod at a time  :P

Quote from: SihvMan on October 24, 2017, 07:51:48 PMA little playtesting shows that your changes seem to add bones to even mod added creatures. No patches required except for mechanoids.
It works on modded creatures because it has no concept of core. All it does is look at xml data for the creature being butchered and at that time the game has apparently completely forgotten which mod added it. The result is that everything will act the same way and since nothing has the stat I added, everything goes to the default I added. I planned this to be easy to make compatible with as many mods as possible as well as easy to maintain.

Sadly it's not completely true that it only needs to patch mechanoids. It also needs to patch mods. There is one, which adds more mechanoids, one which adds androids and so on. This means the task of patching is not completely gone, but it's extremely small compared to the task of adding bones. Also you don't have to consider which number to add, because it's 0 for all.

You might consider changing the base number for specific creatures though, like some armored exoskeleton might need a higher baseline like 80. It's not strictly needed, but it can be done without modifying the DLL.

Quote from: SihvMan on May 28, 2017, 07:44:28 PM
Quote from: zanfino on May 28, 2017, 05:37:40 PM
[Bug / Unintended behavior]
When a creature is butchered the cook hauls the bone item rather than the meat. This is by no means game breaking but does potentially cause excess rotting. Without looking at the mod it seems like the bone is about meat in the list.

This is, as far as I can tell, vanilla behavior. It similarly occurs when butchering elephants, where the cook carries tusks first. I'll see what I can on on my end, but no promises. While I'm back working on this, anyone have other bugs/ideas/suggestions to include/fix?
While working on the C# mod for bones, I studied the ButcherProducts in Verse.Pawn. In fact it's the one I patch to add bones. What happens is that it creates a list of items to spawn and then the butcher hauls the first one. The order in vanilla is butcherProducts(xml), meat, leather, all stuff on the body (like cloth) and then I used Harmony to add bones after that. If there is no butcherProducts in xml, meat becomes the first. If there is something, then it will be first.

I have posted a bug report asking to swap the order of butcherProducts(xml) and meat. Hopefully this problem will be gone in A18, not just for this mod, but for good for all mods.
ModCheck - boost your patch loading times and include patchmods in your main mod.

SheiFoxy

I installed perl, used the patch in the races def folder as suggested... it created an autogen bones patch which has only vanilla animals instead of the races I have added....
The query here is... how is it supposed to pull all the mod-added animals from this folder when they are all in separate folders with their own mods?
SheiFoxy's Mods on Steam Workshop
SF Grim Reality ⚝ SF Materials Rebalanced ⚝ SF Traits Expansion ⚝ SF Cave Life

Canute

QuoteIf there is no butcherProducts in xml, meat becomes the first. If there is something, then it will be first.
Let me suggest to put meat allways on the first, so meat get hauled allways.
Because meat is rotable and timecritical at this way. While bones and leather can lay around and build full stacks at this way and are haul efficent this way.