JSPM

@magicborn/dialogue-forge

0.1.5
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 22
  • Score
    100M100P100Q73132F
  • License MIT

Visual node-based dialogue editor with Yarn Spinner support

Package Exports

  • @magicborn/dialogue-forge
  • @magicborn/dialogue-forge/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@magicborn/dialogue-forge) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Dialogue Forge

A visual node-based dialogue editor with Yarn Spinner support for game development.

πŸš€ Quick Start

Run the Demo

npx @magicborn/dialogue-forge

This will download the package and start an interactive demo server at http://localhost:3000.

Install as Library

npm install @magicborn/dialogue-forge

Quick Start

1. Define Your Flags

import { FlagSchema, FLAG_TYPE, FLAG_VALUE_TYPE } from '@magicborn/dialogue-forge';

const flagSchema: FlagSchema = {
  categories: ['quests', 'items', 'stats'],
  flags: [
    {
      id: 'quest_dragon_slayer',
      name: 'Dragon Slayer Quest',
      type: FLAG_TYPE.QUEST,  // βœ… Use constant, not 'quest'
      category: 'quests',
      valueType: FLAG_VALUE_TYPE.STRING
    },
    {
      id: 'item_ancient_key',
      name: 'Ancient Key',
      type: FLAG_TYPE.ITEM,  // βœ… Use constant
      category: 'items'
    },
    {
      id: 'stat_gold',
      name: 'Gold',
      type: FLAG_TYPE.STAT,  // βœ… Use constant
      category: 'stats',
      valueType: FLAG_VALUE_TYPE.NUMBER,
      defaultValue: 0
    }
  ]
};

2. Load Dialogue from Yarn

import { importFromYarn } from '@magicborn/dialogue-forge';

const yarnContent = await loadFile('merchant.yarn');
const dialogue = importFromYarn(yarnContent, 'Merchant Dialogue');

3. Edit Dialogue

import { DialogueEditor, exportToYarn } from '@magicborn/dialogue-forge';

<DialogueEditor
  dialogue={dialogue}
  onChange={(updated) => {
    const yarn = exportToYarn(updated);
    saveFile('merchant.yarn', yarn);
  }}
  flagSchema={flagSchema}
/>

4. Run Dialogue with Game State

import { DialogueSimulator } from '@magicborn/dialogue-forge';

// Get current game flags
const gameFlags = {
  quest_dragon_slayer: 'complete',
  item_ancient_key: true,
  stat_gold: 1000
};

<DialogueSimulator
  dialogue={dialogue}
  initialFlags={gameFlags}
  onComplete={(result) => {
    // Update game state with new flags
    gameState.flags = {
      ...gameState.flags,
      ...result.updatedFlags
    };
  }}
/>

Features

  • Visual Node Editor - Drag nodes, connect edges, right-click menus
  • Yarn Spinner Import/Export - Work with .yarn files
  • Flag System - Reference game flags with autocomplete dropdown
  • Simulation Mode - Test dialogues with current game state
  • Built-in Guide - Click book icon for complete documentation

Flag System

Flags represent game state (quests, items, achievements, etc.). The editor:

  • Shows available flags in dropdowns when setting flags
  • Validates flag references
  • Exports flags to Yarn format
  • Returns updated flags after dialogue completes

Flag Types (use FLAG_TYPE constant):

  • FLAG_TYPE.QUEST - Quest state and completion
  • FLAG_TYPE.ACHIEVEMENT - Unlocked achievements
  • FLAG_TYPE.ITEM - Inventory items
  • FLAG_TYPE.STAT - Player statistics
  • FLAG_TYPE.TITLE - Earned titles
  • FLAG_TYPE.DIALOGUE - Temporary, dialogue-scoped
  • FLAG_TYPE.GLOBAL - Global game state

Important: Always use the exported constants (FLAG_TYPE, NODE_TYPE, etc.) instead of string literals for type safety.

See DATA_STRUCTURES.md for complete type documentation and FLAG_SYSTEM.md for flag system details.

API Reference

Components

  • DialogueEditor - Visual editor for creating/editing dialogues
  • DialogueSimulator - Run dialogues with game state, returns updated flags
  • GuidePanel - Built-in documentation panel
  • FlagSelector - Flag autocomplete component

Utilities

  • importFromYarn(yarnContent, title) - Parse Yarn file to DialogueTree
  • exportToYarn(dialogue) - Convert DialogueTree to Yarn format
  • initializeFlags(schema) - Create default flag state from schema
  • mergeFlagUpdates(current, updates, schema) - Merge flag updates
  • validateFlags(flags, schema) - Validate flags against schema

Types

  • DialogueTree - Dialogue structure
  • DialogueNode - Individual dialogue node (NPC or Player)
  • FlagSchema - Flag definitions
  • GameFlagState - Current flag values { [flagId]: value }
  • DialogueResult - Result from running dialogue (updated flags, visited nodes)

Dialogue Editor V2 with View Modes

DialogueEditorV2 supports graph, yarn, and play views. Use the exported VIEW_MODE constant (instead of string literals) alongside the ViewMode type so consumers get auto-complete and type safety when switching views.

import { DialogueEditorV2, VIEW_MODE, type DialogueTree, type ViewMode } from '@magicborn/dialogue-forge';
import { useState } from 'react';

export function DialogueEditorDemo() {
  const [dialogue, setDialogue] = useState<DialogueTree | null>(null);
  const [viewMode, setViewMode] = useState<ViewMode>(VIEW_MODE.GRAPH);

  return (
    <DialogueEditorV2
      dialogue={dialogue}
      onChange={setDialogue}
      viewMode={viewMode}
      onViewModeChange={setViewMode}
    />
  );
}

Authoring dialogue data programmatically

You can build dialogue content without the editor and still take advantage of the types and constants that power the scene player. This makes it easy to script nonlinear stories, export them, or feed them directly into ScenePlayer.

import {
  NODE_TYPE,
  type DialogueTree,
  type DialogueNode,
  ScenePlayer,
} from '@magicborn/dialogue-forge';

const nodes: Record<string, DialogueNode> = {
  npc_1: {
    id: 'npc_1',
    type: NODE_TYPE.NPC,
    speaker: 'Merchant',
    content: 'Welcome, traveler! Looking for supplies?',
    nextNodeId: 'player_1',
    x: 0,
    y: 0,
  },
  player_1: {
    id: 'player_1',
    type: NODE_TYPE.PLAYER,
    content: ' ',
    choices: [
      { id: 'buy', text: 'Show me your wares.', nextNodeId: 'npc_2' },
      { id: 'chat', text: 'Any rumors?', nextNodeId: 'npc_3' },
    ],
    x: 320,
    y: 0,
  },
  npc_2: {
    id: 'npc_2',
    type: NODE_TYPE.NPC,
    content: 'Take a look! Fresh stock just arrived.',
    x: 640,
    y: -120,
  },
  npc_3: {
    id: 'npc_3',
    type: NODE_TYPE.NPC,
    content: 'Bandits have been spotted near the bridgeβ€”stay sharp.',
    x: 640,
    y: 120,
  },
};

const merchantIntro: DialogueTree = {
  id: 'merchant_intro',
  title: 'Merchant Greeting',
  startNodeId: 'npc_1',
  nodes,
};

// Render or test the dialogue without the editor
// <ScenePlayer dialogue={merchantIntro} gameState={yourGameState} onComplete={...} />

Complete Example

import {
  DialogueEditor,
  DialogueSimulator,
  importFromYarn,
  exportToYarn,
  FlagSchema,
  GameFlagState
} from '@magicborn/dialogue-forge';

// Define flags
import { FLAG_TYPE } from '@magicborn/dialogue-forge';

const flagSchema: FlagSchema = {
  flags: [
    { id: 'quest_complete', type: FLAG_TYPE.QUEST, category: 'quests' },
    { id: 'item_key', type: FLAG_TYPE.ITEM, category: 'items' },
  ]
};

// Load dialogue
const dialogue = importFromYarn(yarnFile, 'Merchant');

// Get current game state
const gameFlags: GameFlagState = {
  quest_complete: 'complete',
  item_key: true
};

// Edit dialogue
<DialogueEditor
  dialogue={dialogue}
  onChange={(updated) => {
    const yarn = exportToYarn(updated);
    saveFile(yarn);
  }}
  flagSchema={flagSchema}
  initialFlags={gameFlags}
/>

// OR run dialogue
<DialogueSimulator
  dialogue={dialogue}
  initialFlags={gameFlags}
  onComplete={(result) => {
    // Update game with new flags
    gameState.flags = result.updatedFlags;
    // Next dialogue will have different options
    // based on updated flags
  }}
/>

Documentation

Click the book icon in the editor to open the built-in guide.

Key Concepts

Flags = Yarn Variables: Flags you define in Dialogue Forge become $variable in Yarn Spinner. These variables are stored in Yarn Spinner's Variable Storage at runtime, not in the .yarn file.

Bidirectional Flow:

  • Edit in Dialogue Forge β†’ Export .yarn β†’ Import to Unreal
  • Game sets variables β†’ Yarn reads them β†’ Dialogue reacts
  • Dialogue sets variables β†’ Yarn stores them β†’ Game reads them

See UNREAL_INTEGRATION.md for complete details.