docs: Update Rails Engine migration plans for current codebase

Updated migration plans to reflect significant codebase evolution:

NEW SYSTEMS DOCUMENTED:
- NPC system (fully implemented with NPCManager, conversation state, events)
- Event system (80+ events across codebase)
- Global game state management (window.gameState.globalVariables)
- Multiple scenarios (24 total, up from 1 originally planned)

KEY UPDATES:
- UPDATED_MIGRATION_STATUS.md: Comprehensive status of what's changed
  - What's implemented vs what still needs server-side integration
  - Updated timeline: 22 weeks (was 18 weeks)
  - New database schema requirements
  - Updated risk assessment

- CLIENT_SERVER_SEPARATION_PLAN.md: Added 3 new systems
  - System 5: NPC System (hybrid approach confirmed)
  - System 6: Event System (selective logging)
  - System 7: Global Game State (server as source of truth)
  - Updated migration checklist: 9 phases (was 7)
  - Updated timeline: 18-22 weeks

- README_UPDATED.md: New master index document
  - Quick start guide
  - Document index
  - What's changed summary
  - Timeline breakdown
  - Architecture decisions
  - Success metrics

MIGRATION APPROACH:
- Hybrid NPC approach: Scripts client-side, validation server-side
- Selective event logging: Critical events only
- State sync: Server as source of truth, client cache for performance
- Incremental rollout with dual-mode support

TIMELINE: 22 weeks (~5.5 months)
- Added 4 weeks for NPC, Event, State integration
- Original: 18 weeks → Updated: 22 weeks (+22%)

All plans are complete, self-contained, actionable, and feature-focused.
Ready for team review and implementation.
This commit is contained in:
Z. Cliffe Schreuders
2025-11-20 15:37:37 +00:00
parent 1c391c9d78
commit 1e775ef89c
3 changed files with 1451 additions and 19 deletions

View File

@@ -0,0 +1,394 @@
# Rails Engine Migration Plans - Updated November 2025
## Overview
This directory contains comprehensive plans for migrating BreakEscape from a standalone browser application to a Rails Engine that can be mounted in Hacktivity Cyber Security Labs and run standalone.
**Last Updated:** November 20, 2025
**Status:** Plans updated to reflect current codebase state
---
## Quick Start
### 📋 Start Here
1. **[UPDATED_MIGRATION_STATUS.md](./UPDATED_MIGRATION_STATUS.md)** ⭐ **READ THIS FIRST**
- Comprehensive status of what's changed since original plans
- What's been implemented (NPCs, Events, Game State)
- What still needs to be done (server-side sync)
- Updated timeline (22 weeks vs 18 weeks)
- Risk assessment and success metrics
2. **[progress/CLIENT_SERVER_SEPARATION_PLAN.md](./progress/CLIENT_SERVER_SEPARATION_PLAN.md)** ⭐ **READ THIS SECOND**
- System-by-system separation strategy
- Updated with NPC, Event, and Game State systems
- Detailed implementation examples
- Migration checklist with 9 phases (was 7)
3. **[progress/RAILS_ENGINE_MIGRATION_PLAN.md](./progress/RAILS_ENGINE_MIGRATION_PLAN.md)**
- Complete Rails Engine creation guide
- Database schema (needs updates for new systems)
- Phase-by-phase implementation (18 week plan)
- Deployment checklist
---
## Document Index
### Core Planning Documents (Updated)
| Document | Status | Purpose |
|----------|--------|---------|
| **UPDATED_MIGRATION_STATUS.md** | ✅ **Current** | Master status document - what's changed, what's needed |
| **CLIENT_SERVER_SEPARATION_PLAN.md** | ✅ **Updated** | System-by-system separation (added NPCs, Events, State) |
| **RAILS_ENGINE_MIGRATION_PLAN.md** | ⚠️ **Needs Schema Updates** | Rails Engine creation guide (phases still valid) |
| **SERVER_CLIENT_MODEL_ASSESSMENT.md** | ✅ **Still Valid** | Architecture assessment and compatibility |
| **SERVER_CLIENT_MIGRATION_GUIDE.md** | ✅ **Still Valid** | Quick reference guide |
| **MIGRATION_CODE_EXAMPLES.md** | ✅ **Still Valid** | Before/after code examples |
| **NPC_MIGRATION_OPTIONS.md** | ✅ **Validated** | NPC-specific migration strategy (hybrid confirmed) |
| **ARCHITECTURE_COMPARISON.md** | ✅ **Still Valid** | Visual architecture diagrams |
---
## What's Changed Since Original Plans
### ✅ Fully Implemented (New Features)
#### 1. NPC System (Production Ready)
- **NPCManager** with full lifecycle management
- Event-driven dialogue (20+ event patterns)
- Conversation state persistence
- Two NPC types: phone and person (sprite-based)
- Line-of-sight system
- NPC item giving and door unlocking
- Timed messages and conversations
**Files:** 10+ files in `js/systems/` and `js/minigames/`
**Impact:** Need server validation for NPC actions, conversation state sync
#### 2. Event System (Production Ready)
- **EventDispatcher** with 80+ emit calls
- 20+ event types for game actions
- NPCs react to events
- Event-driven game mechanics
**Impact:** Need selective server logging for critical events
#### 3. Global Game State (Production Ready)
- `window.gameState.globalVariables` for scenario-wide state
- NPCs use global variables for relationships
- Persistent state across rooms
**Impact:** Need server sync for all global state changes
#### 4. Multiple Scenarios (24 Total)
- Production scenarios: ceo_exfil, cybok_heist, biometric_breach
- Test scenarios for NPCs, RFID, layouts
- **Was:** 1 scenario planned
- **Now:** 24 scenarios to import
**Impact:** Need to import all scenarios, may need per-scenario permissions
#### 5. Advanced Unlock System
- 5 lock types fully working
- Key ring support
- NPC lockpick interruption
- Event emission for unlocks
**Impact:** All validation MUST move server-side
---
### ❌ Not Yet Implemented (High Priority)
#### 1. Server-Side Sync Functions
- No API endpoints exist
- No server validation
- All validation client-side (insecure)
#### 2. Rails Engine Structure
- No Rails engine created
- No database schema
- No models, controllers, or views
#### 3. Server-Side Validation
- Players can manipulate state in console
- Can read all scenario data
- Can bypass unlock requirements
---
## Updated Migration Timeline
### Total Duration: 22 weeks (~5.5 months)
**Breakdown:**
- Weeks 1-4: Server Infrastructure (Rails Engine, Database, Models)
- Weeks 5-6: Client Data Access Layer
- Weeks 7-8: Room Loading
- Weeks 9-10: Unlock System
- Weeks 11-12: Inventory System
- Weeks 13-14: NPC System ⚠️ **NEW** (+2 weeks)
- Weeks 15-16: Minigame Validation
- Weeks 17-18: Event System ⚠️ **NEW** (+2 weeks)
- Weeks 19-20: Global Game State ⚠️ **NEW** (+2 weeks)
- Weeks 21-22: Testing & Deployment ⚠️ **Extended** (+2 weeks)
**Original Estimate:** 18 weeks
**Updated Estimate:** 22 weeks
**Increase:** 4 weeks (22% longer due to new systems)
---
## Key Architecture Decisions
### 1. NPC System: Hybrid Approach ✅ CONFIRMED
**Decision:** Keep Ink scripts client-side, validate actions server-side
**Rationale:**
- Instant dialogue critical for UX
- 80% of dialogue is flavor (low security risk)
- Only item giving and door unlocking need validation
- NPCs fully implemented and working well client-side
**Implementation:**
- Client runs dialogue engine locally (no changes)
- Client validates actions with server before executing
- Client syncs conversation state asynchronously
---
### 2. Event System: Selective Logging ✅ NEW
**Decision:** Most events stay client-side, critical events logged server-side
**Rationale:**
- 80+ events, most are UI-only
- Some events critical for progression tracking
- Some events useful for anti-cheat
**Events to Log Server-Side:**
- door_unlocked (progression)
- item_picked_up (inventory validation)
- minigame_completed (anti-cheat)
- unlock_attempt (brute force detection)
- npc_action_performed (audit)
---
### 3. Global Game State: Server as Source of Truth ✅ NEW
**Decision:** All critical state syncs to server
**Rationale:**
- Current state 100% client-side (insecure)
- Players can manipulate state in console
- NPCs rely on global variables for relationships
- Need persistence across sessions
**Implementation:**
- Client maintains local cache for performance
- Debounced sync to server (every 2s)
- Server is source of truth
- Optimistic updates for UX
---
## Database Schema Updates Needed
### New Tables Required
```ruby
# Global game state per player
create_table :player_game_states do |t|
t.references :game_instance, null: false
t.jsonb :global_variables, default: {}
t.jsonb :discovered_rooms, default: []
t.jsonb :completed_objectives, default: []
t.timestamps
end
# NPC conversation state
create_table :conversations do |t|
t.references :game_instance, null: false
t.references :npc, null: false
t.jsonb :history, default: []
t.text :story_state # Serialized Ink state
t.jsonb :variables, default: {} # Ink variables
t.string :current_knot
t.datetime :last_message_at
t.timestamps
end
# Game events for analytics/anti-cheat
create_table :game_events do |t|
t.references :game_instance, null: false
t.string :event_type, null: false
t.jsonb :event_data, default: {}
t.datetime :occurred_at, null: false
t.timestamps
end
# NPC permissions
create_table :npc_permissions do |t|
t.references :npc, null: false
t.string :action_type, null: false # unlock_door, give_item
t.string :target # door_id, item_id
t.jsonb :conditions, default: {}
t.timestamps
end
```
---
## API Endpoints Needed
### Core Endpoints (From Original Plans)
- `GET /api/scenario/metadata` - Bootstrap data
- `GET /api/rooms/:id` - Room data
- `POST /api/unlock/:type/:id` - Unlock validation
- `POST /api/inventory` - Inventory sync
- `GET /api/inventory` - Get inventory
### New Endpoints Required
#### NPC Endpoints
- `POST /api/npcs/:id/validate_action` - Validate NPC actions
- `POST /api/npcs/:id/sync_conversation` - Sync conversation state
- `GET /api/npcs/:id/story` - Progressive loading (optional)
#### Event Endpoints
- `POST /api/events` - Log game events
#### Game State Endpoints
- `GET /api/game_state` - Get current state
- `PUT /api/game_state/sync` - Sync state changes
- `POST /api/game_state/reconcile` - Conflict resolution
---
## Risk Assessment
### Original Risk: Medium-Low
### Updated Risk: Medium
**Risk Increase Factors:**
- More systems to integrate (NPCs, Events, State)
- More complex state management
- Conversation state persistence adds complexity
- 24 scenarios to import and test
**Mitigation Strategies:**
- Incremental rollout (system by system)
- Extensive testing at each phase
- Hybrid approach keeps working systems intact
- Dual-mode support (local JSON fallback)
- All systems well-architected and ready
---
## Success Metrics
### Performance Targets
- Room loading: < 500ms (p95)
- Unlock validation: < 300ms (p95)
- Inventory sync: < 200ms (p95)
- NPC action validation: < 300ms (p95)
- Event logging: < 100ms (p95, async)
- State sync: < 200ms (p95, debounced)
- Cache hit rate: > 80%
### Security Targets
- 0 scenario spoilers in client
- 0 unlock bypass exploits
- 0 inventory manipulation exploits
- Server validates 100% of critical actions
- All NPC actions authorized server-side
### Reliability Targets
- 99.9% API uptime
- < 0.1% error rate
- Offline queue: 100% eventual consistency
- State conflicts: < 1% of syncs
---
## Next Steps
### Immediate Actions (Week 1)
1. **Review Updated Plans**
- Read UPDATED_MIGRATION_STATUS.md
- Read updated CLIENT_SERVER_SEPARATION_PLAN.md
- Team discussion and approval
2. **Update Database Schema Design**
- Add tables for NPCs, Events, State
- Design indexes for performance
- Plan migration strategy
3. **Setup Development Environment**
- Rails Engine skeleton
- Test database
- Dual-mode testing setup
4. **Scenario Import Strategy**
- Plan how to import 24 scenarios
- Ink script storage strategy
- NPC permission seeding
### Medium-Term Actions (Weeks 2-4)
1. **Create Rails Engine**
2. **Implement Database Models**
3. **Build API Endpoints** (starting with Room Loading)
4. **Create Client Data Access Layer**
---
## Team Communication
### Regular Updates
- Weekly progress reviews
- Blockers and risks
- Timeline adjustments
### Key Stakeholders
- Development team
- Hacktivity integration team
- QA/Testing team
- Security review team
---
## Conclusion
The codebase has matured significantly with production-ready implementations of NPCs, events, and game state. The original migration plans are fundamentally sound but need:
- ✅ 4 additional weeks for new systems
- ✅ Updated database schema
- ✅ Additional API endpoints
- ✅ More comprehensive testing
**The migration is READY TO BEGIN** with these updated plans.
**Estimated Completion:** 22 weeks from start
**Confidence Level:** High
**Risk Level:** Medium (manageable with incremental approach)
---
## Document Maintenance
This README and associated plans should be updated:
- Weekly during active development
- After major architectural decisions
- When scope changes
- When timeline adjustments are made
**Current Maintainer:** AI Assistant
**Last Review:** November 20, 2025
**Next Review Due:** December 2025 or at project start

View File

@@ -0,0 +1,607 @@
# Updated Rails Engine Migration Status & Plans
## Last Updated: 2025-11-20
## Executive Summary
This document provides an updated assessment of the BreakEscape codebase and Rails Engine migration plans based on the **current state of implementation**. The codebase has evolved significantly since the original plans were created, with major systems now fully implemented.
---
## What's Changed Since Original Plans
### ✅ Fully Implemented (New Since Original Plans)
#### 1. **Comprehensive NPC System**
**Status:** ✅ **COMPLETE** - Production ready
**What's Implemented:**
- **NPCManager** (`js/systems/npc-manager.js`)
- Full lifecycle management for NPCs
- Event mapping system (20+ event patterns)
- Conversation history tracking per NPC
- Timed messages and timed conversations
- InkEngine caching and optimization
- NPC item inventory ("itemsHeld")
- **Two NPC Types:**
- `phone`: Text-only NPCs on phones
- `person`: In-world sprite-based NPCs
- **Line-of-Sight (LOS) System** (`js/systems/npc-los.js`)
- NPCs can detect player in their field of view
- Configurable range and angle
- Can interrupt lockpicking if player is seen
- **Conversation State Management** (`js/systems/npc-conversation-state.js`)
- Persists Ink story state across conversations
- Saves variables (favor, trust_level, etc.)
- Restores conversation progress
- Handles story endings gracefully
- **Event-Driven Dialogue:**
- NPCs react to game events (item_picked_up, door_unlocked, room_entered, etc.)
- Configurable cooldowns and "once-only" triggers
- Pattern matching for flexible event routing
- **NPC Item Giving:**
- NPCs can give items to player via Ink tags
- Integrated with inventory system
- Server validation will be needed for this
**Files:**
- `js/systems/npc-manager.js` (500+ lines)
- `js/systems/npc-conversation-state.js`
- `js/systems/npc-barks.js`
- `js/systems/npc-lazy-loader.js`
- `js/systems/npc-los.js`
- `js/systems/npc-game-bridge.js`
- `js/systems/npc-behavior.js`
- `js/systems/npc-hostile.js`
- `js/minigames/person-chat/person-chat-minigame.js`
- `js/minigames/person-chat/person-chat-conversation.js`
- `js/minigames/phone-chat/phone-chat-minigame.js`
- `js/minigames/phone-chat/phone-chat-conversation.js`
**Migration Impact:**
- ✅ Original NPC_MIGRATION_OPTIONS.md is still relevant
- ⚠️ Need to add conversation state sync to server
- ⚠️ Need server validation for NPC actions (give items, unlock doors)
- ⚠️ Need to handle event system on server
---
#### 2. **Comprehensive Event System**
**Status:** ✅ **COMPLETE** - Production ready
**What's Implemented:**
- **EventDispatcher** with 80+ emit calls across codebase
- **20+ Event Types:**
- `door_unlock_attempt`
- `door_unlocked`
- `item_picked_up`
- `item_used`
- `minigame_completed`
- `room_entered`
- `room_revealed`
- `container_opened`
- `lockpick_used_in_view`
- `health_changed`
- `player_detected`
- Many more...
**Migration Impact:**
- ⚠️ Server needs to track player actions for event validation
- ⚠️ Some events may need server authorization (e.g., door_unlocked)
- ⚠️ Event history could be used for anti-cheat
- ✅ Most events can stay client-side for UI/NPC reactions
---
#### 3. **Game State Management**
**Status:** ✅ **COMPLETE** - Production ready
**What's Implemented:**
- **Global Variables System:**
- `window.gameState.globalVariables` - persists across rooms
- Used by NPCs for tracking player relationships
- Used for scenario-wide flags and progression
- **Player State:**
- Health system (`js/systems/player-health.js`)
- Position tracking
- Room discovery
- Inventory
- **NPC State:**
- Conversation history per NPC
- Story variables (favor, trust, etc.)
- Items held by NPCs
- **Scenario State:**
- Unlocked rooms
- Unlocked objects
- Completed objectives
**Migration Impact:**
- ⚠️ Server must become source of truth for all game state
- ⚠️ Need state reconciliation on connect/reconnect
- ⚠️ Need atomic updates to prevent race conditions
- ⚠️ Need to sync state changes server-side
---
#### 4. **Multiple Scenarios**
**Status:** ✅ **COMPLETE** - 24 scenarios exist
**What's Implemented:**
- **Production Scenarios:**
- `ceo_exfil.json` - Original CEO heist scenario
- `cybok_heist.json` - Educational CyBOK scenario
- `biometric_breach.json` - Biometrics-focused scenario
- **Test Scenarios:**
- NPC testing scenarios (patrol, waypoints, LOS, personal space)
- RFID testing scenarios
- Layout testing scenarios (vertical, horizontal, complex)
- Timed messages demo
- **Total:** 24 different scenarios in `scenarios/` directory
**Migration Impact:**
- ✅ Need to import all scenarios into database
- ✅ Need scenario versioning/updates strategy
- ✅ Multiple scenarios handled by original plans
- ⚠️ May want scenario-level permissions (which users can access which scenarios)
---
#### 5. **Advanced Unlock System**
**Status:** ✅ **COMPLETE** - Production ready
**What's Implemented:**
- **Lock Types Supported:**
- `key` - Physical keys with key ring support
- `pin` - PIN code entry
- `password` - Password entry with hints
- `biometric` - Fingerprint/DNA matching
- `bluetooth` - Bluetooth pairing
- `lockpick` - Lockpicking minigame (uses keyPins)
- **Advanced Features:**
- Key rings (multiple keys in one item)
- NPC lockpick interruption (if NPC sees player)
- Event emission for unlock attempts
- Testing mode (`window.DISABLE_LOCKS`)
- Support for both snake_case and camelCase property names
**Files:**
- `js/systems/unlock-system.js`
- `js/systems/minigame-starters.js`
- 16 different minigame implementations
**Migration Impact:**
- ⚠️ **CRITICAL:** All unlock validation MUST move server-side
- ⚠️ Server must validate key matches lock
- ⚠️ Server must validate PIN/password correctness
- ⚠️ Server must check lockpick success (anti-cheat)
- ⚠️ Server must authorize NPC lockpick interruptions
- ✅ Minigame UI can stay client-side
---
### ❌ Not Yet Implemented (Still Needed)
#### 1. **Server-Side Sync Functions**
**Status:** ❌ **NOT IMPLEMENTED** - High Priority
**What's Missing:**
- No server API endpoints exist yet
- No sync functions for:
- Game state changes
- Inventory updates
- Unlock validation
- NPC action validation
- Conversation state sync
- Event logging
**What's Needed:**
See updated CLIENT_SERVER_SEPARATION_PLAN.md for details.
Key areas:
1. Room loading API
2. Unlock validation API
3. Inventory sync API
4. NPC action validation API
5. Game state sync API
6. Event logging API
---
#### 2. **Rails Engine Structure**
**Status:** ❌ **NOT IMPLEMENTED** - Medium Priority
**What's Missing:**
- No Rails engine created yet
- No database schema
- No models, controllers, or views
- No Rails integration
**What's Needed:**
Follow RAILS_ENGINE_MIGRATION_PLAN.md phases 1-12.
---
#### 3. **Server-Side Validation**
**Status:** ❌ **NOT IMPLEMENTED** - High Priority
**What's Missing:**
- All validation is client-side (insecure)
- Players can:
- Modify `window.DISABLE_LOCKS = true`
- Edit inventory in console
- Read all scenario data from network tab
- Manipulate game state variables
- Bypass unlock requirements
**What's Needed:**
- Server validates every critical action
- Server is source of truth for game state
- Client is just UI presentation layer
---
## Updated Migration Approach
### Phase 1: Server Infrastructure (Weeks 1-4)
**Goal:** Build Rails Engine with database and basic API
**Tasks:**
- [ ] Create Rails Engine skeleton (`rails plugin new break_escape --mountable`)
- [ ] Design database schema accounting for:
- NPCs with conversation state
- Event system tracking
- Global variables
- Multiple scenarios
- [ ] Create models: GameInstance, Scenario, Room, RoomObject, NPC, Conversation, PlayerState, InventoryItem
- [ ] Add NPC-specific models:
- ConversationState (stores Ink story state per player-NPC pair)
- NPCPermission (which NPCs can give which items/unlock which doors)
- GameEvent (log of player actions)
- [ ] Create seed data importer for 24 scenarios
- [ ] Setup test framework
**Updated Schema Additions:**
```ruby
# New: Global game state per player
create_table :player_game_states do |t|
t.references :game_instance, null: false
t.jsonb :global_variables, default: {}
t.jsonb :discovered_rooms, default: []
t.jsonb :completed_objectives, default: []
t.timestamps
t.index :global_variables, using: :gin
end
# Updated: NPC conversations with state
create_table :conversations do |t|
t.references :game_instance, null: false
t.references :npc, null: false
t.jsonb :history, default: [] # Message array
t.text :story_state # Serialized Ink state
t.jsonb :variables, default: {} # Ink variables
t.string :current_knot
t.datetime :last_message_at
t.timestamps
t.index [:game_instance_id, :npc_id], unique: true
t.index :variables, using: :gin
end
# New: Track game events for analytics and anti-cheat
create_table :game_events do |t|
t.references :game_instance, null: false
t.string :event_type, null: false # door_unlocked, item_picked_up, etc.
t.jsonb :event_data, default: {} # Event-specific data
t.datetime :occurred_at, null: false
t.timestamps
t.index [:game_instance_id, :event_type]
t.index :occurred_at
t.index :event_data, using: :gin
end
# New: NPC permissions for action validation
create_table :npc_permissions do |t|
t.references :npc, null: false
t.string :action_type, null: false # unlock_door, give_item
t.string :target # door_id, item_id
t.jsonb :conditions, default: {} # trust_level, flags, etc.
t.timestamps
t.index [:npc_id, :action_type, :target], unique: true
end
```
---
### Phase 2: Client Data Access Layer (Weeks 5-6)
**Goal:** Create abstraction for server communication
**Tasks:**
- [ ] Create `GameDataAccess` class (`js/core/game-data-access.js`)
- [ ] Add dual-mode support (local JSON fallback for development)
- [ ] Implement methods:
- `getRoomData(roomId)` → replaces `window.gameScenario.rooms[roomId]`
- `validateUnlock(targetType, targetId, attempt)` → server validation
- `syncInventory(action, itemData)` → inventory changes
- `validateNPCAction(npcId, action, context)` → NPC actions
- `syncConversationState(npcId, state)` → conversation persistence
- `syncGameState(globalVariables)` → global state
- `logEvent(eventType, eventData)` → event logging
- [ ] Add error handling, retry logic, caching
- [ ] Add offline queue for operations
---
### Phase 3: System-by-System Migration (Weeks 7-14)
#### Week 7-8: Room Loading
- [ ] Modify `loadRoom()` to use `GameDataAccess.getRoomData()`
- [ ] Add loading indicators
- [ ] Test room lazy loading from server
- [ ] Add prefetching for adjacent rooms
#### Week 9-10: Unlock System
- [ ] Create `Api::UnlockController`
- [ ] Add validation for all lock types
- [ ] Modify `handleUnlock()` to call server
- [ ] Server returns unlocked content
- [ ] Add rate limiting for brute force protection
#### Week 11-12: Inventory System
- [ ] Create `Api::InventoryController`
- [ ] Add server sync to `addToInventory()`, `removeFromInventory()`
- [ ] Implement optimistic UI updates
- [ ] Add rollback on server rejection
- [ ] Handle offline mode
#### Week 13-14: NPC System
- [ ] Create `Api::NpcsController`
- [ ] Add endpoints:
- `POST /api/npcs/:id/validate_action` - Validate NPC actions
- `POST /api/npcs/:id/sync_conversation` - Sync conversation state
- `GET /api/npcs/:id/story` - Optional progressive loading
- [ ] Modify NPC action handlers to validate with server
- [ ] Add conversation state sync (async)
- [ ] Server validates:
- Can NPC give this item?
- Can NPC unlock this door?
- Does player meet trust requirements?
**NPC Migration Strategy (Hybrid Approach):**
**Keep client-side:** Ink scripts, dialogue engine, conversation UI
**Keep client-side:** Event listener setup, timed messages
⚠️ **Add server validation:** Item giving, door unlocking, trust checks
⚠️ **Add server sync:** Conversation state, story variables
---
### Phase 4: Game State Management (Weeks 15-16)
- [ ] Create `Api::GameStateController`
- [ ] Add endpoints:
- `GET /api/game_state` - Get current state
- `PUT /api/game_state/global_variables` - Update globals
- `POST /api/game_state/sync` - Full state sync
- [ ] Modify `window.gameState` to sync changes to server
- [ ] Add state reconciliation on connect
- [ ] Handle offline queue
---
### Phase 5: Event System Integration (Weeks 17-18)
- [ ] Create `Api::EventsController`
- [ ] Add event logging endpoint
- [ ] Modify event dispatcher to log critical events server-side
- [ ] Events to log:
- door_unlocked (for progression tracking)
- item_picked_up (for inventory validation)
- minigame_completed (for anti-cheat)
- health_changed (for failure detection)
- npc_action_performed (for permissions audit)
- [ ] Add analytics dashboard for game events
---
### Phase 6: Testing & Deployment (Weeks 19-22)
- [ ] Integration tests for all systems
- [ ] Performance testing (latency, throughput)
- [ ] Security audit (authorization, validation)
- [ ] Load testing
- [ ] Deploy to staging
- [ ] User acceptance testing
- [ ] Deploy to production
**Total Timeline: 22 weeks (~5 months)**
---
## Key Architecture Decisions
### 1. NPC System: Hybrid Approach (Confirmed)
**Decision:** Keep Ink scripts client-side, validate actions server-side
**Rationale:**
- ✅ NPCs are fully implemented with complex dialogue trees
- ✅ Instant dialogue response critical for UX
- ✅ 80% of dialogue is flavor text (low security risk)
- ⚠️ Only item giving and door unlocking need validation
- ⚠️ Can add progressive loading for high-security NPCs later
**Implementation:**
- Client loads Ink scripts at startup (or progressively)
- Client runs dialogue engine locally
- When NPC performs action (give item, unlock door):
- Client asks server: "Can this NPC do this?"
- Server validates conditions (trust level, permissions, prerequisites)
- Server executes action if allowed
- Client syncs conversation state periodically (async)
---
### 2. Event System: Selective Server Logging
**Decision:** Most events stay client-side, critical events logged server-side
**Rationale:**
- ✅ 80+ events emitted across codebase
- ✅ Most are for UI reactions (don't need server)
- ⚠️ Some events critical for progression tracking
- ⚠️ Some events useful for anti-cheat
**Events to Log Server-Side:**
- door_unlocked → Track progression
- item_picked_up → Validate inventory
- minigame_completed → Anti-cheat metrics
- unlock_attempt → Brute force detection
- npc_action_performed → Audit NPC permissions
**Events to Keep Client-Only:**
- room_revealed → UI only
- player_moved → Too frequent
- container_opened → UI only
- bark_displayed → UI only
---
### 3. Game State: Server as Source of Truth
**Decision:** All critical state must sync to server
**Rationale:**
- ⚠️ Current state is 100% client-side (insecure)
- ⚠️ Players can manipulate state in console
- ✅ Server must validate all state changes
- ✅ Client should optimistically update for UX
**Critical State (Must Sync):**
- Player inventory
- Unlocked rooms/objects
- Global variables
- NPC conversation state
- Player health
- Completed objectives
**UI State (Can Stay Client-Only):**
- Camera position
- UI panel states
- Volume settings
- Debug visualizations
---
## Risk Assessment
### High Risk Areas
#### 1. Network Latency
**Risk:** Server round-trips add 100-300ms delay
**Mitigation:**
- ✅ Aggressive client-side caching
- ✅ Prefetch adjacent rooms in background
- ✅ Optimistic UI updates
- ✅ Keep minigames 100% client-side
- ✅ Keep dialogue engine client-side
#### 2. State Consistency
**Risk:** Client and server state diverge
**Mitigation:**
- ✅ Server is source of truth (always)
- ✅ Periodic state reconciliation
- ✅ Rollback on server rejection
- ✅ Audit log of all state changes
- ✅ Offline queue with conflict resolution
#### 3. NPC Complexity
**Risk:** NPC system is complex with many interactions
**Mitigation:**
- ✅ Start with action validation only (minimal change)
- ✅ Add conversation sync as async background task
- ✅ Progressive enhancement (don't break existing features)
- ✅ Extensive testing of NPC interactions
---
## Success Metrics
### Performance Targets
- Room loading: < 500ms (p95)
- Unlock validation: < 300ms (p95)
- Inventory sync: < 200ms (p95)
- NPC action validation: < 300ms (p95)
- Cache hit rate: > 80%
### Security Targets
- 0 scenario spoilers in client
- 0 unlock bypass exploits
- 0 inventory manipulation exploits
- Server validates 100% of critical actions
### Reliability Targets
- 99.9% API uptime
- < 0.1% error rate
- Offline queue: 100% eventual consistency
---
## Next Steps (Immediate Actions)
1. **Review this document** with team
2. **Approve updated timeline** (22 weeks vs original 18 weeks)
3. **Begin Phase 1:** Rails Engine creation
4. **Setup development environment** for server-client testing
5. **Create test scenarios** for each migration phase
---
## Document References
### Planning Documents (Updated)
-`SERVER_CLIENT_MODEL_ASSESSMENT.md` - Still accurate
- ⚠️ `CLIENT_SERVER_SEPARATION_PLAN.md` - Needs NPC/Event updates (below)
-`NPC_MIGRATION_OPTIONS.md` - Confirmed: Hybrid approach
-`RAILS_ENGINE_MIGRATION_PLAN.md` - Needs Phase updates (below)
-`MIGRATION_CODE_EXAMPLES.md` - Still accurate
### New Documentation Needed
- [ ] Event system migration guide
- [ ] NPC conversation state sync specification
- [ ] Global game state sync specification
- [ ] Offline queue design document
- [ ] Anti-cheat strategy document
---
## Conclusion
**The codebase has matured significantly** with production-ready implementations of NPCs, events, game state, and multiple scenarios. The original migration plans are still fundamentally sound, but need updates to account for:
1. **NPC system complexity** - More sophisticated than originally planned
2. **Event system** - Wasn't in original plans, needs integration
3. **Game state management** - More comprehensive than originally planned
4. **Multiple scenarios** - 24 vs 1 expected
**Recommended Approach:**
- ✅ Follow original plan structure (phases 1-12)
- ⚠️ Add 4 weeks for NPC/Event/State integration
- ✅ Use hybrid approach for NPCs (validated in plans)
- ✅ Start with Phase 1 (Rails Engine creation)
- ✅ Implement dual-mode testing (local JSON fallback)
**Total Effort: 22 weeks (~5 months)**
**Risk Level: Medium** (more complexity but clearer requirements)
**Confidence: High** (architecture proven, team experienced)

View File

@@ -1,9 +1,16 @@
# Client-Server Separation Plan for BreakEscape
## Last Updated: 2025-11-20
## Executive Summary
This document outlines the preparation needed to cleanly separate BreakEscape into client-side and server-side responsibilities. The goal is to identify what stays client-side (UI, rendering, minigames) vs what moves server-side (validation, content delivery, state management).
**⚠️ NOTE:** This plan has been updated to reflect the current state of the codebase, including:
- Fully implemented NPC system with conversation state
- Comprehensive event system (80+ events)
- Global game state management
- Multiple scenarios (24 total)
---
## Current Architecture: Single Point of Truth
@@ -419,14 +426,321 @@ async function takeItemFromContainer(container, item) {
See detailed analysis in **NPC_MIGRATION_OPTIONS.md**.
**⚠️ UPDATE:** NPC system is now fully implemented with:
- NPCManager (event mappings, conversation history, timed messages)
- Two NPC types: 'phone' and 'person' (sprite-based)
- Line-of-sight system for NPCs
- Conversation state persistence (NPCConversationStateManager)
- NPC item giving system
- Event-driven dialogue (20+ event patterns)
**Summary:**
- **Recommended:** Hybrid approach (scripts client-side, actions server-side)
- **What's Client-Side:** Ink engine, dialogue rendering, conversation UI
- **What's Server-Side:** Action validation, conversation history, unlock permissions
- **Recommended:** Hybrid approach (scripts client-side, actions server-side)**CONFIRMED**
- **What's Client-Side:** Ink engine, dialogue rendering, conversation UI, event listeners, timed messages
- **What's Server-Side:** Action validation (give items, unlock doors), conversation state sync, trust level validation
#### Current Implementation (Client-Side)
```javascript
// NPCManager handles full lifecycle
class NPCManager {
registerNPC(id, opts) {
// opts: { displayName, storyPath, avatar, currentKnot, phoneId, npcType, eventMappings, timedMessages }
// Registers NPC with event listeners and timed message scheduling
}
// Conversation history tracked per NPC
conversationHistory = new Map(); // { npcId: [ {type, text, timestamp} ] }
// Conversation state persisted
saveNPCState(npcId, story) {
// Saves Ink story state and variables to NPCConversationStateManager
}
// Event-driven dialogue
_setupEventMappings(npcId, eventMappings) {
// Maps game events → Ink story knots
// Supports patterns like "item_picked_up:lockpick" → "on_lockpick_pickup"
}
}
```
**What Needs Server Migration:**
```javascript
// js/systems/npc-game-bridge.js - NPC Actions
async function handleNPCGiveItem(npcId, itemType, itemName) {
// CURRENT: Client-side only (insecure)
const item = { type: itemType, name: itemName };
addToInventory(createInventorySprite(item));
// NEEDED: Server validation
const response = await fetch(`/api/npcs/${npcId}/validate_action`, {
method: 'POST',
body: JSON.stringify({
action: 'give_item',
context: { itemType, itemName }
})
});
const result = await response.json();
if (result.allowed) {
addToInventory(createInventorySprite(item));
} else {
showError('NPC cannot give this item');
}
}
// Conversation state sync (async, non-blocking)
async function syncConversationState(npcId) {
const state = window.npcConversationStateManager.getState(npcId);
// Fire and forget - don't block UI
fetch(`/api/npcs/${npcId}/sync_conversation`, {
method: 'POST',
body: JSON.stringify({
history: state.history,
variables: state.variables,
storyState: state.storyState,
currentKnot: state.currentKnot
})
}).catch(err => console.warn('Failed to sync conversation:', err));
}
```
**Changes Needed:**
- 🔄 Add server validation for NPC actions (give items, unlock doors)
- 🔄 Add async conversation state sync
- 🔄 Validate trust levels server-side
- ⚠️ Keep Ink scripts client-side (instant dialogue)
- ⚠️ Keep event listeners client-side (UI reactions)
---
### System 6: Minigames
### System 6: Event System (NEW)
#### Current Implementation (Client-Side)
**Status:****FULLY IMPLEMENTED** - 80+ events across codebase
```javascript
// EventDispatcher emits events for:
// - door_unlock_attempt
// - door_unlocked
// - item_picked_up
// - item_used
// - minigame_completed
// - room_entered
// - room_revealed
// - container_opened
// - lockpick_used_in_view
// - health_changed
// - player_detected
// - npc_action_performed
// ... and many more
// Example usage:
window.eventDispatcher.emit('door_unlocked', {
roomId: 'office',
connectedRoom: 'ceo_office',
direction: 'north'
});
// NPCs listen to events:
npc.eventMappings = [
{
eventPattern: 'item_picked_up:lockpick',
targetKnot: 'on_lockpick_pickup',
onceOnly: true,
cooldown: 0
}
];
```
**Issues:**
- All events client-side only
- No server visibility into player actions
- Can't use for anti-cheat or analytics
- Event history not persisted
#### Future (Server-Client)
**Strategy:** Selective server logging (not all events need server)
```javascript
// Client-side event system stays the same for UI
window.eventDispatcher.emit('door_unlocked', eventData);
// But critical events also logged server-side
async function logCriticalEvent(eventType, eventData) {
// Only log events that matter for progression/anti-cheat
const criticalEvents = [
'door_unlocked',
'item_picked_up',
'minigame_completed',
'unlock_attempt',
'npc_action_performed',
'health_changed'
];
if (!criticalEvents.includes(eventType)) return;
// Fire and forget - don't block gameplay
fetch('/api/events', {
method: 'POST',
body: JSON.stringify({ eventType, eventData, timestamp: Date.now() })
}).catch(err => console.warn('Failed to log event:', err));
}
// Hook into event dispatcher
const originalEmit = window.eventDispatcher.emit.bind(window.eventDispatcher);
window.eventDispatcher.emit = function(eventType, eventData) {
originalEmit(eventType, eventData);
logCriticalEvent(eventType, eventData); // Async log to server
};
```
**What's Client-Side:**
- Event dispatcher
- Event listener registration
- UI reactions to events
- NPC event mappings
- Timed message triggers
- Bark system triggers
**What's Server-Side:**
- Event logging (for critical events)
- Event validation (e.g., was door unlock legitimate?)
- Event analytics
- Anti-cheat metrics
**Changes Needed:**
- 🔄 Add server event logging endpoint
- 🔄 Hook event dispatcher to log critical events
- 🔄 Server validates event legitimacy (optional)
- ⚠️ Keep event system 100% functional without server (offline mode)
---
### System 7: Global Game State (NEW)
#### Current Implementation (Client-Side)
**Status:****FULLY IMPLEMENTED** - Comprehensive state management
```javascript
// Global variables shared across rooms/NPCs
window.gameState = {
globalVariables: {
player_favor_with_security: 0,
player_trust_level: 1,
ceo_office_unlocked: false,
alarm_triggered: false,
// ... many more
}
};
// NPCs read/write global variables via Ink:
VAR player_favor = 0
VAR trust_level = 1
// Game systems read global state:
if (window.gameState.globalVariables.alarm_triggered) {
// Handle alarm state
}
```
**Issues:**
- All state client-side only
- Players can manipulate in console: `window.gameState.globalVariables.trust_level = 999`
- No persistence across sessions
- No validation of state changes
- No audit trail
#### Future (Server-Client)
**Strategy:** Server as source of truth, client caches for performance
```javascript
// Client maintains local copy for performance
window.gameState = {
globalVariables: {}, // Cached from server
_dirty: new Set(), // Track unsaved changes
_syncing: false
};
// Intercept writes to track changes
function setGlobalVariable(key, value) {
// Optimistically update local state
window.gameState.globalVariables[key] = value;
window.gameState._dirty.add(key);
// Trigger sync (debounced)
scheduleGameStateSync();
}
// Sync to server (debounced to avoid too many requests)
const scheduleGameStateSync = debounce(async () => {
if (window.gameState._syncing) return;
if (window.gameState._dirty.size === 0) return;
window.gameState._syncing = true;
const changes = {};
for (const key of window.gameState._dirty) {
changes[key] = window.gameState.globalVariables[key];
}
try {
const response = await fetch('/api/game_state/sync', {
method: 'PUT',
body: JSON.stringify({ globalVariables: changes })
});
if (response.ok) {
const serverState = await response.json();
// Server might reject some changes - reconcile
window.gameState.globalVariables = serverState.globalVariables;
window.gameState._dirty.clear();
} else {
// Server rejected - rollback?
console.warn('Server rejected state changes');
}
} finally {
window.gameState._syncing = false;
}
}, 2000); // Sync every 2 seconds
// On game start, load state from server
async function loadGameState() {
const response = await fetch('/api/game_state');
const state = await response.json();
window.gameState.globalVariables = state.globalVariables;
}
```
**What's Client-Side:**
- Local cache of global variables (for performance)
- Optimistic updates
- UI that reads state
**What's Server-Side:**
- Source of truth for all global variables
- Validation of state changes
- State persistence
- State reconciliation
- Audit log of changes
**Changes Needed:**
- 🔄 Add server state management endpoints
- 🔄 Intercept global variable writes
- 🔄 Add debounced sync to server
- 🔄 Add state reconciliation on load
- ⚠️ Handle offline mode (queue changes)
---
### System 8: Minigames
#### Current (Client-Side)
@@ -831,15 +1145,24 @@ describe('Room Loading', () => {
---
## Migration Checklist
## Migration Checklist (UPDATED)
### Preparation Phase (Week 1-2)
- [ ] Audit all `window.gameScenario` access points
- [ ] Audit all `window.gameState` access points ⚠️ **NEW**
- [ ] Audit all `eventDispatcher.emit` calls ⚠️ **NEW**
- [ ] Create `GameDataAccess` abstraction layer
- [ ] Design database schema
- [ ] Create Rails models (Scenario, Room, RoomObject, NPC)
- [ ] Write import script for scenario JSON → database
- [ ] Design database schema (updated for NPCs, events, state)
- [ ] Create Rails models:
- [ ] Scenario, Room, RoomObject
- [ ] NPC, Conversation, ConversationState ⚠️ **NEW**
- [ ] GameEvent ⚠️ **NEW**
- [ ] PlayerGameState (for global variables) ⚠️ **NEW**
- [ ] NPCPermission ⚠️ **NEW**
- [ ] InventoryItem, PlayerState
- [ ] Write import script for 24 scenarios → database ⚠️ **UPDATED** (was 1 scenario)
- [ ] Import all NPC Ink scripts into database ⚠️ **NEW**
- [ ] Setup test scenarios in database
### Phase 1: Room Loading (Week 3)
@@ -886,14 +1209,37 @@ describe('Room Loading', () => {
- [ ] Test add/remove items
- [ ] Test item use validation
### Phase 5: NPC System (Week 8+)
### Phase 5: NPC System (Week 8-10) ⚠️ **UPDATED**
See **NPC_MIGRATION_OPTIONS.md** for detailed plan.
- [ ] Choose NPC migration approach (hybrid recommended)
- [ ] Implement action validation endpoints
- [ ] Add conversation history sync
- [ ] Test NPC actions (give items, unlock doors)
**Status:** NPC system fully implemented client-side, needs server integration only
- [ ] Create `Api::NpcsController`
- [ ] Add endpoints:
- [ ] `POST /api/npcs/:id/validate_action` - Validate NPC actions (give items, unlock doors)
- [ ] `POST /api/npcs/:id/sync_conversation` - Sync conversation state (async)
- [ ] `GET /api/npcs/:id/story` - Progressive loading (optional)
- [ ] Create NPC permission system:
- [ ] `NPCPermission` model (which NPCs can do what)
- [ ] Server validates trust levels, prerequisites
- [ ] Update NPC action handlers:
- [ ] `handleNPCGiveItem()` - Add server validation
- [ ] `handleNPCUnlockDoor()` - Add server validation
- [ ] Add conversation state sync:
- [ ] Hook into NPCConversationStateManager
- [ ] Async sync after each conversation turn
- [ ] Restore state on game load
- [ ] Test NPC actions thoroughly:
- [ ] Give items (authorized and unauthorized)
- [ ] Unlock doors (authorized and unauthorized)
- [ ] Trust level requirements
- [ ] Conversation state persistence
- [ ] Import all Ink scripts into database
- [ ] Test event-driven dialogue still works
⚠️ **Keep client-side:** Ink engine, dialogue UI, event listeners, timed messages
**Add server-side:** Action validation, conversation state persistence
### Phase 6: Minigame Validation (Week 9)
@@ -905,7 +1251,73 @@ See **NPC_MIGRATION_OPTIONS.md** for detailed plan.
- [ ] Add metrics collection for anti-cheat
- [ ] Test each minigame validation
### Phase 7: Polish & Deployment (Week 10+)
### Phase 7: Event System Integration (Week 11-12) ⚠️ **NEW**
**Status:** Event system fully implemented client-side, needs server integration only
- [ ] Create `Api::EventsController`
- [ ] Add endpoint:
- [ ] `POST /api/events` - Log critical game events
- [ ] Create `GameEvent` model
- [ ] Identify critical events to log:
- [ ] door_unlocked
- [ ] item_picked_up
- [ ] minigame_completed
- [ ] unlock_attempt
- [ ] npc_action_performed
- [ ] health_changed
- [ ] Hook event dispatcher:
- [ ] Intercept `eventDispatcher.emit()`
- [ ] Log critical events to server (async, non-blocking)
- [ ] Keep all events client-side for UI reactions
- [ ] Add event analytics:
- [ ] Dashboard for viewing player progression
- [ ] Anti-cheat metrics
- [ ] Completion rates
- [ ] Test event logging:
- [ ] Events logged correctly
- [ ] No impact on gameplay performance
- [ ] Works offline (queues events)
⚠️ **Keep client-side:** All event listeners, UI reactions, NPC event mappings
**Add server-side:** Selective event logging for progression/analytics
---
### Phase 8: Global Game State Management (Week 13-14) ⚠️ **NEW**
**Status:** Global variables system fully implemented client-side, needs server integration
- [ ] Create `Api::GameStateController`
- [ ] Add endpoints:
- [ ] `GET /api/game_state` - Get current global state
- [ ] `PUT /api/game_state/sync` - Sync state changes
- [ ] `POST /api/game_state/reconcile` - Handle conflicts
- [ ] Create `PlayerGameState` model
- [ ] Intercept global variable writes:
- [ ] Hook `window.gameState.globalVariables` writes
- [ ] Track dirty changes
- [ ] Debounced sync to server (every 2s)
- [ ] Add state reconciliation:
- [ ] Load state from server on game start
- [ ] Handle conflicts (server wins vs client wins)
- [ ] Merge offline changes on reconnect
- [ ] Add offline support:
- [ ] Queue state changes when offline
- [ ] Sync when reconnected
- [ ] Conflict resolution strategy
- [ ] Test state management:
- [ ] NPCs read/write global variables correctly
- [ ] State persists across sessions
- [ ] State syncs correctly
- [ ] Offline mode works
⚠️ **Keep client-side:** Local cache for performance, optimistic updates
**Add server-side:** Source of truth, validation, persistence
---
### Phase 9: Polish & Deployment (Week 15-18+)
- [ ] Add comprehensive error handling
- [ ] Add offline mode support
@@ -1003,7 +1415,7 @@ See **NPC_MIGRATION_OPTIONS.md** for detailed plan.
---
## Conclusion
## Conclusion (UPDATED)
**Key Principles:**
1. **Gradual Migration:** Use abstraction layer for dual-mode operation
@@ -1011,13 +1423,32 @@ See **NPC_MIGRATION_OPTIONS.md** for detailed plan.
3. **Client Responsiveness:** Keep UI instant with optimistic updates
4. **Graceful Degradation:** Handle offline mode and errors elegantly
5. **Security First:** Never trust client for solutions
6. **Hybrid Approach:** Keep complex client systems (NPCs, dialogue) with server validation ⚠️ **NEW**
**Critical Path:**
Room Loading → Container System → Unlock System → Inventory System
**Critical Path (UPDATED):**
Room Loading → Unlock System → Inventory System → NPC Action Validation → Event Logging → Global State Sync
**Timeline:** 10-12 weeks for complete migration
**Timeline:** 18-22 weeks for complete migration ⚠️ **UPDATED** (was 10-12 weeks)
- Added: NPC system integration (2 weeks)
- Added: Event system integration (2 weeks)
- Added: Global state management (2 weeks)
- Added: Additional testing (2 weeks)
**Confidence:** High - architecture already supports this model (see ARCHITECTURE_COMPARISON.md)
**Confidence:** High - architecture already supports this model
**Key Changes Since Original Plans:**
- ✅ NPC system fully implemented (needs server validation only)
- ✅ Event system fully implemented (needs server logging only)
- ✅ Global game state fully implemented (needs server sync only)
- ✅ 24 scenarios exist (vs 1 originally planned)
- ⚠️ More complex state management than originally anticipated
- ⚠️ Conversation state persistence adds complexity
- ✅ But all systems are well-architected and ready for server integration
**Risk Assessment:**
- **Original Risk:** Medium-Low
- **Updated Risk:** Medium (slightly higher due to NPC/event/state complexity)
- **Mitigation:** Incremental rollout, extensive testing, hybrid approach keeps working systems intact