# 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?).