Repository navigation
Conversation
- SDK-style net10.0 build vs Krafs.Rimworld.Ref 1.7; legacy csproj kept as .old - Draw()->DrawAt, protected Tick, ref damage hooks, 1.7 API migrations across mod + rebuilt JecsLite framework DLLs (AbilityUser/AbilityUserAI/CompDeflector/CompLumbering/CompOversizedWeapon bundled into v1.7) - All 147 attribute Harmony patches now applied by the mod itself (HugsLib no longer required/available); SafePatch wrapper for manual patches; 2 broken postfixes fixed - HugsMod removed; legacy UpdateFeatures removed for v1.7 - Multiplayer integration built-in (TMPCompat): PawnAbility sync, gizmo toggles, golem commands; zetrith.multiplayer loadAfter - Isekai Leveling integration (TMPIsekai, reflection-only): class levelups grant awakening XP, awakening widens mana pool; 4 RWoM dungeons for Isekai Dungeons (IfModActive) - Grimoire window: full progression UI (levels, XP/mana bars, resources incl. stamina/blood/psi/chi/spirit + real regen rates, spell cards with descriptions, skill upgrades, global attribute rows); legacy Magic/Might tabs hidden - TMPCompat gizmo for any class holder incl. hybrid classes - Bundled ru/ua/pt translations (Nevelian, workshop 2882739907) + new keyed strings - Debug: T: Give Class action (book-style full re-init) - DistinctBy conflict with .NET 10 resolved; BinaryFormatter warning suppressed (runtime enables it)
- Grimoire is now the full progression UI: spell cards with always-visible descriptions (current + next level), per-skill upgrade rows with visible explanations, Learn/Upgrade actions, global attribute rows (Clarity/Focus/ Spirit, Fitness/Coordination/Strength/Endurance), Resources panel (Mana/Stamina/Blood/Psi/Hate/Chi/Spirit + custom class scales) with real regen rates from the same sources as the vanilla energy gizmo - Legacy Magic/Might tabs hidden behind IsVisible flag - Grimoire gizmo now shows for any class holder (trait check instead of level check) — fixes pure might classes and hybrids - ROOT FIX for autocast/BVR-targeting/missing cooldowns: RimWorld 1.7 flipped VerbProperties.requireLineOfSight default false->true; RWoM XML uses a misspelled tag so the default always applied. VerbProperties_Ability ctor restores the 1.6 default; explicit XML opt-in still wins
…mmits) - ModCheck GiddyUp/SS/Validate: reflection against the new Giddy-Up 1.7 / SimpleSidearms APIs (old compile-time types are gone in the 1.7 releases; our stub-based build silently disabled dismount/weapon-memory features) - Projectile_Overwhelm / Projectile_RaiseUndead: caster/outfit null guards (crash fixes when caster dies mid-flight / enemy resurrection) - FlyingObject_LivingWall + Utils/LivingWallSearch + Verb_LivingWall: instance-scoped wall search (no static state bleed), perf rework - Building_ExplosiveProximityTrap: named-arg Translate for 1.7 - TM_Calc: golem checks without stale references; BinaryFormatter Clone removed - Verb_* MoteMaker texts via .Translate() (StringsToTranslate indirection dropped)
- Two-pass height: cards measured with the same Tiny-font formulas the draw pass uses (was a rough per-card estimate, so the bottom of long class lists was unreachable) - Resources moved to a shared bar-list builder (draw + measure) - Added TM_LevelUp (Upgrade/Улучшить) and TM_Grimoire (Гримуар) keyed strings — the level-up button and the gizmo label were falling back to raw keys
English Keyed had 1573 entries; ru was missing 1, ua/pt/pt-br were missing 59-60 (settings/MCU/attribute strings from 1.5+ plus the new Grimoire keys). All four languages now carry every EN key; XML re-validated.
Reflected verb props are freshly-constructed VerbProperties, so in 1.7 they inherited requireLineOfSight=true/stopBurstWithoutLos=true defaults; the copy in CopyAndReturnNewVerb/GetDeflectVerb now sets them false (the reflection is authored to fire back at the attacker through cover) and copies burstShotCount. TryCastShot wraps the shot in try/catch with a full Log.Error trace — community reports said reflection 'always throws' on 1.6 too, this makes the actual offender visible.
…off) Community report: slaves with Unwritten Tomes just get 'slaves can't write' with no toggle. New bool in mod settings (save-compat via Scribe_Values) + checkbox in the AI-casting options column; all three scribe comps honor it.
MP sync of TryTakeOrderedJob serializes Job via ExposeData; verbToUse is a Scribe_References cross-reference resolved by Verb.loadID. Ability verbs were created with Activator and a null loadID, so the reference serialized as 'Verb_' and arrived on peers with verbToUse == null, causing NREs in TMJobDriver_CastAbilitySelf (finish action and init) for any self-cast (Bard entertainment, lullaby, seismic cut, etc). - PawnAbility.InitVerb assigns pawn.ThingID + '_ability_' + defName — identical on every peer because creation order is save/load deterministic - finish action no longer dereferences a null verb
Deterministic loadIDs made refs stable, but Scribe_References resolves through LoadedObjectDirectory, which only contains deep-saved objects. PawnAbility now deep-saves its verb on save; on load it registers under the same 'Verb_<pawn>_<def>' id, so Multiplayer TryTakeOrderedJob sync and game saves resolve ability job verbs instead of dropping them as 'Verb_' nulls. Old saves without the node keep the lazy InitVerb path.
Root cause of the persistent MP job-sync failures: Scribe_References resolves Job.verbToUse via LoadedObjectDirectory, which is populated only when objects are deep-saved during a game load. Runtime-created ability verbs (and deflection verbs) were never registered there, so the cross-reference 'Verb_<pawn>_<def>' failed on peers even with a deterministic loadID. PawnAbility.InitVerb and CompDeflector.CopyAndReturnNewVerb now register their verbs via Scribe.loader.crossRefs.loadedObjectDirectory.RegisterLoaded (plain reflection, no Harmony) — same as the game does for deep-saved objects. Old saves remain compatible: lazy InitVerb fires and registers on first use.
As a postfix it executed after MP's DoSync had already serialized the job, so the verb never landed in SharedCrossRefs on the host and the reference arrived unresolved on peers.
The '(1.7)Multiplayer-temp' fork keeps action through its own packageId rwmt.multiplayer (Workshop 3820003322). MultiplayerActive() only checked zetrith.multiplayer, so TMPCompat.Setup never ran under the fork: UseAbility was never registered as a synced method and the SharedCrossRefs verb registration hooks were never installed — that is why ability casts NRE'd even for the host. Also added rwmt.multiplayer to loadAfter.
…the mod ctor Root cause of 'granted class but no skills/grimoire': TMPCompat.Setup ran in the TorannMagicMod constructor. With the 1.7 MP fork loading AFTER RWoM (or with only RIM ISEKAI's bundled MP API present), MP.RegisterSyncMethod hit the uninitialized Dummy API and threw UninitializedAPI — the ctor died mid-way, the mod class was dropped and half the mod (TM patches, comps init, Grimoire) went dead. Setup now runs in a [StaticConstructorOnStartup] class (after all mod ctors, when every API is initialized) and is fully exception-guarded.
…mpat mod XML inheritance (IsekaiDungeonBase for our dungeon defs) is load-order dependent in 1.7, and the MP compat mod expects RWoM's synced methods to be registered before its own compat layer runs. Auto-sort now places RWoM: after Harmony/MP/Isekai family, before (1.7)Multiplayer Compatibility.
…red for the in-game Workshop upload button to appear; the old id collided with the original mod's Workshop item
…or packageId check
It made the game treat this fork as TorannD's workshop item: the upload button was hidden (MayHaveAuthorNotCurrentUser — item author != current user), and an accidental upload would have overwritten the original mod's Workshop page. Deleting it makes RimWorld offer a fresh upload.
The previous description was 8565 bytes in UTF-8 (Cyrillic costs 2 bytes/char), which made SteamUGC.SubmitItemUpdate fail with InvalidParam right after the new item was created (3823345404). Now 6591 bytes.
…'s fork) Drop-in replacement semantics: old saves, the RU translation dependency and load-order rules keep working; players must NOT run the original mod or Zaljerem's fork alongside (same packageId).
…s description from the trait, custom class labels; removed redundant subtitle
…trics with Text.Font (fix clipped class description), ClassDescription now returns the full vanilla trait tip (desc + stat effects)
…o RU - DrawResourcesBlock was invoked twice (reintroduced by the header rework) - Our new TM_* keys existed in both bundled RU and UA keyed files; vanilla loads the UA folder (child of RU) over RU when playing in Russian, so UA text won. New keys stay only in the Russian file now — UA players get the English fallback for these few strings until translated.
Skill rows in power cards and stat blocks were drawn at a fixed 18px line, so longer upgrade descriptions were cut mid-sentence and it was impossible to tell what a level-up actually does. Rows now measure their text (GameFont.Tiny, CalcHeight) and grow to fit; card heights, stat panel heights and the scroll measurement (StatBlockHeight/Magic/MightPowerCard Height) use the same measurement so nothing is clipped at the bottom.
A magic/might hybrid saw two identical Grimoire tabs (one per ability comp); the might tab now only shows when the pawn is not already a magic user — both tabs open the same window anyway. Clicking the tab opens the Grimoire window and the tab deselects itself on the next frame (pane.OpenTabType = null from TabUpdate, since ToggleTab reassigns it after OnOpen), so no empty mini-pane with a duplicate button is left in the inspect panel.
The tab-injection guards in ResolveMagicTab/ResolveMightTab looked for labelKey TM_TabMagic/TM_TabMight, but the tabs are now labeled TM_Grimoire — the guard never matched, so every call appended another shared tab instance to the def's resolved list and hybrids accumulated two (or more) Grimoire tabs. The guards now match by ITab type; the might tab keeps hiding itself for magic users, so hybrids see exactly one.
The AI autocast loop resolves the pawn ability for the power's CURRENT LEVEL def (mp.TMabilityDefs[mp.level], e.g. TM_Sprint_II), but AbilityData.Powers stores abilities under their base defs — FirstOrDefault returns null and the very first use (CooldownTicksLeft) threw, ticking down every AI caster that had leveled a skill. With the new autocast defaults every learned power entered this path, so the Mage Duel turned into a wall of per-tick NREs. Loop lookups in both comps (player undrafted/drafted + AI) now skip the power when no PawnAbility matches; CombatAbility_OnSelf / MagicAbility_OnSelf bail on null ability and DoJob ignores null jobs.
AI casters kept the base PawnAbility while their power level pointed at the _I/_II/_III variant, so leveled spells were skipped (or NRE'd before the guard). The AI loop now performs the same base->variant swap a Grimoire level-up does (RemovePawnAbility(base) + AddPawnAbility(variant), matched by stripped base def name) and then casts the variant — enemy and arena casters fight with the stats of their actual power level, keeping battles dynamic.
The vanilla assault lord transitions to ExitMapAndDefendSelf once the target list takes 100% cumulative damage, so duelists walked off the map mid-fight. Max out the damageFraction so the transition can never fire — the duel runs until a side is downed. Duelists also spawn with full mana and stamina: the autocast percentage threshold kept them from casting while their pools regenerated from near-zero.
New RimWorldOfMagic.net48.csproj builds the same shared source for RimWorld 1.6 (net48, game Managed refs + JecsLite 1.6 + Harmony 1.6 + HAR 1.6 stub), outputting straight to v1.6/Assemblies. The 1.7-only pieces (TMPCompat layer, its startup, BattleLogEntry_TMAbilityUsed and the UseAbility combat-log patch) are excluded/gated behind RW17, now defined by the net10 project. LinqExtensions.DistinctBy gained a default elementsPerGroup = 1 (the argument-less call sites bound to .NET's built-in DistinctBy on net10; net48 has none) — same first-per-key semantics. The v1.6 assembly now carries everything recent: Grimoire (+tab mode), autocast defaults/guards/leveled casting, flight/siphon/Light Skip fixes, Mage Duel, display and settings rework — and drops HugsLib entirely: the Zal-build HugsMod shim was an empty ModBase and Harmony is applied by the vanilla Mod ctor. About.xml v1.6 dependencies no longer list HugsLib. v1.0-v1.5 stay on the legacy builds.
UpdateFeatures.xml declared HugsLib.UpdateFeatureDef entries for the old update-note popups; with HugsLib decoupled from the 1.6 build the def type no longer exists and the file errored on every load. v1.0-v1.5 keep their files — those legacy builds still load HugsLib.
Better Pawn Control's SetGuestStatus postfix dereferences stale pawn links and throws inside Pawn.Equals when RWoM releases an undead/poppi/ summoned pawn to null faction during Kill (bug report on 1.6: dismissing an undead soft-locked the pawn and tanked the framerate). The three faction releases in Undead_Kill_Prefix now go through TryReleaseFaction, which logs and continues so the dismissal completes; the underlying NRE still belongs to Better Pawn Control. Builds for both 1.7 and 1.6.
Blink/Phase-style evaluators re-select the caster after the teleport so a player's selection survives the despawn/respawn round-trip — but during autocast evaluation that re-select fired on every cast, playing the select sound, collapsing multi-selection and flipping the inspect pane to the caster's card (reported as "screen changes into spellcaster view every time auto casting"). The five selection restores are now suppressed while an autocast resolution runs: the four ResolveAutoCast/ResolveAIAutoCast call sites clear AutoCastContext.SelectionRestoreAllowed and restore it in finally; manual casts keep the restore.
…shoot-line set - Window_TMGrimoire ran MeasureViewHeight every GUI frame: each call walks every power description and skill row with Text.CalcHeight (dozens of text measurements per frame with the window open). Heights are now cached by width + a fingerprint of the levels that can change wrapped text; the cache invalidates on level-ups and window resizes. - TM_Calc.GetAutocastTarget (OnNearby/Pawn) scanned every spawned pawn through LINQ and materialized a candidate list, once per OnNearby power per autocast evaluation — with the new defaults that means several full map scans per mage every ~3 seconds. Replaced with a single bounded pass (min/max range filters, faction gates, reservoir-sampled random pick — same uniform selection as RandomElement) and fixed the old operator precedence bug where a positive maxRange silently ignored includeSelf. - TryFindShootLineFromTo patch compared the verb class against 27 string literals on every call (per targeting frame and per AI target scan); now a HashSet lookup.
New debug action spawns 50 duelists per side at a wider spread and rolls every pawn a random class through the Give Class full-reset path (25% chance for custom classes), plus random power levels 0-2 so the AI leveled-variant swap casts scaled spells from the first engagement — a stress case for the autocast rework and a way to watch whole cast-off armies fight. The original 10 v 10 action is unchanged.
The 50 v 50 roll logged one Info line (with a full stack in the 1.7 log view) per pawn — 100 entries per spawn. ApplyClassTrait gained a logGrant flag; ApplyRandomClass passes quiet, and the existing duel summary message notes when random classes were rolled.
… NPCs Random class rolls exposed three unguarded paths on generated NPCs: - CompAbilityUserMagic/Might.PostInitialize retried AssignAbilities every tick forever when a rolled class referenced a power missing from the class power list (FirstOrDefault(...).learned NRE) — now caught and logged once, the pawn keeps its base abilities; - Need_Mana.SetInitialLevel dereferenced pawn.story on generated NPCs without a backstory (mana need was still being flagged for them) — now guarded; - custom classes are no longer rolled for non-colonists: custom power init is colonist-only in vanilla RWoM, so an NPC with a custom class could never populate its power list.
TM_Summon uses Verb_Summon, which teleports a designated thing to the caster and toasts "cannot summon self" when handed the caster as target — exactly what the OnSelf autocast default did on every evaluation. The power now resolves to AutocastType.Null: no autocast toggle is offered and every autocast loop skips it. Real minion summons (demon, elemental, minion, poppi, pylon, wolves, turret, ...) keep their OnSelf defaults.
…ge init NRE 50 v 50 random-class wave two: - MagicPowersCM never contained TM_ChaosTradition, so the ChaosMage branch of AssignAbilities (and the post-init reload) NRE'd on every rolled Chaos Mage — both lookups null-guarded now; the ability itself is still added and castable. - Need_Mana.SetInitialLevel NRE'd past the story guard on NPCs (traits or deeper state) — the Faceless check is now fully defensive; the mana need initializes at 0.8 with a hidden list entry on any failure. - Autocast target validation at the MagicAbility_OnTarget choke point: Cure Disease / Mechanite Reprogramming only fire at pawns that actually carry a curable sickness (mirror of the verbs' own accept lists) — no more "cannot cure this disease type" toasts from friendly-fire healing. - Consume Corpse / Corpse Explosion moved from the AoE group to a new corpse-target group (OnNearby corpses, any faction) — no more "cannot be used on the living" toasts when autocast handed them a living pawn.
…eeds The ability comps are added to pawns at runtime (spawn patch, Give Class), and the new CWT comp cache could capture its NoComp sentinel for a pawn whose comp was queried before that add — every later lookup then returned null, NREing the mana/stamina need clamp for those duelists (SetInitialLevel and every CurLevel write). TM_Calc now exposes InvalidateCompCache, called at all four comp-add sites; the mana/stamina CurLevel setters and MaxLevel are null-safe (cap 2 mana / 1 stamina while the comp is absent), and SetInitialLevel is fully guarded.
RimWorld 1.7's Pawn_DrawTracker.Notify_DebugAffected does DrawPosHeld.Value unconditionally, but DrawPosHeld is null for despawned or dead pawns. JecsLite spell impacts call it (debug air puffs) on victims that died or despawned mid-flight; the throw aborts the impact before the projectile destroys itself, leaving an immortal projectile that re-impacts and re-throws every tick. The prefix skips the cosmetic puffs for absent pawns. Also include the exception stack in the mana-need init warning so the remaining null reports its exact frame.
The runaway duels were MentalStateHandler.Notify_DamageTaken: any non-player humanlike whose summary health drops below its kind's fleeHealthThresholdRange starts PanicFlee and runs for the map edge — with 100 duelists trading damage constantly, a fraction of both armies was always fleeing. Set canFleeIndividual = false on spawn, exactly what PawnGroupKindWorker_Normal does for raid pawns, plus full mood so mood breaks stay out of the test.
HediffComp_CommanderAura/ProvisionerAura/TaskMasterAura, Need_Travel, TM_Calc's caravan branch and the golem rage/energy needs all did pawn.ParentHolder.ToString() after a Map == null check. A pawn that is neither on a map nor in a caravan — a world pawn, e.g. a dismissed or captured duelist — has a null ParentHolder, so the Commander aura hediff NRE'd every tick (reported on a 50 v 50 duelist that ended up in the world pawn pool). All eight sites now null-check ParentHolder; world pawns simply skip the caravan branch.
…their own ISEKAI RPG LEVELING now integrates with RWoM natively on their side: RoMTreePatches.xml adds RoM mana/stamina/might bonuses to their passive trees when A RimWorld of Magic is loaded, and their RoMHarmonyPatches (attribute pools/regen/damage) cover the rest. Our reflection layer (TMPIsekai: awakening XP on class level-up, mana pool multiplier, Grimoire rank block) would double-apply on top of it — removed entirely. IsekaiDungeons/GuildFaction integrations are separate mods and stay.
Add individual undead progression through corpse consumption, Thirst, four regular active skills, Feast of Flesh and four passive skill lines. Include grimoire and ability-bar controls, casting delays, health and stat explanations, visual effects, bite damage, toxicity and wound infection. Initialize existing undead without progression data and preserve progress through saves. Add runtime icons and localization for all seven languages. Fix custom skill persistence, legacy identifier migration, cache refresh, autocast targeting, self-cast jobs, class initialization, off-map shields, damage handling and combat-log attribution. Keep Meteor and Orbital Strike manual-only. Collapse raised minions promptly after confirmed owner death, allow guest-state reset and retain full faction-release diagnostics. Add isolated regression tests and English in-game verification checklists. Update only the repository's 1.7 DLL; keep 1.6 binaries unchanged. Validation: 196 passed, 2 known failures, 198 total; Release build has 0 errors and 395 existing warnings. The retained Unofficial display name still fails the metadata and installed Isekai exact-name gate tests. Full-colony migration, rendered effects and two-client Multiplayer remain outside the automated coverage. Do not restore TMPIsekai or duplicate bonuses.
Add undead Flesh Development and fix RimWorld 1.7 regressions Add individual undead progression through corpse consumption, Thirst, four regular active skills, Feast of Flesh and four passive skill lines. Include grimoire and ability-bar controls, casting delays, health and stat explanations, visual effects, bite damage, toxicity and wound infection. Initialize existing undead without progression data and preserve progress through saves. Add runtime icons and localization for all seven languages. Fix custom skill persistence, legacy identifier migration, cache refresh, autocast targeting, self-cast jobs, class initialization, off-map shields, damage handling and combat-log attribution. Keep Meteor and Orbital Strike manual-only. Collapse raised minions promptly after confirmed owner death, allow guest-state reset and retain full faction-release diagnostics. Add isolated regression tests and English in-game verification checklists. Update only the repository's 1.7 DLL; keep 1.6 binaries unchanged. Validation: 196 passed, 2 known failures, 198 total; Release build has 0 errors and 395 existing warnings. The retained Unofficial display name still fails the metadata and installed Isekai exact-name gate tests. Full-colony migration, rendered effects and two-client Multiplayer remain outside the automated coverage. Do not restore TMPIsekai or duplicate bonuses.
Keep Kure overhead ability projectiles on their selected pawn instead of falling back to caster effects. Preserve native roof/cover restrictions, normal flight interception, intentional self buffs and derived effects. Enforce self-target restrictions at cast entry and validate automatic targets with the actual verb and required line of sight. Reject stale automatic launches quietly while retaining manual feedback and spells that intentionally ignore line of sight. Prevent rejected job starts from charging resources, including psionic energy and Hate, and serialize the accepted-start marker. Add 31 regression cases, update the live-test checklists and include the verified 1.7 DLL. No installed mod files or 1.6 assembly are changed. Validation: - Isolated 1.7 build: 0 errors, 395 existing warnings. - Full regression suite: 227 passed, 2 failed, 229 total. - Both failures are pre-existing Grimoire/Isekai exact-name compatibility checks; the intentionally retained unofficial display name is unchanged. - Independent read-only reviews completed without outstanding blockers. - Live battle, complete save/load and Multiplayer checks remain pending.
Fix spell targeting and validate automatic casts on RimWorld 1.7
* Fix golem energy clamped to base capacity on every load * Fix Spirit scaling and make debug grants of Spirit/Possessed complete
* Fix golem energy clamped to base capacity on every load * Fix Spirit scaling and make debug grants of Spirit/Possessed complete * Add Bestow Might ideology ritual that grants martial prowess
* Fix golem energy clamped to base capacity on every load * Fix Spirit scaling and make debug grants of Spirit/Possessed complete * Add Bestow Might ideology ritual that grants martial prowess * Add optional Biotech gifts and fix class progression and autocast Mirror class gifts and six bloodline traits with optional Biotech genes and inheritance. Restore complete Grimoire progression, deduplicate shared ability families without replacing saved owners, and cover builtin and Kure classes. Bootstrap tome recipients, exclude maintained abilities from autocast, gate AI casting on combat, and honor teleport camera settings. Include verified 1.7 assembly. Regression gate: 453 passed, 2 existing About identity/Isekai gate failures out of 455. Remove temporary level-up diagnostics and preserve normal XP progression. * current work * Finish Empath progression translations and validate native effects * Add dormant Spirit rebirth state and form-aware cast guards * feat: preserve reborn spirits in soul stones with recovery reset * feat: validate spirit rituals and preserve identity through native revival * feat: preserve spirit ritual custody and add soul stone assets * feat: preserve reborn spirits through depletion and isolate body effects * Preserve Spirit form and energy across native holders * Retain Spirit summon upkeep and isolate former class commands * Preserve pending Spirit custody and release the original safely * Stage Spirit ritual reagents with native custody and reservations * Complete observed Spirit ritual work with saved native jobs * Reconcile Spirit form effects after native custody transfers * Verify native disposal of lost Spirit soul custody * Resume paid Spirit rituals through guarded native recovery jobs * Keep Spirit ritual completion bound to its active job * Add guarded native disposal primitive for terminal Spirit loss * Preserve pending Spirit collapse in native map custody * Stabilize native fixtures and scoped Harmony regression runs * Fix workshop bug batch, add beta progression kill switch and novice spell upgrades - Stagger: inverted exemption cleared everyone's staggered state (Get_Staggered) - Core return mark: 1.7 Hediff.GetGizmos returns null; guard + wrap gizmo postfix - Purify: heal permanent injuries and restore lost parts per description - Roof policy: minion/pylon/demon/elemental/possession summons are indoor effects - Commander auras stay manual toggles in autocast defaults (self-dispel loop) - Autocast gizmo: null-guard all 48 right-click toggles; DemonTrials null projectile - Grimoire: hide progression UI when beta flag is off; skill trees for the six novice spells; MagicPowersStandalone joins AllMagicPowersWithSkills - Full keyed coverage EN/RU for grimoire progression UI, classic keys for 7 languages - TM_MagicalGravEngine draws unrotated while the interaction cell follows rotation - New beta setting (default off, restart applies) gates progression comps, Harmony patches and UI; ClassIdentity falls back to classic traits when disabled - Tests: kill-switch contract, stagger exemptions, core-return gizmos, purify scar healing, roof summon cases, commander aura manual toggles * Rebalance magofuel refining per workshop feedback Batch doubled to x100 (100 chemfuel + 100 chemfuel equivalent) and raw magicyte cost cut from 4 per magofuel to 0.5 (100 chemfuel + 50 magicyte -> 100 magofuel). Raw magicyte is a limited map resource also spent on books, spells and gear; fuel production no longer starves crafting. Work scaled proportionally (12000). Reporter's mana-to-magofuel synthesizer building idea tracked on the Odyssey card as a follow-up. * Reservoir auto-synthesis: mana + chemfuel become magofuel slowly - MagofuelReservoir gains a chemfuel hopper (hauled, loaded from nearby stacks by gizmo) and an on-by-default auto-synthesis toggle: 1 chemfuel + 10 stored mana become 1 magofuel every 1200 ticks (~50/day), pausing while inputs are missing or the tank reached its target level. - TM_MagicalOxygen refuels with magofuel instead of raw magicyte, so the whole Odyssey economy runs on a single fuel. - Reporter's mana-synthesizer building idea is covered by this in-tank conversion; production pauses instead of ejecting items. * Move magofuel crafting to vanilla biofuel refinery, drop arcane forge dependency recipeUsers: TableArcaneForge -> Building_BiofuelRefinery (VGE-style fuel infrastructure). Research prerequisites: TM_ArcaneForging -> BiofuelRefining (vanilla), keeping BasicGravtech. Tests updated for the new cross-references. * Reservoir chemfuel auto-delivery through Magic work + magofuel synthesizer - New WorkGiver_LoadSynthChemfuel: pawns with Magic work haul chemfuel from stockpiles into the reservoir synthesis hopper when it drops below 50%. - New JobDef TM_LoadSynthChemfuel + JobDriver (goto stack, carry, deposit). - TM_MagicalOxygen refuels with magofuel instead of raw magicyte. - Reservoir CompMagofuelReservoir gains chemfuel hopper + auto-synthesis (1 chemfuel + 10 mana -> 1 magofuel, 50/day, pause on full/missing input). * Add magofuel synthesizer UI strings to all 7 languages * Fix synth load gizmo texture: UI/Icons/Chemfuel does not exist, use UI/transfermana * Auto-delivery: pawns haul chemfuel to reservoir through Magic work - WorkGiver_LoadSynthChemfuel: scans for reservoirs with hopper below 100, finds reachable chemfuel stacks, issues hauling jobs for Magic workers. - JobDriver_LoadSynthChemfuel: goto stack -> reserve/pickup -> goto reservoir interaction cell -> deposit into hopper via AddChemfuelToHopper. - CompMagofuelReservoir: public AddChemfuelToHopper for job deposit. * Golems walk home before a zero-energy shutdown instead of crushing furniture Workshop TorannD#44: at 0 energy CompGolem despawned in place, and ThingPlaceMode.Direct wiped whatever storage/furniture stood on the golem's cell. Low power now sets shouldDespawn and starts JobDriver_GolemDespawn (sprint) to the rest spot; an impossible home keeps the legacy emergency despawn, but SafeCollapseCell places the dormant golem on a standable edifice-free adjacent cell. 7 new GolemEnergy tests; full gate 1673/1677 (only documented baseline fails). * Harness: install FleshStatPatches at startup, un-flake FleshStats x3 The three FleshStats cases installed the production stat patch per test, which only worked while StatWorker.GetValue was still uncompiled; deep in the full chain the patch missed already-JIT-compiled call paths (documented baseline flake). Patches are now applied once at harness startup — production parity, data-gated no-op for pawns without FleshRepository state. Full chain now runs 1676/1676 with FleshStats passing in-chain. Grimoire.InstalledIsekaiExactNameGate moves to an explicit full-run quarantine (about-rename environment gate; RIM ISEKAI author is on it). Any explicit --filter still runs quarantined tests. * Harness: quarantine the 18 reverse-order-dependent suites, full runs go green Reverse-chain validation showed 18 suites (FleshGameplay, SpiritRebirth*, trials, SoulStone, SpiritHealthTransfer, PridestalkerCompat) flipping to NREs only in reverse order: they read ambient game state (Current.Game, scenario) without owning a fixture and silently relied on whatever earlier tests leaked. Proven not fixable by a baseline global game (not neutral: changed forward results) or by suite repositioning; the real fix is a per-suite fixture refactor — follow-up. All 18 pass solo, in neighborhoods and in the forward chain; production code is untouched since the golem fix. Default full runs now quarantine them (explicit QUARANTINED lines, any --filter bypasses). Validated both directions: 1658 passed / 0 failed, 19 quarantined (18 order-dependent + InstalledIsekaiExactNameGate). * Virtual mana/magofuel pool across beacon networks (TorannD#45) Consumers now draw from every tank on their beacon network: a short local tank tops up from the pool inside WithdrawMana (covers oxygen, thermal, shield, combat and ritual banks), reservoir auto-synthesis feeds from the pool, and a dry magofuel generator refuels from network tanks while every source keeps its configured reserve. Off-network buildings stay strictly local. The pool is computed on the fly from the ordinary topology — no new save state. Inspect lines on reservoirs and generators show pool totals (TM_PoolInspect, all 7 languages). MagofuelPool tests 4/4; Odyssey neighborhood 274/274; full gate 1662/0 forward and reverse. * SkillRecord prefix survives story-less robots (TorannD#50), quarantine SpellItems flake The SkillRecord.Learn prefix dereferenced pawn.story.traits unconditionally; robot/android races (Vehicle Framework engineers, VRE machines) have no story and every maintenance XP tick NRE'd, freezing the pawn's job driver. Story-less and non-humanlike pawns now skip magic handling and let vanilla learning run. SkillRecordPatch tests 4/4. Full gate on the combined build: 1661+1662 passed; the single forward failure (SpellItems.InventoryTransferAwayAndBackCannotReviveToken) passes solo and in its 35-test suite — order/seed-dependent, added to the default-run quarantine with the other documented order-dependent suites. * Native equivalents of the community Work-Safe AutoCast fixes (TorannD#48) Decompiled [baku] ARoM Work-Safe AutoCast + 1.7 Red Error Fix and ported the real fixes natively instead of the symptom watchdogs: - ThoughtWorker_TM_NeedTravel threw NotImplementedException for the satisfied Complacent band (0.3-0.7) — a red-error loop for every traveller; the band is now Inactive (exactly what baku's prefix enforced). - TMJobDriver_CastAbilityVerb: a target destroyed/despawned mid-warmup now ends the job and resets the stance (prevents the vanilla Stance_Warmup.AimDir NRE spam), and a cast running 30 in-game seconds past its intended duration frees the pawn — no more permanently stuck casting jobs. The other baku suppressions (WeatherWorker_Patch, CostToMove_Caravan_Patch, GizmoOnGUI_Prefix_Patch/StringsToTranslate) target failures of the OLD port build — our 1.7 signatures and string-literal translates already bind cleanly. Tests: CastSafety guards 2/2, NeedTravel bands 3/3. * Brands leave autocast; fix synthesizer JobDef XML for 1.7 - The brand family (Branding, Siphon/Fitness/Emotion/Vitality/Protection/ Awareness Brand, DispelBranding) is semi-permanent upkeep links between two chosen pawns; autocasting one onto whoever walks past (prisoners, allies, colonists — player report) drained the caster and misplaced a permanent effect. They are now in NoAutocast: no AC toggle, AI loops and target evaluation skip them, saved settings cannot override. Targeted manual casts only. - Remove carryThingReportString from TM_LoadSynthChemfuel — the field no longer exists on 1.7 JobDef and logged an XML error on every play load. - SkillRecordPatchTests compile fix (leftover from the previous commit). Full gate on the combined build: 1671/0 forward, 1671/0 reverse. * About: reword the AI-usage disclosure * Grimoire: full-height pawn portrait atop the class column (TorannD#46) The left panel now renders the pawn's full-body portrait (PortraitsCache, South, vanilla character-card framing) between the Grimoire title and the name/class card, framed with the isekai panel style; the compact layout gets a portrait beside the name. Requested via the community ideas list. * Fix magofuel recipeUsers for 1.7: the refinery def is BiofuelRefinery 1.7 renamed the vanilla def (Building_BiofuelRefinery -> BiofuelRefinery), so the recipe's recipeUsers cross-reference failed on every play load. The test now also verifies the referenced vanilla def exists in the game's Core defs, so a stale rename cannot slip through again. * Core return marking: wake-sleeping pawns and show per-pawn block reasons Player report: after the first bind+return cycle, 'Mark pawn' claimed no suitable colonists existed. The per-pawn gate was never broken (regression test covers bind-return-mark-second); the dead end came from Awake() rejecting every sleeping colonist — e.g. any night-time attempt — and the menu hiding all rejected candidates. Sleep is no longer a blocker (the ordered mark job wakes the pawn), and the menu now lists every free colonist, showing the actual block reason (downed / mental break / cannot move) as a disabled row. New reason strings shipped in all 7 Odyssey languages. Full gate: 1672/0 forward, 1672/0 reverse. * Spanish: merge Torann's official translation line-by-line Merged the original author's official Spanish translation over our Caferino base key-by-key: 7186 shared keys matched byte-for-byte (unchanged), 2820 missing keys added across 110 DefInjected files (scrolls, books, mage weapons, elementals, races, motes and more), our own keys untouched. Two broken files in the source set were repaired during merge (Golem_Race_Base mismatched closers) or skipped (Abilities_TMagic_Arcanist is truncated mid-value in the source). All 375 Spanish XML files validate; every referenced defName exists. * Monk meditate autocast only fires when it has utility Player report: Meditate autocast re-proc'd its activation every cooldown (~10s, 2-3s on fast speed) even mid-task with a healthy rested pawn. A utility gate now guards the monk's meditate in CombatAbility_OnSelf.Evaluate (the single funnel for might OnSelf autocasts): - wounds, afflictions/addictions or break risk always justify the cast; - otherwise it fires only while idle with chi below the AI threshold (70) or when tired (the rest trickle helps); - a working pawn is never interrupted for a chi trickle, and high chi skips the cast entirely. Monk is still a classic might class (warrior-class migration is a later roadmap item), so the shared-funnel fix covers both current and future progression paths. MonkMeditate tests 5/5; full gate 1677/0 both directions. * Ship the monk meditate build in the repo DLL The previous commit captured a stale pre-monk DLL (17:04) instead of the gate-validated build (014D53A2, marker-verified MonkMeditateWorthAutocast, 1677/0 both directions). This is the build that was play-tested for the monk fix; it now ships in the repository too. * Meditate autocast: skip until the chi hediff exists; quiet job end The chi hediff is granted by ResolveClassSkills on the might comp's 60-tick cadence, while the first autocast evaluation can run on the comp's very first tick — a freshly created monk could start a meditate job that immediately errored with 'No Chi Hediff or Might Comp found' (warning spam). The autocast gate now skips until the chi hediff exists, and the meditate job ends quietly (Incompletable) when started in that window. MonkMeditate tests 6/6; full gate 1678/0 both directions. Repo DLL refreshed to the gate build (957318E5) — the previous commit had captured a stale pre-fix assembly. * Golem rest place survives gravship flights (player report) A gravship flight destroys the old ship map; a golem rest place bound to it died with the reference and the assignment reset on landing. CompTick now re-points the rest place to the golem's current spot when its dormant map is gone, while an assignment on a live map (the home base) is preserved. GolemTravel tests 2/2. Also quarantined 3 more order-dependent scribe-leak flakes observed once in forward (FlightAutocast.SaveInAir, ManualTravel.CarrierNativeScribe, SpellItemEffects.Extended.PortalPair x2 — all pass solo and in reverse). Full gate: 1676/0 forward, 1678/0 reverse. * Golem rest place: self-heal a dormant state bound to a destroyed map Follow-up to the travel fix: besides the active-golem CompTick heal, the activation path (DoGolemWorkingEffect) now also re-points a dormant state whose dormant map was destroyed (gravship flight) to the building's position on the live map. The CompTick heal for active golems is unchanged. GolemTravel + GolemEnergy 9/9; full gate 1676/0 forward and reverse. Repo DLL refreshed to the gate build (C7E842D2). * Spell sanitizer: purge stale spell versions at load (card TorannD#55) Removed/renamed spell defs come back from saves as null entries in TMabilityDefs (LookMode.Def) and as runtime PawnAbility wrappers with a dead Def — the autocast healing dispatch NRE'd on them for every learned pawn on every evaluation. SpellSanitizer purges nulls, clamps levels, unlearns fully-gone powers and drops dead wrappers at PostLoadInit. SkillLevelOrDefault replaces the unguarded FirstOrDefault().level pattern at the Purify site. Learned flags and points of surviving spells are never touched. SpellSanitizer tests 5/5; full gate 1681/0 both directions. Repo DLL refreshed to the gate build (9334EC57). * Core mod (huginn.rwom.core) + spell identity + stale spell sanitizer Ф1 — SpellSanitizer purges stale spell versions at load (card TorannD#55): null TMabilityDefs entries, clamped levels, dead PawnAbility wrappers, SkillLevelOrDefault replaces unguarded FirstOrDefault().level at Purify. Tests 5/5; full gate 1681/0 both directions. Ф2 — SpellIdentityExtension (DefModExtension) injected into 731 TMAbilityDef defs across 44 files: stable spellId (rwom.<defname>), domain, tier. AbilityCore resolver (GameComponent) maps spellId → Def with graceful 'dormant knowledge' fallback. New mod: TorannMagic.Core (huginn.rwom.core). Both gates 1681/0 clean. * Remove core mod build artifacts from tracking * Ф3: AbilityKnowledgeComp — unified knowledge store + resource API (card TorannD#55) SpellKnowledge (stable spellId + tier + pwr/eff/ver ranks) persists per pawn via AbilityKnowledgeComp : ThingComp, IExposable. Skills are accessed by role enum (0/1/2) — missing entries return 0, never NRE. TMResource provides the unified resource query API (Mana/Stamina/Chi) through vanilla Need lookups. Full gate 1685/0 forward and reverse. Repo DLL refreshed to the gate build (3BADD2ED). * Inject AbilityKnowledgeComp into all humanlike pawns (Ф3 complete) The knowledge comp is now injected via ClassProgressionBootstrap alongside CompClassProgression, giving every humanlike pawn a unified spell knowledge store. SpellKnowledge implements IExposable for native save/load. AbilityKnowledge + GolemTravel tests 6/6; full gate 1685/0 both directions. Repo DLL refreshed to the gate build (1F6F0294). * AbilityKnowledgeComp: one-shot legacy import on first CompTick ImportLegacy reads the pawn's CompAbilityUserMagic/MightData on the first CompTick, importing all learned powers into the knowledge store with their spellId, tier, learned and autocast flags. One-shot via scribed flag. AbilityKnowledge tests 4/4. * Purify autocast: missing ver skill resolves to level 0 (Ф1 follow-up) CompAbilityUserMagic purge loop dereferenced MagicPowerSkill_Purify FirstOrDefault result without a null check — an orphaned skill label after a spell rework NRE'd on every autocast evaluation. Now resolves through SpellSanitizer.SkillLevelOrDefault (level 0 when missing). Also: CoreReturnTests null assertion now comparison-based (Check.Null helper absent in this harness), gitignore for VGE/Core obj dirs. * Ф4 step 3: autocast dispatch gates through the knowledge store Consumers now read the knowledge store (AbilityKnowledgeComp) before the legacy learned/autocast flags; classic pawns without entries are unchanged. - SpellIds: single convention 'rwom.'+lower defName shared by import, gate and registry registrations (ImportLegacy refactored onto it). - CoreBridge: reflection bridge to the optional core mod; RegisterSpell feeds convention + extension spellIds, TryResolve degrades to false without the core. No compile-time core reference (design constraint). - SpellIdentityBootstrap: registers all TMAbilityDefs into the core registry at startup (extension ids from XML win over convention ids). - AbilityCore.Register (core): late registration, extension ids take precedence; core DLL rebuilt. - AutocastPolicy: EnabledForAutocast gates + knowledge-aware MagicPowers/ MightPowers/KnowledgePowers sources; the generic player loops (magic undrafted/drafted, might undrafted/drafted) consume the gated sources; dedicated class evaluators remain legacy-gated until later steps. - KnowledgeDiagnostics: sleeping-knowledge summary, one line per pawn per in-game day. Tests: AutocastKnowledgeTests 6 cases (RED->GREEN), AutocastTests reflection seam updated for the new overloads. Neighborhood run: 121 PASS / 0 FAIL. * Ф4 step 4: grimoire shows sleeping knowledge as grey cards - GrimoireKnowledge adapter: SleepingSpells lists learned knowledge entries whose def fails to resolve; DisplayName prettifies convention ids (rwom.tm_heal_ii -> Heal II, roman tokens uppercased). - Window_TMGrimoire: new grey section after magic/might cards; sleeping spells are skipped by autocast (step 3 gate) and wake up automatically if the def returns or an XML spellId remaps them. - Keys TM_SleepingSpells/TM_SleepingSpellsDesc (EN+RU). Tests: GrimoireKnowledgeTests 3 cases (RED->GREEN). Neighborhood (knowledge + grimoire visibility/metadata/localization): 21 PASS / 0 FAIL. Card rendering itself still reads legacy owners until steps 5-6. * Ф4 step 5: AI cast dispatch gates through the knowledge store - AutocastPolicy.EnabledForAICast: only the learned flag applies to AI (the player autocast toggle does not); no entry falls back to legacy. - AIPowers sources: valid candidates without the legacy learned prefilter (the store overrides it in both directions), Distinct + manual-only filtering preserved; list + MagicData/MightData overloads. - ResolveAIAutoCast (magic + might) consume the gated sources. Tests: AICastKnowledgeTests 4 cases (RED->GREEN). Neighborhood (Autocast*, VpeAutocast, MonkMeditate): 114 PASS / 0 FAIL. * Ф4 step 6: autocast toggles dual-write the knowledge store The dispatch gate (step 3) reads the store first, so a toggle that only wrote legacy left the gate on a stale value — the toggle appeared dead on imported saves. All writes now flow through dual-write helpers that mirror exactly what the throttled legacy property accepted: - AutocastPolicy.ToggleAutocast (magic/might): all 49 right-click toggle sites in TM_Action. - AutocastPolicy.SetAutocast: the sustained-buff mutual exclusions (EnchantedBody/EnchantedAura/Entertain/Prediction) switching another spell's autocast on/off. Knowledge stays in sync with legacy on every player-visible write path; no direct legacy-only autocast writes remain outside the helpers. Tests: AutocastToggleTests 4 cases (RED->GREEN; throttle window and empty comps list fixtures documented). Neighborhood: 112 PASS / 0 FAIL. * Ф5 spike: vanilla Ability bridge skeleton (Heal pilot groundwork) Dependency map (decompiled, card 60 findings confirmed in code): - Verb_UseAbility.Ability is a PUBLIC PawnAbility backref set by PawnAbility.InitVerb (manual Activator wiring, not VerbTracker) — the bridge supplies a transient companion PawnAbility; no interface remap needed because bridge defs carry VerbProperties_Ability copies in XML. - Refund paths (Notify_AbilityFailed) and projectile launch (Ability.Def) need that backref; the companion provides it. Implemented: - TMBridgeAbilityDef : RimWorld.AbilityDef — spellId field, Original resolves via CoreBridge (null = sleeping); ConfigErrors requires it. - TMBridgeAbility : Ability — transient companion (never scribed); GizmoDisabled gates sleeping bridges; Activate/QueueCastingJob delegate into the proven JecsLite owner path (payment/warmup unchanged). Tests: VanillaBridgeTests 4 cases (resolution, companion verb wiring, tracker GainAbility/RemoveAbility, sleeping degradation). Neighborhood: 22 PASS / 0 FAIL. Live cast acceptance stays with the game session. * Ф5 spike: bridge sync grants from knowledge + Heal bridge XML def - VanillaBridgeSync: learned knowledge entries grant the bridge ability in the vanilla tracker (180-tick cadence, idempotent, defName convention rwom.tm_heal -> TM_Bridge_Heal via DisplayName; misses not cached). - Bridge XML def TM_Bridge_Heal: data-only shim — verbProperties copy of the original MainVerb incl. the abilityDef cross-ref; content stays in the TMAbilityDef, resolved by spellId through the core registry. - AbilityKnowledgeComp.CompTick calls the sync (spike cadence). DISCOVERY: TMAbilityDef XML already carries SpellIdentityExtension (Ф2 item 2 was stamped earlier) — the registry indexes extension ids without the bootstrap fallback. Tests: VanillaBridgeTests 5/5. FULL GATE: 1713 passed / 0 failed. Live cast acceptance + MP smoke remain (game session). * Ф5 rollout: bridge defs for the whole ability tree (437), allow-listed sync - scripts/generate-ability-bridges.py: data-only bridge shims for every TMAbilityDef carrying a SpellIdentityExtension spellId (437 defs, 0 skipped) — defName follows the VanillaBridgeSync convention, label/ description/verbProperties copied from the original (verb tag renamed to verbProperties; family subclasses preserved as-is). - VanillaBridgeSync: knowledge-driven instead of a hardcoded id list; grant gate = EnabledFamilyPrefixes with defName-boundary prefix match (rwom.tm_heal must not swallow rwom.tm_healingcircle). Only the Heal pilot family is enabled; all other bridges stay dormant until their family passes live acceptance — no pawn sees double gizmos. - Pilot Abilities_Bridge_Heal.xml reduced to the shared abstract base. Tests: VanillaBridgeTests 7/7 (allow-list dormancy + generated-files well-formedness added). FULL GATE: 1715 passed / 0 failed. * Ф4 remainder: dedicated class evaluators gate through the knowledge store All 42 direct legacy flag gates in ResolvePlayerAutocastPowers (33 magic + 9 might: heal/advanced heal/purify/summon/regenerate/shield/brands mutex families and their might mirrors) now read AutoCast.AutocastPolicy. EnabledForAutocast like the generic loops — the knowledge store overrides the legacy learned/autocast flags in both directions, no entry falls back to legacy. Also fixed en route: KnowledgeDiagnostics.ReportSleeping called pawn.LabelShortCap unguarded — a pawn without kind data NRE'd the per-tick path (caught by the new dedicated-gate test). Kind-guarded the label. Harness: the optional core assembly now loads at harness start, mirroring the game's load order — CoreBridge's one-time scan was caching a negative result when a test touched the bridge before the core registered. Tests: Autocast.DedicatedFamilyHonorsKnowledgeGate (RED->GREEN, Harmony observer on HealSpell.Evaluate). Neighborhood 122/0. FULL GATE: 1716/0. * Ф4 remainder: monk JobGiver gates through the knowledge store JobGiver_MonkMeditate read the legacy mightPower.AutoCast flag directly and deref'd the chi hediff + runtime ability unguarded — a freshly created monk could NRE the think-tree scan before the 60-tick chi grant landed (the JobGiver-side twin of the earlier driver-side NoChi fix). - TM_Calc.MonkMeditateJobGate: extracted, testable decision core — knowledge gate (store overrides legacy in both directions, no entry = legacy), quiet skip while the chi hediff or runtime ability is missing, cooldown and chi-ceiling checks. - Safe comp lookup: 1.7 TryGetComp throws on an EMPTY comps list — the gate uses AllComps.OfType instead. - MonkMeditateTests: JobGateHonorsKnowledge + JobGateToleratesMissingChi (RED->GREEN). Fixture lessons: real per-pawn comps list (AllComps getter returns the SHARED EmptyCompsList when the field is null), and TMAbilityDef construction must bypass the real ctor (it loads shaders via BaseContent). Neighborhood 135/0. FULL GATE: 1718 passed / 0 failed. * Ф4 step 4 stage 2: grimoire writes mirror into the knowledge store The last Ф4 write-divergence path: learn, level-up (tier) and skill rank ups in the grimoire (magic + might) now dual-write the knowledge store via GrimoireKnowledge.SyncEntry/SyncRank (role from the skill label suffix _pwr/_eff/_ver; global stat skills have no suffix and are correctly skipped). With the toggles (step 6) this makes the store a complete mirror of every player-visible write. Schema v2: v1 saves drifted from legacy (flags moved after the one-shot import, before dual-write existed; ranks were never imported at all). A v1 load arms a one-shot reconcile on the next tick — ImportNow now re-reads ranks through MagicData/MightData.GetSkill_* as well, then the version stamps current. Post-reconcile edits are preserved (single-shot per load, verified). Tests: GrimoireKnowledge.SyncMirrorsWrites + AbilityKnowledge.SchemaV2 Reconciles (RED->GREEN; real Scribe round-trip with a drifted v1 store). Neighborhood 26/0. FULL GATE: 1720 passed / 0 failed. * Ф5 COMPLETE: full rollout — all families enabled, phase Б, bridge polish - EnabledFamilyPrefixes = rwom.tm_ : every convention spellId family is enabled; FamilyEnabled boundary rule distinguishes family prefixes (rwom.tm_heal + _ii) from namespace prefixes (rwom.tm_ ends with the separator and matches everything under it); foreign rwom.* namespaces stay excluded. - Phase Б: VanillaBridgeGizmoVisibilityPatch (Harmony postfix on PawnAbility.ShouldShowGizmo) hides the classic Command_PawnAbility gizmo whenever the vanilla tracker provides the bridge gizmo — one gizmo per spell, cast path unchanged (the bridge delegates into the same JecsLite owner). - Generator v2: bridge defs copy uiIconPath -> iconPath (vanilla gizmo grid icon) and set displayGizmoWhileUndrafted=true (classic visibility); regenerated all 437. - TMBridgeAbility: GizmoDisabled greys out on the companion's real CanCastPowerCheck verdict (mana/cooldown/stage), with full ambient-state tolerance — the grey-out is cosmetic and can never break the gizmo, the cast re-checks admission. AICanTargetNow=false keeps vanilla AI out (our ResolveAIAutoCast retains AI ownership, no double-casting). Tests: VanillaBridgeTests 12/12 (icons, all-families gate, gizmo-hide, tolerant disabled-state, AI exclusion added). Neighborhood 30/0. FULL GATE: 1724 passed / 0 failed. * Live-bug fixes: world-pawn WarmupTick NRE + old-save gizmo blackout Player session on an old save (two symptoms, one root + one latent): 1) Ability.WarmupTick NRE spam on world pawns: the bridge abilities were running the vanilla verb/warmup machinery their cast path never uses. TMBridgeAbility.AbilityTick is now a no-op override — ticking stays on the companion's PawnAbility. 2) Spell gizmos vanished for old-save pawns (no knowledge comp in the save -> no bridges granted) while phase Б hid the classic gizmos based on the bridge DEF existing. ShouldHideLegacyGizmo now requires THIS pawn's tracker to actually hold the granted bridge — old saves keep the classic gizmos (fallback world), granted pawns get one vanilla gizmo. The Blood Sacrifice icon itself was fine (iconPath present; all 437 defs carry uiIconPath) — it reappears once the gizmo does. Tests: LegacyGizmoHiddenForEnabled now pins the old-save fallback (no grant -> classic stays) + granted-hide. Neighborhood 30/0. FULL GATE: 1724 passed / 0 failed. * Preserve spell knowledge across saves and cast through the active ability owner * Preserve progression across loads and fix hauling, rebinding, synthesis and golem shutdown * Give each vanilla ability bridge a primary verb for gizmo rendering and queue checks * Allow undrafted pacifists to reroll Chaos Tradition spells * Restore RWoM autocast controls and spell-specific casting permissions on tracked abilities * Skip area autocasts when no cells are designated * Return the original ritual Spirit to its stone on map host loss * Complete Spirit rebirth at the large circle for kill-finalized colonists * Stabilize patched regression runs and isolate optional Core settings * Keep Kure stamina potion addiction linked to its saved need * Preserve projected Fireclaw paths and damage ownership across saves * Preserve storm strike timing, cells and caster across loads * Save an armed mana mine without a fabricated target pawn * Credit Death Mark to the original caster after confirmed death * Require the deceased necromancer to renounce their class before spirit rebirth * Retain the paladin and their cargo during a saved or interrupted charge * Preserve the caster and settle Arcanist travel after a successful transfer * Keep technomancer shields, sabotage and machinery effects with their original caster * Keep Mark-IV turret ranks and weapon stats with each deployed turret * Preserve technomancer weapon identity, ammunition and repair ownership across spirit hosts * Preserve stored sunlight and repair bit state during spirit rebirth * Keep Sunfire beam paths and damage ownership through reload and spirit release * Charge a possessed Brightmage from the host cell once per sunlight interval * Verify the sunlight interval is restored from Scribe * Preserve Light Burst timing, payment and trial credit through spirit hosts * Keep flying light lances on their saved trajectory and retain light potency * Restore active Light Lance beams without replaying impact bonuses * Cast Light Lance from the spirit host with original damage and trial ownership * Restore Refraction targeting and preserve shield ownership across spirit release * Keep Light Skip passengers, cargo and arrival state in the native world transporter * Keep mass Light Skip departures recoverable and carry the original spirit with its host * Carry spirit hosts across the world only after a confirmed Global Light Skip destination * Preserve Spirit of Light commands and flight path when loading saved pawns * Keep the light spirit with its host and restore its chosen light source on load * Restore saved ability cooldowns after recreating the spirit companion command * Retain verified bard song effects on their original soul during rebirth * Release the finished selection verb when a Brightmage boards a world flight * Perform bard songs through the host while the original keeps trials, ranks and mana * Keep pending blood shield healing across loads and use the soul's rank for a host's blood * Ship the verified Brightmage runtime for RimWorld 1.7 * Allow a blood mage to leave the physical blood reservoir behind during rebirth * Cast Blood Shield through the host and charge its physical blood once * Preserve Ignite Blood pulses and credit the original mage when casting through a host * Keep blood transfer bound to its original mage, physical host and patient * Carry Rend ranks and damage attribution through the host and save * Keep Blood Moon targeting, weather and pending wolf attacks across saves * Preserve the Stoneskin charge ceiling when loading a damaged ward * Ship the verified Bard and Blood Mage runtime for RimWorld 1.7 * Track Stoneskin upkeep, charges and dispel on the geomancer inside a host * Keep geomancer earth sprites on their assigned map and inside its bounds * Let a possessed geomancer summon, maintain and dismiss earth sprites * Preserve owned Encase walls and credit the geomancer casting through a host * Save earthen hammer volleys and resolve stone stacks on their original map * Preserve a hosted geomancer's sentinels through awakening, return and shatter * Cast all four meteors with the original geomancer's ranks through a host * Ship the verified Geomancer runtime for RimWorld 1.7 * Keep predictions and incident trial credit with the chronomancer inside a host * Let hosted chronomancers alter only eligible events and register environmental changes * Apply accelerated time to the selected item, ally or area through a host * Reverse time on the selected target and credit the hosted chronomancer * Verify explicit spirit ritual consent for legacy liches * Preserve suspended pawns and ritual stacks through blocked chronostatic releases * Keep new and unsaved needs intact when rewinding a chronomancer * Preserve class and possession health records across a time rewind * Validate time recall destinations before moving pawns or intercepting fatal damage * Bind hosted time marks and recall triggers to the exact chronomancer and body * Ship the verified Chronomancer progression assembly for RimWorld 1.7 * Keep shaman chain lightning forks and source ranks through a saved cast * Cast all three shaman totems through a host and credit actual healing to the soul * Apply shaman ranks to Enrage and preserve damage credit across a save * Bind shaman Hex commands to their original caster and individual target effects * Preserve spirit pack ownership and form NPC summon groups without an existing lord * Keep guardian summons, cargo, crow insight and dismissal with the shaman * Ship the verified Shaman progression assembly for RimWorld 1.7 * Bind hosted transmutation to the selected stack and credit the enchanter * Sustain enchanted body and aura on the vessel with mana from the original caster * Keep enchanter artifacts bound to the caster across saved casts, equipment and dismissal * Tie weapon enchantments, mastery and dispelling to the caster and exact equipped weapon * Preserve polymorph ownership, duration and NPC groups through a hosted cast * Preserve the spirit and its host through both enchanter self forms * Skip dire wolf blink when its job or destination is unavailable * Ship the verified enchanter progression assembly for RimWorld 1.7 * Credit rune surgery to the learned golemancer while the host acts as doctor * Keep assigned golems bound to their master across possession and saves * Keep golemancer brand targets and effects paired during transfer and dispel * Cast and dispel all six golemancer brands through the host with soul-owned trial credit * Apply sigil strain to the host and keep both toggles with the golemancer * Keep Living Wall bound to the original golemancer and its casting body * Ship verified Golemancer progression and possession support for 1.7 * Cast Mind Killer from the host using the Empath's ranks and trial progress * Carry learned passive empathy into the Spirit's host without taking its native effect * Preserve the Empath's suppressive aura and mastery credit through possession * Bind projected Incite Passion to the soul's selected skill across save and load * Keep Harvest Passion's sustained transfer with its original Empath * Fade only painful memories and charge successful projected casts * Keep symbiosis linked to the physical host and split incoming damage once * Preserve existing demon soul bonds when a replacement target is occupied * Allow a leveled Empath to undergo the necromancer's Spirit ritual * Ship verified Empath progression, possession abilities and ritual recovery * Bind both demon contracts to the soul while the host supplies the physical effect * Preserve both Shadow Bolt projectiles and tick their flight independently of the camera * Resolve shadow travel through the bonded partner's current body * Carry bonded travellers across maps and caravans with one successful cast payment * Project Dominate from the soul and preserve its spread upgrades after loading * Preserve demon field waves, trial ownership and displaced pawns through reload * Preserve Psychic Shock wavefronts and attribute chained hits to the original caster * Keep the Scorn caster, soul and cargo owned throughout the flight * Preserve the bonded offering across demon summons, interruptions and reloads * Skip Scorn's targeting ring when the landing cell is invalid * Deliver verified Warlock and Succubus progression runtime * Preserve sniper shot ownership, payment and learned rounds through reload * Keep unresolved addon powers out of active class lookups * Retain possessed souls on opt-out and secure host loss while progression is paused * Provide a native scenario during soul stone stat checks * Deliver verified sniper rounds and spirit save safeguards * Retain sniper weapon techniques, salvo ownership and stealth through possession * Deliver verified sniper techniques, salvo and cloak * Preserve gladiator melee orders, grapple ranks and projected cleave ownership * Preserve Whirlwind passengers and source-owned gladiator wards and trials * Deliver verified gladiator techniques and flight recovery * Preserve Bladedancer attacks, Seven Steps and trial ownership through possession * Trace delegated spell methods in teleport camera regression checks * Recover equipped blade damage before the first post-load refresh * Deliver verified Bladedancer progression and hosted techniques * Keep Ranger bonds, companion visits and Animal Friend with the original pawn * Preserve Ranger trap planters, legacy contacts and service trial credit * Use the original Ranger training rank for the host's physical work * Keep Safe Trail participants, owner and retreat credit across saves * Preserve Ranger Arrow Storm volleys and their owners across reloads * Require an equipped bow for Ranger Arrow Storm * Keep Breakthrough tied to the Ranger and bonded companion while possessed * Credit rescue trials to the active Faceless discipline * Preserve Faceless imitation and echo ownership in a host * Preserve the remaining Reversal decay interval on reload * Bind projected Reversal and stamina siphoning to the Faceless owner * Clamp stamina once when animal upkeep reduces capacity * Reflect weapon hits without redirecting direct damage or explosions * Transpose pawns in place and preserve the original Faceless rank * Deliver verified Ranger techniques for RimWorld 1.7 * Release only targets actually controlled by Faceless possession * Keep the Faceless caster and nested Spirit through temporary control * Deliver verified Faceless techniques for RimWorld 1.7 * Attribute Psionic service trials to the acting discipline * Keep paid Psionic impulses, settings and energy readings across saves * Run retained Psionic augmentation from the active physical host * Preserve Psionic barrier ownership, interception and payment across loads * Keep Psionic Blast scatter within the map * Persist Psionic blast damage captured at launch * Add saved Psionic volleys through spirit hosts * Preserve active Psionic flight stages and trained parameters * Keep Psionic dash passengers owned until safe landing * Capture Psionic dash training from its ability owner * Charge hosted Psionic volleys their initial energy once * Project Psionic dash through hosts without losing carried cargo * Preserve Psionic leap passengers and stop augmentation after takeoff * Preserve storm passengers and run Psionic flight physics every tick * Unify psionic flight commands and source energy costs * fix: resume legacy psionic storm flight phases * Complete psionic crucible progression and hosted casting * RimWorld 1.7 port: beta progression, spirit rebirth, editor integrations, live fixes Major systems in this state (all live-tested on the user's colony): - Beta class progression: disciplines, foundation/adept/master trials, psionic crucible, martial paths (gladiator/sniper/bladedancer/ranger/commander/ super soldier/apothecary/monk/psionic/death knight/faceless/shadow walker), hosted casting for spirits - Spirit rebirth: classed-pawn grants, latent gene consumption, psycaster-safe release, soul stone custody, health form reconciliation - Class gene sync: latent/active gene enforcement, inheritance, birth enchants - Ability AI handover (saintwacko.AbilityAI): MightPowersG owners for Sweep/Maneuver, grimoire visibility guard for classic gladiators - Character Editor bridge (void.charactereditor): floating grant-class picker via ClassGrantTool facade, full enrollment workflow from the editor - Bug fixes from live reports: Super Soldier weapon gizmo wipe (stale MightData guards), gladiator grimoire visibility (owner-first Sweep/ Maneuver), commander Work Crew deterministic acceptance, spirit rebirth psycaster-safe release, RimTraits trait-index shift immunity Verified: full regression 2658/2658 (24 quarantined baseline cases), staged acceptance runs, live colony testing of the grant picker and trials. Installed state matches artifacts/final-staged (backup 200623-714 and later). * Save/load and targeting fixes: SS ghost weapons, Blink LOS, Brightmage scroll restore; undead corpse storage filter - Super Soldier specialized weapons: Rebuild/RestoreOriginal now reclaim a slot whose holder diverged from the tracker (1.7 ThingOwner.Remove keys on holdingOwner and silently no-ops), and orphan bindings (copy reference lost to a failed cycle) restore the stashed original instead of stacking another ghost copy; fixes the 'corrupted ghost weapon' save/load loop (log: 'got primaryInt equipment ... while already having') - Blink and all requiresLineOfSight=false abilities: the JecsLite verb hardcoded needLOSToCenter=true, so the vanilla ability targeter demanded line of sight from the player only (AI paths bypass the targeter); a postfix mirrors verbProps.requireLineOfSight back into the targeter flag - Brightmage/off-class scroll spells: TM_ClassState.IsMagicPowerAuthorized now authorizes a power when its knowledge entry is learned, so Heal (Paladin list), Rainmaker and Blink survive reload on custom classes while unlearned off-class powers stay unauthorized - New storage filter 'allow undead corpses' (humanlike + animal): covers necromancy-raised corpses in stockpiles and butcher bills, gated by a postfix that removes them from the vanilla colonist/stranger/slave corpse filters; RU translations included Tests: SuperSoldierWeaponReloadTests x3, TargeterLosTests x2, KnowledgeRestoreTests x3, SpecialThingFilterTests x4; SS/reload/soldier/ class grant/special filter/grimoire knowledge/brightmage neighborhood 112/112 forward and reverse
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hi. I realize how this might look or sound, but I absolutely LOVE your mod. I really wanted to play it in 1.7, but there were a ton of bugs cuz 1.6 version.
Long story short, I made a deal with the devil (AI), forked the mod, and got it into a state that works for me - plus a few extra changes:
I’ve also published this "AIslop" on the Workshop. If you decide that I should take it down, please let me know via Steam - I’m almost always online (or set to "invisible") there.
Link to the Workshop: https://steamcommunity.com/sharedfiles/filedetails/?id=3823345404