diff --git a/docs/plans/2026-08-24-character-advancement-campaign.md b/docs/plans/2026-08-24-character-advancement-campaign.md index 47c730d0..35eacb65 100644 --- a/docs/plans/2026-08-24-character-advancement-campaign.md +++ b/docs/plans/2026-08-24-character-advancement-campaign.md @@ -123,4 +123,4 @@ neighborhood). | CA2 | COMPLETE 2026-08-24 (`65430d4c`) | 0x02E3/0x02DD parsers + WorldSession events + router routing into LocalPlayerState; conformance tests incl. holtburger golden fixture; 0x02DF deliberately unparsed (no ACE producer) | | CA3 | COMPLETE 2026-08-24 | Live formula recompute (SkillFormulaBonusResolver over RetailSkillFormula) on attribute writes + fresh-train derivation; movement re-applied down the PD seam (PushMovementSkillTotals — Quickness raise → run speed, no relog); vitals bar pull-model verified; router behavior + fresh-train tests | | CA4 | COMPLETE 2026-08-24 | Optimistic ApplyLocalRaise layer DELETED; retail one-in-flight + ghost + server-authoritative flow ported per the pinned §5 pseudocode (AP-73 NARROWED — rejection-release semantics owed to CA5 live); train cost verified DAT-exact; specialize correctly has no panel send (gem + confirmation route, seams already present); provider contract tests rewritten | -| CA5 | — | | +| CA5 | SCRIPT WRITTEN 2026-08-24 — awaiting the owner drive | docs/research/2026-08-24-campaign-ca-test-script.md (scratch character; §3.2 resolves the narrowed AP-73) | diff --git a/docs/research/2026-08-24-campaign-ca-test-script.md b/docs/research/2026-08-24-campaign-ca-test-script.md new file mode 100644 index 00000000..cae336db --- /dev/null +++ b/docs/research/2026-08-24-campaign-ca-test-script.md @@ -0,0 +1,142 @@ +# Campaign CA — connected gate script (CA5, user-driven) + +**Purpose:** live verification of the whole advancement chain against ACE +after CA1–CA4 (`1fc64984`, `65430d4c`, `57818959`, `08b77e20`). Everything +below should be visible **without a relog** — that is the entire point of +the campaign. + +**Character:** use a SCRATCH character (owner decision 2026-08-24 — XP and +skill credits will be spent, and the respec checks are destructive). +A fresh character is ideal: low attribute costs mean many cheap raises. + +**Launch:** the normal connected launch (`ACDREAM_RETAIL_UI=1`, live ACE at +`127.0.0.1:9000`). No diagnostic env vars needed. Useful ACE console +helpers: `@ci ` to spawn gems, `@grantxp`, `@grantskillcredits` +(see `claude-memory/../memory/reference_ace_commands.md`). + +Open the Character panel (F9 / toolbar) before starting; keep the vitals +bar visible throughout. + +--- + +## 1. Attribute raise → derived skills + run speed (the original #431) + +Prep: bank some XP (`@grantxp` if the scratch character is too poor). +Note current run speed by running a straight line; note the Run skill's +displayed value and one other Quickness-fed skill (e.g. Melee Defense). + +1. Raise **Quickness** by 1. + - PASS: the attribute value updates when the server record lands (a + round trip, not a relog); **Run and every Quickness-fed skill row + update in the same moment**; XP remaining drops by the server's + accounting. +2. Raise Quickness repeatedly until the formula contribution crosses a + point (attribute current +2 → skill formula +1 for /2-divisor skills). + - PASS: skill rows tick up as the attribute crosses each threshold. +3. **Run before and after.** With `runrate_add_hooks` active on ACE the + server also re-broadcasts your movement speed mid-run. + - PASS: run speed visibly increases after the raise — at latest on the + next movement start. FAIL if speed only changes after relog. +4. While the raise is in flight (click and watch closely): the raise + buttons ghost momentarily and un-ghost when the record lands. + - PASS: brief ghost; no double-send on rapid double-click (the second + click does nothing). + +## 2. Endurance/Self raises → vitals maxima (the single-record quirk) + +Note max health / max stamina / max mana from the vitals bar. + +1. Raise **Endurance** by 1–2 points. + - PASS: **max health AND max stamina both move** on the bar and the + panel (ACE only pushes a Health record; the client-side fan-out must + cover Stamina — research doc §4.1). +2. Raise **Self**. + - PASS: max mana moves. +3. Sanity: current values don't jump wrongly (regen keeps ticking + normally; watch ~10 s). + +## 3. Direct vital raise + the retail raise-10 client bug (AP-73 CHECK) + +1. Raise **Max Health** directly by 1. + - PASS: bar max + panel update on the record; XP debits. +2. **The deliberate failure case** — this resolves the narrowed AP-73 row. + Arrange XP so you can afford exactly ONE vital raise but not ten + (spend down; the cost curve is steep so this is easy). The retail + client bug ACE documents: the raise-10 button is enabled anyway. + Click **raise ×10**. + - EXPECTED from ACE: chat line "Your attempt to raise ... has failed." + and NO stat change. + - **RECORD: do the raise buttons stay ghosted afterward?** + - If they un-ghost on their own → note what un-ghosted them (a regen + tick counts as a quality change — that is retail-plausible and + AP-73 can then RETIRE with that mechanism recorded). + - If they stay ghosted until you close/reopen the panel → AP-73's + symptom confirmed; report it and we decide the fix against the + retail oracle (cdb on the live retail client if needed). + +## 4. Skill raise + +1. Select a TRAINED skill, raise ×1 and ×10. + - PASS: ranks/value update on the record; XP debits; the + "Your base skill is now N!" advancement line appears in the + SpewBox with the advancement color. +2. Confirm an attribute-less skill (e.g. **Salvaging**, if trained) shows + value = ranks-only progression and raises normally. + +## 5. Train a new skill + +Prep: ensure ≥ the DAT cost in skill credits (`@grantskillcredits`). + +1. Select an UNTRAINED skill, click Train. + - PASS: the skill flips to Trained on the record; credits drop by the + DAT cost; chat: " trained. You now have N credits available." +2. NEGATIVE (silent-failure probe): nothing client-side should allow a + wrong cost, so simply confirm no double-send on rapid clicks and that + the button ghosts while awaiting. + +## 6. Specialize / lower (SkillAlterationDevice) + +Prep: `@ci` a **Gem of Enlightenment** (specialize) and a +**Gem of Forgetfulness** (lower) — wcids per ACE's db (ask the console +with `@acecommands` if unsure). + +1. Use the Enlightenment gem on a TRAINED skill. + - PASS: retail confirmation dialog appears; on accept, the skill flips + to Specialized, credits drop, and the "You have succeeded + specializing..." notice lands in chat (the 0x028B + WeenieErrorWithString route). + - Also confirm DECLINING the dialog changes nothing. +2. Use the Forgetfulness gem: Specialized → Trained, then Trained → + Untrained. + - PASS: each step updates the panel on the record and refunds credits + per ACE's accounting; an untrained skill row returns to the + untrained section with formula-only value. + +## 7. Respec-adjacent (as far as ACE supports) + +If ACE's Enlightenment/attribute-reset paths are reachable on this server +(level requirements may block a scratch character — skip if so), exercise +one and confirm the client tracks every pushed record without a relog. +Otherwise mark N/A — the message shapes are identical to §6's, so §6 +passing covers the client-side mechanism. + +## 8. Regression sweep (5 minutes) + +- Vitae/buff display still correct after raises (buff an attribute; panel + shows effective + base pair; skill values include the buff through the + formula). +- Logout/login: everything you raised persists and PlayerDescription + agrees with what the live records showed (any mismatch = a parser bug — + report exact numbers). +- Ordinary play smoke: run, jump, cast, fight one mob — nothing about + movement feel changed outside the raises. + +--- + +## Report back + +Per section: PASS/FAIL plus anything odd. The three answers that matter +most: +1. §1.3 — did run speed change live? +2. §2.1 — did max STAMINA move on an Endurance raise? +3. §3.2 — the AP-73 ghost question (un-ghosted by what / stayed stuck?).