Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - CosmicDan

#1
Outdated / Re: [A17] cuproPanda's Mods (28 Jun 17)
June 29, 2017, 05:29:30 PM
Quote from: cuproPanda on June 29, 2017, 02:00:16 PM
I had every intention of renaming my defs. Instead of redefining BuildingBase, for example, I was going to change it to QuarryBuildingBase, etc. That way, I got the base I was expecting without affecting other mods.

Oh, you are? That wasn't clear to me, either. Because this is indeed a good thing - there's absolutely nothing wrong with that (mostly - worst case scenario is your mod doesn't inherit some base patches that other mods do - but that is completely your prerogative, nothing really wrong with that).

I could have figured as much though I suppose, like all your other def's are prefixed with "POW_" already.
#2
Outdated / Re: [A17] cuproPanda's Mods (26 Jun 17)
June 29, 2017, 05:20:24 AM
Quote from: cuproPanda on June 29, 2017, 03:27:16 AM
Quote from: CosmicDan on June 28, 2017, 07:12:20 AM
Quote from: cuproPanda on June 28, 2017, 01:44:58 AM
It seems like the best bet is to keep the bases as they are. If a mod loaded before mine changes a base - like BuildingBase - and I simply inherit the same base, I inherit the changes the previous relevant mod made. If, however, I redefine the base as it looks in the Core defs, I not only get the base I was expecting, but I also reset the base for future mods.

So you not only want to ignore inheritance but you also want to play policeman on other people's modding? People can still just change everything with patches since they're loaded last, all you're doing is introducing unexpected behavior and making more work for yourself.

The stupid crap that other people do in modding isn't your concern - if anybody completely overrides base classes then they should be shamed for it. It's just completely unnecessary and causes more issues than it solves.

But suit yourself, who am I to complain - your mods are still good. Just don't be surprised when this bites you in the butt with someone raging about how long it took for them to narrow down a compatibility bug that was caused by it!

I'm trying to remove issues other mods will cause with my mods. I'm the one who has to hear it from people when they find an issue with one of my mods. If the issue is caused by a different mod changing the defs in unexpected ways, how am I supposed to fix the problem? If a user is having an issue with one of my mods, I go looking for the problem both in my code and in my modded playthrough. If I'm not using the mod in question, I'll never see the issue, which means I'll never be able to fix it. So yes, stupid crap other people do is a little bit my concern, because that stupid crap has a direct impact on my mods. It's not like I'm doing anything harmful - I'm getting the bases as I expect them to be in order for my mods to work the way they should. This is how all mods used to operate, and how quite a few still do.

I understand your reasoning. It is a bit disappointing to hear but I guess as you say it's not really a big deal for others (as long as you keep those base classes 100% in line with the core). I meant no disrespect, of course I appreciate and thank you for the great work you have done :) Thanks for not blowing up at my blunt confrontation on the matter.
#3
Outdated / Re: [A17] BlackFuel
June 29, 2017, 01:13:18 AM
Ok, I've also noticed that the Coal Scuttles don't really do anything either - they just act as storage spots.

I can mod the CompPowerPlant class in C# and make it pull from the hopper, won't be too difficult ;)

You do ask for permission to modify but you're not around and I'm really impatient so I'm going to go ahead and do this, hope you don't mind!

Will upload to GitHub and share the repo link with you, so you can see the exact changes I've done.
#4
Outdated / Re: [A17] cuproPanda's Mods (26 Jun 17)
June 28, 2017, 07:12:20 AM
Quote from: cuproPanda on June 28, 2017, 01:44:58 AM
It seems like the best bet is to keep the bases as they are. If a mod loaded before mine changes a base - like BuildingBase - and I simply inherit the same base, I inherit the changes the previous relevant mod made. If, however, I redefine the base as it looks in the Core defs, I not only get the base I was expecting, but I also reset the base for future mods.

So you not only want to ignore inheritance but you also want to play policeman on other people's modding? People can still just change everything with patches since they're loaded last, all you're doing is introducing unexpected behavior and making more work for yourself.

The stupid crap that other people do in modding isn't your concern - if anybody completely overrides base classes then they should be shamed for it. It's just completely unnecessary and causes more issues than it solves.

But suit yourself, who am I to complain - your mods are still good. Just don't be surprised when this bites you in the butt with someone raging about how long it took for them to narrow down a compatibility bug that was caused by it!
#5
Mods / Re: What would make the game easier to mod?
June 28, 2017, 12:36:54 AM
Quote from: CosmicDan on June 28, 2017, 12:22:36 AM
I like how Tynan asked if modders could talk together about the major important things, but then almost a year later we still have newbie modders asking for every single little hardcoded thing to be moved out of the code and into XML...

Guys, just learn C#. Seriously, it's not THAT hard. This is the most modable game without direct programming knowledge I've ever seen (except maybe for Westwood's old C&C games), and so many are STILL unhappy  ::)

Quote from: JT on June 26, 2017, 09:04:01 AM
Currently, the only error produced if a PatchOperationSequence fails is: "[modName] Patch operation Verse.PatchOperationSequence failed"

[snip]

It's pretty easy to just diagnose this yourself. Just move each operation outside of the PatchOperationSequence and see which one fails. "(The) entire mod has to be discarded and then reassembled piecemeal" is a massive exaggeration - you dont NEED to have them inside a PatchOperationSequence to work; the whole point of PatchOperationSequence is to do multiple patches based on preconditions. But when you're developing yourself, you're in full control of the preconditions and environment. So just move them outside of the sequence to debug yourself - it's not that complicated.

Quote from: Weyrling on June 27, 2017, 02:42:28 PM
Quote from: kaptain_kavern on June 16, 2017, 11:47:07 AM
With the new patching possibility it could be nice to have way of triggering a patching "when something happen" in game. Like a research or a comp...
I'm not sure how you think this should work, but trying to patch files during run time would be a lot more complicated than it sounds.

I imagine what you want is the ability to replace a thing with a different thing when a condition is met, which could be useful for a ton of things.

This is already possible, it's called "write it in C# and compile an assembly". Patching is for modifying XML definitions, but you're trying to do runtime logic. You can't do runtime logic in definitions - this is the whole point of coding.

And if you think that's too hard, it really isn't. I've modded a lot of games in the past, and the RimWorld wiki with Harmony library and Visual Studio is some of the easiest and most powerful modding I've ever seen. Two days ago I didn't even know C# (albeit I am a Java developer by profession) and today my WIP mod replaces Steel with Iron Ore and makes Iron Ore > Steel production (done only via XML and Patches) and I've also managed to make Charcoal from cuproPanda's Powerless! Mod and Coal from Black Fuel mod act as a fuel that is 3x as potent a fuel source as wood (done via C# and the Harmony library).


Considering how great the Harmony library is, there are so many requests here that I really don't think are important at all - they can all already be done, even if it's in some slightly roundabout or awkward way. What WOULD be nice is a pre-patch system that runs before XML loading, or some kind of automatic *Def Name attribute resolution so we can use ParentDefName="AParentThingDefToInheritFrom" for def inheritance - but the chances of developers ever seeing these serious technical requests are likely slim because everyone spams all these open-ended and vague wishes that are extremely novice things that only lazy or unpracticed people would have trouble with.

No offense, it's just frustrating seeing so few legitimate concerns that are lost in the screams of amateurs.
#6
Mods / Re: What would make the game easier to mod?
June 28, 2017, 12:22:36 AM
I like how Tynan asked if modders could talk together about the major important things, but then almost a year later we still have newbie modders asking for every single little hardcoded thing to be moved out of the code and into XML...

Guys, just learn C#. Seriously, it's not THAT hard. This is the most modable game without direct programming knowledge I've ever seen (except maybe for Westwood's old C&C games), and so many are STILL unhappy  ::)

Quote from: JT on June 26, 2017, 09:04:01 AM
Currently, the only error produced if a PatchOperationSequence fails is: "[modName] Patch operation Verse.PatchOperationSequence failed"

[snip]

It's pretty easy to just diagnose this yourself. Just move each operation outside of the PatchOperationSequence and see which one fails. "(The) entire mod has to be discarded and then reassembled piecemeal" is a massive exaggeration - you dont NEED to have them inside a PatchOperationSequence to work; the whole point of PatchOperationSequence is to do multiple patches based on preconditions. But when you're developing yourself, you're in full control of the preconditions and environment. So just move them outside of the sequence to debug yourself - it's not that complicated.

Quote from: Weyrling on June 27, 2017, 02:42:28 PM
Quote from: kaptain_kavern on June 16, 2017, 11:47:07 AM
With the new patching possibility it could be nice to have way of triggering a patching "when something happen" in game. Like a research or a comp...
I'm not sure how you think this should work, but trying to patch files during run time would be a lot more complicated than it sounds.

I imagine what you want is the ability to replace a thing with a different thing when a condition is met, which could be useful for a ton of things.

This is already possible, it's called "write it in C# and compile an assembly". Patching is for modifying XML definitions, but you're trying to do runtime logic. You can't do runtime logic in definitions - this is the whole point of coding.

And if you think that's too hard, it really isn't. I've modded a lot of games in the past, and the RimWorld wiki with Harmony library and Visual Studio is some of the easiest and most powerful modding I've ever seen. Two days ago I didn't even know C# (albeit I am a Java developer by profession) and today my WIP mod replaces Steel with Iron Ore and makes Iron Ore > Steel production (done only via XML and Patches) and I've also managed to make Charcoal from cuproPanda's Powerless! Mod and Coal from Black Fuel mod act as a fuel that is 3x as potent a fuel source as wood (done via C# and the Harmony library).

Considering how great the Harmony library is, I don't consider *any* of these features as important - they can already be done. What WOULD be nice is a pre-patch system that runs before XML loading, or some kind of automatic *Def Name attribute resolution so we can use ParentDefName="AParentThingDefToInheritFrom" - but the chances of developers ever seeing these serious technical requests are likely slim because everyone spams all these open-ended and vague wishes that are extremely novice things that only lazy or unpracticed people would have trouble with.

No offense, it's just frustrating seeing so few legitimate concerns that are lost in the screams of amateurs.
#7
Quote from: wwWraith on June 27, 2017, 08:04:25 PM
Quote from: CosmicDan on June 27, 2017, 05:46:32 PM
Now, if only there was a way to do some kind of "prerequisite" XML patching, that'd be awesome (even if it only allows insertions). I just found out that you can inherit from any Def that has a Name attribute set, not just Def's that have abstract flag set! So I was thinking it'd be great if you could, say, have an XML patch run that injects Name="ElectricSmelter" to the base ElectricSmelter def, then in your mod XML you could set Parent="ElectricSmelter" to quickly make a custom smelter - override whatever tags necessary.

I think it could be done by setting Parent as attribute also in the same patch after you injected Name.

Hmm, that's not a bad idea. Because after the patching is done, all the XML needs to be "refreshed" anyway. So theoretically that could work, but it will very likely throw config errors due to incomplete XML in the pre-patch phase of mod loading.

I'm just getting into the Harmony library at the moment though (man this is some powerful stuff, and so much easier than Java's ASM library) so I might be able to make a mod that does this anyway. Maybe it's something worthy to go into HugsLib if not the base game...

EDIT: Actually it's not quite that easy, Verse.XmlInheritance is a bit more complicated than I thought...

EDIT2: I could probably hook onto Verse.XmlInheritance#TryRegister postfix but I'm wondering if there's a downside to this (apart from a possible load time increase)...
#8
Outdated / Re: [A17] cuproPanda's Mods (26 Jun 17)
June 27, 2017, 06:40:08 PM
Quote from: wwWraith on June 27, 2017, 04:10:17 PM
Quote from: cuproPanda on June 27, 2017, 03:33:00 PM
Unless it has changed in the newest alpha, all mods need to put the bases into their defs. We can't just fetch the ones from the core defs
So I'm pretty sure it was changed. I made some mini XML mods for myself just fetching bases from the core defs without copying them even in A16. And sometimes I just commented the sections that redefined the bases in other people's mods when some other mod redefined them for a good reason. And all worked fine.

It's definitely changed. I had no idea that cupro was re-defining ResourceBase, even - I did not need to (I literally just started modding RimWorld yesterday haha) and it works perfectly fine.

Quote from: cuproPanda on June 27, 2017, 04:09:21 PM
If this is the case, I need to go through and remove a bunch of stuff, and make sure to change the base names of the ones I need. Thank you for letting me know, I have a lot of changes to make :)

No problem! I've already done some minor changes and cleanups in the fork I made if you want to check out the commit log. Let me know if you want me to make a PR, or you can just cherry-pick whatever you want of course.

Of particular note, for your reference, is my patch to inject the POW_Forge recipes into any weapon. xpath is pretty cool! The patch in question will find any item that can be crafted at a FueledSmithy, and if so then it will also inject the POW_Forge as a recipeUser entry. Very cool - automagical mod integration :D
#9
Quote from: wwWraith on June 27, 2017, 04:14:53 PM
May be it's better not to delete this because a lot of mods still copying the bases defs and it could be a cause of incompatibilities, their authors should have this information.

Really, it's that much of a problem? So maybe I should turn this into some kind of PSA thread heh...

Now, if only there was a way to do some kind of "prerequisite" XML patching, that'd be awesome (even if it only allows insertions). I just found out that you can inherit from any Def that has a Name attribute set, not just Def's that have abstract flag set! So I was thinking it'd be great if you could, say, have an XML patch run that injects Name="ElectricSmelter" to the base ElectricSmelter def, then in your mod XML you could set Parent="ElectricSmelter" to quickly make a custom smelter - override whatever tags necessary.

Or, even easier, if the RimWorld mod API just implicitly added a Name attribute to any *Def tags that don't already have one, just copied from the defName...

...Do the dev's check this forum much? :D Maybe they already have these suggestions or plans.

EDIT: Done. For posterity's sake, here was the original thread before I re-wrote it:

Hi, wondering if someone semi-experienced in modding can help me real quick

I'm just going through the XML of the great "Powerless!" mod with the intention of making a "modpack" (a compatibility/integration mod) and I've noticed that the mod re-declares some base defs in e.g. ThingDefs_Bases.xml. Stuff like BaseMeleeWeapon, PlantFoodRawBase, quite a lot of stuff actually (it's quite daunting).

Am I correct in assuming that this does not replace the core abstracts, but rather redefines them for future use with the intention of being placed early in the load order? I.e., so any other mods that use these base classes will inherit the changes that Powerless! made instead of from the core game?

Hope that makes sense :)

If this is true, which I'm assuming it is, can anybody think of why this was done in this case? Is there a legitimate reason to not patch these base classes so that even the core stuff takes advantage of it yet mod-added stuff will (seems like an inconsistency IMO)? Or is it perhaps just something that cuproPanda hasn't had time to update to the new XML patching stuff (maybe I'll have to ask him/her if they are around)?

Thanks :D
#10
Outdated / Re: [A17] cuproPanda's Mods (26 Jun 17)
June 27, 2017, 03:57:36 PM
Quote from: cuproPanda on June 27, 2017, 03:33:00 PM
Quote from: CosmicDan on June 27, 2017, 03:19:22 PM
Hey cuproPanda,

I'm wondering if you have time to answer my question. I'm making an integration/compatibility patch designed for a modpack and in going through your Powerless! mod (awesome stuff btw), I've noticed that you redefine a lot of base classes instead of patching. Is there a specific reason for this (or have I noobed-it-up and misunderstood the effect)? Or should these ideally be migrated to new patches?

I asked about XML inheritance/load order referencing your mod in a new thread here, just in case you're not around - would be great if you could check it out to get a better explanation.

EDIT: I just read your last post, I guess this is the reason (for the weapons at least) or related? If so, what about all the other stuff like PlantFoodRawBase? I don't quite understand why your crops need to inherit an overridden abstract. The only thing it seems you want to do is remove the food poisoning from your crops, but could you not have just written a new abstract which redefines the properties you want to change instead? Or are these Def's from a time where it wasn't possible for Abstract to inherit from another Abstract or something?

Unless it has changed in the newest alpha, all mods need to put the bases into their defs. We can't just fetch the ones from the core defs

Oh wow, that's pretty limited! Not sure when but it's no longer the case, thankfully, as I've noticed in my own modding. I just now tested it in your mod; I removed your "PlantFoodRawBase" definition completely, then removed the nutrition = 0.4 from Turnip so it *should* inherit nutrition = 0.5 from the core PlantFoodRawBase, which it indeed does :)

According to what I've read, this also means that any mod loaded after yours will be using your PlantFoodRawBase definition instead of the core game (makes sense to me too, that's how modding should work) so that's a possible problem... e.g. there will be no food poisoning on any mod-added PlantFoodRawBase that come after your mod. I'm not 99% sure if this is what RimWorld mod API does but it should inherit from earlier mods so it's safe to assume so.

You've got the most permissive (non-)license in existence so I've gone ahead and forked your repo to convert all this stuff into patches so it's more compatible/integrated with other mods, you can take a look when you decide to update  the main build for A18.
#11
Outdated / Re: [A17] cuproPanda's Mods (26 Jun 17)
June 27, 2017, 03:19:22 PM
Hey cuproPanda,

I'm wondering if you have time to answer my question. I'm making an integration/compatibility patch designed for a modpack and in going through your Powerless! mod (awesome stuff btw), I've noticed that you redefine a lot of base classes instead of patching. Is there a specific reason for this (or have I noobed-it-up and misunderstood the effect)? Or should these ideally be migrated to new patches?

I asked about XML inheritance/load order referencing your mod in a new thread here, just in case you're not around - would be great if you could check it out to get a better explanation.

EDIT: I just read your last post, I guess this is the reason (for the weapons at least) or related? If so, what about all the other stuff like PlantFoodRawBase? I don't quite understand why your crops need to inherit an overridden abstract. The only thing it seems you want to do is remove the food poisoning from your crops, but could you not have just written a new abstract which redefines the properties you want to change instead? Or are these Def's from a time where it wasn't possible for Abstract to inherit from another Abstract or something?
#12
I just started modding the other day (A17b has already been out for some time) and discovered a peculiarity when working with another mod - core def's being re-declared inside the mod itself. Apparently this was how you had to do it before A17 (or possibly older). Oh, the horror! Apparently a lot of modders are not aware that they can directly reference def's from other "packages" now. The benefits of doing so are obvious.

So, I may be a brand new modder but after looking through some prominent mods, I feel it very necessary to raise awareness of two important things...

1) XML inheritance is a new fantastic thing. Don't copy-paste Core (or other mod) Def's into your own mods - you can set your ParentName attribute to any other Def with a Name attribute and it will inherit (copy) all of it's nodes as a base (as long as your mod is loaded after whatever mod the parent is from). You then only need to (re)define the nodes that you want to change, add or remove (FYI, you can remove with empty nodes e.g. <nutrition/>).

Also remember that you can inherit from *any* named def, it does NOT have to be abstract. Aside: It would be great if Ludeon made a change so that every *Def with a defName childnode could be loaded with a runtime-generated Name attribute that matches it's defName (if not already taken) - this would make inheritance even more powerful.

2) Patching and xpath criteria. I don't think a lot of people understand how the xpath stuff works, they just copy-paste other stuff and hack it with a vague understanding. As mentioned in the thread that warns about xpath performance, I feel I need to first reiterate that:

  • //ThingDef[defName="someDefName"]
    Recursively searches an unlimited number of child nodes for ThingDef nodes containing <defName>someDefName</defName>. Very slow and completely unnecessary. This is like searching a lot of text for a relatively common string.
  • */ThingDef[defName="someDefName"]
    Will search child nodes that are nested ONE level ONLY named ThingDef and containing <defName>someDefName</defName>. The * is a wildcard, meaning match any single node. Very fast and how it should be done.


Now, about the "wildcard-like xpath patching" I mention. I see a lot of mods xpathing partially, but in a round-about way. Example:

<Operation Class="PatchOperationInsert">
<xpath>//ThingDef[defName = "FueledGenerator"]/comps/li[@Class = "CompProperties_Refuelable"]/fuelFilter/thingDefs/li</xpath>
<value>
<li>Coal</li>
</value>
</Operation>


In case it wasn't obvious, the intention here is to inject an additional fuel source of Coal (sorry and no offense to the modder who did this - many modders seem to do it this way so I don't blame you) which is repeated similarly a few more times for other machines that use WoodLog as a fuel source. This is not optimal - why not just find every ThingDef that already uses WoodLog as a fuel source, and then inject upon them? There's no reason why you'd not want Coal to be a fuel source for everything! Here's how you'd do that:

<Operation Class="PatchOperationSequence">
<success>Always</success>
<operations>
<li Class="PatchOperationTest">
<!-- Only add if this is a machine that has WoodLog as a fuel source already -->
<xpath>*/ThingDef/comps/li[@Class = "CompProperties_Refuelable"]/fuelFilter/thingDefs/li[text() = "WoodLog"]</xpath>
</li>
<li Class="PatchOperationTest">
<!-- Skip if already patched -->
<xpath>*/ThingDef/comps/li[@Class = "CompProperties_Refuelable"]/fuelFilter/thingDefs/li[text() = "Coal"]</xpath>
<success>Invert</success>
</li>
<li Class="PatchOperationAdd">
<!-- Inject Coal fuel source alongside WoodLog -->
<xpath>*/ThingDef/comps/li[@Class = "CompProperties_Refuelable" and fuelFilter/thingDefs/li[text() = "WoodLog"]]/fuelFilter/thingDefs</xpath>
<value>
<li>Coal</li>
</value>
</li>
</operations>
</Operation>


Comments should make that pretty self-explanatory. Simples! To everyone who hasn't learned about XPathing, I highly suggest the W3CSchools tutorial at least (although it doesn't seem to mention text() and other node tests which is curious, info about them can be found here).

Aside: Regarding the Coal, I'm working on a mod which makes Coal and Charcoal three-time as potent a fuel source as Wood Logs, among many other things (I only just started learning C# yesterday, and coming from Java + ASM for Minecraft modding, this .NET and Harmony library is an absolutely beautiful change and I can't get over how easy this game is to mod... just look at it <3).




I hope this thread gets some exposure so we can see modders making their work as compatible and optimized as possible :)
#13
Outdated / Re: [A17] BlackFuel
June 27, 2017, 03:39:17 AM
Hi,

Nice work on this, love the idea.

I am wondering if it's OK with you for me to use/host this in a modpack I'm working on (it will be hosted on GitHub)? It is a modpack in similar vein to Hardcore SK except less "heavy" and more lore-friendly.

If so, I would also like to modify it a bit with my own integration patch - specifically to move it into a "Carbon/Fuel" category along with Charcoal (from cuproPanda's Powerless!) so they both can be used as generic fuel and as carbon sources for refining iron into steel.

This will come in my own patch, I don't have to modify or even host your mod on the GitHub repo if you don't want to give permission for that. Thanks either way!

EDIT: Another problem; you're using recursive xpath matching (e.g. "//ThingDef", this is really really slow and bad. Use wildcard matching on the root node (e.g. "*/ThingDef") instead.

EDIT2: Actually, it's better to just do a conditional patching to check if a ThingDef accepts WoodLog as fuel, and if so then inject Coal as a fuel source too. If you want help on how to do this I would be happy to show you :)