JSON Schema (draft 2020-12) for content validation: district, location, npc-profile, dialogue-pool, monologue-pool, triangle, routine, and fact-catalog. NPC schema uses if/then conditional for FRIEND pattern validation. Implements ticket #386. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
210 lines
6.0 KiB
JSON
210 lines
6.0 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "npc-profile.schema.json",
|
|
"title": "NPC Profile",
|
|
"description": "10-axis NPC model profile — one file per NPC (D-024, D-034).",
|
|
"type": "object",
|
|
"required": ["canonical_id", "display_name", "tier", "pattern", "motivation"],
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"canonical_id": {
|
|
"type": "string",
|
|
"pattern": "^npc:[a-z][a-z0-9-]*$",
|
|
"description": "Short-form canonical ID: npc:{slug}"
|
|
},
|
|
"display_name": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"tier": {
|
|
"type": "integer",
|
|
"enum": [1, 2, 3],
|
|
"description": "NPC tier: 1 = conspiracy (full depth), 2 = template (social context), 3 = filler (atmosphere)"
|
|
},
|
|
"pattern": {
|
|
"type": "string",
|
|
"enum": ["FRIEND", "MIRROR", "ANCHOR", "GHOST", "CATALYST", "THRESHOLD", "REMNANT", "SYSTEM", "NOBODY"],
|
|
"description": "Thematic pattern — System A (D-050)"
|
|
},
|
|
"motivation": {
|
|
"type": "string",
|
|
"enum": ["HANDLER", "WITNESS", "TURNCOAT", "CIVILIAN", "OPERATOR", "SKEPTIC"],
|
|
"description": "Functional motivation — System B (D-050)"
|
|
},
|
|
"description": {
|
|
"type": "string"
|
|
},
|
|
"want": {
|
|
"type": "object",
|
|
"description": "Primary want/need driving this NPC",
|
|
"properties": {
|
|
"primary": { "type": "string" },
|
|
"intensity": { "type": "integer", "minimum": 0, "maximum": 10 },
|
|
"description": { "type": "string" }
|
|
},
|
|
"required": ["primary"]
|
|
},
|
|
"secret": {
|
|
"type": "string",
|
|
"description": "The NPC's hidden truth — what they don't want the player to know"
|
|
},
|
|
"relationships": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/$defs/relationship" },
|
|
"description": "Named relationships to other NPCs"
|
|
},
|
|
"tolerance": {
|
|
"type": "object",
|
|
"description": "Stress tolerance threshold",
|
|
"properties": {
|
|
"threshold": { "type": "integer" },
|
|
"description": { "type": "string" }
|
|
}
|
|
},
|
|
"routine": {
|
|
"type": "object",
|
|
"description": "Summary of daily routine (full schedule in routines/schedules.yaml)",
|
|
"properties": {
|
|
"summary": { "type": "string" }
|
|
}
|
|
},
|
|
"information": {
|
|
"type": "object",
|
|
"description": "What this NPC knows",
|
|
"properties": {
|
|
"knows": {
|
|
"type": "array",
|
|
"items": { "type": "string" },
|
|
"description": "Fact IDs this NPC knows"
|
|
},
|
|
"access_tier": {
|
|
"type": "string",
|
|
"enum": ["public", "insider", "authority", "peer", "hostile"]
|
|
}
|
|
}
|
|
},
|
|
"contentment": {
|
|
"type": "object",
|
|
"properties": {
|
|
"level": { "type": "integer", "minimum": -10, "maximum": 10 },
|
|
"description": { "type": "string" }
|
|
}
|
|
},
|
|
"personality": {
|
|
"type": "object",
|
|
"description": "Personality traits and behavioral tendencies",
|
|
"additionalProperties": { "type": "string" }
|
|
},
|
|
"tells": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/$defs/tell" },
|
|
"description": "Observable behavioral tells (D-024)"
|
|
},
|
|
"skills": {
|
|
"type": "object",
|
|
"description": "Skill set and combat capability",
|
|
"properties": {
|
|
"combat_trained": { "type": "boolean" },
|
|
"skills": {
|
|
"type": "object",
|
|
"additionalProperties": { "type": "integer", "minimum": 0, "maximum": 10 }
|
|
}
|
|
}
|
|
},
|
|
"triangle_membership": {
|
|
"type": "array",
|
|
"items": { "type": "string" },
|
|
"description": "Triangle slugs this NPC participates in"
|
|
},
|
|
"trust_levels": {
|
|
"type": "object",
|
|
"description": "What the NPC reveals at each trust level",
|
|
"properties": {
|
|
"surface": { "type": "string" },
|
|
"real": { "type": "string" },
|
|
"secret": { "type": "string" }
|
|
}
|
|
},
|
|
"friend_arc": {
|
|
"type": "object",
|
|
"description": "FRIEND arc data — only valid on FRIEND-pattern Tier 1 NPCs (D-034)",
|
|
"properties": {
|
|
"bonded_character": {
|
|
"type": "string",
|
|
"enum": ["smuggler", "detective"]
|
|
},
|
|
"phases": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/$defs/friend_phase" }
|
|
}
|
|
},
|
|
"required": ["bonded_character", "phases"]
|
|
},
|
|
"dual_lens": {
|
|
"type": "object",
|
|
"description": "Authoring-only: how smuggler vs detective perceives this NPC",
|
|
"properties": {
|
|
"smuggler": { "type": "string" },
|
|
"detective": { "type": "string" }
|
|
}
|
|
},
|
|
"notes": {
|
|
"type": "string",
|
|
"description": "Authoring-only: design notes"
|
|
}
|
|
},
|
|
"if": {
|
|
"properties": { "pattern": { "const": "FRIEND" } }
|
|
},
|
|
"then": {
|
|
"required": ["friend_arc"]
|
|
},
|
|
"$defs": {
|
|
"relationship": {
|
|
"type": "object",
|
|
"required": ["target", "kind"],
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"target": {
|
|
"type": "string",
|
|
"pattern": "^npc:[a-z][a-z0-9-]*$"
|
|
},
|
|
"kind": {
|
|
"type": "string",
|
|
"enum": ["colleague", "friend", "rival", "romantic", "family", "superior", "subordinate"]
|
|
},
|
|
"trust": {
|
|
"type": "integer",
|
|
"minimum": -10,
|
|
"maximum": 10
|
|
},
|
|
"notes": { "type": "string" }
|
|
}
|
|
},
|
|
"tell": {
|
|
"type": "object",
|
|
"required": ["trigger", "behavior"],
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"trigger": { "type": "string" },
|
|
"behavior": { "type": "string" },
|
|
"visible_to": {
|
|
"type": "string",
|
|
"enum": ["forward", "peripheral", "any"]
|
|
}
|
|
}
|
|
},
|
|
"friend_phase": {
|
|
"type": "object",
|
|
"required": ["phase", "description"],
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"phase": { "type": "integer", "minimum": 1, "maximum": 5 },
|
|
"description": { "type": "string" },
|
|
"trigger": { "type": "string" },
|
|
"routine_deviation": { "type": "string" }
|
|
}
|
|
}
|
|
}
|
|
}
|