J. Rogers, SE Ohio
Phase 1: Command Formalization
Define the Command Class: Create codex_engine/core/command.py. Fields: id (UUID), timestamp, action (str), data (dict), inverse_data (dict/optional).
Controller Update: Update all _handle_action methods to return or accept Command objects. Refactor Change from simple dictionary lookup to a pipeline: Pre-process: Inject metadata (timestamp, user_id). Validation: Check if action is valid for self.state. Execution: Invoke handler. Post-process: Push to CommandHistory and UndoStack.
Phase 2: Undo/Redo Stack
UndoStack Implementation: Add self.undo_stack = [] and self.redo_stack = [] to CampaignManager.
Inversion Strategy: Update controllers to provide an "inverse" for state-mutating actions (e.g., move_marker inverse is move_marker to original (x, y)). When a Command is executed, package the current state as inverse_data.
Global Key Binding: Map Ctrl+Z to CampaignManager.undo() and Ctrl+Y to CampaignManager.redo(). undo() pops the stack, executes the inverse command, and pushes the original to redo_stack.
Phase 3: Serialization & Replay Harness
Serialization Layer: Implement Command.to_json() and Command.from_json().
Headless Test Harness: Create tests/harness.py: Initialize CodexApp with pygame in headless mode (no window). Add a MockInputProvider that reads a JSON file of Command objects. Inject commands into CampaignManager._handle_action.
State Validation: Add assert_state(node_id, property_key, expected_value) to the harness to verify controller outputs after specific command sequences.
Phase 4: Network Synchronization (Async Actions)
Queue-to-Network Bridge: In main.py, create a CommandBridge that sits between the multiprocessing.Queue and the FastAPI server.
Broadcast Protocol: When CampaignManager executes a local Command, emit it to the CommandBridge. Bridge broadcasts the JSON-serialized Command via WebSockets to all connected clients.
Remote Execution: Remote instances listen for the packet and call _handle_action(Command.from_json(packet)). Constraint: Ensure all generation IDs are synchronized; use the DBManager as the source of truth for all node references.
Implementation Roadmap
Success Metrics
Decoupling: TacticalController and GeoController should have zero knowledge of how an action is stored or undone; they only provide the "how-to-execute" logic. Determinism: Running the same sequence of commands in the test harness must result in an identical codex.db state every time. Performance: UI interactions must remain frame-locked; dispatching a command must remain an
operation to ensure no input lag.
No comments:
Post a Comment