Getting Started - ByteSower/qnce-engine GitHub Wiki

āš ļø QNCE Engine is Under Major Reconstruction

Notice (Feb 2026): The QNCE Engine is currently undergoing major reconstruction. Many features, including narrative rules and story flow, may not behave as expected. The engine is transitioning toward broader quantum modeling principles and improved performance. If you require stability, consider waiting for a future release. See GitHub and npm for updates.

Getting Started with QNCE Engine

Welcome to QNCE Engine! This guide will help you get up and running with creating interactive narratives using quantum-inspired mechanics.

šŸ“¦ Installation

Basic Installation

# Install QNCE Engine
npm install qnce-engine

Global CLI Installation (Recommended)

# Install globally for CLI tools
npm install -g qnce-engine

# Verify installation
qnce-init --version

System Requirements

  • Node.js: 16.0.0 or higher
  • TypeScript: 4.5.0 or higher (for TypeScript projects)
  • Memory: Minimum 50MB available RAM
  • Platform: Windows, macOS, Linux

šŸ Quick Start (5 Minutes)

Let's create your first interactive story in just a few steps!

Step 1: Create a New Project

# Create a new QNCE project
npx qnce-init my-first-story

# Navigate to the project
cd my-first-story

# Install dependencies
npm install

Step 2: Your First Story

Create a simple story file:

// story.js
import { createQNCEEngine } from 'qnce-engine';

// Define your story
const myStory = {
  nodes: [
    {
      id: 'start',
      text: 'You wake up in a mysterious forest. The morning mist swirls around ancient trees.',
      choices: [
        {
          text: 'Follow the winding path',
          nextNodeId: 'path',
          flagEffects: { courage: 1 }
        },
        {
          text: 'Investigate the strange glowing mushrooms',
          nextNodeId: 'mushrooms',
          flagEffects: { curiosity: 1 }
        }
      ]
    },
    {
      id: 'path',
      text: 'The path leads to a clearing with a bubbling brook. You feel more confident.',
      choices: [
        {
          text: 'Drink from the brook',
          nextNodeId: 'brook',
          flagEffects: { refreshed: true }
        }
      ]
    },
    {
      id: 'mushrooms',
      text: 'The mushrooms pulse with an otherworldly light. Your curiosity is rewarded!',
      choices: [
        {
          text: 'Touch one of the glowing mushrooms',
          nextNodeId: 'magic',
          flagEffects: { magic_discovered: true }
        }
      ]
    },
    {
      id: 'brook',
      text: 'The cool water refreshes you. You notice fish swimming in patterns that seem almost deliberate.',
      choices: []
    },
    {
      id: 'magic',
      text: 'The mushroom responds to your touch, revealing hidden pathways through reality itself!',
      choices: []
    }
  ]
};

// Create and run the engine
const engine = createQNCEEngine(myStory);

console.log('🌟 Welcome to Your Story!');
console.log('========================\\n');

function displayCurrentState() {
  const currentNode = engine.getCurrentNode();
  const flags = engine.getFlags();
  
  console.log(currentNode.text);
  console.log('\\nFlags:', flags);
  
  const choices = engine.getAvailableChoices();
  if (choices.length > 0) {
    console.log('\\nChoices:');
    choices.forEach((choice, index) => {
      console.log(`${index + 1}. ${choice.text}`);
    });
  } else {
    console.log('\\nšŸŽ­ Story Complete!');
  }
}

// Display initial state
displayCurrentState();

// Simulate making a choice (in a real app, this would be user input)
if (engine.getAvailableChoices().length > 0) {
  console.log('\\n✨ Making choice: "Follow the winding path"');
  engine.makeChoice(0);
  displayCurrentState();
}

Step 3: Run Your Story

node story.js

Expected output:

🌟 Welcome to Your Story!
========================

You wake up in a mysterious forest. The morning mist swirls around ancient trees.

Flags: {}

Choices:
1. Follow the winding path
2. Investigate the strange glowing mushrooms

✨ Making choice: "Follow the winding path"
The path leads to a clearing with a bubbling brook. You feel more confident.

Flags: { courage: 1 }

Choices:
1. Drink from the brook

šŸŽÆ Core Concepts in Action

Superposition

Before a choice is made, multiple story outcomes exist simultaneously:

// Multiple potential futures exist
const choices = engine.getAvailableChoices();
console.log(`${choices.length} potential futures available`);

Collapse

Making a choice "collapses" the narrative to a specific path:

// Collapse to a specific reality
engine.makeChoice(0);
console.log('Reality collapsed to:', engine.getCurrentNode().id);

Entanglement

Decisions create flags that affect future story paths:

// Early decision creates entanglement
engine.makeChoice(0); // Sets { courage: 1 }

// Later story can check this flag
if (engine.getFlags().courage > 0) {
  console.log('Your earlier courage affects this moment!');
}

šŸš€ Framework Integration

React Integration

QNCE Engine provides a built-in React hook and UI components for seamless integration.

// StoryComponent.tsx
import React, { useState } from 'react';
import { createQNCEEngine } from 'qnce-engine';
import { useQNCE } from 'qnce-engine/integrations/react';
import { UndoRedoControls, AutosaveIndicator } from 'qnce-engine/ui';
import { myStory } from './story';

export function StoryComponent() {
  const [engine] = useState(() => createQNCEEngine(myStory));
  
  const {
    currentNode,
    availableChoices,
    selectChoice,
    flags,
    undo,
    redo,
    canUndo,
    canRedo,
    isComplete
  } = useQNCE(engine, {
    enableUndoRedo: true,
    enableAutosave: true,
    maxUndoEntries: 50
  });

  return (
    <div className="story-container">
      {/* Autosave indicator */}
      <AutosaveIndicator
        engine={engine}
        position="top-right"
        variant="detailed"
        showTimestamp={true}
      />
      
      <div className="story-text">
        <p>{currentNode?.text}</p>
      </div>
      
      <div className="choices">
        {availableChoices.map((choice, index) => (
          <button
            key={index}
            onClick={() => selectChoice(choice)}
            className="choice-button"
          >
            {choice.text}
          </button>
        ))}
      </div>
      
      {/* Undo/Redo controls */}
      <UndoRedoControls
        engine={engine}
        size="md"
        showLabels={true}
        layout="horizontal"
      />
      
      {isComplete && (
        <div className="story-complete">
          <h3>Story Complete!</h3>
        </div>
      )}
      
      <div className="flags">
        <h4>Story Flags:</h4>
        <pre>{JSON.stringify(flags, null, 2)}</pre>
      </div>
    </div>
  );
}

Vue 3 Integration

// useQNCE.ts (Vue Composition API)
import { ref, reactive } from 'vue';
import { createQNCEEngine, QNCEStory } from 'qnce-engine';

export function useQNCE(story: QNCEStory) {
  const engine = createQNCEEngine(story);
  const currentNode = ref(engine.getCurrentNode());
  const flags = reactive(engine.getFlags());

  const makeChoice = (choiceIndex: number) => {
    engine.makeChoice(choiceIndex);
    currentNode.value = engine.getCurrentNode();
    Object.assign(flags, engine.getFlags());
  };

  return {
    currentNode,
    choices: engine.getAvailableChoices(),
    flags,
    makeChoice
  };
}
<!-- StoryComponent.vue -->
<template>
  <div class="story-container">
    <div class="story-text">
      <p>{{ currentNode.text }}</p>
    </div>
    
    <div class="choices">
      <button
        v-for="(choice, index) in choices"
        :key="index"
        @click="makeChoice(index)"
        class="choice-button"
      >
        {{ choice.text }}
      </button>
    </div>
    
    <div class="flags">
      <h4>Story Flags:</h4>
      <pre>{{ JSON.stringify(flags, null, 2) }}</pre>
    </div>
  </div>
</template>

<script setup lang="ts">
import { useQNCE } from './useQNCE';
import { myStory } from './story';

const { currentNode, choices, flags, makeChoice } = useQNCE(myStory);
</script>

Node.js Server Integration

// server.ts
import express from 'express';
import { createQNCEEngine, QNCEStory } from 'qnce-engine';
import { myStory } from './story';

const app = express();
app.use(express.json());

// Store engine instances per session
const sessions = new Map<string, any>();

app.post('/story/start', (req, res) => {
  const sessionId = req.body.sessionId || generateSessionId();
  const engine = createQNCEEngine(myStory);
  
  sessions.set(sessionId, engine);
  
  res.json({
    sessionId,
    node: engine.getCurrentNode(),
    choices: engine.getAvailableChoices(),
    flags: engine.getFlags()
  });
});

app.post('/story/choice', (req, res) => {
  const { sessionId, choiceIndex } = req.body;
  const engine = sessions.get(sessionId);
  
  if (!engine) {
    return res.status(404).json({ error: 'Session not found' });
  }
  
  engine.makeChoice(choiceIndex);
  
  res.json({
    node: engine.getCurrentNode(),
    choices: engine.getAvailableChoices(),
    flags: engine.getFlags()
  });
});

app.listen(3000, () => {
  console.log('QNCE Story Server running on port 3000');
});

Vanilla JavaScript

<!DOCTYPE html>
<html>
<head>
  <title>QNCE Story</title>
  <style>
    .story-container { max-width: 600px; margin: 0 auto; padding: 20px; }
    .story-text { font-size: 18px; line-height: 1.6; margin-bottom: 20px; }
    .choice-button { 
      display: block; 
      width: 100%; 
      margin: 10px 0; 
      padding: 15px; 
      font-size: 16px;
      background: #007acc;
      color: white;
      border: none;
      border-radius: 5px;
      cursor: pointer;
    }
    .choice-button:hover { background: #005a9e; }
    .flags { margin-top: 20px; padding: 10px; background: #f5f5f5; }
  </style>
</head>
<body>
  <div class="story-container">
    <div id="story-text" class="story-text"></div>
    <div id="choices"></div>
    <div id="flags" class="flags"></div>
  </div>

  <script src="path/to/qnce-engine.js"></script>
  <script>
    // Initialize the story
    const story = {
      nodes: [
        // ... your story data
      ]
    };

    const engine = QNCE.createQNCEEngine(story);

    function updateDisplay() {
      const currentNode = engine.getCurrentNode();
      const choices = engine.getAvailableChoices();
      const flags = engine.getFlags();

      // Update story text
      document.getElementById('story-text').textContent = currentNode.text;

      // Update choices
      const choicesContainer = document.getElementById('choices');
      choicesContainer.innerHTML = '';
      
      choices.forEach((choice, index) => {
        const button = document.createElement('button');
        button.className = 'choice-button';
        button.textContent = choice.text;
        button.onclick = () => {
          engine.makeChoice(index);
          updateDisplay();
        };
        choicesContainer.appendChild(button);
      });

      // Update flags
      document.getElementById('flags').innerHTML = 
        '<h4>Story Flags:</h4><pre>' + JSON.stringify(flags, null, 2) + '</pre>';
    }

    // Initial display
    updateDisplay();
  </script>
</body>
</html>

šŸ› ļø Development Tools

CLI Tools Overview

# Create new project with templates
qnce-init my-story --template interactive-fiction

# Audit story for issues
qnce-audit story.json

# Monitor performance in real-time
qnce-perf --watch --dashboard

# Export performance data
qnce-perf export --format json

Story Validation

import { createQNCEEngine } from 'qnce-engine';

// Load your story
const story = { /* your story data */ };

try {
  const engine = createQNCEEngine(story);
  console.log('āœ… Story structure is valid');
} catch (error) {
  console.error('āŒ Story validation failed:', error.message);
}

Performance Monitoring

import { createQNCEEngine } from 'qnce-engine';

const engine = createQNCEEngine(story, {
  enablePerformanceMode: true,
  performanceOptions: {
    enableProfiling: true,
    maxCacheSize: 1000
  }
});

// Monitor performance
engine.on('performanceData', (data) => {
  console.log('Performance metrics:', data);
});

šŸ› Troubleshooting

Common Issues

Module Not Found

# Ensure you've installed the package
npm install qnce-engine

# For TypeScript projects, install types
npm install @types/node

Story Not Loading

// Verify story structure
const isValidStory = story.nodes && Array.isArray(story.nodes);
if (!isValidStory) {
  console.error('Invalid story structure');
}

Performance Issues

// Enable performance mode for large stories
const engine = createQNCEEngine(story, {
  enablePerformanceMode: true
});

Getting Help

šŸŽÆ Next Steps

Now that you have QNCE Engine set up, here's what to explore next:

  1. Branching Guide - Learn advanced branching and AI integration
  2. Performance Tuning - Optimize your stories for production
  3. CLI Usage - Master the command-line tools
  4. API Reference - Dive deep into the complete API

Ready to build amazing interactive narratives?

Branching Guide → | Examples → | Join Community →

Built with ā¤ļø by the QNCE development team


šŸ“ Wiki Navigation

← Previous: Home | You are here: Getting Started | Next: Branching Guide →

All Pages: Home • Getting Started • Branching Guide • Performance Tuning • CLI Usage • API Reference • Contributing • Release Notes


This documentation is maintained for QNCE Engine v1.2.3 with advanced feature set including Choice Validation, State Persistence, Conditional Choices, Autosave & Undo/Redo, and UI Components.

āš ļø **GitHub.com Fallback** āš ļø