Class Materials System
Master NPCs generate structured class material — a lesson document with learning objectives, key concepts, and teaching sections — alongside a strictly-scoped statement pool. Players can then take a game session whose challenges come exclusively from that lesson content.
The system supports two class types:
- Individual classes — a single NPC generates the full lesson
- Guild group classes — multiple NPCs from a guild each contribute a section, merged into one collaborative lesson
Overview
The class materials system bridges NPC knowledge bases and the training game engine.
Individual Class Generation
When an admin triggers material generation for a Master NPC:
- The NPC’s CoSTAR configuration shapes the voice and teaching style
- AutoRAG retrieves relevant knowledge base content for the topic
- AI generates a structured lesson document (JSON)
- A companion statement pool is generated using the lesson text as the knowledge boundary
- Game sessions created from this material pull challenges only from its pool
Guild Group Class Generation
When a guild owner generates a group class:
- All active NPC members of the guild are fetched
- Each NPC generates a lesson section based on its unique expertise and CoSTAR config
- Sections are merged into a single lesson with combined learning objectives and key concepts
- Each NPC also generates statements scoped to its section; all are merged into one statement pool
- Contributor records track which NPC authored each section
- All guild members (players) can view and take game sessions from group classes
Architecture
Data Model
npc_class_materials stores the lesson and links to its pool:
id(UUID),npc_id,topic,title,difficultycontent(JSON):{ learning_objectives[], key_concepts[], sections[{heading, body}], references[], summary }statement_pool_idFK tostatement_poolsstatus: draft / published / archivedclass_type:individual(default) orgroupguild_id: FK toguild_halls(set for group classes)
guild_class_contributors tracks NPC contributions to group classes:
class_material_id,npc_id,npc_name,section_index,statement_count
class_material_sessions joins game sessions to materials for analytics:
- Links
class_material_idtosession_idingame_training_sessions
game_training_sessions extended with:
class_material_idcolumn for direct referencesession_type = 'class_material'to route through the scoped engine path
Service Layer
ClassMaterialService (src/lib/services/ClassMaterialService.ts) orchestrates:
generateClassMaterial(npcId, topic, difficulty)— full individual generation pipelinegenerateGuildGroupClass(guildId, topic, difficulty, statementsPerNpc?)— guild group class generationlistClassMaterials(npcId, filters?)— list NPC materials with statement countslistGuildClassMaterials(guildId, filters?)— list guild group classesgetClassMaterial(materialId)— fetch with parsed content and contributorsupdateStatus(materialId, status)— lifecycle managementstartScopedSession(materialId, playerUuid)— create a game session scoped to the material
Game Engine
TrueFalseCognitiveEngine.generateChallenge() handles session_type === 'class_material' by:
- Looking up the material’s
statement_pool_id - Pulling challenges exclusively from that pool
- Using synthetic negative IDs to track which statements have been shown
No engine changes are needed for group classes — they simply have a larger merged statement pool.
API Endpoints
Individual NPC Class Materials
All individual class endpoints are under /api/npcs/[id]/class-materials/.
| Method | Path | Description |
|---|---|---|
| POST | /api/npcs/:npcId/class-materials | Generate class material |
| GET | /api/npcs/:npcId/class-materials | List materials (query: topic, difficulty, status) |
| GET | /api/npcs/:npcId/class-materials/:materialId | Get material detail |
| PUT | /api/npcs/:npcId/class-materials/:materialId | Update status |
| POST | /api/npcs/:npcId/class-materials/:materialId/session | Start scoped game session |
Guild Group Class Materials
Guild class endpoints are under /api/guilds/[id]/class-materials/. All require authentication. Generating requires guild owner or System Admin; viewing requires guild membership.
| Method | Path | Description |
|---|---|---|
| POST | /api/guilds/:guildId/class-materials | Generate guild group class |
| GET | /api/guilds/:guildId/class-materials | List guild group classes |
| GET | /api/guilds/:guildId/class-materials/:materialId | Get group class detail |
| POST | /api/guilds/:guildId/class-materials/:materialId/session | Start scoped session |
Generate Individual Class Material
POST /api/npcs/:npcId/class-materials
Request body:
{
"topic": "Photosynthesis",
"difficulty": "beginner",
"count": 42
}
Generate Guild Group Class
POST /api/guilds/:guildId/class-materials
Request body:
{
"topic": "Photosynthesis",
"difficulty": "beginner",
"statements_per_npc": 14
}
Start Scoped Game Session
Works identically for both individual and guild classes:
POST /api/npcs/:npcId/class-materials/:materialId/session
POST /api/guilds/:guildId/class-materials/:materialId/session
Request body:
{
"player_uuid": "uuid",
"total_questions": 20,
"time_limit_seconds": 300
}
Admin UI
Individual Class Materials
The admin page at /admin/class-materials?npcId=X provides:
- Generation form with topic, difficulty, and statement count inputs
- Expandable material list with status badges and difficulty indicators
- Inline lesson preview showing objectives, concepts, sections, and references
- Status management: Draft → Published → Archived (with revert)
Guild Group Classes
The admin page at /admin/guild-classes?guildId=X provides:
- Guild NPC roster display showing which NPCs will contribute
- Generation form with topic, difficulty, and statements-per-NPC inputs
- Group class list with “group” type badge
- Per-section NPC attribution in the lesson preview
- Contributor summary showing statement counts per NPC
Configuration
No additional environment variables required. The feature uses existing:
- Cloudflare Workers AI binding (
AI) - D1 database binding (
DB) - NPC CoSTAR configuration (
npc_configurationstable) - AutoRAG knowledge bases (when enabled on the NPC)