402 lines
11 KiB
Markdown
402 lines
11 KiB
Markdown
# 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`:
|
|
```typescript
|
|
export interface NewModuleNodeData {
|
|
type: 'newModule';
|
|
field1: string;
|
|
field2: number;
|
|
}
|
|
```
|
|
|
|
2. **Create component** in `src/components/nodes/NewModuleNode.tsx`:
|
|
```typescript
|
|
export const NewModuleNode = memo(({ data }: NodeProps<NewModuleNodeData>) => {
|
|
// Implementation
|
|
});
|
|
```
|
|
|
|
3. **Register in NodeCanvas.tsx**:
|
|
```typescript
|
|
const nodeTypes: NodeTypes = {
|
|
// ... existing types
|
|
newModule: NewModuleNode,
|
|
};
|
|
```
|
|
|
|
4. **Add to palette** in NodeCanvas.tsx:
|
|
```typescript
|
|
{
|
|
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
|
|
|
|
- [React Flow Documentation](https://reactflow.dev/)
|
|
- [Cobblemon Mod Documentation](https://wiki.cobblemon.com/)
|
|
- [Tailwind CSS Documentation](https://tailwindcss.com/)
|
|
- [TypeScript Documentation](https://www.typescriptlang.org/)
|
|
|
|
## 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.
|