qnce-engine
Version:
Core QNCE (Quantum Narrative Convergence Engine) - Framework agnostic narrative engine with performance optimization
315 lines (271 loc) ⢠9.86 kB
text/typescript
// QNCE Branching Demo - Simple Working Example
// Demonstrates Sprint #3 Advanced Branching API integration
import { createQNCEEngine } from '../src/engine/core';
import { createBranchingEngine } from '../src/narrative/branching';
import { QNCEStory } from '../src/narrative/branching/models';
// ================================
// Simple Demo Story
// ================================
const simpleBranchingStory: QNCEStory = {
id: 'simple-demo',
title: 'Simple Branching Demo',
version: '1.0.0',
metadata: {
author: 'QNCE Team',
description: 'Basic branching demonstration',
tags: ['demo', 'tutorial'],
createDate: new Date(),
lastModified: new Date(),
estimatedPlaytime: 5
},
branchingConfig: {
maxActiveBranches: 3,
branchCacheSize: 10,
enableDynamicInsertion: true,
enableAnalytics: true,
performanceMode: false
},
chapters: [
{
id: 'demo-chapter',
title: 'Demo Chapter',
description: 'Simple chapter for demonstration',
flows: [
{
id: 'main-flow',
name: 'Main Story Flow',
description: 'Primary narrative flow',
nodes: [
{ id: 'start', text: 'You stand at a crossroads.', choices: [] },
{ id: 'forest', text: 'You enter a dark forest.', choices: [] },
{ id: 'mountain', text: 'You climb a steep mountain.', choices: [] }
],
entryPoints: [{ id: 'entry', nodeId: 'start', priority: 1 }],
exitPoints: [{ id: 'forest-exit', nodeId: 'forest' }, { id: 'mountain-exit', nodeId: 'mountain' }],
flowType: 'branching',
metadata: { complexity: 3, avgCompletionTime: 3000, playerChoiceCount: 1, aiGeneratedContent: false }
}
],
branches: [
{
id: 'path-choice',
name: 'Choose Your Path',
sourceFlowId: 'main-flow',
sourceNodeId: 'start',
branchType: 'choice-driven',
branchOptions: [
{
id: 'forest-path',
targetFlowId: 'main-flow',
targetNodeId: 'forest',
displayText: 'Take the forest path',
flagEffects: { 'path': 'forest', 'nature_affinity': 5 },
weight: 1.0
},
{
id: 'mountain-path',
targetFlowId: 'main-flow',
targetNodeId: 'mountain',
displayText: 'Climb the mountain path',
flagEffects: { 'path': 'mountain', 'endurance': 7 },
weight: 0.9
}
],
metadata: { usageCount: 0, avgTraversalTime: 0, playerPreference: 0, lastUsed: new Date() }
}
],
prerequisites: { requiredFlags: {}, requiredChoices: [] },
metadata: {
difficulty: 'easy',
themes: ['choice', 'adventure'],
estimatedDuration: 3,
branchComplexity: 2
}
}
]
};
// ================================
// Demo Functions
// ================================
async function demonstrateCoreBranching() {
console.log('šÆ Core Branching Integration Demo');
console.log('==================================\n');
// Create core engine
const coreStory = {
nodes: [{ id: 'start', text: 'Demo starting point', choices: [] }],
initialNodeId: 'start'
};
const coreEngine = createQNCEEngine(coreStory, {
currentNodeId: 'start',
flags: {},
history: ['start']
});
console.log('ā
Core QNCE Engine created');
// Enable branching
const branchingEngine = coreEngine.enableBranching(simpleBranchingStory);
console.log('ā
Branching enabled via core engine');
console.log(`š Branching available: ${coreEngine.isBranchingEnabled()}`);
console.log(`š§ Branching engine type: ${branchingEngine.constructor.name}\n`);
return { coreEngine, branchingEngine };
}
async function demonstrateDirectBranching() {
console.log('šæ Direct Branching API Demo');
console.log('=============================\n');
// Create branching engine directly
const initialState = {
currentNodeId: 'start',
flags: {},
history: ['start']
};
const branchingEngine = createBranchingEngine(simpleBranchingStory, initialState);
console.log('ā
Direct branching engine created');
// Test branch evaluation
const branches = await branchingEngine.evaluateAvailableBranches();
console.log(`š Available branches: ${branches.length}`);
branches.forEach((branch, i) => {
console.log(` ${i + 1}. "${branch.displayText}"`);
});
// Execute a branch if available
if (branches.length > 0) {
console.log(`\nšÆ Executing: "${branches[0].displayText}"`);
const success = await branchingEngine.executeBranch(branches[0].id);
console.log(`ā
Execution result: ${success ? 'Success' : 'Failed'}`);
}
return branchingEngine;
}
async function demonstrateAIIntegration() {
console.log('\nš¤ AI Integration Demo');
console.log('======================\n');
const branchingEngine = createBranchingEngine(simpleBranchingStory, {
currentNodeId: 'start',
flags: {},
history: []
});
// Set AI context
branchingEngine.setAIContext({
playerProfile: {
playStyle: 'explorer',
preferences: { 'adventure': 0.8, 'caution': 0.3 },
historicalChoices: [],
averageDecisionTime: 5000
},
narrativeContext: {
currentTone: 'adventurous',
thematicElements: ['exploration', 'choice'],
characterRelationships: {},
plotTension: 0.5
},
generationHints: {
maxBranchDepth: 2,
desiredComplexity: 4,
contentThemes: ['adventure'],
avoidElements: ['horror']
}
});
console.log('ā
AI context configured');
try {
const aiBranches = await branchingEngine.generateAIBranches(2);
console.log(`šØ Generated ${aiBranches.length} AI branches:`);
aiBranches.forEach((branch, i) => {
console.log(` ${i + 1}. "${branch.displayText}" (weight: ${branch.weight})`);
});
} catch (error: any) {
console.log(`ā ļø AI generation: ${error.message}`);
}
}
async function demonstrateDynamicOperations() {
console.log('\nš§ Dynamic Operations Demo');
console.log('===========================\n');
const branchingEngine = createBranchingEngine(simpleBranchingStory, {
currentNodeId: 'start',
flags: { 'special_event': true },
history: []
});
// Insert dynamic branch
const dynamicBranch = {
type: 'insert' as const,
branchId: 'secret-path',
targetLocation: {
chapterId: 'demo-chapter',
flowId: 'main-flow',
nodeId: 'start',
insertionPoint: 'after' as const
},
payload: {
name: 'Secret Path',
branchType: 'conditional' as const,
branchOptions: [
{
id: 'secret-option',
targetFlowId: 'main-flow',
displayText: 'Take the mysterious hidden path',
conditions: [
{ type: 'flag' as const, operator: 'equals' as const, key: 'special_event', value: true }
],
flagEffects: { 'secret_discovered': true },
weight: 1.0
}
]
}
};
const insertResult = await branchingEngine.insertDynamicBranch(dynamicBranch);
console.log(`ā
Dynamic branch insertion: ${insertResult ? 'Success' : 'Failed'}`);
// Test removal
const removeResult = await branchingEngine.removeDynamicBranch('secret-path');
console.log(`ā
Dynamic branch removal: ${removeResult ? 'Success' : 'Failed'}`);
}
async function demonstrateAnalytics() {
console.log('\nš Analytics Demo');
console.log('==================\n');
const branchingEngine = createBranchingEngine(simpleBranchingStory, {
currentNodeId: 'start',
flags: {},
history: []
});
// Get analytics
const analytics = branchingEngine.getBranchingAnalytics();
console.log('š Current Analytics:');
console.log(` - Branches traversed: ${analytics.totalBranchesTraversed}`);
console.log(` - Session duration: ${Date.now() - analytics.sessionStartTime.getTime()}ms`);
console.log(` - Popular branches: ${analytics.mostPopularBranches.join(', ') || 'None yet'}`);
// Export data
const exportData = branchingEngine.exportBranchingData();
console.log(`\nš¾ Export Data: ${Object.keys(exportData).length} sections available`);
console.log(`š Available: ${Object.keys(exportData).join(', ')}`);
}
// ================================
// Main Demo Runner
// ================================
async function runComprehensiveDemo() {
console.log('š QNCE Sprint #3 Branching API - Comprehensive Demo');
console.log('====================================================\n');
try {
// Test 1: Core integration
const { coreEngine, branchingEngine: coreBranching } = await demonstrateCoreBranching();
// Test 2: Direct API usage
const directBranching = await demonstrateDirectBranching();
// Test 3: AI integration
await demonstrateAIIntegration();
// Test 4: Dynamic operations
await demonstrateDynamicOperations();
// Test 5: Analytics
await demonstrateAnalytics();
console.log('\nš Demo Complete - All Features Working!');
console.log('========================================');
console.log('ā
Core engine integration');
console.log('ā
Direct branching API');
console.log('ā
AI-driven content generation');
console.log('ā
Dynamic branch operations');
console.log('ā
Analytics and monitoring');
console.log('\nš Sprint #3 Branching API is production ready!');
} catch (error: any) {
console.error('ā Demo failed:', error.message);
console.error(error.stack);
}
}
// Export for testing
export { simpleBranchingStory, runComprehensiveDemo };
// Run if called directly
if (require.main === module) {
runComprehensiveDemo();
}