# Lock & Key System - Quick Start Guide ## Quick Reference: Where Things Are ### Adding a Locked Door/Room File: `scenario.json` ```json { "rooms": { "office": { "locked": true, "lockType": "key", // key, pin, password, biometric, bluetooth "requires": "office_key", // ID of key/password/etc. "keyPins": [32, 28, 35, 30] // Optional: for pin tumbler locks } } } ``` ### Adding a Key to Inventory File: `scenario.json` ```json { "startItemsInInventory": [ { "type": "key", "name": "Office Key", "key_id": "office_key", // Must match "requires" in lock "keyPins": [32, 28, 35, 30], // Must match lock's keyPins "observations": "A brass key" } ] } ``` ### Adding a Key in a Container File: `scenario.json` ```json { "type": "safe", "locked": true, "lockType": "password", "requires": "1234", "contents": [ { "type": "key", "name": "CEO Key", "key_id": "ceo_key", "keyPins": [40, 35, 38, 32, 36] } ] } ``` --- ## System Entry Points ### When Player Clicks a Locked Object ``` interactions.js: handleObjectInteraction(sprite) → Gets scenario data from sprite → Calls: handleUnlock(lockable, 'door'|'item') ``` ### Unlock System Decision Tree ``` unlock-system.js: handleUnlock() ├─ Lock type: 'key' │ ├─ Has keys in inventory? → Key Selection Minigame │ └─ Has lockpick? → Lockpicking Minigame ├─ Lock type: 'pin' → PIN Entry Minigame ├─ Lock type: 'password' → Password Entry Minigame ├─ Lock type: 'biometric' → Check fingerprint samples └─ Lock type: 'bluetooth' → Check BLE devices ``` --- ## Key Code Files ### Primary Lock Logic ``` js/systems/ ├─ unlock-system.js [400 lines] Main unlock handler ├─ key-lock-system.js [370 lines] Key-lock mappings & cuts ├─ inventory.js [630 lines] Item/key management └─ interactions.js [600 lines] Object interaction detector ``` ### Lockpicking Minigame (Pin Tumbler) ``` js/minigames/lockpicking/ ├─ lockpicking-game-phaser.js [300+ lines] Main controller ├─ pin-management.js [150+ lines] Pin creation ├─ key-operations.js [100+ lines] Key handling ├─ hook-mechanics.js [100+ lines] Tension simulation ├─ pin-visuals.js [80+ lines] Rendering └─ lock-configuration.js [60+ lines] State storage ``` ### Minigame Framework ``` js/minigames/framework/ ├─ minigame-manager.js [180 lines] Framework lifecycle ├─ base-minigame.js [150+ lines] Base class └─ index.js [96 lines] Registration ``` ### Conversation Integration ``` js/minigames/helpers/ └─ chat-helpers.js [326 lines] Ink tag processing js/minigames/person-chat/ └─ person-chat-minigame.js [300+ lines] Conversation UI ``` --- ## Key Data Structures ### Pin Tumbler Lock (During Gameplay) ```javascript pin = { index: 0, binding: 2, // Which pin sets first (0-3) isSet: false, keyPinLength: 32, // Lock pin height (pixels) driverPinLength: 43, // Spring pin height keyPinHeight: 0, // Current key pin position container: Phaser.Container } ``` ### Key Data (In Inventory) ```javascript key = { scenarioData: { type: 'key', name: 'Office Key', key_id: 'office_key', keyPins: [32, 28, 35, 30], // Lock pin heights this key opens observations: 'A brass key' }, objectId: 'inventory_key_office_key' } ``` ### Lock Requirements (From Scenario) ```javascript lockRequirements = { lockType: 'key', // Type of lock requires: 'office_key', // Key ID / password / etc. keyPins: [32, 28, 35, 30], // For scenario-defined locks difficulty: 'medium' // For lockpicking } ``` --- ## Common Workflows ### Scenario Designer: Add New Key-Protected Door 1. **Define the lock in room:** ```json { "room_name": { "locked": true, "lockType": "key", "requires": "storage_key", "keyPins": [30, 32, 28, 35] // IMPORTANT: unique pin heights } } ``` 2. **Add key to inventory or container:** ```json { "type": "key", "name": "Storage Key", "key_id": "storage_key", // Must match "requires" "keyPins": [30, 32, 28, 35] // Must match lock exactly } ``` 3. **Test: Player should see key icon when near lock** ### Scenario Designer: Add PIN-Protected Door ```json { "room_name": { "locked": true, "lockType": "pin", "requires": "4567" // The PIN code } } ``` ### Scenario Designer: Add Password-Protected Safe ```json { "type": "safe", "locked": true, "lockType": "password", "requires": "correct_password", "contents": [ { "type": "notes", "name": "Secret Document" } ] } ``` ### Ink Writer: Give Key During Conversation In `.ink` file: ```ink === hub === # speaker:npc Here's the key you'll need! # give_item:key|Storage Key What else can I help with? ``` This triggers: 1. NPC gives item to player 2. Opens container minigame showing the key 3. Player can take it to inventory --- ## Debugging Tips ### Check Key-Lock Mappings In browser console: ```javascript window.showKeyLockMappings() // Shows all key-lock pairs ``` ### Check Player Inventory ```javascript console.log(window.inventory.items) // All items console.log(window.inventory.keyRing) // Keys specifically ``` ### Check Lock Requirements ```javascript window.getLockRequirementsForDoor(doorSprite) // Door lock details window.getLockRequirementsForItem(item) // Item lock details ``` ### Force Unlock (Testing) ```javascript window.DISABLE_LOCKS = true // Disables all locks temporarily ``` --- ## Common Errors & Solutions | Error | Cause | Solution | |-------|-------|----------| | Key doesn't unlock door | `key_id` doesn't match `requires` | Ensure exact match | | Wrong pins in lock | `keyPins` mismatch | Key's keyPins must match lock's keyPins | | Key doesn't appear in inventory | Item not in `startItemsInInventory` | Add it to scenario or container | | Conversation tag not working | Tag format incorrect | Use `# action:param` format | | Minigame won't start | Framework not initialized | Check if MinigameFramework is loaded | --- ## Implementation Checklist For adding a new lock type (e.g., RFID/Keycard): - [ ] Add case in `unlock-system.js` switch statement - [ ] Check inventory for matching keycard - [ ] Verify access level (if applicable) - [ ] Call `unlockTarget()` on success - [ ] Show appropriate alert messages - [ ] Update scenario schema with examples - [ ] Add documentation with tag examples - [ ] Test with example scenario