bms-forge/docs/TECHNICAL_ARCHITECTURE.md
2026-03-19 01:09:12 -04:00

419 lines
No EOL
11 KiB
Markdown

# BMS BattleMap Generator - Technical Architecture
## System Overview
```
┌─────────────────────────────────────────────────────────────┐
│ Frontend Application │
├─────────────────────────────────────────────────────────────┤
│ Editor Interface Preview Canvas Tools Panel │
│ (Monaco Editor) (Konva.js Canvas) (Export/Options) │
├─────────────────────────────────────────────────────────────┤
│ State Management │
│ (React Hooks/Context) │
├─────────────────────────────────────────────────────────────┤
│ YAML Parser │ Schema Validator │ Renderer Engine │
│ (js-yaml) │ (Zod) │ (Konva.js Layers) │
└─────────────────────────────────────────────────────────────┘
```
## Component Architecture
### 1. BMS Schema Module (`src/schema/`)
```
schema/
├── types.ts # TypeScript interfaces
├── validators.ts # Zod validation schemas
├── parsers.ts # Coordinate/range parsing
├── transformers.ts # Data transformation
└── index.ts # Public API
```
### 2. Parser Module (`src/parser/`)
```
parser/
├── yaml-parser.ts # BMS YAML parsing
├── coordinate-parser.ts # Grid coordinate parsing
├── validation.ts # Schema validation logic
├── errors.ts # Error types and messages
└── index.ts
```
### 3. Renderer Module (`src/renderer/`)
```
renderer/
├── base-renderer.ts # Abstract base class
├── paperly-renderer.ts # Paperly style implementation
├── texture-renderer.ts # Future: texture pack rendering
├── layers/ # Individual layer renderers
│ ├── grid-layer.ts
│ ├── room-layer.ts
│ ├── door-layer.ts
│ ├── object-layer.ts
│ ├── hazard-layer.ts
│ ├── lighting-layer.ts
│ └── annotation-layer.ts
├── styles/ # Style definitions
│ ├── paperly-style.ts
│ └── texture-styles.ts # Future
└── utils/ # Rendering utilities
├── geometry.ts
├── colors.ts
└── textures.ts
```
### 4. UI Components (`src/components/`)
```
components/
├── Editor/
│ ├── YAMLEditor.tsx # Monaco editor wrapper
│ └── EditorPanel.tsx # Editor with error display
├── Preview/
│ ├── MapCanvas.tsx # Konva canvas wrapper
│ └── PreviewPanel.tsx # Preview with controls
├── Tools/
│ ├── ExportMenu.tsx # Export options
│ ├── StylePicker.tsx # Style selection
│ └── ValidationPanel.tsx # Validation status
├── Layout/
│ ├── Header.tsx
│ ├── Sidebar.tsx
│ └── StatusBar.tsx
└── Common/
├── ErrorDisplay.tsx
├── LoadingSpinner.tsx
└── Tooltip.tsx
```
### 5. State Management (`src/hooks/`, `src/context/`)
```
hooks/
├── useBMS.ts # BMS schema state
├── useRenderer.ts # Renderer instance
├── useExport.ts # Export functionality
└── useUndoRedo.ts # Undo/redo history
context/
├── AppContext.tsx # Global app state
└── ThemeContext.tsx # Theme/stylesheet
```
## Data Flow
### 1. Parsing Pipeline
```
User Input (YAML)
YAML Parser (js-yaml)
Schema Validator (Zod)
BMSSchema Object
Renderer Engine
Canvas Output
```
### 2. Rendering Pipeline
```
BMSSchema
Setup Canvas (grid size, scale)
Render Layers (in order):
1. Grid Layer
2. Room Layer (walls, floors)
3. Door Layer
4. Object Layer
5. Hazard Layer
6. Lighting Layer
7. Annotation Layer
Canvas Output
```
### 3. Export Pipeline
```
Canvas State
Export Format Selection
Format-Specific Exporter:
- PNG: canvas.toDataURL()
- JSON: JSON.stringify(BMSSchema)
- BMS: serializeBMSToYAML()
File Download
```
## Key Technical Decisions
### 1. Canvas Library: Konva.js
**Why Konva.js over alternatives:**
- **React Integration**: react-konva provides React component wrappers
- **Performance**: Hardware acceleration, efficient rendering
- **Features**: Layers, events, transforms, filters
- **Size**: Smaller than PIXI.js, more focused than raw Canvas API
- **Maintenance**: Active development, good documentation
### 2. Validation: Zod
**Why Zod over alternatives:**
- **TypeScript Integration**: Automatic type inference
- **Runtime Safety**: Comprehensive validation at runtime
- **Error Messages**: Customizable error messages
- **Size**: Small bundle size
- **Schema Composition**: Easy to compose and extend schemas
### 3. YAML Parsing: js-yaml
**Why js-yaml:**
- **Browser Support**: Works in browser environments
- **Safety**: Secure parsing options
- **Performance**: Fast and efficient
- **Features**: Full YAML 1.2 support
### 4. State Management: React Hooks
**Why React Hooks over Redux/MobX:**
- **Simplicity**: Less boilerplate for MVP
- **Performance**: Optimized re-renders with useMemo/useCallback
- **Scalability**: Can migrate to Context or Zustand if needed
- **Learning Curve**: Familiar to React developers
## Performance Considerations
### 1. Rendering Optimization
```typescript
// Use Konva.js optimizations
const optimizedRender = () => {
// Batch updates
stage.batchDraw();
// Use caching for static elements
shape.cache();
// Implement viewport culling
if (isInViewport(element)) {
renderElement(element);
}
};
```
### 2. Memory Management
```typescript
// Clean up resources
useEffect(() => {
const renderer = new PaperlyRenderer();
return () => {
renderer.destroy(); // Clean up Konva objects
};
}, []);
```
### 3. Large Map Handling
```typescript
// Implement level of detail
const getDetailLevel = (zoom: number): DetailLevel => {
if (zoom < 0.5) return 'low';
if (zoom < 1.0) return 'medium';
return 'high';
};
// Progressive rendering
const renderProgressive = async (schema: BMSSchema) => {
// Render grid first
renderGrid();
// Render rooms
await renderRooms(schema.rooms);
// Render details progressively
requestIdleCallback(() => {
renderDoors(schema.doors);
renderObjects(schema.objects);
});
};
```
## Security Considerations
### 1. YAML Parsing Security
```typescript
import { load } from 'js-yaml';
// Safe YAML parsing
const parseBMSYAML = (yaml: string): BMSSchema => {
try {
// Use safeLoad to prevent code execution
const parsed = load(yaml, {
schema: yaml.DEFAULT_SAFE_SCHEMA,
onWarning: (warning) => console.warn(warning)
});
// Validate structure
return bmsSchema.parse(parsed);
} catch (error) {
throw new BMSValidationError('Invalid BMS YAML', error);
}
};
```
### 2. File Export Security
```typescript
// Safe file naming
const sanitizeFilename = (name: string): string => {
return name.replace(/[^a-z0-9-_.]/gi, '_');
};
// Content security for downloads
const downloadFile = (content: string, filename: string) => {
const blob = new Blob([content], { type: 'application/octet-stream' });
const url = URL.createObjectURL(blob);
// Use safe download pattern
const a = document.createElement('a');
a.href = url;
a.download = sanitizeFilename(filename);
a.click();
URL.revokeObjectURL(url);
};
```
## Testing Strategy
### 1. Unit Tests
```typescript
// Test coordinate parsing
describe('parseCoordinate', () => {
it('should parse valid coordinates', () => {
expect(parseCoordinate('(5,10)')).toEqual([5, 10]);
});
it('should throw error for invalid format', () => {
expect(() => parseCoordinate('5,10')).toThrow();
});
});
```
### 2. Integration Tests
```typescript
// Test full parsing pipeline
describe('BMS Parser Integration', () => {
it('should parse and validate complete BMS', () => {
const yaml = sampleBMSYAML;
const schema = parseBMSYAML(yaml);
expect(schema.mapName).toBe('Guard Room');
expect(schema.rooms).toHaveLength(1);
});
});
```
### 3. Visual Regression Tests
```typescript
// Compare rendered output
describe('Renderer Visual Tests', () => {
it('should render rooms correctly', async () => {
const schema = createTestSchema();
const renderer = new PaperlyRenderer();
const image = await renderer.renderToImage(schema);
// Compare with baseline
expect(image).toMatchImageSnapshot();
});
});
```
## Deployment Architecture
### 1. Development Environment
```
Local Machine → Vite Dev Server → Browser
```
### 2. Alpha Deployment
```
Git Repository → Build (Vite) → Static Files → maps.bouncypixel.com
```
### 3. Future Production Deployment
```
GitHub Actions → Build & Test → CDN (Vercel/Netlify) → Custom Domain
↘ Texture Packs → Cloud Storage (S3/Cloudflare)
```
## Scalability Considerations
### 1. Frontend Scaling
- **Code Splitting**: Lazy load components
- **Bundle Optimization**: Tree shaking, compression
- **CDN**: Static assets via CDN
### 2. Rendering Scaling
- **Virtualization**: Only render visible area
- **Web Workers**: Offload heavy computation
- **Caching**: Cache rendered elements
### 3. Data Scaling
- **IndexedDB**: Local storage for large maps
- **Compression**: Compress BMS data
- **Streaming**: Progressive loading
## Monitoring & Analytics
### 1. Performance Monitoring
```typescript
// Track rendering performance
const measureRender = (schema: BMSSchema) => {
performance.mark('render-start');
renderer.render(schema);
performance.mark('render-end');
const measure = performance.measure('render', 'render-start', 'render-end');
console.log(`Render time: ${measure.duration}ms`);
};
```
### 2. Error Tracking
```typescript
// Centralized error handling
class ErrorTracker {
static track(error: Error, context?: any) {
console.error('BMS Error:', error, context);
// Send to error tracking service (future)
}
}
```
### 3. Usage Analytics (Optional)
```typescript
// Basic usage tracking
const trackEvent = (event: string, data?: any) => {
if (process.env.NODE_ENV === 'production') {
// Send to analytics service
}
};
```
## Future Technical Considerations
### 1. Plugin System
```typescript
interface BMSPlugin {
name: string;
version: string;
init: (app: BMSApp) => void;
render?: (context: RenderContext) => void;
export?: (schema: BMSSchema) => any;
}
```
### 2. Collaborative Features
- **WebSocket**: Real-time collaboration
- **Conflict Resolution**: Operational transforms
- **Presence**: User cursor/selection
### 3. Offline Support
- **Service Workers**: Offline functionality
- **Local Storage**: Save work locally
- **Sync**: Background synchronization
---
*Last Updated: March 19, 2026*