mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-20 13:50:46 +00:00
5.6 KiB
5.6 KiB
Scenario JSON Format Fixes - Summary
Files Compared
- ✅ Correct Format:
scenarios/test-npc-patrol.json - ❌ Had Errors:
scenarios/npc-patrol-lockpick.json(NOW FIXED)
Issues Found and Fixed
1. ✅ Root-level Properties
Before:
{
"scenario_brief": "...",
"globalVariables": { "player_caught_lockpicking": false },
"startRoom": "patrol_corridor",
"startItemsInInventory": []
}
After:
{
"scenario_brief": "...",
"endGoal": "Test NPC line-of-sight detection and lockpicking interruption",
"startRoom": "patrol_corridor"
}
Changes:
- ✅ Removed unnecessary
globalVariables - ✅ Removed
startItemsInInventory(not needed) - ✅ Added
endGoal(standard property)
2. ✅ First NPC (patrol_with_face) Structure
Before (WRONG NESTING):
{
"storyPath": "scenarios/ink/security-guard.json",
"currentKnot": "start",
"los": { ... }, // ← Out of order
"behavior": {
"facePlayer": true,
"patrol": { ... }
}, // ← Trailing comma (syntax error)
"eventMappings": [ ... ] // ← Inside behavior close (wrong nesting)
}
After (CORRECT NESTING):
{
"storyPath": "scenarios/ink/security-guard.json",
"currentKnot": "start",
"behavior": {
"facePlayer": true,
"patrol": {
"enabled": true,
"speed": 100,
"changeDirectionInterval": 4000,
"bounds": { ... }
}
},
"los": { ... }, // ← Moved after behavior
"eventMappings": [ ... ], // ← At NPC root level (correct)
"_comment": "..."
}
Changes:
- ✅ Moved
behaviorobject before other properties - ✅ Removed trailing comma after
behavior - ✅ Moved
eventMappingsto NPC root level - ✅ Added
enabled: trueto patrol config - ✅ Added
_commentfor clarity
3. ✅ Second NPC (security_guard) Structure
Before (MAJOR STRUCTURAL ERROR):
{
"storyPath": "scenarios/ink/security-guard.json",
"currentKnot": "start",
"los": { ... },
"patrol": { // ← WRONG: patrol at root level!
"route": [ ... ],
"speed": 40,
"pauseTime": 10
}, // ← Trailing comma
"eventMappings": [ ... ] // ← Should be at root, but nested wrong
}
After (CORRECT STRUCTURE):
{
"storyPath": "scenarios/ink/security-guard.json",
"currentKnot": "start",
"behavior": { // ← CORRECT: patrol inside behavior
"patrol": {
"route": [
{ "x": 2, "y": 3 },
{ "x": 8, "y": 3 },
{ "x": 8, "y": 6 },
{ "x": 2, "y": 6 }
],
"speed": 40,
"pauseTime": 10
}
},
"los": { ... },
"eventMappings": [ ... ], // ← Now at correct nesting level
"_comment": "..."
}
Changes:
- ✅ Wrapped
patrolinsidebehaviorobject - ✅ Removed trailing comma after patrol object
- ✅ Moved
eventMappingsto NPC root level - ✅ Added
_commentfor clarity
Key Format Rules Enforced
| Property | Location | Notes |
|---|---|---|
behavior |
NPC root | Contains facePlayer, patrol, etc. |
patrol |
Inside behavior |
Not at NPC root level |
los |
NPC root | Line-of-sight configuration |
eventMappings |
NPC root | Event handlers for NPC |
storyPath, currentKnot |
NPC root | Ink story integration |
spriteSheet, position |
NPC root | Display properties |
_comment |
NPC root | Documentation string |
Validation Checklist
✅ All NPCs have:
behaviorobject containingpatrollosconfiguration for LOS detectioneventMappingsat root level- Proper comma placement (no trailing commas)
✅ Scenario root has:
scenario_brief- Brief descriptionendGoal- Mission objectivestartRoom- Initial roomplayer- Player configurationrooms- Rooms dictionary
✅ No syntax errors:
- All braces/brackets properly closed
- No trailing commas
- Proper property nesting
File Status
📁 scenarios/npc-patrol-lockpick.json
- ✅ FIXED - Now matches correct format
- ✅ Valid JSON structure
- ✅ Ready for testing
📖 docs/SCENARIO_FORMAT_COMPARISON.md
- ✅ CREATED - Detailed comparison guide
- Shows before/after examples
- Explains why each fix was needed
Testing the Corrected Scenario
To test that the fixes work:
- Load scenario:
npc-patrol-lockpick.json - Enable LOS visualization:
window.enableLOS() - Verify:
- Both NPCs patrol correctly
- Green LOS cones appear
- Lockpicking triggers person-chat when NPC sees player
Reference: Correct NPC Structure
{
"id": "npc_id",
"displayName": "NPC Name",
"npcType": "person",
"position": { "x": 5, "y": 5 },
"spriteSheet": "hacker",
"spriteTalk": "assets/characters/hacker-talk.png",
"spriteConfig": {
"idleFrameStart": 20,
"idleFrameEnd": 23
},
"storyPath": "scenarios/ink/story.json",
"currentKnot": "start",
"behavior": {
"facePlayer": true,
"facePlayerDistance": 96,
"patrol": {
"enabled": true,
"speed": 100,
"changeDirectionInterval": 4000,
"bounds": { "x": 128, "y": 128, "width": 128, "height": 128 }
}
},
"los": {
"enabled": true,
"range": 300,
"angle": 140,
"visualize": true
},
"eventMappings": [
{
"eventPattern": "lockpick_used_in_view",
"targetKnot": "on_lockpick_used",
"conversationMode": "person-chat",
"cooldown": 0
}
],
"_comment": "Description of NPC behavior"
}
This is the authoritative structure for all NPC definitions.