mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-21 11:18:08 +00:00
187 lines
8.4 KiB
Markdown
187 lines
8.4 KiB
Markdown
# Break Escape: AI Coding Agent Instructions
|
|
|
|
## Project Overview
|
|
Break Escape is a Rails Engine implementing a web-based educational game framework combining escape room mechanics with cyber-physical security learning. Players navigate 2D top-down environments (powered by Phaser.js), collect items, and solve security-themed mini-games aligned to the Cyber Security Body of Knowledge (CyBOK).
|
|
|
|
### Deployment Modes
|
|
Break Escape always runs as a Rails Engine, but operates in two distinct modes:
|
|
1. **Standalone Mode**: Local Rails instance with demo user support (development/testing)
|
|
2. **Mounted Mode**: Integrated into parent Rails applications like Hacktivity for course management and secure assessment delivery
|
|
|
|
**Server-Side Validation**: Solution validation is enforced server-side. Client-side validation is for UX and gameplay only; solutions (such as passwords and pins) are verified against solutions on the backend before further game content such as rooms can be accessed.
|
|
|
|
## Architecture
|
|
|
|
### Rails Engine Integration
|
|
Break Escape is always a Rails Engine, operating in one of two modes:
|
|
|
|
**Standalone Mode** (Local Development):
|
|
- Runs as a self-contained Rails app with demo user support
|
|
- Uses `break_escape_demo_users` table for test players
|
|
- Scenarios rendered on-demand with ERB template substitution (randomized passwords/PINs)
|
|
- State persisted in `break_escape_games` JSONB column
|
|
|
|
**Mounted Mode** (Production/Hacktivity):
|
|
- Mounts into host Rails application (e.g., Hacktivity) via `config/routes.rb`
|
|
- Uses host app's `current_user` via Devise for player authentication
|
|
- Game frontend served from `app/views/` and `public/` assets
|
|
- Scenario data and player progress persisted via Rails models (`app/models/`)
|
|
- Solution validation endpoints exposed as Rails controllers (`app/controllers/`)
|
|
- Admin/instructor UI for scenario management runs in the host application
|
|
- **Server-side validation of all solutions** prevents client-side tampering and ensures assessment integrity
|
|
|
|
### Core Systems (Sequential Initialization)
|
|
1. **Game Engine** (`js/core/game.js`): Phaser.js initialization, scene management (preload → create → update)
|
|
2. **Rooms** (`js/core/rooms.js`): Dynamic room loading from JSON scenarios, depth layering by Y-position + layer offset
|
|
3. **Player** (`js/core/player.js`): Character sprite with pathfinding, keyboard/mouse controls, animation system
|
|
4. **Systems** (`js/systems/`): Modular subsystems (interactions, inventory, doors, collisions, biometrics)
|
|
5. **Mini-games** (`js/minigames/`): Framework-based educational challenges (lockpicking, password, biometrics, etc.)
|
|
|
|
### Data Flow
|
|
- **Scenarios** (JSON) → loaded into `window.gameScenario` → populate rooms/objects → create interactive environment
|
|
- **Player Actions** → interaction system checks proximity → triggers object interactions or mini-games
|
|
- **Game State** stored in `window.gameState`: `{ biometricSamples, bluetoothDevices, notes, startTime }`
|
|
|
|
### Global Window Object
|
|
Break Escape attaches critical runtime objects to `window` for cross-module access (no complex bundling):
|
|
```javascript
|
|
window.game // Phaser game instance
|
|
window.gameScenario // Current scenario JSON
|
|
window.player // Player sprite
|
|
window.rooms // Object of room data
|
|
window.gameState // Persistent game state
|
|
window.inventory // Player's collected items
|
|
```
|
|
|
|
## Key Patterns & Conventions
|
|
|
|
### Room System & Depth Calculation
|
|
**Every object's depth = worldY + layerOffset** (not Z-index). This ensures correct perspective in top-down view:
|
|
- Walls: `roomY + 0.2`
|
|
- Interactive Objects: `objectBottomY + 0.5`
|
|
- Player: `playerBottomY + 0.5`
|
|
- Doors: `doorY + 0.45`
|
|
|
|
See `js/core/rooms.js` (lines 1-40) for detailed depth hierarchy documentation.
|
|
|
|
### Object Interactions
|
|
1. Objects must have `interactable: true` and `active: true` in scenario JSON
|
|
2. Interaction distance: `INTERACTION_RANGE = 64px` (checked every 100ms)
|
|
3. Interaction handlers in `js/systems/interactions.js` dispatch to specialized systems:
|
|
- Locks: `unlock-system.js` (key-based, password, PIN, biometric)
|
|
- Doors: `doors.js` (movement triggers)
|
|
- Inventory: `inventory.js` (item collection)
|
|
- Biometrics: `biometrics.js` (fingerprint collection/scanning)
|
|
|
|
### Mini-game Framework
|
|
All mini-games extend `MinigameScene` (`js/minigames/framework/base-minigame.js`):
|
|
```javascript
|
|
// Registration in js/minigames/index.js
|
|
MinigameFramework.registerScene('game-name', GameClass);
|
|
|
|
// Usage
|
|
window.MinigameFramework.startMinigame('game-name', { data });
|
|
```
|
|
Mini-games handle modal display, pause/resume, and return callbacks automatically.
|
|
|
|
### Inventory System
|
|
- Items stored as objects with `id`, `name`, `texture` properties
|
|
- Item identifiers created via `createItemIdentifier()` for UI display
|
|
- Starting items defined in `startItemsInInventory` array at scenario root level
|
|
- Starting items automatically added to inventory on game initialization
|
|
|
|
### Scenario JSON Structure
|
|
```json
|
|
{
|
|
"scenario_brief": "Mission description",
|
|
"endGoal": "What player must accomplish",
|
|
"startRoom": "room_id",
|
|
"startItemsInInventory": [
|
|
{
|
|
"type": "object_type",
|
|
"name": "Display name",
|
|
"takeable": true,
|
|
"observations": "Item description"
|
|
}
|
|
],
|
|
"rooms": {
|
|
"room_id": {
|
|
"type": "room_type",
|
|
"connections": { "north": "next_room" },
|
|
"objects": [
|
|
{
|
|
"type": "object_type",
|
|
"name": "Display name",
|
|
"takeable": false,
|
|
"interactable": true,
|
|
"scenarioData": { /* unlock conditions */ }
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Essential Development Workflows
|
|
|
|
### Adding a New Security Challenge
|
|
1. Create mini-game class in `js/minigames/{challenge-name}/`
|
|
2. Extend `MinigameScene` base class (see `js/minigames/framework/base-minigame.js`)
|
|
3. Register in `js/minigames/index.js` and export
|
|
4. Trigger from interactions via `window.MinigameFramework.startMinigame()`
|
|
|
|
### Adding Scenario Content
|
|
1. Create `scenarios/{name}.json` with room/object definitions
|
|
2. Use existing room types from `assets/rooms/*.json` Tiled files
|
|
3. Objects must match registered texture names (loaded in `game.js` preload)
|
|
4. Reference scenarios from `scenario_select.html`
|
|
|
|
### Debugging Game Issues
|
|
- **Player stuck/pathfinding**: Check `STUCK_THRESHOLD` (1px) and `PATH_UPDATE_INTERVAL` (500ms) in `constants.js`
|
|
- **Object not interactive**: Verify `interactable: true`, `active: true`, and `INTERACTION_RANGE` distance in scenario JSON
|
|
- **Depth/layering wrong**: Recalculate depth = `worldY + layerOffset` in `rooms.js` hierarchy
|
|
- **Mini-game not loading**: Verify registered in `minigames/index.js` and exported from minigame class
|
|
|
|
## Project-Specific Patterns
|
|
|
|
### Tiled Map Integration
|
|
Rooms use Tiled editor JSON format (`assets/rooms/*.tmj`). Key workflow:
|
|
- Objects stored in `map.getObjectLayer()` collections
|
|
- Tiled object GID → texture lookup via tileset registry
|
|
- `TiledItemPool` class manages available objects to prevent duplicates
|
|
|
|
### External Dependencies
|
|
- **Phaser.js v3.60**: Game engine (graphics, physics, input)
|
|
- **EasyStar.js v0.4.4**: Pathfinding (A* algorithm for player movement)
|
|
- **CyberChef v10.19.4**: Embedded crypto tools (iframe-based in laptop minigame)
|
|
|
|
### URL Versioning Convention
|
|
Assets use query string versioning: `import { x } from 'file.js?v=7'` to bust browser cache during development.
|
|
|
|
### CSS Styling Conventions
|
|
Maintain pixel-art aesthetic consistency:
|
|
- **Avoid `border-radius`** - All UI elements use sharp, 90-degree corners
|
|
- **Borders must be exactly 2px** - This matches the pixel-art tile size (32px tiles = 2px scale factor)
|
|
- Examples: buttons, panels, modals, and input fields in `css/*.css`
|
|
|
|
## Quick Command Reference
|
|
|
|
### Local Development
|
|
```bash
|
|
python3 -m http.server # Start local web server (root dir)
|
|
# Access: http://localhost:8000/scenario_select.html
|
|
```
|
|
|
|
### Scenario Testing
|
|
- Edit scenario JSON directly
|
|
- Reload browser (hard refresh if using version queries)
|
|
- Test from `scenario_select.html` dropdown
|
|
|
|
## Files to Read First When Onboarding
|
|
1. `README.md` - Project overview and feature list
|
|
2. `js/main.js` - Game initialization and global state setup
|
|
3. `js/core/game.js` - Phaser scene lifecycle and asset loading
|
|
4. `js/core/rooms.js` - Room management and depth layering documentation
|
|
5. `scenarios/biometric_breach.json` - Full example scenario structure
|
|
6. `js/minigames/framework/minigame-manager.js` - Mini-game architecture
|