[ISSUE-1] Refactor NPC forms to modular node-based system #2
401
MODULAR_ARCHITECTURE.md
Normal file
401
MODULAR_ARCHITECTURE.md
Normal file
@@ -0,0 +1,401 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user