Repository navigation
Description
MVCF.Comps.Comp_VerbGiver.PostExposeData scribes its tracker under the node name "verbTracker", which is the same name vanilla's own IVerbOwner comps use. Put a second IVerbOwner comp on the same thing and the save ends up with two same-named sibling nodes. Scribe_Deep resolves the child by name and takes the first match, so both comps deserialize the same block.
Source/MVCF/Comps/Comp_VerbGiver.cs:34:
Scribe_Deep.Look(ref verbTracker, "verbTracker", this);The sibling comp in the same folder already namespaces it. Source/MVCF/Comps/CompVerbsFromInventory.cs:27:
Scribe_Deep.Look(ref verbTracker, "inventoryVerbTracker", this);Repro from my 216-mod list: Combat Extended adds CompProperties_ApparelReloadable to VAEA_Apparel_MiniTurretPack. That derives from CompProperties_ApparelVerbOwnerCharged, so the comp it creates is a CompApparelVerbOwner, which is an IVerbOwner. The def already carries MVCF's Comp_VerbGiver from Vanilla Apparel Expanded Accessories. Loading a save with two of those packs worn produces four errors and two warnings on every load:
Cannot register CombatExtended.Verb_LaunchProjectileStaticCE,
(id=Verb_Thing_VAEA_Apparel_MiniTurretPack8010_4_0 ... Id already used by
Cannot register MVCF.VerbWithComps,
(id=Thing_VAEA_Apparel_MiniTurretPack8010_4_0_Managed ... Id already used
Replaced verb CombatExtended.Verb_LaunchProjectileStaticCE/CompVerbOwner_VAEA_Apparel_MiniTurretPack8010_0;
may have been changed through a version update or a mod change
The two comps do not generate colliding IDs on their own. Comp_VerbGiver.UniqueVerbOwnerID() returns parent.GetUniqueLoadID() + "_" + parent.AllComps.IndexOf(this), and CompApparelVerbOwner returns CompVerbOwner_<ThingID>. Those are distinct. The collision comes only from the shared scribe label putting both trackers in one node.
The consequence beyond log noise: the losing comp's VerbTracker.ExposeData cannot find its own ID inside the block it was handed, so InitVerbs falls through to Activator.CreateInstance and rebuilds the verb from scratch. That drops state, currentTarget, currentDestination, burstShotsLeft, ticksToNextBurstShot and lastShotTick, so the item loses its shot cooldown and any in-progress burst across a load. remainingCharges lives on the comp rather than the verb and is scribed separately, so ammo is not affected.
This is not dev-mode-only. LoadedObjectDirectory.RegisterLoaded runs its pre-check under if (Prefs.DevMode), which produces the Cannot register wording above. With dev mode off the duplicate still reaches Dictionary.Add, which throws, and the catch logs Exception registering ... An item with the same key has already been added. Dev mode changes the wording, not the outcome.
Giving Comp_VerbGiver its own label fixes it, matching what CompVerbsFromInventory already does. I run that locally as a Harmony prefix writing "mvcfVerbTracker", with a fallback that reads the legacy "verbTracker" when the new name is absent so existing saves migrate on their next write. That took the four errors and two warnings to zero across a save, re-save and cold restart, and the re-saved file shows both trackers under distinct names with their verb data intact. A fallback read is worth including, since saves in the wild already contain the old node name.
Environment: RimWorld 1.6.4871, Vanilla Expanded Framework (Workshop 2023507013), with Combat Extended and Vanilla Apparel Expanded Accessories.
Activity