Skip to content

Miden edge execution: combat engine + arena account#7

Draft
WiktorStarczewski wants to merge 11 commits intomainfrom
wiktor-edge-execution
Draft

Miden edge execution: combat engine + arena account#7
WiktorStarczewski wants to merge 11 commits intomainfrom
wiktor-edge-execution

Conversation

@WiktorStarczewski
Copy link
Owner

Summary

  • Pure Rust combat engine (crates/combat-engine/) with 40 tests — deterministic damage, buffs, debuffs, burn, heals, KO, full 3v3 battles
  • Arena account component (contracts/arena-account/) with 21-slot storage layout and 6 procedures: join, set_team, submit_commit, submit_reveal, resolve_current_turn, claim_timeout
  • Champion state packing/unpacking ([u64; 4]ChampionState) for Miden Word storage
  • Miden VM prototype (contracts/combat-test/) validating deterministic combat execution — native Rust and Miden VM produce identical results
  • Compiler bug repro (contracts/combat-test-broken/) — large struct returns lose mutations in Miden compiler v0.7.1, reported upstream

Deferred

  • SHA-256 hash verification (placeholder in submit_reveal)
  • P2ID note creation for payouts
  • Block height access for timeout enforcement
  • Note scripts for move/team/stake submission

Also includes

  • Mobile battle HUD fix (turn phase indicator)
  • Death pose persistence after KO
  • TypeScript env type fix

Test plan

  • cargo test -p combat-engine — 40 tests pass
  • cargo miden build --release in contracts/arena-account/ — produces 381KB .masp
  • miden vm run of combat-test — output matches native Rust exactly
  • Integration test with Miden VM account execution (blocked on cargo miden test bug)

- Clamp death animation on last frame using LoopOnce so the model
  stays collapsed instead of looping
- Show KO'd champions in death pose during settle/second anim phases
  and outside animation phase when no survivors remain
- Track secondActed in AnimScript to avoid playing attack animation
  for champions KO'd before their turn
Port TypeScript combat engine to #![no_std] Rust in crates/combat-engine/.
Zero dependencies, fixed-point arithmetic, no heap allocation.

Modules: types, elements, champions, damage, codec, combat.
33 tests including full 3v3 battle integration test.
- Install cargo-miden v0.7.1, scaffold account + program templates
- Import combat-engine crate into Miden program, compile to .masp
- Execute 1v1 combat in Miden VM: output matches native Rust exactly
- Add resolve_turn_mut to combat-engine (Miden-friendly in-place variant)
- Discovered compiler bug: large struct returns silently miscompiled
- Workaround: inline combat logic instead of returning TurnResult
- Track findings in tasks/todo.md and tasks/lessons.md
- Arena account component (contracts/arena-account/) with 21-slot storage layout
- 6 procedures: join, set_team, submit_commit, submit_reveal, resolve_current_turn, claim_timeout
- Inlined combat resolution (all ability types, burn, buffs, team elimination)
- Champion state packing module (crates/combat-engine/src/pack.rs) with 7 native tests
- Compiler bug repro (contracts/combat-test-broken/) for Dennis
- SHA-256 verification, P2ID payouts, and block height access deferred as TODOs
- Builds to 381KB .masp, all 40 combat-engine tests pass

let mut rounds = 0u32;

while !storm.is_ko && !quake.is_ko && rounds < 50 {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it an equivalent (inlined) code from the combat-test-broken entrypoint? It seems different.

Replace P2P note patterns with arena contract interactions for
staking, team submission, and combat commit/reveal. Matchmaking
and draft picks remain P2P.

- Add arenaNote.ts: note script loader, builders, two-tx orchestrator
- Add useArenaState: arena storage polling backed by Zustand store
- Add ArenaSetupScreen: post-draft stake + team submission flow
- Rewrite commitment.ts: SHA-256 to RPO256 (sync, matches contract)
- Rewrite useStaking: P2IDE to process_stake_note via arena
- Rewrite useCommitReveal: P2P attachments to submit_move_note
- Rewrite useCombatTurn: arena-based phase machine with fallback
- Update useNoteDecoder: remove stake/raw categories
- Update gameStore: add ArenaState slice, arenaSetup screen
- Remove dead code: CommitRevealStatus, bytes.ts, MSG_TYPE_*
- Update tests for new RPO256 commitment API
- WebClient → WasmWebClient (has syncState method)
- Remove unused ARENA_ACCOUNT_ID import from arenaNote.ts
- Get note ID via note.id() before submission instead of from TransactionId
- Word.asInt() → Word.toFelts()[0].asInt()
- AccountId.toWord() → AccountId.prefix()/suffix().asInt()
- Remove burn system (DamageDot, burn_turns, calculateBurnDamage)
- Flatten champion data to struct-of-arrays (SoA) for smaller WASM
- Reduce champions 10→8, merge Buff/Debuff→StatMod ability type
- Add feature gates (track-damage, events, resolve-mut) to combat-engine
- Create matchmaking-account (212KB): join, set_team, receive_result,
  claim_timeout, send_payout, receive_asset
- Create combat-account (425KB): init_combat, submit_commit,
  submit_reveal, resolve, claim_combat_timeout, send_result_note
- Add init-combat-note and process-result-note for cross-account comms
- Retarget stake/team notes → matchmaking, move note → combat
- Update all WIT bindings for new account names
- Add defense-in-depth validation (duplicate/overlap) in init_combat
- Update frontend: remove burn UI, dual-account polling, codec ranges
- Fix getChampionHp bug, pool size constant, codec test ranges
- Exclude combat-test-broken from workspace
- All 38 Rust tests pass, 50 TS tests pass, TSC clean
Add native MASM combat account (143KB, under 256KB limit) replacing
the Rust-compiled version (425KB). Includes MASM note scripts for
init_combat and submit_move, compiled against the combat library to
ensure correct procedure digest resolution. Deploy script updated to
use the MASM build for combat artifacts.
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.

2 participants