More Quality Scaling

by sh4dow

Extends quality scaling to locomotives, wagons, storage tanks, rocket silos, roboports and more.

Content
an hour ago
2.0
5.98K
Transportation Logistics Trains Mining Fluids Logistic network Power Storage

b Accidentally changes mod entities

a day ago
(updated 23 hours ago)

Hi! Just wanted to let you know that the mod accidentally creates new entities for the thermal solar panels from my mod Thermal Solar Power (Lite). They use the reactor prototype and won't be affected if the setting Heat pipe/reactor scaling is disabled. The Change mod entities setting makes no difference. You can read more in this thread.

The above creates a few issues: The new variants won't be recognized by my mod, so the script that generates heat can't be applied to them. And if the relevant setting is ever disabled, or the mod is uninstalled, the higher tier variants of the thermal panels will just disappear. I can create a compatibility fix for the first issue, but probably not for the second. EDIT: Another small issue: The replacement also happens without raising an event from the destroy() function, so my mod's storage table fills with non-existing entity IDs. Not sure yet whether I can fix that myself.

I figure it would be best if this mod avoids changing the thermal panels, which are outside of its intended scope.

11 hours ago

Alright, so there are 4 separate issues:
a) "qualitized" versions of thermal solar panels not working
Fixing that would need specific logic on either end (either your mod looking for the quality variants, or my mod blacklisting these specific entities)
I would find it more elegant if your mod could handle the quality versions of the entities, but if you'd prefer otherwise, I'll think about how best to implement the blacklist: I could simply hardcode exceptions, but some interface for other mods to blacklist "technical" entities (ie. those requiring script support) would be more flexible. Giving the user the choice would in principle be desirable, but would add even more settings...
I guess either way, there should be some standardized way for how to deal with a mod making copies of script-dependent entities of another - either through a "my mod made a copy of this with that name - apply your script to that as well" interface (called from the modifier), or at least a "be careful with modifying and/or copying this entity" flag set by the entity creator.

b) entity loss on setting changes
Not trivial to mitigate, since you can't use migration scripts for setting changes. Keeping the internal entities for unmodified types would unnecessarily use up startup time and memory, but without those, my mod doesn't get any chance to react to the lost entities. I guess I could keep an internal table of all modified quality entities as well as previous startup settings, and on setting change go through the table and restore the normal quality machines, though that would still lose modules/items inside those machines, not to mention circuit connections, reactor temperature,...
Another option would be to add commands to revert categories to the base entities before switching off the startup setting - the same logic could then also be used to retroactively apply quality bonuses to existing entities, if desired, but communicating this process to the user might be non-trivial...

c) replacement events
I'm using the fast-replace option of create_entity, so eg. blueprint configuration automatically carries over - I'm setting raise_built = true, but apparently that doesn't fire a destroy event...
Do you know if that is the same behavior as for manual fast-replace? If so, your logic would need to factor in built events anyway (and including on_script_built in there shouldn't complicate that logic); otherwise, I should probably implement a custom event to let other mods know... Is there some standard for sending "my mod replaced your entity" events?

d) change mod entities inconsistent behavior
The "change mod entities" setting was mostly left over from earlier versions, since the way I implemented this for eg. trains didn't carry over as well for entity types with more individual entities. Currently, it affects only some categories (eg. trains, storage tanks, roboports), but not others (eg. belts, reactors, mining drills). I should probably either discontinue this option, replace it with a more granular "enforce whitelist per type" option or at least change the implementation to reference some compact export of vanilla/spage entity names, so it's consistent over all categories.

7 hours ago

Thank you for the detailed response, I really appreciate it! I will go over it all carefully, do some additional testing and consider what specifically I want to request of you.

Quick question, does the event on_script_built really exist? I can't find it in the API. Maybe you are referring to script_raised_built, which I already use? (I account for 6 build and 7 destruction events.)

6 hours ago

sorry, yes, you are right on that event name.

If fast replace in general doesn't send any destroy signal, then you would have to remove replaced entities from your storage table inside the corresponding on_built_entity/script_raised_built anyway. If it usually does send a signal, I could manually raise a custom event for you to react to.

5 hours ago
(updated 5 hours ago)

All right. XD

Regarding manual fast-replacement: I did some testing with your mod disabled, and replacing any quality tier with another works without any issues. The old panel has its ID removed from the storage table, while the new panel has its ID added to it. With the technical variants from your mod enabled, replacement generally isn't possible at all, probably because they lack a shared fast_replaceable_group. Only the normal variant can be replaced. But even then, the script does not apply to the new technical variant.

I have already been working on a compatibility fix on my end: By checking for the presence of your mod, looking up all currently existing quality tiers in prototypes (including those added by other mods, excluding "normal" and "quality-unknown"), building a list of the names of all the technical variants through string concatenation and adding them to a reference list, the script at least applies to them. But the IDs of the entities replaced by your mod remain in my global table, which is not great. And the higher quality variants still disappear when the mod is uninstalled (or its relevant setting is disabled). I want to find a more reliable and generalized solution.

Anyway, still working on things, thinking things over.

5 hours ago

Quick remark: It would certainly be helpful if the relevant destroy function would raise an event, such that other mods can know of its use on their entities by listening to script_raised_destroy. It can be written like .destroy({raise_destroy = true}). I am pretty sure this is also the convention: The responsibility is on the mod that destroys entities from other mods, to signal that it happened. For some reason, this requires explicit code.

I modified the code of your mod like that and found that it at least solves the issue with storage table bloat.

3 hours ago

The destroy not raising an event is a legitimate oversight on my part. I expected qualitized entities to usually fast replace with their original, since they are just clones, and should inherit the fast replace category of the original.
Are you setting the fast replace category in data-final-fixes, or do the different panel tiers no longer fast replace with each other?

3 hours ago
(updated 3 hours ago)

Well, my thermal panels don't actually have a fast_replaceable_group declared, because it's not needed. I only have one 3x3 and one 9x9 panel, and the game sorts out the replacement with different quality tiers on its own. But that changes with the "qualitized" variants. The base variant can be fast-replaced, but I don't exactly know why even that is possible, when any other combination/sequence doesn't work. They get a "Thermal solar panel is in the way" message, while original higher quality variants (placed before mod activation) won't get any feedback at all (just the same red color overlay).

3 hours ago

I made a release with the raise_destroy bugfix, as well as an overhaul of the "ignore mod entities" functionality.

Concerning issue a), I added a mod data entry data.raw["mod-data"]["entity-clones"] that, in its data, contains a table mapping original entity names to lists of their clones.
In practice, you could simply read eg. data.raw["mod-data"]["entity-clones"].data["thermal-solar-panel-1"] for a list of the quality versions of it - and, should this catch on, maybe also eventually copies made by other mods.
I now also look at data.raw["mod-data"]["clone-blacklist"] before making my quality copies, so you could stop my mod affecting your entities in that way if necessary.

Unless there are some further issues, this should leave only issue b) open.

2 hours ago

Now actually online, after I fixed some typos.

2 hours ago
(updated 2 hours ago)

You move fast! I am still reading our discussion and mulling over what exactly I want to accomplish. XD

But this seems like a very fine solution (I did not know about "mod-data"!). This should allow me to immediately exclude just my thermal solar panels from being affected by your mod, while still giving me opportunity to create compatibility for it later.

I just downloaded the new version to try it out, but I get a crash with a message:


Failed to load mods: more-quality-scaling/data-final-fixes.lua:24: attempt to index field 'mod-data' (a nil value)
stack traceback:
more-quality-scaling/data-final-fixes.lua:24: in main chunk
Mods to be disabled:
- more-quality-scaling (1.4.8) [ ] Reset mod settings.


an hour ago

Interesting - maybe the mod-data section of data.raw isn't initialized if no other enabled mod adds any mod-data?
Should be fixed in 1.4.9.

4 minutes ago

It partially works now. But the game crashes when I try to write to the "clone-blacklist", and I can't make it work no matter what. Is it still WIP?

New response