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.
This commit is contained in:
Z. Cliffe Schreuders
2025-11-29 23:46:39 +00:00
parent ef8e2f294a
commit bca619aeac
2 changed files with 268 additions and 0 deletions

201
docs/LOCK_SCENARIO_GUIDE.md Normal file
View File

@@ -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"] }
```

View File

@@ -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