From bca619aeacab3d633f6ab15d13d5b0d67600dc4f Mon Sep 17 00:00:00 2001 From: "Z. Cliffe Schreuders" Date: Sat, 29 Nov 2025 23:46:39 +0000 Subject: [PATCH] Add Lock Scenario and System Architecture Documentation - Introduced `LOCK_SCENARIO_GUIDE.md` to provide a comprehensive reference for implementing locks in scenarios, detailing room and object lock configurations, lock types, and quick examples. - Added `LOCK_SYSTEM_ARCHITECTURE.md` to outline the data flow from scenario definition to server validation, including steps for scenario definition, server bootstrap filtering, client lock checks, and server validation processes. - Included security notes and references for various lockable object types and items related to the locking system. --- docs/LOCK_SCENARIO_GUIDE.md | 201 +++++++++++++++++++++++++++++++ docs/LOCK_SYSTEM_ARCHITECTURE.md | 67 +++++++++++ 2 files changed, 268 insertions(+) create mode 100644 docs/LOCK_SCENARIO_GUIDE.md create mode 100644 docs/LOCK_SYSTEM_ARCHITECTURE.md diff --git a/docs/LOCK_SCENARIO_GUIDE.md b/docs/LOCK_SCENARIO_GUIDE.md new file mode 100644 index 0000000..976df35 --- /dev/null +++ b/docs/LOCK_SCENARIO_GUIDE.md @@ -0,0 +1,201 @@ +# Lock Scenario Guide + +Quick reference for adding locks to scenarios. + +## Room Locks (Doors) + +Add these properties to a **room** to lock all doors leading to it: + +```json +"server_room": { + "type": "room_servers", + "locked": true, + "lockType": "pin", + "requires": "1234", + "connections": { "south": "lobby" } +} +``` + +## Object Locks (Containers) + +Add these properties to lockable objects: + +```json +{ + "type": "safe", + "name": "Wall Safe", + "locked": true, + "lockType": "password", + "requires": "secret123", + "contents": [{ "type": "key", "name": "Gold Key" }] +} +``` + +--- + +## Lock Types Reference + +### `key` - Physical Key +```json +"lockType": "key", +"requires": "office_key", +"keyPins": [45, 35, 25, 55] // Optional: for lockpicking +``` +**Player needs:** `type: "key"` with matching `key_id` + +### `lockpick` - Lockpickable (No Key Exists) +```json +"lockType": "key", +"requires": "nonexistent_key", +"difficulty": "hard" +``` +**Player needs:** `type: "lockpick"` + +### `pin` - Numeric Code +```json +"lockType": "pin", +"requires": "4829" +``` +**Player needs:** Guess or find the code + +### `password` - Text Password +```json +"lockType": "password", +"requires": "secret123", +"passwordHint": "My pet's name", +"showHint": true, +"showKeyboard": true +``` +**Player needs:** Guess or find the password + +### `rfid` - Keycard +```json +"lockType": "rfid", +"requires": ["server_keycard"] +``` +**Player needs:** `type: "keycard"` with matching `card_id` OR cloned card in RFID cloner + +### `biometric` - Fingerprint +```json +"lockType": "biometric", +"requires": "Dr Smith", +"biometricMatchThreshold": 0.5 +``` +**Player needs:** Collected fingerprint from that person + +### `bluetooth` - Device Proximity +```json +"lockType": "bluetooth", +"requires": "00:11:22:33:44:55" +``` +**Player needs:** `type: "bluetooth_scanner"` + scanned device + +--- + +## Items Reference + +### Keys +```json +{ + "type": "key", + "name": "Office Key", + "key_id": "office_key", + "keyPins": [45, 35, 25, 55], + "takeable": true +} +``` + +### Keycards +```json +{ + "type": "keycard", + "name": "Server Keycard", + "card_id": "server_keycard", + "rfid_protocol": "EM4100", + "takeable": true +} +``` + +### Lockpick +```json +{ + "type": "lockpick", + "name": "Lockpick Set", + "takeable": true +} +``` + +### RFID Cloner +```json +{ + "type": "rfid_cloner", + "name": "RFID Flipper", + "saved_cards": [], + "takeable": true +} +``` + +### Fingerprint Kit +```json +{ + "type": "fingerprint_kit", + "name": "Fingerprint Kit", + "takeable": true +} +``` + +### Bluetooth Scanner +```json +{ + "type": "bluetooth_scanner", + "name": "Bluetooth Scanner", + "takeable": true +} +``` + +--- + +## NPC RFID Cards (For Cloning) + +```json +{ + "id": "guard", + "npcType": "person", + "rfidCard": { + "card_id": "master_keycard", + "rfid_protocol": "EM4100", + "name": "Master Keycard" + } +} +``` + +--- + +## Lockable Object Types + +These objects support `locked`, `lockType`, `requires`: + +- `safe` - Wall/floor safe +- `briefcase` / `suitcase` - Portable containers +- `pc` / `laptop` / `tablet` - Computing devices +- `closet` / `cabinet` - Storage furniture + +--- + +## Quick Examples + +**PIN-locked room:** +```json +"vault": { "locked": true, "lockType": "pin", "requires": "9999" } +``` + +**Key-locked safe:** +```json +{ "type": "safe", "locked": true, "lockType": "key", "requires": "safe_key" } +``` + +**RFID door:** +```json +"server_room": { "locked": true, "lockType": "rfid", "requires": ["admin_card"] } +``` + diff --git a/docs/LOCK_SYSTEM_ARCHITECTURE.md b/docs/LOCK_SYSTEM_ARCHITECTURE.md new file mode 100644 index 0000000..519ef90 --- /dev/null +++ b/docs/LOCK_SYSTEM_ARCHITECTURE.md @@ -0,0 +1,67 @@ +# Lock System Architecture + +How locks flow from scenario definition to server validation. + +## Data Flow + +``` +scenario.json.erb → Server Bootstrap → Client Game → Unlock Attempt → Server Validation +``` + +## 1. Scenario Definition + +Locks are defined on **rooms** (for doors) or **objects** (for containers): + +```json +{ + "room_id": { + "locked": true, + "lockType": "pin", + "requires": "1234" + } +} +``` + +## 2. Server Bootstrap Filtering + +When game starts, `filtered_scenario_for_bootstrap` sends room metadata to client: + +**Kept:** `locked`, `lockType`, `keyPins`, `difficulty` +**Removed:** `requires` (for pin/password/key - the "answer") +**Kept:** `requires` (for rfid/biometric/bluetooth - references collectible items) + +## 3. Client Lock Check + +When player interacts with a locked door/object: + +1. `handleUnlock()` gets lock requirements from sprite properties +2. Checks `lockRequirements.locked` - if false, asks server to verify +3. If locked, launches appropriate minigame based on `lockType` + +## 4. Server Validation + +`validate_unlock(target_type, target_id, attempt, method)`: + +| Method | Server Validates | +|--------|------------------| +| `key` | Player has matching `key_id` in inventory | +| `lockpick` | Player has lockpick in inventory | +| `pin`/`password` | `attempt` matches room's `requires` | +| `rfid`/`biometric`/`bluetooth` | Trusted (client validated item possession) | +| `npc` | NPC encountered + has unlock permission | +| `unlocked` | Room has `locked: false` in scenario | + +## 5. Unlock Success + +On success: +1. Server adds room to `player_state['unlockedRooms']` +2. Server returns `roomData` for the connected room +3. Client opens door and loads room + +## Security Notes + +- PINs/passwords validated server-side only +- Keys validated against server inventory +- `requires` field stripped for exploitable locks +- Already-unlocked rooms bypass validation +