Skip to content

refactor: split the four longest production functions - #413

Merged
Mathih13 merged 3 commits into
mainfrom
refactor/split-longest-functions
Sep 3, 2026
Merged

Mathih13 merged 3 commits into
mainfrom
refactor/split-longest-functions

Conversation

@Mathih13

@Mathih13 Mathih13 commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor

Four production functions had grown past the point where anyone — human or agent — can hold one in their head: build_dump_plan at 1,387 lines, map_action at 929, build_spell_rows at 712, and apply_effect at 681. Each already carried section markers or a per-family match, so the structure was there; only the boundaries were missing.

This splits each along the seams it already had.

build_dump_plan now reads as its own numbered sections: the World Import Scope's creature spawns, the entry set the EventAI fixpoint grows, the template rows, the cast rows, the packed spawn payload, the waypoints, the gameobject import, the trainer offerings and the four loot families. The per-family clear+reload blocks push in the same order as before, off one borrowed view of the mapped rows.

map_action keeps the match as the dispatcher and sends each family to its own mapper: speech, combat, phase, summons, movement, unit state, encounter and quest. Every ACTION id is distinct, so grouping the arms preserves each kind's own arm order, guards and fallbacks.

build_spell_rows splits into the DBC open, the header row, the effect rows and the trainer offerings, with the effect kind and target resolution named apart.

apply_effect keeps its dispatch shape — a match on e.kind, one arm per family — and hands off to a named applier per family. The aura branch stays inline, because an architecture test pins apply_effect itself on the aura-application boundary.

function before after
build_dump_plan 1,387 184
map_action 929 140
build_spell_rows 712 58
apply_effect 681 129

The longest function this branch introduces is push_spell_header_row at 197 lines, about a fifth of it the schema-bug note it inherited.

Keeping it that way

clippy::too_many_lines now warns workspace-wide. Its default threshold of 100 fires on 140 pre-existing functions and would bury every real finding, so clippy.toml sets 200 — the size this split targeted. That leaves 43 warnings, none in the code this branch touched: 16 are the generated SpacetimeDB bindings, the rest are long functions that were already there. Lower the threshold as those shrink.

Verification

The split preserves each section’s behavior. Review follow-up removed extraction-only borrow and return lint findings and reused the existing creature-spawn row alias.

  • cargo test -p lyracore-importer: 337 pass, 2 ignored (they need the pinned classic-db SQL).
  • cargo test -p lyracore-module --lib --features=debug_reducers: 1,461 pass.
  • Determinism: a throwaway test hashed each fixture's whole DumpPlan — statements, spawn and EventAI batches, Compatibility Manifest, provenance stamps — across all eleven families, before and after. Every hash matches. The test is not in the branch.
  • bash importer/scripts/import-world-sql-test.sh and import-manifest-smoke.sh give the same results as main (the SQL script's 11 failures are pre-existing and stub-driven).
  • rustfmt was run per file with skip_children, so no other file drifted. It did reflow two assertions in targeting.rs's own test module that were already unformatted on main; that is the only change outside the four functions.

build_spell_rows has no test coverage — it needs a real client MPQ chain — so its split rests on the compiler and on the verbatim copy.

Written by Claude Fable 5.1 (Opus 5, 1M context) in Claude Code.

Review fixes by GPT-5.6 through the Codex harness in T3 Code.

Mathih13 and others added 3 commits September 3, 2026 19:40
`build_dump_plan` (1,387 lines), `map_action` (929) and `build_spell_rows`
(712) each held a whole pipeline in one body. Each already carried its own
section markers, so the split follows them.

`build_dump_plan` now reads as its numbered sections: the World Import Scope's
creature spawns, the entry set the EventAI fixpoint grows, the template rows,
the cast rows, the packed spawn payload, the waypoints, the gameobject import,
the trainer offerings and the loot families. The per-family clear+reload blocks
push in the same order as before, off one borrowed view of the mapped rows.

`map_action` keeps the match as the dispatcher and sends each family to its own
mapper: speech, combat, phase, summons, movement, unit state, encounter and
quest. Every ACTION id is distinct, so grouping the arms keeps each kind's own
arm order, guards and fallbacks intact.

`build_spell_rows` splits into the DBC open, the header row, the effect rows and
the trainer offerings, with the effect kind and target resolution named apart.

Behaviour is unchanged: every section body moved verbatim. A throwaway
fingerprint over each fixture's whole `DumpPlan` (statements, batches, manifest,
stamps) across all eleven families hashes identically before and after.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ngth

`apply_effect` dispatched 30 effect kinds in 681 lines. The dispatch shape
stays: a match on `e.kind`, one arm per family, each handing off to a named
applier — damage, restore, threat, reposition, inventory, character and the two
that delegate to another engine path. The aura branch stays inline, because an
architecture test pins `apply_effect` itself on the aura-application boundary.
Every arm body moved verbatim; the 1,461 module tests pass unchanged.

`clippy::too_many_lines` now warns workspace-wide so this does not grow back.
Its default threshold of 100 fires on 140 pre-existing functions and would bury
every real finding, so `clippy.toml` sets 200 — the size this split targeted.
That leaves 43 warnings, none in the code this branch touched: 16 of them are
the generated SpacetimeDB bindings, and the rest are long functions that were
already there.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Mathih13
Mathih13 merged commit 5c10f13 into main Sep 3, 2026
1 check passed
@Mathih13
Mathih13 deleted the refactor/split-longest-functions branch September 3, 2026 20:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant