Hi! In a large pack (~56k recipes) every finished research after s6x-void-flux costs about 0.1 s in unlock_variants (control.lua), so researching many technologies at once gets slow.
On each on_research_finished it iterates pairs(owner.recipes) and reads owner.recipes[pr].prototype.categories[1] for every recipe, although only the voidcrafting* recipes with a -flx, -qual or -coh variant matter.
A patch below: the list of those base recipes is built once from prototypes.recipe; a finished research checks only the base recipes it unlocks, and the full pass (over the list) stays for s6x-void-flux, s6x-void-coherence, s6x-void-quality, on_technology_effects_reset, on_configuration_changed and /vc_fix_recipes. The loop body is unchanged.
Tested on a copy of a save with ~2000 technologies researched in order: the enabled recipes are the same as with 2.11.0, also after reset_technology_effects() and /vc_fix_recipes; the handler went from ~97 ms to ~0.1 ms per research. One difference: if a base recipe is enabled by another mod's script rather than by a technology, its variant waits for the next full pass.
--- a/control.lua
+++ b/control.lua
@@ -5,6 +5,45 @@
end
end
+-- Base recipes (voidcrafting* categories) that have a -flx, -qual or -coh variant.
+-- Built once on first use: prototypes do not change during a session, so nothing goes to storage.
+local variant_bases = nil
+local variant_bases_set = nil
+
+local get_variant_bases = function()
+ if (not variant_bases) then
+ variant_bases = {}
+ variant_bases_set = {}
+ for pr, proto in pairs(prototypes.recipe) do
+ if (string.sub(proto.categories[1], 1, 12) == "voidcrafting") then
+ if (prototypes.recipe[pr .. "-flx"] or prototypes.recipe[pr .. "-qual"] or prototypes.recipe[pr .. "-coh"]) then
+ variant_bases[#variant_bases + 1] = pr
+ variant_bases_set[pr] = true
+ end
+ end
+ end
+ end
+ return variant_bases, variant_bases_set
+end
+
+-- Base recipes to check: all of them on a full pass (always, or one of the three technologies that switch
+-- the variant kinds on), otherwise only those the finished technology unlocks. A variant unlocked by the
+-- technology itself is enabled by the game.
+local recipes_to_check = function(always, event)
+ local bases, bases_set = get_variant_bases()
+ if (always) then return bases end
+ local name = event.research.name
+ if (name == "s6x-void-flux" or name == "s6x-void-coherence" or name == "s6x-void-quality") then return bases end
+
+ local found = {}
+ for _, effect in pairs(event.research.prototype.effects) do
+ if (effect.type == "unlock-recipe" and bases_set[effect.recipe]) then
+ found[#found + 1] = effect.recipe
+ end
+ end
+ return found
+end
+
local unlock_variants = function(always, owner, event)
local coh_also_enable = {
["s6xvc-voidtronic-circuit"] = "s6xvc-advanced-circuit-coh"
@@ -14,9 +53,8 @@
local coherence = ((not always and event.research.name == "s6x-void-coherence") or owner.technologies['s6x-void-coherence'].researched)
local quality = (script.active_mods['quality'] and not script.active_mods['no-quality']) and ((not always and event.research.name == "s6x-void-quality") or owner.technologies['s6x-void-quality'].researched)
- for pr in pairs(owner.recipes) do
- local rcat = owner.recipes[pr].prototype.categories[1]
- if (string.sub(rcat, 1, 12) == "voidcrafting") then
+ for _, pr in ipairs(recipes_to_check(always, event)) do
+ if (owner.recipes[pr]) then
local fluxized = pr .. "-flx"
if (owner.recipes[fluxized]) then
if (owner.recipes[pr].enabled and not owner.recipes[fluxized].enabled) then
Unrelated small thing: /vc_fix_recipes run from the server console fails on game.get_player(nil) (no player_index).
Thanks for the mod!