Man0u1 "Court in the Sands": full port of the Ul'dah MSQ #2 + the end-of-man0u0 teardown crash (#53, #26)#205
Conversation
#26) The post-tutorial teardown of the Ul'dah opener hard-closed the 1.23b client. PR #156's packet forensics (Rounds 6-8, closed unmerged) proved the SetEventStatus-disable burst apply_despawn_actor emitted before each RemoveActor was the single byte-level delta in both captured instant-crash bursts vs the surviving load — pmeteor's Npc.Despawn never emits disables. Both Round-7 halves re-landed: - apply_despawn_actor reverted to RemoveActor-only (pmeteor parity). - SimpleContent30079 no longer spawns the 1090385 arena stopper — the only circle-bearing prop, source of the original +4s ghost-exit-circle crash the disarm was chasing. Limsa's upstream-tested twin (30002) ships no stopper either. Rounds 6-8 forensics ported into docs/implementation/quest_man0u0_seq000_qflag_none.md with per-fix status vs the current tree (hunks 1/2 superseded by the DepictionJudge hateType findings and the fresh-ordinal group-id scheme; hunk 3 landed via 86c8df2; hunk 5 party /_init HELD pending retest). Known follow-up (out of scope): Gridania's SimpleContent30010 still spawns its 1090384 stopper and carries the same latent ghost-circle risk post-battle.
SetCounter/IncCounter/DecCounter on LuaQuestDataHandle queued the persistence command but never updated the handle's in-VM counters copy, so a script that mutates then re-reads the same counter inside ONE hook call saw the pre-mutation snapshot — the exact counter twin of the #41 SetFlag/GetFlags write-through bug. Surfaced by man0u1's SEQ_057 calming check (IncCounter then GetCounter in the same onEmote), which could never advance. Inc/Dec now also return the true post-mutation value.
Finishes the skeleton (previously dead-ended at the SEQ_005 attune): the complete retail sequence machine SEQ_000 -> SEQ_105, evidence- backed by 12 OCR'd playthrough/dev videos, the decoded client script (113 events, text sheet 1359), the client quest_marker/quest_new_reward sheets, and the pmeteor phase-table header — source map in docs/implementation/quest_man0u1_court_in_the_sands.md. - man0u1.lua: guild legs with GSM/GLD counters (Eshtaime's 2,000-gil flower echo; Coliseum recruit -> Lulutsu pass check -> arena), the Amajina brawl instances (F'lhaminn's six-emote school 103/108/121/ 125/140/135 + the Maddened/Manic calming with per-miner rebuffs), the Gate of Nald escort handoff, the Camp Black Brush Ascilia echo, the Momodi/F'lhaminn payment beats, the Phrontistery ward survey + Warburton echo, three Momodi linkpearl calls (NpcLS packs), journal markers off the client 110010xx block, completion 200 EXP + 6,000 gil (quest_new_reward.csv row 110010) + mid-quest 2,000/3,000 gil. Fixes the #53 defects: debug SendMessage removed, undefined marker globals replaced with the real sheet block, placeholder ids resolved (Velodyna Cosmos 11000089, Coliseum Pass 11000126, Thancred 1000948 confirmed via the display-name indirection). - SimpleContentMan0u101 + QuestDirectorMan0u101: the unwinnable Tourney Gladiator match — loss (1-HP floor pin or timeout) IS the completion condition; post-match "splendid match" cutscene -> gathering echo -> linkpearl handback. - SimpleContentMan0u102 + QuestDirectorMan0u102: the F'lhaminn escort (30-min duty, chinchilla ambushes, retail barks 365-376, retreat-and-retry fail) on the sibling escort machinery. - Seeds 093-096: 44 scene-cast/trigger spawn rows (marker-anchored), the 1090285 gate trigger + 1090283/1090119 condition merges, emote conditions for F'lhaminn/Manic/Maddened, and the arena/escort battle-npc pools/groups/spawns (bnpc 42-51). - content-test: new emote driver (+ testkit expire_time_parks) and expectCompleted assertion; scripts/tests/quests/uldah_msq2.lua walks all nine legs — 18/18 cases green; all six CI gates pass. Live-test checkpoints (fade shapes, arena/route coordinates, emote motion ids) are enumerated in the design doc.
…iene, Quicksand cast Adversarial branch review (3 lenses, 0 CRITICAL/HIGH) surfaced six actionable items: - QuestDirectorMan0u101: UpdateENPCs after the GLD SetCounter — SetCounter alone never re-runs onStateChange, so the echo-PA zone-in replayed the stale GLD==3 snapshot and Greinfarr (the only quest-advancing NPC there) landed un-iconed. - SimpleContentMan0u101: pacify the gladiator (ChangeState 0) in the completion tick so no live combat packets interleave the post-match kick/cutscene (the sibling escorts' arrival-gate invariant, which a lose-to-complete fight can't otherwise satisfy); restore the player to full HP before teardown (retail revives the loser; a 1-HP exit would persist into open-world zone 170); defeat line switched to the literal-fallback shape (30121 with a runtime actor id renders a blank subject — the #199 DispId-sender finding). - man0u1.lua: arena duty warp offset ~6 units from the gladiator's spawn point (no more materializing inside the opponent); the SEQ_000 onNotice explainer driven with the raw non-parking RunEventFunction (its client body is the no-EventUpdate worldMaster.say shape — the documented callClientFunction park-forever family); Lulutsu's pass-check gated on the briefing having happened. - seed/097: the SEQ_000 Quicksand intro-instance ambient cast — nine PA (175,PrivateAreaMasterPast,4) spawn rows + the classPath fills for the eight stripped classes (the seed/061 crash family), making the processEvent000_2..10 talk branches reachable. Remaining review notes (Corguevais corpse pose at SEQ_058, formula- derived emote motion ids, arena/route coordinates) stay as live-test checkpoints in the design doc.
6 tasks
…ndle (#26) The client still died seconds into the QuestDirectorMan0u001 handoff warp with the teardown disarm + arena stopper already fixed. Packet forensics against the SURVIVING Gridania/Limsa handoffs (identical warp machinery, byte-identical player-stream opcode order) pinned the delta to Ul'dah's destination spawn set — the crash was in the bundle, not the warp: - seed-031 row 943 'mumpish_miqote' has actorClassId=0 (the only class-0 spawn row in the DB); the junk class-0 gamedata row let the spawn pass materialize an actor whose 0x00CC ActorInstantiate ships an EMPTY class name + client-script path. That instantiate appears exactly 4 times in the retained packet logs (2026-06-17, 07-01, 07-09 x2) — every occurrence shows the same death signature (pings stop instantly, type-0x1001 close ~15 s later), including a controlled A/B where the same client survived the Gridania handoff nine minutes earlier. - Rows 936/937 seed bare 5900004 doors into PA_3 with neither a mapobj row nor an appearance row — the 0x00D6 model_id-0 nil-deref family migration 092 removed from Gridania for the same reason. Fixes: - seed/098: DELETE rows 936/937/943 (containment is already handled by the blocker push rows + uldah_opening_exit; the intended mumpish class is documented unused on this client version). - npc/spawner.rs: skip any spawn row whose class has an empty classPath, with a warn — the guard covers the whole family, and the first boot already caught two MORE latent client-fatal rows (zone 171 'audouin' + 'flame_sergeant_hanette'). - exit_trigger.lua (zone 184): the GetStaticActor("Man0u0") GetQuestFlag nil error on every post-claim push → player:GetQuest + a SEQ_000 gate (without it the legacy arm would re-create the tutorial content on a stray push once the flags latch at 0xF), plus the man0U0Quest typo. Not the crash, but live noise from the same session. All six gates green (876 workspace tests, 18/18 content-test, SMOKE_OK).
swstegall
deleted the
53-man0u1-court-in-the-sands-uldah-msq-2-finish-the-skeleton-port-only-seq_000005-wired-dead-ends-at-attune-miners-guild-coliseum-instances-unimplemented-fix-debugundefined-global-defects
branch
July 10, 2026 02:23
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.
Summary
Two deliverables, four commits:
1. The end-of-Flowers-for-All Wine crash (#26 tail) — fixed. The
post-tutorial teardown hard-closed the client. PR #156's unmerged
packet forensics (Rounds 6-8) proved the SetEventStatus-disable burst
apply_despawn_actoremitted before each RemoveActor was the singlebyte-level delta in both captured instant-crash bursts vs the run that
survived. Re-landed both Round-7 halves surgically: RemoveActor-only
despawn (pmeteor parity) + SimpleContent30079 no longer spawns the
1090385 arena stopper (the only circle-bearing prop — the source of the
original +4s ghost-exit-circle crash the disarm was chasing). The
Rounds 6-8 forensics are ported into
docs/implementation/quest_man0u0_seq000_qflag_none.mdwith per-fixstatus vs the current tree (#156's other hunks were superseded by the
DepictionJudge hateType findings / the fresh-ordinal group-id scheme /
86c8df2; the party
/_inithunk is HELD pending retest). Knownfollow-up out of scope: Gridania's SimpleContent30010 still spawns its
1090384 stopper and carries the same latent risk.
2. Man0u1 "Court in the Sands" (#53) — complete. The skeleton
(dead-ended at the SEQ_005 attune) is now the full retail
SEQ_000→SEQ_105 machine, evidence-backed by 12 OCR'd videos (both
retail full playthroughs, the 5-part Siddeon run, Slerp Lederp's dev
demo — which leaks the internal SEQ numbers and the six retail journal
texts verbatim — and his emote-segment capture), the decoded client
script (113 events, sheet 1359), and the client
quest_marker/quest_new_reward sheets. Source map + live-test
checkpoints:
docs/implementation/quest_man0u1_court_in_the_sands.md.echo (+2,000 gil), the Coliseum recruit cutscene → Lulutsu pass check
→ the unwinnable Tourney Gladiator arena match (content area
Man0u101— the loss IS the completion condition; Mirke: "There isno way to win.") → the "splendid match" + "gathering" echoes →
Momodi's linkpearl (NpcLS).
F'lhaminn's six-emote school (Furious/Beckon/Laugh/Deny/Upset/Soothe
— ids decoded from the client demo schedulers), the Maddened/Manic
calming with per-miner retail rebuff barks, the Popokkuli & Seserukka
ending.
of Nald → Camp Black Brush, chinchilla ambushes, retail barks
(sheet texts 365-376), retreat-and-retry fail — on the wire-proven
sibling escort machinery (content area
Man0u102).(ward survey + the Warburton echo + the no-pay report), three Momodi
linkpearl calls, journal markers from the client 110010xx block,
completion 200 EXP + 6,000 gil (quest_new_reward.csv row 110010).
marker globals replaced with the real sheet block; placeholder ids
resolved (Velodyna Cosmos 11000089, Coliseum Pass 11000126, Thancred
1000948 confirmed via the display-name indirection).
mirror (the counter twin of the Man0g1 "Souls Gone Wild" (Gridania MSQ #2): implement stubbed escort duty + fix SEQ_003/journal-marker/onNotice bugs #41 flag bug — without it the miner
calming could never advance).
Quicksand intro crowd), the 1090285 gate trigger + 1090283/1090119
condition merges, emote conditions, arena/escort battle-npc data.
emotedriver +expectCompleted;scripts/tests/quests/uldah_msq2.luawalks all nine legs (18/18cases green).
An adversarial 3-lens branch review (0 CRITICAL/HIGH) drove the final
commit (echo-PA icon re-arm, arena loss hygiene, the Quicksand cast).
Test plan
cargo fmt --all --checkcargo clippy --workspace --all-targets -- -D warningscargo build --workspace --all-targets --lockedcargo test --workspace --locked(774 + 51 + 19 + 10 + 22 green)cargo run --locked -p content-test(18/18 incl. the new Man0u1 spec)PROFILE=debug scripts/smoke-local.sh(SMOKE_OK all services)fade-shape assumptions on processEvent075/080/220, arena coords
(GC-marker anchored), the escort route interpolation (wants the
RECORD_MODE re-capture pass the siblings got), formula-derived
DoEmote motion ids, the Corguevais corpse pose at SEQ_058.
Fixes #53. Finishes #26 (the teardown crash — the SEQ_000 softlock half
was already closed).