Files
npc-config-app/MODULAR_ARCHITECTURE.md

11 KiB

Modular NPC Builder - Architecture Documentation

Overview

The Cobblemon NPC Creator has been refactored from a traditional tab-based form interface to a modern, modular node-based system inspired by tools like n8n, ComfyUI, and Unreal Engine's Blueprint system. This new approach provides a more intuitive, visual way to create and customize NPCs through connectable modules.

Why This Refactor?

Problems with the Old System

  • Complex, multi-tab forms were overwhelming for users
  • Hard to see the complete NPC configuration at a glance
  • Difficult to understand relationships between different components
  • Linear workflow didn't match the non-linear nature of NPC creation

Benefits of the New System

  • Visual representation of NPC structure
  • Drag-and-drop modular components
  • Clear data flow through connections
  • Easier to add/remove features on demand
  • More scalable and extensible architecture
  • Better separation of concerns

Technology Stack

Core Library: React Flow (@xyflow/react)

Why React Flow?

  • Production-ready, battle-tested in many applications
  • Excellent TypeScript support
  • Highly customizable node and edge rendering
  • Built-in features: minimap, controls, background grid
  • Great performance with many nodes
  • Active development and community
  • MIT licensed

Other Options Considered:

  • jsPlumb: Older library, less React-friendly
  • Vue Flow: Excellent but Vue-specific
  • React Diagrams: Less maintained, fewer features
  • Rete.js: Good but more complex API

React Flow was chosen for its perfect balance of features, performance, and ease of use.

Architecture

File Structure

src/
├── components/
│   ├── NodeCanvas.tsx                 # Main workspace component
│   └── nodes/                         # Individual node modules
│       ├── BasicInfoNode.tsx          # Basic NPC settings module
│       ├── BattleConfigNode.tsx       # Battle configuration module
│       ├── PartyNode.tsx              # Pokemon party builder module
│       ├── InteractionNode.tsx        # Interaction system module
│       ├── VariablesNode.tsx          # MoLang variables module
│       └── OutputNode.tsx             # JSON preview and export module
├── types/
│   ├── npc.ts                         # Original NPC type definitions
│   └── nodes.ts                       # New node-based type definitions
└── App.tsx                            # Updated main app with modular view

Module Types

1. BasicInfoNode (Blue)

Purpose: Configure core NPC properties Inputs: None (root node) Outputs: Basic info data Fields:

  • Resource Identifier
  • Names (comma-separated)
  • Model Scale
  • Aspects
  • Behavior flags (invulnerable, persistent, movable, etc.)

2. BattleConfigNode (Red)

Purpose: Set up battle-related configurations Inputs: Connection from any module Outputs: Battle config data Fields:

  • Can Battle / Can Challenge toggles
  • Battle Theme
  • Victory Theme
  • Defeat Theme
  • Simultaneous Battles option
  • Heal After Battle option

3. PartyNode (Green)

Purpose: Configure Pokemon party Inputs: Connection from any module Outputs: Party data Fields:

  • Party Type selector (Simple/Pool/Script)
  • Pokemon list with add/remove
  • Static Party toggle Features:
  • Add/remove Pokemon
  • Inline Pokemon string editing
  • Support for different party provider types

4. InteractionNode (Purple)

Purpose: Define NPC interaction behavior Inputs: Connection from any module Outputs: Interaction data Fields:

  • Interaction Type (None/Dialogue/Script/Shop/Heal)
  • Dialogue Reference (for dialogue type)
  • Script Reference (for script type)

5. VariablesNode (Yellow)

Purpose: Manage MoLang configuration variables Inputs: Connection from any module Outputs: Variables data Fields:

  • Variable list with add/remove
  • Per-variable configuration:
    • Variable Name
    • Display Name
    • Type (Number/Text/Boolean)
    • Default Value

6. OutputNode (Indigo)

Purpose: Preview and export final NPC JSON Inputs: Collects data from all modules Outputs: None (terminal node) Features:

  • NPC summary view
  • Live JSON preview
  • Download JSON button
  • Character count display

Data Flow

BasicInfoNode ─┐
               ├─► OutputNode (JSON Preview)
BattleNode ────┤
               ├─► [Collects all module data]
PartyNode ─────┤
               ├─► [Generates final NPC config]
InteractionNode┤
               │
VariablesNode ─┘

Key Components

NodeCanvas.tsx

The main workspace component that:

  • Manages the React Flow instance
  • Handles node and edge state
  • Provides "Add Module" functionality
  • Aggregates node data into final NPC configuration
  • Updates OutputNode preview in real-time
  • Renders control panels and minimap

Key Features:

  • Drag-and-drop node positioning
  • Visual connections between modules
  • Module palette for adding new nodes
  • Real-time configuration updates
  • Responsive design

Individual Node Components

Each node module follows a consistent pattern:

  • Collapsible header with icon and color coding
  • Input/output handles for connections
  • Expandable/collapsible content area
  • Form fields for configuration
  • Real-time data updates

Design Principles:

  • Self-contained logic
  • Minimal external dependencies
  • Consistent UI patterns
  • Color-coded by category
  • Icon-based identification

Usage Patterns

Basic Workflow

  1. Start with BasicInfoNode (automatically created)

    • Set NPC name and identifier
    • Configure basic properties
  2. Add Required Modules via "Add Module" button

    • Click desired module from palette
    • Module appears on canvas
  3. Configure Each Module

    • Click to expand/collapse
    • Fill in relevant fields
    • Data updates automatically
  4. Connect Modules (optional, visual only)

    • Drag from output handle to input handle
    • Creates visual relationship
  5. Preview Output in OutputNode

    • View NPC summary
    • Check JSON preview
    • Download when ready

Adding New Module Types

To add a new module type:

  1. Define types in src/types/nodes.ts:
export interface NewModuleNodeData {
  type: 'newModule';
  field1: string;
  field2: number;
}
  1. Create component in src/components/nodes/NewModuleNode.tsx:
export const NewModuleNode = memo(({ data }: NodeProps<NewModuleNodeData>) => {
  // Implementation
});
  1. Register in NodeCanvas.tsx:
const nodeTypes: NodeTypes = {
  // ... existing types
  newModule: NewModuleNode,
};
  1. Add to palette in NodeCanvas.tsx:
{
  type: 'newModule',
  label: 'New Module',
  description: 'Description here',
  color: 'bg-color-500',
  icon: '🎨',
}

State Management

Current Approach

  • React Flow manages node positions and connections
  • Each node stores its own data in node.data
  • NodeCanvas aggregates node data into final NPC config
  • Parent App.tsx maintains final state

Data Updates

  • Node changes trigger immediate updates
  • NodeCanvas effect listens for node changes
  • Aggregates all node data into NPCConfiguration
  • Updates OutputNode preview automatically
  • Parent receives final config via callback

Extensibility

Future Enhancements

  1. Dialogue Editor Module

    • Visual dialogue tree within a node
    • Inline page editing
    • Speaker management
  2. Advanced Party Builder

    • Pokemon selector modal
    • Visual Pokemon cards
    • Type-based team generation
  3. Quest Module

    • Quest objectives
    • Reward configuration
    • Quest chain visualization
  4. AI Behavior Module

    • Pathfinding settings
    • Custom behaviors
    • Schedule configuration
  5. Import/Export Module

    • Load from datapack
    • Save workflow templates
    • Share configurations

API Integration Opportunities

  • Pokemon data from PokeAPI
  • Cobblemon mod documentation links
  • Community preset sharing
  • Validation against mod version

Performance Considerations

  • React Flow handles virtualization automatically
  • Memoized components prevent unnecessary re-renders
  • Debounced updates for text inputs (can be added)
  • Lazy loading for heavy modules (can be added)

Styling

Design System

  • Tailwind CSS for utility-first styling
  • Color-coded modules for easy identification:
    • Blue: Core settings
    • Red: Battle/Combat
    • Green: Pokemon/Party
    • Purple: Interactions
    • Yellow: Configuration/Variables
    • Indigo: Output/Export

Responsive Design

  • Nodes have minimum widths
  • Collapsible sections for small screens
  • Touch-friendly controls
  • Mobile-optimized panels

Testing Strategy

Manual Testing Checklist

  • Can add all module types
  • Can delete nodes
  • Can connect nodes (visual)
  • Can collapse/expand nodes
  • Data persists when nodes are moved
  • OutputNode shows correct preview
  • Can download valid JSON
  • All form fields work correctly
  • Checkbox states persist
  • Number inputs validate properly

Automated Testing (Future)

  • Unit tests for node components
  • Integration tests for data flow
  • E2E tests for complete workflows
  • Visual regression tests for UI

Migration Guide

For Users

  • Old tab-based view is still accessible (Classic mode)
  • Existing save files remain compatible
  • New modular view is opt-in
  • Can switch between modes

For Developers

  • Old components still exist in codebase
  • New modular system is additive
  • Can maintain both systems
  • Gradual migration path

Known Limitations

  1. Connection Logic: Connections are currently visual only and don't enforce data flow
  2. Undo/Redo: Not yet implemented
  3. Copy/Paste Nodes: Not yet implemented
  4. Node Templates: Can't save/load node configurations
  5. Mobile Experience: Best on desktop/tablet

Troubleshooting

Common Issues

Nodes not appearing:

  • Check if nodeTypes are registered in NodeCanvas
  • Verify component import paths
  • Check for TypeScript errors

Data not updating:

  • Ensure node data is being mutated correctly
  • Check useEffect dependencies in NodeCanvas
  • Verify onChange callbacks are called

Styling issues:

  • Ensure @xyflow/react styles are imported
  • Check Tailwind CSS configuration
  • Verify color classes exist

Contributing

When adding new features:

  1. Follow existing node component patterns
  2. Use TypeScript for type safety
  3. Add appropriate color coding
  4. Include descriptions in module palette
  5. Test with various configurations
  6. Update this documentation

Resources

Conclusion

The modular node-based architecture provides a more intuitive and scalable approach to NPC creation. By leveraging React Flow's powerful features and maintaining clean separation of concerns, the system is both user-friendly and developer-friendly. The visual nature of the interface makes complex configurations more approachable while maintaining the full power of the underlying Cobblemon NPC system.