Open
Conversation
Detailed plan for re-implementing doubles battle support on current main, covering data structures, engine execution, effects, commit manager, and tests. https://claude.ai/code/session_01MdUWjZNL2QrK4utE8Lma7H
…anded contexts) Adds GameMode enum, doubles constants (ACTIVE_MON_INDEX_BITS, slot switch flags), and expands Battle/BattleData/BattleConfig/BattleContext/CommitContext structs with doubles support fields (gameMode, slotSwitchFlagsAndGameMode, p0Move2/p1Move2). All existing struct constructors updated with Singles default. https://claude.ai/code/session_01MdUWjZNL2QrK4utE8Lma7H
- Engine.sol: add slot-aware helpers (_getActiveMonIndexForSlot, _setActiveMonIndexForSlot, _isDoublesMode), switchActiveMonForSlot, setMoveForSlot, getGameMode/getActiveMonIndexForSlot getters, update getBattleContext/getCommitContext to populate doubles fields, clear slot 1 moves in end-of-turn cleanup, set gameMode bit in startBattle - IEngine.sol: add switchActiveMonForSlot, setMoveForSlot, getGameMode, getActiveMonIndexForSlot to interface - IValidator.sol: add validatePlayerMoveForSlot and validatePlayerMoveForSlotWithClaimed for doubles slot validation - DefaultValidator.sol: implement slot-aware validation methods with duplicate switch target prevention across slots - DefaultCommitManager.sol: add revealMovePair for doubles commit/reveal with per-slot validation and dual slot move setting - ICommitManager.sol: add revealMovePair to interface - Remove unused GameMode import from DefaultMatchmaker.sol All 237 existing tests pass. Singles behavior unchanged. https://claude.ai/code/session_01MdUWjZNL2QrK4utE8Lma7H
… bug Port DoublesCommitManagerTest (10 tests) and DoublesValidationTest (37 tests) along with 6 mock contracts, adapting them to the unified DefaultCommitManager architecture (commitMove/revealMovePair, new hash format, updated interfaces). Fix critical bug in DefaultMatchmaker.proposeBattle where gameMode field was not stored, causing all doubles battles to be created as singles. 31 DoublesValidationTest tests are skipped pending Engine doubles slot 1 support. https://claude.ai/code/session_01MdUWjZNL2QrK4utE8Lma7H
Port the doubles execution pipeline from the double-battle branch: - Add _executeDoubles() with 4-slot move ordering and per-slot execution - Decompose _handleSwitch into core/switchIn/slotForSlot components - Add _handleMoveForSlot for slot-aware move handling in doubles - Add _runEffects 7-param overload for explicit monIndex targeting - Add doubles helpers: _checkForGameOver, _checkForGameOverOrKO_Doubles, _computeMoveOrderForDoubles, _playerNeedsSwitchTurn, slot switch flags - Initialize doubles activeMonIndex with p0s0=0, p0s1=1, p1s0=0, p1s1=1 - Fix _unpackActiveMonIndex to use 4-bit mask (compatible with both packings) - Pass explicit monIndex in dealDamage/updateMonState for correct effect targeting Result: 25/37 DoublesValidationTest pass (was 6/37), all 10 DoublesCommitManagerTest pass. 12 tests remain skipped pending Validator/Effect/Mock updates for doubles. https://claude.ai/code/session_01MdUWjZNL2QrK4utE8Lma7H
…ulator, and StaminaRegen fixes - Rewrite validatePlayerMoveForSlot with proper doubles NO_OP logic: allow NO_OP when slot's mon is KO'd and no valid switch targets exist - Add _hasValidSwitchTargetForSlot, _validateSwitchForSlot helpers - Add slot-aware getDamageCalcContext overload to Engine/IEngine - Add slot-aware _calculateDamage overload to AttackCalculator - Update DoublesSlotAttack mock to use slot indices from extraData - Update StaminaRegen to regen both slots in doubles mode - Update validateSwitch to check other slot's active mon in doubles All 284 tests pass (37 doubles, 0 skipped). https://claude.ai/code/session_01MdUWjZNL2QrK4utE8Lma7H
… inline gas savings Extract validateSwitchForSlot, validatePlayerMoveBasicsForSlot, and hasValidSwitchTargetForSlotBitmap into the shared ValidatorLogic library so both DefaultValidator and Engine can use them. This follows the same pattern as the existing singles validation (validateSwitch, validatePlayerMoveBasics) where pure logic lives in the library for compiler inlining when the Engine uses address(0) validator. - Engine.switchActiveMonForSlot now uses ValidatorLogic.validateSwitchForSlot instead of ad-hoc inline checks (which were missing other-slot checks) - DefaultValidator delegates to library for switch and move basics validation https://claude.ai/code/session_01MdUWjZNL2QrK4utE8Lma7H
…lidator gap - Extract _prepareMoveSet() and _packMoveDecision() helpers to deduplicate setMove/setMoveForSlot/executeWithMoves move-packing logic - Add ValidatorLogic.checkGameOver() and unify _checkForGameOverOrKO (singles) with _checkForGameOver (doubles) to eliminate duplicated KO bitmap comparison - Add IValidator.validateSwitchForSlot() and implement in DefaultValidator so doubles switchActiveMonForSlot uses slot-aware validation for external validators - Document per-player (not per-slot) salt semantics in setMoveForSlot https://claude.ai/code/session_01MdUWjZNL2QrK4utE8Lma7H
- _unpackMoveIndex(): consolidates 4 identical move-index unpacking sites - _getPriorityAndSpeed(): unifies priority/speed logic between singles and doubles - _validateMoveSelection(): deduplicates inline-vs-external validator dispatch - _runEngineHooks(): replaces 4 hook-loop instances (startBattle, executeInternal, handleGameOver) Note: _executeDoubles keeps inline loops to avoid Yul stack-too-deep Net: -38 lines, 284 tests pass https://claude.ai/code/session_01MdUWjZNL2QrK4utE8Lma7H
- getCommitAuthForDualSigned: drop startTimestamp check to eliminate 2 SLOADs (storageKey lookup + config read). winnerIndex != 2 already catches never-started battles. Return gameMode for free from same slot. - Engine.executeWithMovesForDoubles: new function that sets all 4 slot moves (p0Move, p0Move2, p1Move, p1Move2) and executes in one call. - SignedCommitLib.DualSignedRevealDoubles: new EIP-712 struct covering 2 move indices + 2 extra data fields per revealer for doubles. - SignedCommitManager.executeWithDualSignedMovesForDoubles: doubles variant of the dual-signed flow. Committer hash uses revealMovePair preimage format. Validates gameMode to prevent singles/doubles mismatch. https://claude.ai/code/session_01MdUWjZNL2QrK4utE8Lma7H
✅ Deploy Preview for monchain-wiki canceled.
|
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
This PR implements full support for Doubles battles in the Engine, allowing two players to each control two simultaneously. The implementation is additive and maintains backward compatibility with existing Singles battles.
Key Changes
Core Data Structures
GameModeenum (Singles/Doubles) toEnums.solBattleDatastruct withslotSwitchFlagsAndGameModefield to track game mode and slot-specific stateactiveMonIndexpacking to support 4-bit-per-slot encoding for doubles (p0 slot 0, p0 slot 1, p1 slot 0, p1 slot 1)p0Move2andp1Move2fields toBattleConfigfor second slot moves in doublesgameModefield toBattleandProposedBattlestructsEngine Execution
_executeDoubles()internal function to handle doubles-specific battle logic with parallel slot executionexecuteWithMovesForDoubles()public function for atomic move submission and execution in doubles battles_runEngineHooks()helper to reduce code duplication_isDoublesMode()helper and branching logic in_executeInternal()to route to doubles execution pathswitchActiveMonForSlot()to switch individual slots in doubles battles_packMoveDecision()helper for consistent move encoding across singles and doublesValidation & Commit Management
DefaultValidator.validateSwitch()with doubles-specific checks (mon can't be in both slots)validateSwitchForSlot()toValidatorLogiclibrary for per-slot switch validationrevealMovePairForDoubles()inDefaultCommitManagerfor atomic dual-slot move revealsDualSignedRevealDoublesstruct and related logic toSignedCommitLibfor dual-signed doubles revealsSignedCommitManagerwith doubles-specific error handlingTest Infrastructure
DoublesValidationTest.solcovering move validation, switches, and edge casesDoublesCommitManagerTest.solfor commit/reveal flows in doublesDoublesTargetedAttack- targets specific opponent slotsDoublesSlotAttack- slot-aware damage calculationDoublesEffectAttack- applies effects to specific slotsDoublesForceSwitchMove- forces opponent slot switchesMonIndexTrackingEffect- verifies effects run on correct monsEffectApplyingAttack- applies effects for testingDocumentation
PLAN.mddetailing the design principles and implementation phasesNotable Implementation Details
gameMode == GameMode.Singles; the 4-bit packing inactiveMonIndexis backward compatible with 8-bit packing for singlesexecuteWithMovesForDoubles()allows both slots' moves to be set and executed in a single transaction, matching the commit-reveal patternmonIndexparameters to ensure they run on the correct Pokémon in doublesgetGameMode()getter added for querying battle modeTesting
All existing tests pass with the new code. New test suites comprehensively cover doubles-specific scenarios including move validation, switching, commit/reveal flows, and effect application.