Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
549 commits
Select commit Hold shift + click to select a range
01f4b29
feat: Quaternius Ultimate Monsters Pack — 45 CC0 animated GLBs + norm…
mokn Apr 3, 2026
976aca3
chore: add remaining 24 Quaternius monsters to glb/ (unused in viewer…
mokn Apr 3, 2026
bbf7a31
fix: correct 3/4 left-facing orientation for all GLB creatures
mokn Apr 4, 2026
369839d
fix: yaw -60° for 3/4 left-facing — all GLBs face +Z not -Z
mokn Apr 4, 2026
ba9a2d0
feat: add creature-forge.mjs — Meshy API pipeline for scary monster g…
mokn Apr 4, 2026
0a58f05
fix: creature-forge uses real Meshy test API (no credits, real sample…
mokn Apr 4, 2026
fb614c2
feat: animated dire rat + toon material texture preservation
mokn Apr 4, 2026
fb38759
feat: animated GLB dire rat in pretext ASCII battle renderer
mokn Apr 4, 2026
f07634d
fix: add console logging to glbCreatureLoader to diagnose load failures
mokn Apr 4, 2026
0bd1b5a
fix: preload dire rat GLB on battle scene module load, not first frame
mokn Apr 4, 2026
018fde2
chore: commit pnpm-lock.yaml with three.js dependency
mokn Apr 4, 2026
19fa440
fix: add blob: to CSP connect-src for Three.js GLB texture loading
mokn Apr 4, 2026
5cd0995
fix: dire rat upside-down and not animating
mokn Apr 4, 2026
8ddcacc
fix: hide redundant HP bar and stats from StatsPanel during battle
mokn Apr 4, 2026
fece0da
fix: flip orthographic camera Y instead of canvas transform
mokn Apr 4, 2026
b3476bc
fix: restore canvas Y-flip, revert broken camera top/bottom swap
mokn Apr 4, 2026
a58a564
test: remove canvas Y-flip — test if drawImage handles it natively
mokn Apr 4, 2026
59be921
fix: restructure battle HUD — move monster HP to bottom-right, remove…
mokn Apr 4, 2026
810bad9
fix: add HP bars back to battle cockpit for both player and opponent
mokn Apr 4, 2026
2e83527
chore: upgrade dire-rat in creature lab to GLB pipeline
mokn Apr 4, 2026
c1f0e99
feat: add kobold animated GLB via Meshy rig+animate pipeline
mokn Apr 4, 2026
57fc41f
feat: add kobold.html creature lab viewer page
mokn Apr 4, 2026
f92335c
feat: regenerate kobold with prominent bone spear weapon
mokn Apr 6, 2026
f29daa8
feat: add GLB animated models for goblin, skeleton, goblin shaman, bu…
mokn Apr 6, 2026
a60173f
chore: clean up creature lab — remove test monsters, upgrade to GLB p…
mokn Apr 6, 2026
8afed45
fix: raise MAX_LEVEL from 10 to 20 for beta Z2 leveling
mokn Apr 6, 2026
a4386ca
feat: add headless screenshot pipeline and archetype system for creat…
mokn Apr 6, 2026
9a9c928
feat: add creature review page — all animation clips at game quality
mokn Apr 6, 2026
fd111f7
feat: add side-by-side lab + game view to creature review page
mokn Apr 6, 2026
7139a07
fix: validate monster position on-chain before combat to prevent ghos…
mokn Apr 6, 2026
3d6971b
fix: port production ghost monster fixes to beta
mokn Apr 6, 2026
db94e03
fix: add eviction protection to prevent WS from re-adding ghost monsters
mokn Apr 6, 2026
848eed5
fix: ghost validator reads PositionV2 instead of legacy Position table
mokn Apr 6, 2026
9480d0c
feat: add fog of war to ASCII dungeon map
mokn Apr 6, 2026
c13baa1
fix: remove @chenglou/pretext dependency from map component
mokn Apr 6, 2026
495aae4
fix: resolve blank map canvas — absolute positioning for proper sizing
mokn Apr 6, 2026
96f898d
fix: clean up map — dragon piece, remove counts and axis labels
mokn Apr 6, 2026
dd5987b
fix: strip entity markers from zone map — only NPCs/shops/exits visible
mokn Apr 6, 2026
0eb6319
feat: authored world map with zone toggle
mokn Apr 6, 2026
f559440
fix: world map as full-screen overlay instead of inline panel
mokn Apr 6, 2026
89b6205
chore: force Vercel rebuild for stale CDN cache
mokn Apr 6, 2026
2549a03
fix: move world map overlay into MapPanel scope — was in NavigationCo…
mokn Apr 6, 2026
b3a4cd6
fix: click anywhere on world map overlay to dismiss it
mokn Apr 6, 2026
ac0e07f
feat: creature lab - canvas creatures, review page fixes
mokn Apr 6, 2026
7ef6e9d
feat: creature lab - hook horror, basilisk, giant spider GLBs
mokn Apr 6, 2026
0997d69
chore: add version marker to relayer health check
mokn Apr 6, 2026
ee2a496
chore: deploy marker
mokn Apr 6, 2026
3ffb9ab
chore: cache bust Dockerfile
mokn Apr 6, 2026
aecf4ea
revert: remove temp deploy markers
mokn Apr 6, 2026
231966e
fix: replace all third-party RPC defaults with OVH node
mokn Apr 7, 2026
c8f2176
feat: wire all Meshy creature GLBs into game as ASCII sources
mokn Apr 7, 2026
6473018
fix: revert gelatinous ooze to canvas, update creature lab to use GLBs
mokn Apr 7, 2026
643844d
fix: compact HP bars and fix tooltip z-index (#325)
mokn Apr 7, 2026
7f933c4
fix: keep animated HealthBar (8px), fix Vercel lockfile
mokn Apr 7, 2026
e7874cd
fix: replace inline StatsPanel HP bar with animated HealthBar component
mokn Apr 7, 2026
5e0d727
fix: reduce ghost encounter dismiss timeout from 120s to 15s
mokn Apr 7, 2026
6806384
fix: prevent ghost encounter race condition (contract + client)
mokn Apr 7, 2026
87c8544
fix: remove redundant canvas HP bars, compact HealthBar, fix weapon t…
mokn Apr 7, 2026
7c24844
fix: ghost dismiss only fires when opponent is null (not real battles)
mokn Apr 7, 2026
cecdb4c
feat: forge 5 Z2 Windy Peaks creatures via Meshy pipeline
mokn Apr 7, 2026
25ec602
fix: add Z2 creatures to viewer.html dropdown and navigation
mokn Apr 7, 2026
7ff5fe0
feat: add Orc Shaman and Troll — all 7 Z2 creatures now forged
mokn Apr 7, 2026
2cf2e48
feat: add live animated gallery page to creature lab
mokn Apr 7, 2026
780d5e0
fix: link index cards to review page (shows all animation clips)
mokn Apr 7, 2026
748f2c0
perf: switch review page from pre-capture to live rendering
mokn Apr 7, 2026
ab7f1f0
feat: add procedural ASCII cave background to battle scene
mokn Apr 7, 2026
7c33330
fix: clean up battle console UX — remove noise, compact layout
mokn Apr 7, 2026
1897dd3
fix: harden combat state bootstrap against ghost encounters
mokn Apr 7, 2026
66fb726
docs: update ghost encounter launch checklist
mokn Apr 7, 2026
35db116
fix: run beta deploy via pnpm exec mud
mokn Apr 7, 2026
aab69a7
feat: forge 3 player character base models (human/elf/dwarf)
mokn Apr 7, 2026
9b52c25
feat: add player character to battle scene, fix name positioning
mokn Apr 7, 2026
4b8036e
fix: increase cave background visibility — alphas and colors were too…
mokn Apr 7, 2026
843bbec
fix: align beta deploy workflow with runbook
mokn Apr 8, 2026
00752cc
feat: rewrite cave background with connected rock formations
mokn Apr 8, 2026
a2e4fea
fix: align weapon card layout — center badge, icon, and name in a row
mokn Apr 8, 2026
5cc20fc
fix: align battle scene timing with combat pacing
mokn Apr 8, 2026
79909a6
fix: preserve character race in battle rendering
mokn Apr 8, 2026
b24664a
feat: surface battle results in scene
mokn Apr 8, 2026
93294de
feat: surface battle results in scene
mokn Apr 8, 2026
2163752
fix: relax privy embedded wallet auth matching
mokn Apr 8, 2026
89da21a
fix: harden beta relayer embedded auth matching
mokn Apr 8, 2026
5b4e31a
fix: use embedded wallet for gas retry funding
mokn Apr 8, 2026
c9d1923
fix: refresh embedded relayer auth token
mokn Apr 8, 2026
6403759
feat: creature-edit CLI + dodge/walk clips + bone conventions
mokn Apr 8, 2026
2191fc2
fix: simplify battle feedback and align hit beats
mokn Apr 8, 2026
6773104
feat: block/dodge combat animations + general socket attachment
mokn Apr 8, 2026
5ab00f7
fix: decouple embedded gas refill from privy refresh
mokn Apr 8, 2026
369b7df
feat: rotatable ASCII character viewer on character page
mokn Apr 8, 2026
00c99b0
fix: allow beta relayer refills for existing embedded players
mokn Apr 8, 2026
3666579
feat: UniRig auto-rigging + Blender animation script
mokn Apr 8, 2026
3dd3696
fix: Blender 5.x API compat + spider bone rename map
mokn Apr 8, 2026
c5a1ef1
feat: item-forge CLI for automated 3D item model generation
mokn Apr 8, 2026
4005158
feat: 3D item projectiles — GLB loader + weapon name threading
mokn Apr 8, 2026
7fd175b
feat: rarity-aware item colors + ASCII item viewer for creature lab
mokn Apr 8, 2026
f29e096
feat: equip weapons on CharacterViewer + preload items on battle start
mokn Apr 8, 2026
84262da
fix: bump Meshy refine timeout to 600s + auto-retry failed items
mokn Apr 8, 2026
bcdbb70
merge: resolve conflicts with dev (battle feed + combo system)
mokn Apr 8, 2026
40d17d1
Merge pull request #327 from ultimate-dominion/feat/creature-studio
mokn Apr 8, 2026
08b2fdc
feat: WoW-style character inspection overlay with auto-reveal rotation
mokn Apr 8, 2026
8fd1ff8
Merge pull request #328 from ultimate-dominion/feat/creature-studio
mokn Apr 8, 2026
3d721bc
feat: render weapon projectiles as ASCII through MonsterAsciiRenderer
mokn Apr 8, 2026
07db4f2
Merge pull request #329 from ultimate-dominion/feat/creature-studio
mokn Apr 8, 2026
c55033a
chore: deploy 24 weapon GLBs + manifest for ASCII projectiles
mokn Apr 8, 2026
004a3f8
Merge pull request #330 from ultimate-dominion/feat/creature-studio
mokn Apr 8, 2026
b1b32b3
feat: monster-class-specific attack visuals for counterattacks
mokn Apr 8, 2026
d3be5ce
Merge pull request #331 from ultimate-dominion/feat/creature-studio
mokn Apr 8, 2026
b8c85d1
feat: battle animation UX cleanup — consolidate combat signals, tiere…
mokn Apr 8, 2026
f47b85e
chore: forge retry with cooldown — skip existing GLBs, 45s between AP…
mokn Apr 8, 2026
6b55b9e
chore: deploy 17 forged item GLBs from retry batch
mokn Apr 8, 2026
4f03ee0
Merge remote-tracking branch 'origin/dev' into feat/creature-studio
mokn Apr 8, 2026
f394443
Merge pull request #332 from ultimate-dominion/feat/creature-studio
mokn Apr 8, 2026
9f07d47
fix: battle UX polish — faster fade, CRIT labels, brighter scene, ASC…
mokn Apr 8, 2026
505b517
Merge pull request #333 from ultimate-dominion/feat/creature-studio
mokn Apr 8, 2026
182a6dc
chore: forge + deploy all 43 item GLBs — complete armor set
mokn Apr 8, 2026
9548e35
Merge pull request #334 from ultimate-dominion/feat/creature-studio
mokn Apr 8, 2026
9c88ebf
feat: replace WebP item icons with ASCII art rendering across all UI
mokn Apr 8, 2026
be0932b
Merge pull request #335 from ultimate-dominion/feat/creature-studio
mokn Apr 8, 2026
577acae
fix: use WebP source images for ASCII item icons instead of silhouettes
mokn Apr 8, 2026
28ea575
Merge pull request #336 from ultimate-dominion/feat/creature-studio
mokn Apr 8, 2026
06dd201
fix: show WebP item art directly with rarity CSS effects
mokn Apr 8, 2026
e275822
Merge pull request #337 from ultimate-dominion/feat/creature-studio
mokn Apr 8, 2026
27a6bf0
fix: rarity color tinting for item icons via canvas multiply blend
mokn Apr 8, 2026
707c98a
Merge pull request #338 from ultimate-dominion/feat/item-rarity-tint
mokn Apr 8, 2026
24c0114
feat: animated GLB giant spider in battle scene (#339)
mokn Apr 9, 2026
188d2f3
feat: brighter battle scene + dense cave background (#340)
mokn Apr 9, 2026
282aa89
fix: prevent zone entity bleed between z1 and z2
mokn Apr 9, 2026
fd21dfe
fix: remove impact burst image (#341)
mokn Apr 9, 2026
7ae3d57
fix: prevent double-attack animation on counterattack reveal (#342)
mokn Apr 9, 2026
7c26eb4
chore: remove stale DeployFragmentChains.s.sol
mokn Apr 9, 2026
83267cc
feat: color-coded combat text with hit type labels (#343)
mokn Apr 9, 2026
558c8cd
fix: prevent Z2 NPCs from appearing in Z1 zone filter
mokn Apr 9, 2026
6a20a1a
fix: ASCII spell effects + DOUBLE strike label (#344)
mokn Apr 9, 2026
f671268
fix: tune renderOverrides for spider brightness and basilisk fill (#345)
mokn Apr 9, 2026
dac0bcd
feat: add Carrion Crawler GLB model from Meshy pipeline (#346)
mokn Apr 9, 2026
b1fd024
feat: animated carrion crawler with head-waving idle (#347)
mokn Apr 9, 2026
397dca4
feat: drop cellSize to 3px everywhere (minimum) for max ASCII density…
mokn Apr 9, 2026
44c10c3
feat: cellSize 4px — balance density vs performance (#349)
mokn Apr 9, 2026
d91b590
revert: restore original cellSize values (5-6px) (#350)
mokn Apr 9, 2026
6bcea79
feat: progressive monster sizing + race-based character scale (#351)
mokn Apr 9, 2026
a90db87
feat: pixelated item icons with rarity-driven resolution
mokn Apr 9, 2026
9604ba5
feat: posterized item icons — rarity controls tonal depth, not just c…
mokn Apr 9, 2026
d8c438d
feat: tiered monster attack visuals — escalate projectiles + shake by…
mokn Apr 9, 2026
673b369
fix: max-pool downsampling for item icons — preserves thin features
mokn Apr 9, 2026
3e5fa88
feat: threshold-dilate-downsample pipeline for item icons
mokn Apr 9, 2026
f6099f7
fix: bold 2-color for all rarities — detail from resolution, not tones
mokn Apr 9, 2026
2f255f3
feat: GLB-first item icons — 3D models as pixel art source
mokn Apr 10, 2026
745df0b
feat: render item icons through MonsterAsciiRenderer
mokn Apr 10, 2026
7d6e6e2
fix: boost item icon brightness and fill for small-size ASCII rendering
mokn Apr 10, 2026
4149d6f
feat: oversample item icons — render large, display small for dense d…
mokn Apr 10, 2026
cb8b21b
feat: animated item icons for Epic+ — slow GLB rotation through ASCII…
mokn Apr 10, 2026
6a6a88e
fix: speed up item image loading with caching headers and preloading
mokn Apr 10, 2026
e55339c
fix: classify spells as ItemType.Spell + deploy L15 spells to beta
mokn Apr 10, 2026
e6f1ac7
Merge remote-tracking branch 'origin/dev' into fix/item-image-perf
mokn Apr 10, 2026
91e7690
fix: migrate all player-owned spell items from Weapon to Spell type
mokn Apr 10, 2026
9109b1d
fix: unblock embedded character creation funding
mokn Apr 13, 2026
46ddc99
fix: wait for embedded funding identity token
mokn Apr 13, 2026
11e6261
feat: zone-aware background audio with crossfade
mokn Apr 13, 2026
6c5dc96
Merge remote-tracking branch 'origin/dev' into feat/audio-zones
mokn Apr 13, 2026
dd56e70
feat: zone-aware background audio with crossfade (#354)
mokn Apr 13, 2026
3b0b03e
feat: rework onboarding character creation
mokn Apr 13, 2026
f352066
fix: polish onboarding audit issues
mokn Apr 13, 2026
3f769f1
fix: use script profile for beta access grants
mokn Apr 13, 2026
15fc1b4
fix: align beta smoke access checks
mokn Apr 13, 2026
5500356
docs: codify beta deploy process
mokn Apr 13, 2026
f296a7e
fix: make beta smoke economic checks state-aware
mokn Apr 13, 2026
138cef7
fix: unblock embedded onboarding account prep
mokn Apr 13, 2026
79a0259
fix: fetch embedded funding token actively
mokn Apr 13, 2026
971950e
ci: skip contract checks for ui-only changes
mokn Apr 13, 2026
38e98dc
ci: gate jobs by changed package
mokn Apr 13, 2026
4242f24
fix: harden movement monster display sync
mokn Apr 13, 2026
c8ac3ed
docs: note movement monster sync hardening
mokn Apr 13, 2026
a5e1d93
fix: tighten monster display sync guards
mokn Apr 13, 2026
6941562
docs: note monster sync guard follow-up
mokn Apr 13, 2026
10db5e0
fix: preserve monster selector bigint hp typing
mokn Apr 13, 2026
f9ca405
docs: note monster selector type fix
mokn Apr 13, 2026
783c9b5
fix: clear beta ghost monster snapshots
mokn Apr 13, 2026
2986663
chore: bump indexer for beta ghost fix
mokn Apr 13, 2026
7758514
docs: handoff movement monster display
mokn Apr 13, 2026
8df8772
chore(deploy): exclude .claude/.temper/tools/ from railway upload
mokn Apr 13, 2026
a4de21f
chore(deploy): add railway preflight size check
mokn Apr 13, 2026
bcd3862
feat(audio): battle music layer with 5s linger + autoplay unlock
mokn Apr 13, 2026
b4401f1
fix(audio): init battleMode from currentBattle + zone-1 fallback
mokn Apr 13, 2026
5cf006c
Merge remote-tracking branch 'origin/dev' into feat/audio-zones
mokn Apr 13, 2026
d7c6337
Merge pull request #355 from ultimate-dominion/feat/audio-zones
mokn Apr 13, 2026
4a913a2
fix(audio): resume ctx in toggleSound and unconditionally on first ge…
mokn Apr 13, 2026
75122cf
Merge pull request #356 from ultimate-dominion/feat/audio-zones
mokn Apr 13, 2026
cad04f2
chore(audio): add diagnostic logging to SoundContext
mokn Apr 13, 2026
e8b0183
Merge pull request #357 from ultimate-dominion/feat/audio-zones
mokn Apr 13, 2026
a26c2bb
fix(audio): hoist Howl cache to module scope to survive provider remo…
mokn Apr 13, 2026
2b20c5e
fix(audio): hoist Howl cache to module scope to survive provider remo…
mokn Apr 13, 2026
6e932d1
chore(audio): re-add diagnostic logging for silent-playback investiga…
mokn Apr 13, 2026
4d61e84
Merge remote-tracking branch 'origin/dev' into feat/audio-zones
mokn Apr 13, 2026
2f24e37
chore(audio): diagnostic logs for silent playback on beta (#359)
mokn Apr 13, 2026
dfe27ed
feat: add game sfx integration
mokn Apr 13, 2026
64e5c7c
test: cover fragment sfx guards
mokn Apr 13, 2026
92ca556
fix: merge dev into feat/audio-zones, strip diagnostic logs
mokn Apr 13, 2026
573a7ad
fix: unlock windy peaks exit at level 10
mokn Apr 14, 2026
be3b865
fix(battle-scene): animate counterattack + auto-preload GLBs + click-…
mokn Apr 14, 2026
b5f6f02
Merge remote-tracking branch 'origin/dev' into feat/audio-zones
mokn Apr 14, 2026
40dfc80
Merge pull request #360 from ultimate-dominion/feat/audio-zones
mokn Apr 14, 2026
43335c5
fix(battle): derive hiddenTurn synchronously during render
mokn Apr 14, 2026
3c6f70d
Merge origin/dev into feat/audio-zones after PR #360 landed
mokn Apr 14, 2026
9818e0b
feat(creatures): replace elf GLB with noble-style regen
mokn Apr 14, 2026
1351fce
feat(creature-lab): replace elf GLB + anim clips with noble-style regen
mokn Apr 14, 2026
9a53f43
feat(creature-lab): add sync-to-client.mjs helper
mokn Apr 14, 2026
3d0ce4a
fix(client): correct respec cost constants and wei display in RespecP…
mokn Apr 14, 2026
00020e1
feat(client): move respec to dedicated /respec page hosted by Vel Morrow
mokn Apr 14, 2026
628bc28
chore(zones): rename Z1 shopkeeper to Tal for consistency
mokn Apr 14, 2026
9087017
test(client): cover Respec page and NpcRow interaction dispatch
mokn Apr 14, 2026
6cb97b1
docs: document /respec route and repair locations
mokn Apr 14, 2026
1ed203a
refactor(creatures): extract creatures.json as single source of truth
mokn Apr 14, 2026
b8c2182
chore: refresh direction snapshot
mokn Apr 14, 2026
e3ff430
chore: refresh direction snapshot
Apr 14, 2026
a6acdde
fix: allow new user funding when Privy identity token has empty linke…
mokn Apr 13, 2026
90fb280
chore: untrack stale .temper run artifact
mokn Apr 14, 2026
2dcf6e4
docs: add worktree workflow cheat sheet and direction pointer
mokn Apr 14, 2026
575b6f7
chore: commit shared .claude commands and rules
mokn Apr 14, 2026
129f521
feat(contracts): add ClearGhostEncounters admin script
mokn Apr 14, 2026
32ec07b
chore: remove stale HANDOFF from repo root
mokn Apr 14, 2026
f194568
chore: gitignore .temper/runs per-invocation artifacts
mokn Apr 14, 2026
31bf7d2
feat(creatures): sync 5 monster GLBs with animated lab versions
mokn Apr 14, 2026
fba5e3a
Merge pull request #361 from ultimate-dominion/worktree/creatures-beta
mokn Apr 14, 2026
d9bb1ba
fix: resolve 4 client bugs from beta testing
mokn Apr 14, 2026
ed745be
fix(contracts): deploy spell items as ItemType.Spell (2) not Weapon (0)
mokn Apr 14, 2026
f4e0f82
test: add tests for spell catalog, spell URI detection, i18n merge, a…
mokn Apr 14, 2026
9c7be25
fix(contracts): revert deploy-spell-items to ItemType.Weapon
mokn Apr 14, 2026
dd7e7cb
feat(spells): add 9 L15 entries to SPELL_CATALOG + test coverage
mokn Apr 14, 2026
71b3b8b
fix(gameboard): preserve level-up signal when battle modal blocks
mokn Apr 14, 2026
8004480
refactor(spells): extract SPELLS_MANIFEST as single source of truth
mokn Apr 14, 2026
6a30222
fix(gameboard): advance ref when LevelUpModal already open
mokn Apr 14, 2026
c5216b9
fix(boot): hold dark boot screen through MUD sync on /game-board
mokn Apr 14, 2026
013a10a
chore: refresh direction snapshot
mokn Apr 14, 2026
ac7a132
chore: refresh direction snapshot
mokn Apr 14, 2026
bd85696
fix(client): gate BootScreen on gameStore hydration, not just MUD sync
mokn Apr 14, 2026
07b5171
fix(client): hold BootScreen until GameBoard lazy chunk is cached
mokn Apr 14, 2026
5532ff8
chore: refresh direction snapshot
mokn Apr 15, 2026
ea785a4
fix(client): render BootScreen in AppRoutes Suspense fallback for /ga…
mokn Apr 14, 2026
24fd3f6
fix(client): stop battle HUD from snapping down when status effects a…
mokn Apr 14, 2026
bd8eb36
chore: refresh direction snapshot
mokn Apr 15, 2026
f0dc23e
fix(client): stop orange shell flash on every route + remove item ticker
mokn Apr 15, 2026
6f6b814
chore: refresh direction snapshot
mokn Apr 16, 2026
76c7651
chore: update SESSION.md
mokn Apr 16, 2026
48d046e
chore: refresh direction snapshot
mokn Apr 16, 2026
fe7b040
fix(client): stop Carrion Crawler arena going black on every hit
mokn Apr 16, 2026
abe5a30
fix(contracts): drop redundant prereq gate on zone transitions
mokn Apr 16, 2026
63c19cf
chore(contracts): deploy ZoneTransitionSystem fix to beta
mokn Apr 16, 2026
d880474
fix(client): show Windy Peaks quest HUD, dragon, and fragment echo
mokn Apr 17, 2026
c68ef6f
chore: refresh direction snapshot
mokn Apr 17, 2026
c909d61
chore: update SESSION.md
mokn Apr 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
12 changes: 12 additions & 0 deletions .claude/commands/handoff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Delegate to the `handoff` agent to execute the full handoff protocol. Pass it all context about what was accomplished this session, what's in progress, and any blockers.

The handoff agent will:
1. Gather git state (status, diff, recent log)
2. Write HANDOFF_[task-slug].md to repo root
3. Archive to ~/Documents/ultimate-dominion/docs/handoffs/YYYY-MM-DD_[task-slug].md
4. Update SESSION.md (remove completed tasks, keep active ones)
5. Update today's Obsidian daily note via MCP
6. Delete the handoff file from repo root
7. Output the summary

After it completes, tell Michael to `/clear`.
25 changes: 25 additions & 0 deletions .claude/commands/kaplan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Put on your Jeff Kaplan hat for game design work.

Before responding, read these two docs:
1. `~/Documents/ultimate-dominion/docs/JEFF_KAPLAN_DESIGN_PHILOSOPHY.md` — Kaplan's career-spanning design principles, GDC talks, quotes, and lessons learned
2. `docs/DESIGN_PHILOSOPHY.md` — UD's design philosophy (built on Kaplan's principles + our own identity)

Then apply that lens to whatever Michael is asking about. Think like a principal game designer who:

- Led WoW quest/zone/raid design for 5 years
- Built Overwatch from the ashes of a failed project
- Believes in "concentrated coolness" over diluted content
- Insists on clarity of action (mystery in the world, never in what to do)
- Demands systems that create player stories, not scripted narratives
- Ships and iterates rather than polishing forever
- Respects player time above all else
- Knows that perception > reality for balance
- Celebrates moments — every milestone needs weight
- Hates exposition dumps, fetch quests, and gimmick systems

When designing features, quests, zones, or systems, always run through:
1. Does it pass the filter? (permanent, player-driven, worth it in a year)
2. Where's the moment? (concentrated coolness)
3. Does it create stories? (emergent > scripted)
4. Is the fun path the efficient path? (don't let them optimize the fun out)
5. Can a player explain why this is cool in one sentence?
16 changes: 16 additions & 0 deletions .claude/rules/api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
paths:
- packages/api/**
- packages/relayer/**
---

# API & Relayer Rules

## Security
- All endpoints must have rate limiting, CORS restrictions, and input validation.
- Never leak secrets or stack traces in responses.
- Never hardcode private keys or secrets. Always use environment variables.

## Dependencies
- Pin versions. Run `pnpm audit` before adding new packages.
- Prefer well-maintained packages with small surface area.
36 changes: 36 additions & 0 deletions .claude/rules/client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
paths:
- packages/client/**/*.ts
- packages/client/**/*.tsx
- packages/client/**/*.css
---

# Client / Frontend Rules

## Performance
- This is a browser game — speed is a feature. Every interaction should feel instant.
- Never add blocking operations to the UI thread. All chain reads/writes must be async with loading states.
- Be mindful of bundle size. Lazy-load routes. Don't add heavy dependencies without justification.
- Test that any UI change remains responsive on mobile browsers.

## Usability & Crypto Abstraction
- All UI must work without crypto knowledge. Follow `docs/architecture/frontend_guidelines.md`.
- Never expose wallet addresses, transaction hashes, gas fees, or chain IDs to the player.
- Every action needs clear feedback: loading states, success confirmations, error messages with recovery steps.
- Mobile-first — if it doesn't work on a phone browser, it doesn't ship.

## Security
- No `dangerouslySetInnerHTML`, no `eval`, no user-controlled URLs without validation.
- Validate `chainId` against `supportedChains`.

## Player-Facing Copy
Any text that appears in the game — item descriptions, system messages, patch notes, NPC dialogue, UI labels — must sound like a specific person wrote it. No generic AI language. If a player can tell AI wrote it, it failed.

## SEO (Public Pages Only)
When adding a new page:
1. Import `{ Helmet } from 'react-helmet-async'`
2. Add `<Helmet><title>Page Name | Ultimate Dominion</title></Helmet>`
3. If public (no auth): add to `sitemap.xml`
4. If authenticated/private: add to `Disallow` in `robots.txt`

Canonical domain: `https://ultimatedominion.com`. No SEO needed for beta.
170 changes: 170 additions & 0 deletions .claude/rules/deploy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
---
paths:
- packages/contracts/script/**
- packages/contracts/.env*
- packages/contracts/mud.config.*
- packages/contracts/worlds.json
- packages/indexer/**
- "**/deploy*"
- "**/PostDeploy*"
- "**/EnsureAccess*"
- "**/zone-loader*"
---

# Deploy & Environment Rules

## Environment Separation (CRITICAL — incident 2026-03-30)
- `beta.ultimatedominion.com` = Base Mainnet (beta world address)
- `ultimatedominion.com` = Base Mainnet (production world address)
- Both on chain 8453, distinguished ONLY by WORLD_ADDRESS.
- **`.env` MUST default to beta.** Production requires explicit `.env.mainnet`.
- **Bare commands are blocked.** `zone:load`, `item:sync`, `item:verify` require `:testnet` or `:mainnet` suffix.
- NEVER add the production world address to `.env`. If you see it there, fix it immediately.

## Script Execution Safety (CRITICAL — incident 2026-03-30)
- **NEVER** run `source .env.testnet && npx tsx ...` — `source` does NOT export vars to subprocesses.
- **ALWAYS** use pnpm scripts (`pnpm zone:load:testnet`) or `bash -c 'set -a && source .env.testnet && set +a && npx tsx ...'`
- **ALWAYS** verify the world address in the first lines of script output before continuing.
- Production world: `0x99d01939F58B965E6E84a1D167E710Abdf5764b0` — all TS scripts now require `--confirm-production` flag.
- Beta world: `0xDc34AC3b06fa0ed899696A72B7706369864E5678`

## Branch Convention
| Branch | Target | Confirm? |
|---|---|---|
| `dev` | Beta | No |
| `main` | Production | **Always** |
| Feature branch | Ask user | Yes |

## MUD Deploy Safety
- **Always use `--worldAddress`** when deploying to existing chains. Without it, compiler changes can trigger a fresh world deploy.
- `mud deploy` with nonce errors can silently skip transactions — verify function selectors after every deploy.
- System upgrades create NEW contract addresses — re-run `EnsureAccess.s.sol` after every deploy.
- Always run PostDeploy seed/config scripts after a fresh deploy.
- Backup world state before mainnet upgrades.

## PostDeploy Is All-or-Nothing
PostDeploy.s.sol runs as a single transaction. If ANY line reverts, ALL access grants are lost. This is why `deploy:testnet` and `deploy:mainnet` auto-chain `ensure-access` after `mud deploy`.

When adding a new system that writes cross-namespace: update `EnsureAccess.s.sol` `ensureAll()`.

## worlds.json blockNumber
- Must be the ACTUAL world deployment block. If set too high, new clients miss seed data.
- Use binary search on `cast code` to find the exact deployment block.

## RPC for Deploys
- Base mainnet: use `base-rpc.publicnode.com` (supports 16K+ block ranges).
- dRPC free tier limits to 10K blocks — `mud deploy` will fail once gap exceeds 10K.

## Verification
- Run `pnpm build` in packages/client before pushing.
- Verify function selectors after any `mud deploy`.
- Never deploy to mainnet without testnet verification first.

## Pre-Deploy Required Reading
**BEFORE any `mud deploy` or `pnpm deploy:*`**, read these files for known failure patterns:
1. `~/.claude/projects/-Users-michaelorourke-ultimate-dominion/memory/game/mud-gotchas.md` — table name collisions, schema immutability, access control traps, bytecode issues
2. `~/.claude/projects/-Users-michaelorourke-ultimate-dominion/memory/infra/deploy-guide.md` → "Known Failure Patterns" table — EnsureAccess cache, CreateCollision, etc.

## Railway Service Deployment (CRITICAL — know your target)

Railway has SEPARATE beta and prod services. The naming is misleading.

| Service | Railway name | Service ID | Domain (current) |
|---|---|---|---|
| **Indexer (prod)** | `indexer` | `61172447-73de-410a-943e-49ed3cc20d10` | `indexer-production-d6df.up.railway.app` |
| **Indexer (beta)** | `indexer-beta-us` | `390336a9-3856-4ace-9949-f28fa1c4aa3d` | `indexer-beta-us-production.up.railway.app` |
| **Indexer (legacy)** | `indexer-beta` | `de09dafa-a4c1-4ad8-8873-67a7ae885b90` | `indexer-prod-production-45cf.up.railway.app` (NOT used by beta client) |
| **Relayer (prod)** | `relayer` | `dd62995a-cab5-4a98-b217-0c7bf111364e` | `8453.relay.ultimatedominion.com` |
| **Relayer (beta)** | `relayer-beta` | `c7a2c1e4-4bb8-4ce3-aa54-9a38b1a3d067` | `relayer-beta-us-production.up.railway.app` |

### How `railway up` actually works (read this before debugging a failed deploy — confirmed 2026-04-13)

- `railway up` uploads the files from the **main checkout working tree**, not the current worktree you run it from. Verified empirically: running from `.claude/worktrees/movement-monster-display` (pkg version 0.3.1) produced a build that logged `@ud/[email protected]` — the version sitting on disk in the main checkout. The worktree's files were completely ignored by the upload.
- Practical consequence: **to deploy a commit that's on a feature branch, the main checkout must have that commit's files on disk.** Either merge to the main checkout's current branch, or check out the target branch/SHA in the main checkout before running `railway up` (detached HEAD is fine if another worktree holds the branch).
- Railway builds using the service's configured **root directory** and Dockerfile. For `indexer-beta-us` / `indexer`, the service has `rootDirectory = packages/indexer` and uses `packages/indexer/Dockerfile`. **Do not pass `--path-as-root`** — it bypasses the service config and makes Railway fall back to RAILPACK, which fails.
- The upload context size limit is ~100 MB. Anything close to that will 413. The relevant ignore list is the main checkout's `.railwayignore` + `.gitignore`.

### Pre-deploy sequence (exact steps — follow in order)

```bash
# 1. Make sure the commit you want is reachable on origin/dev (or wherever)
cd ~/ultimate-dominion/.claude/worktrees/<your-worktree>
git push origin <branch> # get the fix onto the remote

# 2. Switch to the main checkout
cd ~/ultimate-dominion
git fetch origin

# 3. Stash any uncommitted work (leave untracked files alone)
git stash push -m "pre-deploy $(date +%F)" -- <modified-tracked-files>

# 4. Check out the target SHA. If dev is locked by another worktree,
# use a detached HEAD at the remote SHA.
git checkout <sha-or-branch> # or: git checkout origin/dev

# 5. Preflight
bash scripts/railway-preflight.sh # must print < 50 MB and exit 0
railway status # must show the expected service

# 6. Deploy
railway up --detach

# 7. Verify (see "Verify after deploy" below). If the build log shows
# the wrong @ud/indexer version, the upload came from a stale main
# checkout — fix that before anything else.

# 8. Restore main checkout
git checkout <original-branch>
git stash pop
```

### Deploy commands (the only commands you should run)
- Beta: `railway service indexer-beta-us && railway up --detach` (service ID: `390336a9`)
- Prod: `railway service indexer && railway up --detach` (**MUST ASK MICHAEL FIRST**)

### Required rules
- NEVER use `railway redeploy` — it reuses cached images and doesn't pull fresh code.
- ALWAYS bump `packages/indexer/package.json` version before deploying (Docker cache busting). Note: `health.ts` hardcodes a separate version string that does NOT auto-update; don't use the `/api/health` `version` field as proof of fresh code. Verify via the Railway **build logs** instead (they print `> @ud/[email protected] build`).
- ALWAYS run `scripts/railway-preflight.sh` before `railway up` to catch `.railwayignore` rot.
- ALWAYS verify with `railway status` that the linked service is correct before `railway up`.
- ALWAYS verify with the Railway GraphQL **build logs** (not the live `/api/health`) that the right version was built.

### If a deploy fails: the debugging order
1. **413 / "Payload Too Large"** → run `scripts/railway-preflight.sh` from the **main checkout**. Find the bloat, add it to `.railwayignore`. Do not try `--path-as-root`, `/tmp/` sub-packages, or any upload-root workaround — those trigger RAILPACK fallback.
2. **Railway used `RAILPACK` instead of the Dockerfile** → you passed `--path-as-root` or pointed at `packages/indexer` as the upload root. Go back to running `railway up --detach` from the repo root of the main checkout.
3. **Build log shows the wrong version / old code** → the main checkout's working tree is on the wrong branch/SHA. `railway up` uploads files from the main checkout, not from your worktree. Checkout the target SHA in the main checkout (detached HEAD is fine) and redeploy.
4. **Build failed inside the Dockerfile** → read the build logs, do not bump versions blindly.
5. **Deployment succeeds but clients don't see changes** → wrong domain. `indexer-beta-us-production.up.railway.app` is the beta client's URL; other indexer services exist but are not wired up. See the service table above.

**Verify after deploy:**
```bash
# Check build status
RAILWAY_TOKEN=$(python3 -c "import json; print(json.load(open('$HOME/.railway/config.json'))['user']['token'])")
# Beta:
curl -s -H "Authorization: Bearer $RAILWAY_TOKEN" -H "Content-Type: application/json" \
-d '{"query":"query { deployments(input: { serviceId: \"390336a9-3856-4ace-9949-f28fa1c4aa3d\" }) { edges { node { id status createdAt } } } }"}' \
https://backboard.railway.com/graphql/v2 | python3 -c "import sys,json; [print(f'{e[\"node\"][\"id\"][:8]} {e[\"node\"][\"status\"]}') for e in json.load(sys.stdin)['data']['deployments']['edges'][:3]]"
# Verify code is live:
curl -s https://indexer-beta-us-production.up.railway.app/api/health
# Prod: swap service ID to 61172447-73de-410a-943e-49ed3cc20d10
```

## Smart Contract Upgrade Checklist (ALWAYS follow)

Full playbook with failure patterns: `~/.claude/projects/-Users-michaelorourke-ultimate-dominion/memory/infra/deploy-guide.md` → "Complete Upgrade Deploy Playbook"

**Before deploy:**
1. Commit all changes — NEVER deploy from dirty tree
2. Run `verify-onchain.ts` — sim vs on-chain must be 0 mismatches
3. Check no players in active combat (schema changes break mid-fight encoding)
4. If schema changed: expect ALL systems to redeploy (new addresses, grants refresh)
5. If new cross-namespace access needed: update EnsureAccess.s.sol FIRST
6. If effect types changed (e.g. MagicDamage→StatusEffect): deploy when no one is using that effect

**After deploy:**
7. `pnpm deploy:mainnet` auto-chains EnsureAccess — verify it ran
8. Run any data scripts (DeployClassSpellsV2, item-sync, effect-sync, etc.)
9. Test incrementally: basic combat → spells → shop → marketplace
10. Check indexer health — reindex if schema changed
11. Monitor relayer logs for `Access_Denied` errors for 5 min
12. Commit deploy artifacts
41 changes: 41 additions & 0 deletions .claude/rules/game.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
paths:
- packages/contracts/src/systems/**
- packages/contracts/zones/**
- packages/contracts/test/**
- "**/items.json"
- "**/effects.json"
- "**/monsters.json"
- "**/balance*"
- "**/combat*"
- "**/sim*"
---

# Game Systems Rules

@./docs/combat-stats/BALANCE_GOALS.md
@./docs/combat-stats/BALANCE_STATE.md

## Memory Pointers (read on demand, not all at once)
When working on game systems, check these memory files for relevant context:
- `game/game-balance.md` — Item IDs, combat triangle, monster roster, drop rates, class spells
- `game/launch-values.md` — Production constants (XP, gold, combat)
- `game/economic-design.md` — Hearthstone model, F2P vs marketplace drivers
- `game/design_principles_kaplan.md` — **READ BEFORE BALANCE WORK**
- `game/gotcha_*.md` — Grep when touching a specific system

## ID Lookups
- Basilisk boss: mob ID `12`
- Item IDs: see `items.json` (single source of truth)
- Effect IDs: see `effects.json` (single source of truth)
- Drop rates: ONLY changeable via items.json → item-sync flow

## Balance Changes
- items.json is the SINGLE SOURCE OF TRUTH. Never bypass with cast/scripts.
- Flow: edit JSON → commit → `item-sync dark_cave --update` → verify (0 mismatches) → stop if verify fails.
- After any `mud deploy`: run item-sync + effect-sync to verify, tag the deploy, run drop-sim.
- Don't over-optimize balance. Set floors and ceilings, not parity. The game is infinite at L20.

## Testing
- Tests run against forked beta world, never local anvil.
- Every code change MUST have tests — happy paths, unhappy paths, edge cases.
35 changes: 35 additions & 0 deletions .claude/rules/indexer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
paths:
- packages/indexer/**
---

# Indexer Rules

## Memory Pointers (read on demand)
- `infra/tools.md` — Railway service IDs, URLs, CLI commands, SSH targets
- `infra/deploy-guide.md` — Deploy commands, failure patterns
- `infra/recovery-runbook.md` — Service failure diagnosis
- `infra/gotcha_*.md` — Grep when touching indexer infra

## Architecture
Custom MUD indexer (replaces RECS). Syncs Store events → PostgreSQL, REST API + WebSocket.
- Database: PostgreSQL via `postgres` library, off-chain tables in `queue.` schema
- WS protocol: typed discriminated unions in `ws/protocol.ts`
- Game events: `queue/eventFeed.ts` scans MUD tables every 10s
- Chat: `ws/chatHandler.ts` — rate limiting, shadow mute, guild auth

## Railway Deploy (CRITICAL)
- Beta: `railway service indexer-beta-us && railway up --detach` (service ID: `390336a9`)
- Prod: `railway service indexer && railway up --detach` (**ASK MICHAEL FIRST**, service ID: `61172447`)
- NEVER use `railway redeploy` — reuses cached images
- ALWAYS bump `packages/indexer/package.json` version before deploying
- ALWAYS run from repo root, not from `packages/indexer/`
- ALWAYS verify `railway status` shows the correct service before deploying
- `railway up` from worktrees uploads main checkout files — deploy from main checkout only
- Full service ID table in `.claude/rules/deploy.md`

## Patterns
- Table init: `async function initXxxTables()` with `CREATE TABLE IF NOT EXISTS` in `queue.` schema
- Broadcast: `broadcaster.broadcastToAll(msg)` or `broadcastToChannel(channel, msg)`
- Dedup: `ON CONFLICT ... DO NOTHING`
- WS message handling: `switch (msg.type)` in broadcaster's `addClient()`
Loading
Loading