DZMM Builder
Overview
Build AI-driven interactive web applications on the DZMM.AI platform using specialized knowledge, complete examples, and reusable code patterns. This skill provides comprehensive support for creating single-file HTML applications that leverage streaming AI conversations, cloud key-value storage, and browser effect systems.
When to Use This Skill
Invoke this skill when users:
- Request creating a new DZMM application ("Build me a DZMM chatbot", "Create an AI story generator", "Make a dating sim game", "Build a social media content generator", "Create a visual novel", "Build an interactive fiction game")
- Ask questions about DZMM API usage ("How do I use dzmm.completions?", "How does KV storage work?", "How to parse structured AI output?", "How to use chat API for branching stories?", "How to implement streaming AI responses?")
- Need help debugging DZMM applications ("My DZMM app returns 400 error", "AI responses are not displaying", "State not persisting", "DZMM API not initializing")
- Want to optimize existing DZMM apps (performance, user experience, architecture improvements, mobile responsiveness, reduce token usage)
- Ask about "fourth wall breaking" effects or browser control from AI
- Need guidance on state management in games (stats, mood, relationships, dynamic UI)
- Want to integrate Markdown rendering or rich text formatting (nested structures, dialogue quotes, options buttons)
- Request configuration/setup UI for applications
- Need branching narrative systems (Galgame save/load, multi-route stories, choice history tracking)
- Ask about available models and their performance characteristics
- Request message management features ("How to add reroll/regenerate?", "How to let users edit messages?", "How to delete conversation branches?")
- Want multi-opening/multi-scenario systems ("How to add multiple starting scenes?", "How to switch between different story routes?")
- Need help migrating from React/Vue to DZMM ("How to migrate my app to DZMM?", "What's the DZMM equivalent of useState?", "Can I use React/TypeScript with DZMM?", "How to build DZMM apps with modern frameworks?", "vite-plugin-singlefile for DZMM", "My DZMM app has sandbox errors", "Form submission blocked in DZMM", "localStorage not working in DZMM", "HTTP 400 error with DZMM API", "maxTokens limit exceeded")
- Ask about resource management ("How to load images/audio in DZMM?", "Should I use URLs or embed resources?")
Core Capabilities
1. Application Generation
Generate complete, single-file HTML applications for the DZMM platform based on user requirements.
Approach:
- Clarify the application type and core features
- Select an appropriate architecture pattern (stateless generator, stateful dialogue, or layered cache platform)
- Use example templates from
assets/examples/ as foundation
- Customize for specific requirements
- Test the complete flow (initialization → AI call → display)
Architecture Patterns:
Stateless Generator - For one-shot content generation:
- Example: Translator, text summarizer, content creator, social media post generator
- No conversation history or state persistence
- Simplest architecture, fastest development
- Optional: Integrate marked.js for Markdown rendering
- Reference: See
assets/examples/小红书文案.html for minimal implementation
- Code snippets:
references/code-snippets.md section 2
State Management Game - For interactive games with dynamic variables:
- Example: Dating sims, RPG games, decision-based narratives
- Multiple state variables (stats, mood, time, relationships)
- Structured AI output parsing (###STATE/###END format)
- Configuration UI for game initialization
- State-driven UI updates (progress bars, backgrounds, effects)
- Auto-save with KV storage
- Reference: See
assets/examples/恋爱游戏.html for complete implementation
Stateful Dialogue System - For multi-turn conversations:
- Example: Chatbots, interactive stories, Q&A systems
- Maintains conversation history
- Uses Alpine.store for state management
- Persists state with KV storage
- Reference: See
assets/examples/dungeon-adventure.html and assets/examples/horror-story.html
Layered Cache Platform - For content communities:
- Example: Forums, story libraries, content platforms
- Two-tier caching (list cache + detail cache)
- On-demand content generation
- Concurrent request locking
- Reference: See
assets/examples/贴吧.html for full implementation
Visual Novel / Galgame System - For narrative-driven interactive fiction:
- Example: Visual novels, interactive stories, AI-driven narrative games
- Multi-opening scene system with dynamic switching
- Rich text rendering with placeholder technique (handles nested structures)
- Message management (reroll, edit, delete with context preservation)
- Multi-slot save/load system with preview
- Modular prompt system (main prompt + character + guidance + emphasis)
- Responsive mobile design with compressed UI
- Reference: See yoshiwara-chronicles project for complete implementation
- Key features: XML-structured prompts, emphasis, streaming AI responses
2. API Integration Guidance
Provide detailed guidance on using DZMM's specialized APIs.
Core APIs:
window.dzmm.completions() - Streaming AI generation:
await window.dzmm.completions(
{
model: 'nalang-turbo-0826' | 'nalang-medium-0826' |
'nalang-max-0826' | 'nalang-xl-0826' |
'nalang-max-0826-16k' | 'nalang-xl-0826-16k',
messages: [{ role: 'user' | 'assistant', content: string }],
maxTokens: number // Optional, 200-3000, default 1000
},
(newContent, done) => {
// newContent is cumulative, not incremental
// done is true when generation completes
}
);
window.dzmm.chat - Tree-structured conversation storage (⭐ NEW):
// Insert messages into conversation tree (supports branching storylines)
const result = await window.dzmm.chat.insert(parentId, [
{ role: 'user', content: 'Player choice' },
{ role: 'assistant', content: 'Story response' }
]);
const newMessageIds = result.ids; // Array of new message IDs
// Get message details (with parent/children relationships)
const messages = await window.dzmm.chat.list(['msg-123', 'msg-124']);
// Returns: [{ id, role, content, timestamp, parent, children }, ...]
// Get complete conversation timeline
const timeline = await window.dzmm.chat.timeline(messageId);
const fullHistory = await window.dzmm.chat.list(timeline);
Use cases: Galgame save/load systems, branching narratives, multi-route stories, interactive fiction with choice history.
window.dzmm.kv - Cloud key-value storage:
// Save (auto-serializes objects)
await window.dzmm.kv.put(key, value);
// Load
const result = await window.dzmm.kv.get(key);
if (result.value) {
const data = result.value;
}
// Delete
await window.dzmm.kv.delete(key);
Limits: Keys ≤256 chars, values ≤1MB recommended. Development mode: data lost on refresh. Production: persistent.
Critical Requirements:
- Must wait for
dzmm:ready event before any API calls
- Only
user and assistant roles supported (no system)
- Limit conversation history to ≤20 messages to avoid token overflow
- maxTokens range: 200-3000, default 1000
- Concurrent requests: ≤3 recommended
- Use versioned keys for KV storage (e.g.,
app_state_v1)
Reference: Consult references/developer-guide.md sections 2-3 for complete API documentation and references/code-snippets.md sections 1-3 for ready-to-use code patterns.
3. Effect System Implementation
Implement "fourth wall breaking" effects where AI can control the user's browser environment.
Effect Categories:
Visual Effects:
- Light control (dimming, darkness, flickering)
- Screen shake (low/medium/high intensity)
- Glitch effects
- Color filters (blood, blur, etc.)
Audio Effects:
- Programmatic sound generation (beeps, drones, heartbeats)
- Web Audio API without external files
- Ambient and tension-building sounds
Dynamic Elements:
- Particle systems (dust, blood, explosions)
- Jumpscare popups
- Element manipulation
Implementation Pattern:
// 1. AI outputs special instructions
const aiPrompt = `When the user says "turn off lights", output:
###EFFECT
{"action":"lights","params":{"state":"off"}}
###END`;
// 2. Parse and execute
const effectMatch = content.match(/###EFFECT\s*({[\s\S]*?})\s*###END/);
if (effectMatch) {
const effect = JSON.parse(effectMatch[1]);
executeEffect(effect);
// Remove instruction from display
content = content.replace(/###EFFECT[\s\S]*?###END/, '').trim();
}
// 3. Effect executor
function executeEffect(effect) {
switch(effect.action) {
case 'lights':
document.body.classList.add(`lights-${effect.params.state}`);
break;
// ... more effects
}
}
Reference: See assets/examples/horror-story.html for complete effect system with CSS animations, Web Audio, and Canvas particles.
4. Debugging and Optimization
Diagnose and fix common DZMM application issues.
Common Issues:
HTTP 400 Errors:
- Cause: Using
role: 'system' in messages (not supported)
- Fix: Convert system prompts to first
user message or maintain in frontend variables
- Cause: Messages array contains undefined/null values
- Fix: Validate and sanitize messages before sending
No Response from AI:
- Cause: API not ready yet
- Fix: Ensure
dzmm:ready event is awaited before any API calls
Context Overflow:
- Cause: Too many messages or overly long content
- Fix: Slice messages array to last 10-20 items, truncate individual messages to 2000 chars
State Not Persisting:
- Cause: KV key naming conflicts or version mismatch
- Fix: Use versioned keys with unique identifiers
Form Submission Blocked (Public Release Only):
Performance Optimization:
- Debounce user input to reduce API calls
- Implement two-tier caching for content-heavy apps
- Use concurrent request locks to prevent duplicate API calls
- Limit conversation history proactively
Reference: Consult references/developer-guide.md section "常见问题" for comprehensive troubleshooting guide.
5. Code Patterns and Snippets
Provide reusable, production-ready code patterns for common DZMM tasks.
Available Patterns:
- Initialization and API readiness (dual detection with timeout)
- AI completions (basic, multi-turn, streaming with real-time display)
- KV storage operations (save, load, delete, multi-slot, batch operations)
- Chat API operations (branching narratives, save/load, timeline retrieval)
- Instruction parsing systems (JSON, XML, ###STATE format)
- Alpine.js state management (local and global stores)
- Visual effect systems (CSS animations, particles, audio)
- Error handling and structured logging (retry with exponential backoff)
- Utility functions (debounce, sanitize, scroll control)
- Prompt templates (structured output, XML hierarchy, emphasis sections)
- Complete application templates
- Rich text rendering (placeholder technique for nested structures)
- Message management (reroll, edit, delete with context preservation)
- Multi-opening system (scene switching with state management)
- Resource management (URL-based asset loading, preloading)
- Modular prompt system (main + character + guidance + emphasis)
- Responsive layout patterns (mobile-first with Tailwind breakpoints)
Usage: Reference references/code-snippets.md for copy-paste ready code snippets organized by category. All snippets are tested and can be used directly or with minimal modifications.
New Visual Novel Patterns (from yoshiwara-chronicles):
- Rich text parser with placeholder technique
- Message reroll/edit/delete functions
- Opening scene switcher with confirmation
- Multi-slot save system with preview extraction
- Streaming AI response with auto-scroll
- XML-structured prompt builder
- Resource manager for external assets
Workflow Guide
For New Applications
Clarify Requirements
- Determine application type (chatbot, game, content platform, etc.)
- Identify core features and interactions
- Choose architecture pattern
Select Template
- Browse
assets/examples/ for similar applications:
小红书文案.html - Simple content generator, Markdown rendering
恋爱游戏.html - Dating sim, multi-variable state management
horror-story.html - Effect system, immersive experience
dungeon-adventure.html - Turn-based game, state management
neon-gomoku.html - AI opponent, game logic
贴吧.html - Content platform, two-tier caching
Build Application
- Start with HTML structure and Alpine.js integration
- Implement DZMM API initialization (wait for
dzmm:ready)
- Add AI completions with appropriate model selection
- Implement state management and KV storage if needed
- Add visual effects or advanced features as required
Test and Refine
- Test initialization and API readiness
- Verify AI responses and parsing
- Check state persistence across page reloads
- Optimize performance (history limits, debouncing)
For Debugging Existing Applications
Identify the Issue
- Review error messages and console logs
- Check network requests in browser DevTools
- Verify API readiness timing
Diagnose Root Cause
- Cross-reference with common issues in
references/developer-guide.md
- Check message format compliance (only
user/assistant)
- Validate conversation history length
Apply Fix
- Use code patterns from
references/code-snippets.md
- Add error handling if missing
- Implement validation for user inputs and API responses
Optimize
- Add performance improvements (caching, debouncing)
- Improve user experience (loading states, error messages)
- Enhance code maintainability (structured logging, modularity)
For Migrating React/Vue Applications to DZMM
Two Approaches Available:
Approach A: Keep React/Vue Framework (Recommended for Large Projects)
Use modern build tools to maintain component-based development, then bundle to single HTML.
Tech Stack: React + TypeScript + Vite + vite-plugin-singlefile
Workflow:
- Setup:
npm create vite@latest my-app -- --template react-ts
- Install Plugin:
npm install -D vite-plugin-singlefile
- Configure Vite: Add plugin for single-file build mode
- Develop: Keep existing React components structure
- Build:
npm run build:single → generates standalone HTML
- Deploy: Upload to DZMM platform
Key Considerations:
- ✅ Keep TypeScript type safety and component modularity
- ✅ Hot reload during development
- ✅ Rich ecosystem (shadcn/ui, React Router, etc.)
- ⚠️ Handle sandbox restrictions (localStorage, form submission)
- ⚠️ Enforce maxTokens limits (200-3000)
- ⚠️ Prevent consecutive same-role messages in API calls
Critical Fixes:
- localStorage: Implement fallback to memory storage
- Forms: Replace
<form> with <div> + button onClick
- maxTokens: Never exceed 3000 (API returns HTTP 400)
- Messages: Merge emphasis into last user message to avoid consecutive roles
See: Q11 in references/developer-guide.md for complete implementation guide
Approach B: Rewrite to Alpine.js (Lightweight Alternative)
Convert component hierarchy to single HTML with Alpine.js reactive sections.
Assessment
- Identify existing resources (images, audio, fonts) - these will be reused via URLs
- Map React/Vue components to Alpine.js x-show pages
- List state variables (useState/Vuex → Alpine data)
- Inventory API calls (fetch → dzmm.completions/kv)
Resource Strategy (Critical)
- DO NOT recreate visual assets with CSS - use GitHub Raw URLs
- Collect all image/audio file URLs from original project
- Create resource manager object with base URL
- Use Google Fonts or existing font CDN links
- Goal: 100% visual fidelity, not approximate simulation
Structure Migration
- Convert component hierarchy to single HTML with x-show sections
- Convert state management:
useState → Alpine reactive data properties
useEffect → Alpine x-init or watchers
props → Alpine function parameters or computed properties
- Convert event handlers:
onClick={fn} → @click="fn"
API Migration
- Replace
fetch('/api/chat') with dzmm.completions()
- Convert localStorage to
dzmm.kv operations (or safe storage wrapper)
- Add
dzmm:ready event waiting
- Implement streaming callbacks if needed
Feature Additions (from yoshiwara-chronicles patterns)
- Add message management (reroll, edit, delete)
- Implement rich text rendering with placeholder technique
- Add multi-opening system if applicable
- Implement modular prompt system
- Add responsive mobile optimizations
Testing and Refinement
- Verify all resources load correctly (images, audio)
- Test DZMM API initialization
- Check mobile responsiveness (375px, 768px, 1920px)
- Validate state persistence with KV storage
- Test on actual DZMM platform (dev and production modes)
Comparison:
| Factor |
React + Vite |
Alpine.js |
| Type Safety |
✅ TypeScript |
❌ Plain JS |
| Dev Experience |
✅ Hot reload |
⚠️ Manual refresh |
| Ecosystem |
✅ Rich (shadcn/ui, etc.) |
⚠️ Limited |
| File Size |
⚠️ Larger (900KB+) |
✅ Smaller (<100KB) |
| Maintenance |
✅ Component-based |
⚠️ Single file can get messy |
| Learning Curve |
⚠️ Steeper for beginners |
✅ Easier to learn |
Model Selection Guide
Choose the appropriate DZMM AI model based on task complexity:
Standard Models (32K context):
- nalang-turbo-0826: Fastest, most economical. Best for simple tasks, quick responses (maxTokens: 1000-1500)
- nalang-medium-0826: Balanced performance. Good for moderate complexity tasks (maxTokens: 1500-2000)
- nalang-max-0826: Enhanced reasoning and strategy. Best for game AI, complex rules, stable output (maxTokens: 2000-3000)
- nalang-xl-0826: Largest model, strongest comprehension. For complex dialogues, long-form content (maxTokens: 2000-3000)
16K Models (faster, shorter context):
- nalang-max-0826-16k: Fast version of max model with 16K context window
- nalang-xl-0826-16k: Fast version of XL model with 16K context window
Legacy Model Names (may still work in some examples):
nalang-xl → likely maps to nalang-xl-0826
nalang-xl-10 → likely maps to nalang-xl-0826
Selection Tips:
- For prototyping: Start with
nalang-turbo-0826 for speed
- For production games: Use
nalang-max-0826 or nalang-xl-0826 for quality
- For short conversations: Try 16K variants for faster response
- All models support maxTokens range: 200-3000 (default 1000)
Resources
references/developer-guide.md
Complete DZMM platform developer guide covering:
- Platform introduction and tech stack
- Core API documentation with examples
- Three architecture patterns with full implementations
- Best practices for prompts, error handling, performance
- Comprehensive FAQ and troubleshooting
- Design philosophy and logging strategies
Load this reference when users need in-depth understanding of DZMM concepts, detailed API specifications, or comprehensive architecture guidance.
references/code-snippets.md
Organized library of reusable code patterns:
- 10 categories covering all common DZMM tasks
- Copy-paste ready snippets
- Complete with comments and usage examples
- Tested and production-ready
Load this reference when implementing specific features or need quick access to proven code patterns.
assets/examples/
Seven complete, working DZMM applications:
小红书文案.html (~15KB) - Stateless Generator
- Minimal architecture for quick prototyping
- Markdown rendering with marked.js integration
- Input validation with character count
- Modern gradient UI design
- Single-purpose content generation
- Best for: Quick tools, text generators, one-shot tasks
恋爱游戏.html (~35KB) - State Management Game
- Multi-variable state system (affection, mood, time, relationship)
- Structured AI output with ###STATE/###END parsing
- Configuration UI for game initialization
- Dynamic UI updates (progress bars, backgrounds)
- Complete save/load system with state filtering
- Responsive mobile design with extensive @media queries
- Best for: Dating sims, stat-based games, visual novels
horror-story.html (29KB) - Effect System
- Comprehensive effect system (lights, sounds, particles, visual effects)
- AI-controlled browser environment
- "Fourth wall breaking" implementation
- Web Audio API sound generation
- Canvas particle system
- Best for: Immersive experiences, atmospheric games
dungeon-adventure.html (41KB) - Turn-based Game
- Turn-based game with state management
- Character stats and inventory system
- Multi-turn AI dialogue with context
- JSON parsing for game state updates
- Best for: RPG games, adventure games
neon-gomoku.html (24KB) - Board Game
- AI opponent for board games
- Game logic and win detection
- Structured AI instruction parsing
- Visual game board rendering
- Best for: Strategy games, puzzle games
贴吧.html (26KB) - Content Platform
- Two-tier caching architecture
- List + detail content loading
- Concurrent request locking
- XML parsing for content structure
- Best for: Forums, content communities, social platforms
yoshiwara-chronicles-dzmm.html (84KB) - Complete Visual Novel System (Alpine.js) ⭐
- Multi-opening system with dynamic scene switching (Night Chapter, Day Chapter)
- Rich text rendering with placeholder technique (handles nested options, dialogue quotes, italics)
- Message management (reroll/regenerate, edit, delete with context preservation)
- Multi-slot save system (3 slots with preview extraction)
- Modular prompt engineering (XML-structured with main + character + guidance + emphasis sections)
- Advanced prompt techniques (
<last_input> emphasis, token optimization, format rules at bottom)
- Streaming AI responses with real-time display and auto-scroll
- Responsive mobile design (compressed navigation, flex-wrap buttons, adaptive spacing)
- Resource reuse pattern (GitHub Raw URLs for background images)
- Complete implementation of all visual novel patterns documented in this skill
- Best for: Visual novels, interactive fiction, narrative-driven games, Galgames
- Reference project: Based on 54-commit development of yoshiwara-chronicles
yoshiwara-chronicles-react (893KB, gzip: 473KB) - React Multi-Component Version 🚀
- Same project as #7, but built with React + TypeScript + Vite
- Component-based architecture: 30+ modular TypeScript/TSX files
- Professional codebase structure: services/lib/contexts/types layered design
- Complete DZMM API encapsulation with TypeScript type safety
- Sandbox compatibility layer: localStorage fallback, form submission handling
- Automatic API parameter validation: maxTokens range checking, consecutive role detection
- Production-ready error handling: Detailed logging, validation, graceful degradation
- Modern build pipeline: Vite + vite-plugin-singlefile (hot reload → single HTML)
- All features from Alpine.js version plus improved maintainability
- Best for: Large projects (>5000 lines), team collaboration, TypeScript projects
- Full source code: https://github.com/waylon256yhw/yoshiwara-chronicles/tree/dzmm-version
- Documentation:
assets/react-examples/yoshiwara-chronicles-react.md
- Key learning: Q11 (React/Vue migration guide), Q12 (backend integration templates)
Use these as starting templates or reference implementations for specific features.
Best Practices
- Always Initialize Properly
- Wait for
dzmm:ready event before any API call
- Initialize AudioContext on first user interaction (browser requirement)
- Show loading state during initialization
- Use dual detection: check
window.dzmm directly + event listener + timeout recheck
- Example pattern:
if (window.dzmm) {
this.dzmmReady = true;
} else {
window.addEventListener('dzmm:ready', () => { this.dzmmReady = true; });
setTimeout(() => {
if (!this.dzmmReady && window.dzmm) this.dzmmReady = true;
}, 2000);
}
1.5. ⚠️ Resource Reuse Strategy (Critical for Migrations)
- Golden Rule: If resources already exist, ALWAYS reference them by URL instead of recreating with code
- Use GitHub Raw URLs for images, audio, fonts from existing projects
- Never simulate textures with CSS gradients/shadows - use real image files
- 100% visual fidelity vs ≤60% with code simulation
- Benefits: Perfect restoration, time savings, smaller file size, easier maintenance
- Example:
<!-- ✅ CORRECT: Direct URL reference -->
<div style="background-image: url('https://raw.githubusercontent.com/user/repo/main/public/image.jpg')">
<!-- ❌ WRONG: CSS simulation of textures -->
<div style="background: linear-gradient(...); box-shadow: inset ...">
- Resource Manager Pattern:
const ASSET_BASE = 'https://raw.githubusercontent.com/user/repo/main/public';
const assets = {
backgrounds: { welcome: `${ASSET_BASE}/bg1.jpg` },
music: [{ src: `${ASSET_BASE}/music/track1.mp3` }]
};
- Migration Checklist: All images referenced? All audio referenced? Fonts from CDN? Any simulated textures replaceable?
Manage Conversation History
- Keep only last 10-20 messages to prevent token overflow
- Truncate individual messages to reasonable lengths (≤2000 chars)
- Use system prompts as first user message, not
role: 'system'
Handle Errors Gracefully
- Wrap all API calls in try-catch blocks
- Provide user-friendly error messages
- Log structured context for debugging (model, message count, error)
Optimize Performance
- Implement debouncing for user input
- Use two-tier caching for content-heavy apps
- Add concurrent request locks to prevent duplicate calls
- Clean up resources (audio nodes, animation frames, particles)
Design Clear Prompts with Format Control
- Use structured output formats (###STATE/###END, XML, or JSON)
- Provide both correct AND incorrect examples in prompts
- Explicitly warn AI what NOT to do (e.g., "❌ Don't put dialogue before STATE")
- Use clear delimiters and validate parsing
- Example from 恋爱游戏.html:
【正确示例】
用户:早上好
回复:
###STATE
{"affection":52,"mood":"高兴"}
###END
早上好呀!
【错误示例 - 绝对不要这样】
❌ 把对话写在STATE前面
❌ 不写STATE
Smart State Persistence
- Exclude temporary state from saves (disabled, loading, input)
- Only save game-critical data
- Use Object.assign() for clean state restoration
- Example pattern:
const excludeKeys = ['disabled', 'loading', 'input'];
const saveData = {};
Object.keys(this).forEach(key => {
if (!excludeKeys.includes(key) && typeof this[key] !== 'function') {
saveData[key] = this[key];
}
});
Responsive Design for Mobile
- Design for touch interactions first
- Use extensive @media queries for layout adjustments
- Test text readability on small screens (14-16px minimum)
- Ensure buttons are finger-friendly (min 44px touch targets)
- Hide non-essential labels on mobile to save space
Configuration UI Pattern
- Provide initial setup screen for user customization
- Include game/app instructions in setup
- Validate inputs before allowing start
- Example: name input, difficulty selection, initial parameters
Markdown Integration (for content generators)
- Load marked.js before Alpine.js
- Configure marked options once:
marked.setOptions({ breaks: true, gfm: true })
- Render with
x-html="renderMarkdown(content)"
- Style rendered HTML with specific CSS selectors (
.post-body h1, .post-body p, etc.)
Version Your Data
- Use versioned keys for KV storage (e.g.,
app_state_v1)
- Include timestamps for cache expiry checks
- Document data schema changes
Use Chat API for Branching Narratives
- Perfect for Galgame save/load systems with multiple routes
- Store each player choice and story branch as separate messages
- Use
parentId to create branching storylines at decision points
- Track current position with last message ID
- Load history with
timeline() for save/load functionality
- Example pattern:
// Save choice and branch
const result = await dzmm.chat.insert(currentNodeId, [
{ role: 'user', content: playerChoice },
{ role: 'assistant', content: storyResponse }
]);
currentNodeId = result.ids[result.ids.length - 1];
localStorage.setItem('savePoint', currentNodeId);
// Load save
const timeline = await dzmm.chat.timeline(savedNodeId);
const history = await dzmm.chat.list(timeline);
Respect API Limits
- Concurrent requests: Keep ≤3 simultaneous API calls
- Call frequency: Add debouncing to avoid rapid-fire requests
- Message size: Limit individual messages to reasonable lengths
- Development vs Production: Remember data persistence differs between modes
- Use loading states to prevent duplicate requests during processing
Rich Text Rendering with Placeholder Technique
- Problem: Nested structures (like
<options> inside AI responses) conflict with regex replacements
- Solution: Extract complex structures → process simple text → restore structures
- Pattern:
renderRichText(text) {
// 1. Extract options blocks with placeholders
const optionsMap = [];
let result = text.replace(/<options>([\s\S]*?)<\/options>/g, (match, content) => {
const placeholder = '___OPTIONS_' + optionsMap.length + '___';
optionsMap.push(content);
return placeholder;
});
// 2. Process regular text (italics, quotes, line breaks)
result = result
.replace(/\*([^*]+)\*/g, '<em>$1</em>')
.replace(/「([^」]+)」/g, '<span class="dialogue">「$1」</span>')
.replace(/\n/g, '<br>');
// 3. Restore options as HTML buttons
optionsMap.forEach((content, i) => {
const buttons = /* generate buttons from content */;
result = result.replace('___OPTIONS_' + i + '___', buttons);
});
return result;
}
- Use data attributes to avoid HTML quote conflicts:
<button data-option="${escaped}">
- Event delegation for dynamic buttons: Single click handler with
event.target.closest('[data-option]')
Message Management Features
- Reroll (Regenerate): Preserve context before target message, call API with same history
- Edit: Update user message, delete all subsequent messages, auto-trigger AI response
- Delete: Slice array to remove message and everything after it
- Key implementation details:
// Reroll: preserve context
const contextMessages = this.messages.slice(0, messageIndex);
// Edit: delete subsequent + auto-respond
this.messages = this.messages.slice(0, index + 1);
await this.getAIResponse(editedContent, false);
// Delete: with confirmation
if (confirm('Delete this and all following messages?')) {
this.messages = this.messages.slice(0, index);
}
- Use
editingIndex and rerollingIndex for UI state tracking
- Always clean
<options> tags from history to prevent AI format inertia
Multi-Opening Scene System
- Configuration: Array of opening objects
[{ id: 'night', label: '夜之章' }]
- Content library: Object mapping
{ night: 'content...', day: 'content...' }
- State management: Track
selectedOpening and previousOpening for cancel support
- Pattern:
changeOpening() {
if (this.messages.length > 1) {
if (!confirm('Switch will clear conversation. Continue?')) {
this.selectedOpening = this.previousOpening; // Revert
return;
}
}
this.previousOpening = this.selectedOpening;
this.messages = [];
this.messages.push({ role: 'assistant', content: this.getOpeningGreeting() });
}
- Extensible design: Easy to add new openings to array and content object
Responsive Mobile Design
- Top navigation: Use
flex-col md:flex-row for vertical (mobile) → horizontal (desktop)
- Button overflow: Add
flex-wrap and gap-1.5 to allow wrapping
- Text scaling:
text-xs md:text-sm for responsive font sizes
- Decorative elements: Hide on mobile with
hidden md:block
- Compressed spacing: Reduce padding/margin on mobile (e.g.,
py-4 → py-1.5)
- Fixed layout: Use
h-screen + flex-1 + flex-shrink-0 for header/content/footer
- Touch targets: Minimum 44px for buttons on mobile
- Whitespace control:
whitespace-nowrap to prevent button text wrapping
- Test at: 375px (iPhone SE), 768px (iPad), 1920px (Desktop)
Advanced Prompt Engineering
- XML Structure: Use tags like
<时代背景>, <创作美学>, <回复规范> for clear hierarchy
- Emphasis section: Put critical format rules at BOTTOM of message array (AI remembers recent content better)
- Message construction:
const messages = [
{ role: 'user', content: systemPrompt }, // Top: World/character setting
...cleanedHistory, // Middle: Conversation
{ role: 'user', content: getEmphasis() } // Bottom: Format rules (strongest)
];
- wrapper: Emphasize most recent user input
for (let i = cleanedMessages.length - 1; i >= 0; i--) {
if (cleanedMessages[i].role === 'user') {
cleanedMessages[i].content = `<last_input>\n${cleanedMessages[i].content}\n</last_input>`;
break;
}
}
- Token optimization: Simplify repeated tags (
<option> → <op> saves ~12 chars × 3)
- Clean history: Remove
<options> blocks from history to prevent AI format inertia
KV Storage Advanced Patterns
- Multi-slot saves with preview:
// Save: Full game state
await dzmm.kv.put(`game_slot_${slotNumber}`, JSON.stringify({
character, messages, timestamp, ...gameState
}));
// Preview: Extract metadata only (don't load full messages)
const data = JSON.parse(result.value);
return {
characterName: data.character.name,
messageCount: data.messages.length,
lastMessage: data.messages[messages.length-1].content.slice(0, 50),
timestamp: new Date(data.timestamp).toLocaleString()
};
- Batch operations: Use
Promise.all() for parallel KV operations
- Versioning: Use keys like
${appName}_v2_${dataKey} for schema upgrades
- Chunking: Split large data if hitting size limits
- Caching with expiry: Store
{ value, expiresAt } and check timestamp on load
Streaming AI Response Optimization
- Real-time display: Update UI in callback with
done === false
- Placeholder message: Add empty message to array, update content in callback
- Auto-scroll: Use
$nextTick() to ensure DOM updated before scrolling
- Error recovery: Remove placeholder message if API fails
- Retry logic: Implement exponential backoff (1s, 2s, 4s) for failed requests
- Pattern:
this.messages.push({ role: 'assistant', content: '' });
const idx = this.messages.length - 1;
await dzmm.completions({ /* ... */ }, (content, done) => {
this.messages[idx].content = content;
if (done) {
this.$nextTick(() => scrollToBottom());
}
});
Writing Style Note
Follow DZMM conventions:
- Use imperative/infinitive verb forms in instructions
- Maintain objective, instructional tone
- Provide concrete examples with actual code
- Reference bundled resources explicitly
- Keep explanations concise and actionable
1---2name: dzmm-builder3description: Comprehensive skill for building, debugging, and optimizing DZMM.AI applications. Use this skill when users request creating interactive web apps on the DZMM platform, need guidance on DZMM API usage, or require help with existing DZMM applications. Covers AI-driven chatbots, visual novels, dating sims, content generators, RPG games, content platforms, and visual effect systems. Includes state management games, message management (reroll/edit/delete), multi-opening systems, rich text rendering, modular prompt engineering, resource reuse strategies, React/Vue to DZMM migration, and responsive mobile design.4---5
6# DZMM Builder
7
8## Overview
9
10Build AI-driven interactive web applications on the DZMM.AI platform using specialized knowledge, complete examples, and reusable code patterns. This skill provides comprehensive support for creating single-file HTML applications that leverage streaming AI conversations, cloud key-value storage, and browser effect systems.
11
12## When to Use This Skill
13
14Invoke this skill when users:
15- Request creating a new DZMM application ("Build me a DZMM chatbot", "Create an AI story generator", "Make a dating sim game", "Build a social media content generator", "Create a visual novel", "Build an interactive fiction game")
16- Ask questions about DZMM API usage ("How do I use dzmm.completions?", "How does KV storage work?", "How to parse structured AI output?", "How to use chat API for branching stories?", "How to implement streaming AI responses?")
17- Need help debugging DZMM applications ("My DZMM app returns 400 error", "AI responses are not displaying", "State not persisting", "DZMM API not initializing")
18- Want to optimize existing DZMM apps (performance, user experience, architecture improvements, mobile responsiveness, reduce token usage)
19- Ask about "fourth wall breaking" effects or browser control from AI
20- Need guidance on state management in games (stats, mood, relationships, dynamic UI)
21- Want to integrate Markdown rendering or rich text formatting (nested structures, dialogue quotes, options buttons)
22- Request configuration/setup UI for applications
23- Need branching narrative systems (Galgame save/load, multi-route stories, choice history tracking)
24- Ask about available models and their performance characteristics
25- **Request message management features** ("How to add reroll/regenerate?", "How to let users edit messages?", "How to delete conversation branches?")
26- **Want multi-opening/multi-scenario systems** ("How to add multiple starting scenes?", "How to switch between different story routes?")
27- **Need help migrating from React/Vue to DZMM** ("How to migrate my app to DZMM?", "What's the DZMM equivalent of useState?", "Can I use React/TypeScript with DZMM?", "How to build DZMM apps with modern frameworks?", "vite-plugin-singlefile for DZMM", "My DZMM app has sandbox errors", "Form submission blocked in DZMM", "localStorage not working in DZMM", "HTTP 400 error with DZMM API", "maxTokens limit exceeded")
28- **Ask about resource management** ("How to load images/audio in DZMM?", "Should I use URLs or embed resources?")
29
30## Core Capabilities
31
32### 1. Application Generation
33
34Generate complete, single-file HTML applications for the DZMM platform based on user requirements.
35
36**Approach:**
371. Clarify the application type and core features
382. Select an appropriate architecture pattern (stateless generator, stateful dialogue, or layered cache platform)
393. Use example templates from `assets/examples/` as foundation
404. Customize for specific requirements
415. Test the complete flow (initialization → AI call → display)
42
43**Architecture Patterns:**
44
45**Stateless Generator** - For one-shot content generation:
46- Example: Translator, text summarizer, content creator, social media post generator
47- No conversation history or state persistence
48- Simplest architecture, fastest development
49- Optional: Integrate marked.js for Markdown rendering
50- Reference: See `assets/examples/小红书文案.html` for minimal implementation
51- Code snippets: `references/code-snippets.md` section 2
52
53**State Management Game** - For interactive games with dynamic variables:
54- Example: Dating sims, RPG games, decision-based narratives
55- Multiple state variables (stats, mood, time, relationships)
56- Structured AI output parsing (###STATE/###END format)
57- Configuration UI for game initialization
58- State-driven UI updates (progress bars, backgrounds, effects)
59- Auto-save with KV storage
60- Reference: See `assets/examples/恋爱游戏.html` for complete implementation
61
62**Stateful Dialogue System** - For multi-turn conversations:
63- Example: Chatbots, interactive stories, Q&A systems
64- Maintains conversation history
65- Uses Alpine.store for state management
66- Persists state with KV storage
67- Reference: See `assets/examples/dungeon-adventure.html` and `assets/examples/horror-story.html`
68
69**Layered Cache Platform** - For content communities:
70- Example: Forums, story libraries, content platforms
71- Two-tier caching (list cache + detail cache)
72- On-demand content generation
73- Concurrent request locking
74- Reference: See `assets/examples/贴吧.html` for full implementation
75
76**Visual Novel / Galgame System** - For narrative-driven interactive fiction:
77- Example: Visual novels, interactive stories, AI-driven narrative games
78- Multi-opening scene system with dynamic switching
79- Rich text rendering with placeholder technique (handles nested structures)
80- Message management (reroll, edit, delete with context preservation)
81- Multi-slot save/load system with preview
82- Modular prompt system (main prompt + character + guidance + emphasis)
83- Responsive mobile design with compressed UI
84- Reference: See yoshiwara-chronicles project for complete implementation
85- Key features: XML-structured prompts, <last_input> emphasis, streaming AI responses
86
87### 2. API Integration Guidance
88
89Provide detailed guidance on using DZMM's specialized APIs.
90
91**Core APIs:**
92
93**window.dzmm.completions()** - Streaming AI generation:
94```javascript
95await window.dzmm.completions(
96 {
97 model: 'nalang-turbo-0826' | 'nalang-medium-0826' |
98 'nalang-max-0826' | 'nalang-xl-0826' |
99 'nalang-max-0826-16k' | 'nalang-xl-0826-16k',
100 messages: [{ role: 'user' | 'assistant', content: string }],
101 maxTokens: number // Optional, 200-3000, default 1000
102 },
103 (newContent, done) => {
104 // newContent is cumulative, not incremental
105 // done is true when generation completes
106 }
107);
108```
109
110**window.dzmm.chat** - Tree-structured conversation storage (⭐ NEW):
111```javascript
112// Insert messages into conversation tree (supports branching storylines)
113const result = await window.dzmm.chat.insert(parentId, [
114 { role: 'user', content: 'Player choice' },
115 { role: 'assistant', content: 'Story response' }
116]);
117const newMessageIds = result.ids; // Array of new message IDs
118
119// Get message details (with parent/children relationships)
120const messages = await window.dzmm.chat.list(['msg-123', 'msg-124']);
121// Returns: [{ id, role, content, timestamp, parent, children }, ...]
122
123// Get complete conversation timeline
124const timeline = await window.dzmm.chat.timeline(messageId);
125const fullHistory = await window.dzmm.chat.list(timeline);
126```
127**Use cases:** Galgame save/load systems, branching narratives, multi-route stories, interactive fiction with choice history.
128
129**window.dzmm.kv** - Cloud key-value storage:
130```javascript
131// Save (auto-serializes objects)
132await window.dzmm.kv.put(key, value);
133
134// Load
135const result = await window.dzmm.kv.get(key);
136if (result.value) {
137 const data = result.value;
138}
139
140// Delete
141await window.dzmm.kv.delete(key);
142```
143**Limits:** Keys ≤256 chars, values ≤1MB recommended. Development mode: data lost on refresh. Production: persistent.
144
145**Critical Requirements:**
146- Must wait for `dzmm:ready` event before any API calls
147- Only `user` and `assistant` roles supported (no `system`)
148- Limit conversation history to ≤20 messages to avoid token overflow
149- maxTokens range: 200-3000, default 1000
150- Concurrent requests: ≤3 recommended
151- Use versioned keys for KV storage (e.g., `app_state_v1`)
152
153**Reference:** Consult `references/developer-guide.md` sections 2-3 for complete API documentation and `references/code-snippets.md` sections 1-3 for ready-to-use code patterns.
154
155### 3. Effect System Implementation
156
157Implement "fourth wall breaking" effects where AI can control the user's browser environment.
158
159**Effect Categories:**
160
161**Visual Effects:**
162- Light control (dimming, darkness, flickering)
163- Screen shake (low/medium/high intensity)
164- Glitch effects
165- Color filters (blood, blur, etc.)
166
167**Audio Effects:**
168- Programmatic sound generation (beeps, drones, heartbeats)
169- Web Audio API without external files
170- Ambient and tension-building sounds
171
172**Dynamic Elements:**
173- Particle systems (dust, blood, explosions)
174- Jumpscare popups
175- Element manipulation
176
177**Implementation Pattern:**
178
179```javascript
180// 1. AI outputs special instructions
181const aiPrompt = `When the user says "turn off lights", output:
182###EFFECT
183{"action":"lights","params":{"state":"off"}}
184###END`;
185
186// 2. Parse and execute
187const effectMatch = content.match(/###EFFECT\s*({[\s\S]*?})\s*###END/);
188if (effectMatch) {
189 const effect = JSON.parse(effectMatch[1]);
190 executeEffect(effect);
191 // Remove instruction from display
192 content = content.replace(/###EFFECT[\s\S]*?###END/, '').trim();
193}
194
195// 3. Effect executor
196function executeEffect(effect) {
197 switch(effect.action) {
198 case 'lights':
199 document.body.classList.add(`lights-${effect.params.state}`);
200 break;
201 // ... more effects
202 }
203}
204```
205
206**Reference:** See `assets/examples/horror-story.html` for complete effect system with CSS animations, Web Audio, and Canvas particles.
207
208### 4. Debugging and Optimization
209
210Diagnose and fix common DZMM application issues.
211
212**Common Issues:**
213
214**HTTP 400 Errors:**
215- Cause: Using `role: 'system'` in messages (not supported)
216- Fix: Convert system prompts to first `user` message or maintain in frontend variables
217- Cause: Messages array contains undefined/null values
218- Fix: Validate and sanitize messages before sending
219
220**No Response from AI:**
221- Cause: API not ready yet
222- Fix: Ensure `dzmm:ready` event is awaited before any API calls
223
224**Context Overflow:**
225- Cause: Too many messages or overly long content
226- Fix: Slice messages array to last 10-20 items, truncate individual messages to 2000 chars
227
228**State Not Persisting:**
229- Cause: KV key naming conflicts or version mismatch
230- Fix: Use versioned keys with unique identifiers
231
232**Form Submission Blocked (Public Release Only):**
233- Cause: DZMM public release uses iframe sandbox without `allow-forms` permission
234- Error: `Blocked form submission to '' because the form's frame is sandboxed`
235- Fix: Replace `<form>` with `<div>`, use `@click` instead of `@submit.prevent`
236- Example:
237 ```html
238 <!-- ❌ WRONG: Will fail in public release -->
239 <form @submit.prevent="handleSubmit()">
240 <button type="submit">Submit</button>
241 </form>
242
243 <!-- ✅ CORRECT: Works in all environments -->
244 <div>
245 <button type="button" @click="handleSubmit()">Submit</button>
246 </div>
247 ```
248- Note: This only affects public release, not development mode or workshop preview
249
250**Performance Optimization:**
251- Debounce user input to reduce API calls
252- Implement two-tier caching for content-heavy apps
253- Use concurrent request locks to prevent duplicate API calls
254- Limit conversation history proactively
255
256**Reference:** Consult `references/developer-guide.md` section "常见问题" for comprehensive troubleshooting guide.
257
258### 5. Code Patterns and Snippets
259
260Provide reusable, production-ready code patterns for common DZMM tasks.
261
262**Available Patterns:**
2631. Initialization and API readiness (dual detection with timeout)
2642. AI completions (basic, multi-turn, streaming with real-time display)
2653. KV storage operations (save, load, delete, multi-slot, batch operations)
2664. Chat API operations (branching narratives, save/load, timeline retrieval)
2675. Instruction parsing systems (JSON, XML, ###STATE format)
2686. Alpine.js state management (local and global stores)
2697. Visual effect systems (CSS animations, particles, audio)
2708. Error handling and structured logging (retry with exponential backoff)
2719. Utility functions (debounce, sanitize, scroll control)
27210. Prompt templates (structured output, XML hierarchy, emphasis sections)
27311. Complete application templates
27412. **Rich text rendering** (placeholder technique for nested structures)
27513. **Message management** (reroll, edit, delete with context preservation)
27614. **Multi-opening system** (scene switching with state management)
27715. **Resource management** (URL-based asset loading, preloading)
27816. **Modular prompt system** (main + character + guidance + emphasis)
27917. **Responsive layout patterns** (mobile-first with Tailwind breakpoints)
280
281**Usage:** Reference `references/code-snippets.md` for copy-paste ready code snippets organized by category. All snippets are tested and can be used directly or with minimal modifications.
282
283**New Visual Novel Patterns (from yoshiwara-chronicles):**
284- Rich text parser with placeholder technique
285- Message reroll/edit/delete functions
286- Opening scene switcher with confirmation
287- Multi-slot save system with preview extraction
288- Streaming AI response with auto-scroll
289- XML-structured prompt builder
290- Resource manager for external assets
291
292## Workflow Guide
293
294### For New Applications
295
2961. **Clarify Requirements**
297 - Determine application type (chatbot, game, content platform, etc.)
298 - Identify core features and interactions
299 - Choose architecture pattern
300
3012. **Select Template**
302 - Browse `assets/examples/` for similar applications:
303 - `小红书文案.html` - Simple content generator, Markdown rendering
304 - `恋爱游戏.html` - Dating sim, multi-variable state management
305 - `horror-story.html` - Effect system, immersive experience
306 - `dungeon-adventure.html` - Turn-based game, state management
307 - `neon-gomoku.html` - AI opponent, game logic
308 - `贴吧.html` - Content platform, two-tier caching
309
3103. **Build Application**
311 - Start with HTML structure and Alpine.js integration
312 - Implement DZMM API initialization (wait for `dzmm:ready`)
313 - Add AI completions with appropriate model selection
314 - Implement state management and KV storage if needed
315 - Add visual effects or advanced features as required
316
3174. **Test and Refine**
318 - Test initialization and API readiness
319 - Verify AI responses and parsing
320 - Check state persistence across page reloads
321 - Optimize performance (history limits, debouncing)
322
323### For Debugging Existing Applications
324
3251. **Identify the Issue**
326 - Review error messages and console logs
327 - Check network requests in browser DevTools
328 - Verify API readiness timing
329
3302. **Diagnose Root Cause**
331 - Cross-reference with common issues in `references/developer-guide.md`
332 - Check message format compliance (only `user`/`assistant`)
333 - Validate conversation history length
334
3353. **Apply Fix**
336 - Use code patterns from `references/code-snippets.md`
337 - Add error handling if missing
338 - Implement validation for user inputs and API responses
339
3404. **Optimize**
341 - Add performance improvements (caching, debouncing)
342 - Improve user experience (loading states, error messages)
343 - Enhance code maintainability (structured logging, modularity)
344
345### For Migrating React/Vue Applications to DZMM
346
347**Two Approaches Available:**
348
349#### Approach A: Keep React/Vue Framework (Recommended for Large Projects)
350
351Use modern build tools to maintain component-based development, then bundle to single HTML.
352
353**Tech Stack**: React + TypeScript + Vite + vite-plugin-singlefile
354
355**Workflow**:
3561. **Setup**: `npm create vite@latest my-app -- --template react-ts`
3572. **Install Plugin**: `npm install -D vite-plugin-singlefile`
3583. **Configure Vite**: Add plugin for single-file build mode
3594. **Develop**: Keep existing React components structure
3605. **Build**: `npm run build:single` → generates standalone HTML
3616. **Deploy**: Upload to DZMM platform
362
363**Key Considerations**:
364- ✅ Keep TypeScript type safety and component modularity
365- ✅ Hot reload during development
366- ✅ Rich ecosystem (shadcn/ui, React Router, etc.)
367- ⚠️ Handle sandbox restrictions (localStorage, form submission)
368- ⚠️ Enforce maxTokens limits (200-3000)
369- ⚠️ Prevent consecutive same-role messages in API calls
370
371**Critical Fixes**:
372- **localStorage**: Implement fallback to memory storage
373- **Forms**: Replace `<form>` with `<div>` + button onClick
374- **maxTokens**: Never exceed 3000 (API returns HTTP 400)
375- **Messages**: Merge emphasis into last user message to avoid consecutive roles
376
377**See**: Q11 in `references/developer-guide.md` for complete implementation guide
378
379#### Approach B: Rewrite to Alpine.js (Lightweight Alternative)
380
381Convert component hierarchy to single HTML with Alpine.js reactive sections.
382
3831. **Assessment**
384 - Identify existing resources (images, audio, fonts) - **these will be reused via URLs**
385 - Map React/Vue components to Alpine.js x-show pages
386 - List state variables (useState/Vuex → Alpine data)
387 - Inventory API calls (fetch → dzmm.completions/kv)
388
3892. **Resource Strategy (Critical)**
390 - **DO NOT recreate visual assets with CSS** - use GitHub Raw URLs
391 - Collect all image/audio file URLs from original project
392 - Create resource manager object with base URL
393 - Use Google Fonts or existing font CDN links
394 - **Goal**: 100% visual fidelity, not approximate simulation
395
3963. **Structure Migration**
397 - Convert component hierarchy to single HTML with x-show sections
398 - Convert state management:
399 - `useState` → Alpine reactive data properties
400 - `useEffect` → Alpine `x-init` or watchers
401 - `props` → Alpine function parameters or computed properties
402 - Convert event handlers: `onClick={fn}` → `@click="fn"`
403
4044. **API Migration**
405 - Replace `fetch('/api/chat')` with `dzmm.completions()`
406 - Convert localStorage to `dzmm.kv` operations (or safe storage wrapper)
407 - Add `dzmm:ready` event waiting
408 - Implement streaming callbacks if needed
409
4105. **Feature Additions (from yoshiwara-chronicles patterns)**
411 - Add message management (reroll, edit, delete)
412 - Implement rich text rendering with placeholder technique
413 - Add multi-opening system if applicable
414 - Implement modular prompt system
415 - Add responsive mobile optimizations
416
4176. **Testing and Refinement**
418 - Verify all resources load correctly (images, audio)
419 - Test DZMM API initialization
420 - Check mobile responsiveness (375px, 768px, 1920px)
421 - Validate state persistence with KV storage
422 - Test on actual DZMM platform (dev and production modes)
423
424**Comparison**:
425| Factor | React + Vite | Alpine.js |
426|--------|--------------|-----------|
427| Type Safety | ✅ TypeScript | ❌ Plain JS |
428| Dev Experience | ✅ Hot reload | ⚠️ Manual refresh |
429| Ecosystem | ✅ Rich (shadcn/ui, etc.) | ⚠️ Limited |
430| File Size | ⚠️ Larger (900KB+) | ✅ Smaller (<100KB) |
431| Maintenance | ✅ Component-based | ⚠️ Single file can get messy |
432| Learning Curve | ⚠️ Steeper for beginners | ✅ Easier to learn |
433
434## Model Selection Guide
435
436Choose the appropriate DZMM AI model based on task complexity:
437
438**Standard Models (32K context):**
439- **nalang-turbo-0826**: Fastest, most economical. Best for simple tasks, quick responses (maxTokens: 1000-1500)
440- **nalang-medium-0826**: Balanced performance. Good for moderate complexity tasks (maxTokens: 1500-2000)
441- **nalang-max-0826**: Enhanced reasoning and strategy. Best for game AI, complex rules, stable output (maxTokens: 2000-3000)
442- **nalang-xl-0826**: Largest model, strongest comprehension. For complex dialogues, long-form content (maxTokens: 2000-3000)
443
444**16K Models (faster, shorter context):**
445- **nalang-max-0826-16k**: Fast version of max model with 16K context window
446- **nalang-xl-0826-16k**: Fast version of XL model with 16K context window
447
448**Legacy Model Names (may still work in some examples):**
449- `nalang-xl` → likely maps to `nalang-xl-0826`
450- `nalang-xl-10` → likely maps to `nalang-xl-0826`
451
452**Selection Tips:**
453- For prototyping: Start with `nalang-turbo-0826` for speed
454- For production games: Use `nalang-max-0826` or `nalang-xl-0826` for quality
455- For short conversations: Try 16K variants for faster response
456- All models support maxTokens range: 200-3000 (default 1000)
457
458## Resources
459
460### references/developer-guide.md
461Complete DZMM platform developer guide covering:
462- Platform introduction and tech stack
463- Core API documentation with examples
464- Three architecture patterns with full implementations
465- Best practices for prompts, error handling, performance
466- Comprehensive FAQ and troubleshooting
467- Design philosophy and logging strategies
468
469Load this reference when users need in-depth understanding of DZMM concepts, detailed API specifications, or comprehensive architecture guidance.
470
471### references/code-snippets.md
472Organized library of reusable code patterns:
473- 10 categories covering all common DZMM tasks
474- Copy-paste ready snippets
475- Complete with comments and usage examples
476- Tested and production-ready
477
478Load this reference when implementing specific features or need quick access to proven code patterns.
479
480### assets/examples/
481Seven complete, working DZMM applications:
482
4831. **小红书文案.html** (~15KB) - Stateless Generator
484 - Minimal architecture for quick prototyping
485 - Markdown rendering with marked.js integration
486 - Input validation with character count
487 - Modern gradient UI design
488 - Single-purpose content generation
489 - Best for: Quick tools, text generators, one-shot tasks
490
4912. **恋爱游戏.html** (~35KB) - State Management Game
492 - Multi-variable state system (affection, mood, time, relationship)
493 - Structured AI output with ###STATE/###END parsing
494 - Configuration UI for game initialization
495 - Dynamic UI updates (progress bars, backgrounds)
496 - Complete save/load system with state filtering
497 - Responsive mobile design with extensive @media queries
498 - Best for: Dating sims, stat-based games, visual novels
499
5003. **horror-story.html** (29KB) - Effect System
501 - Comprehensive effect system (lights, sounds, particles, visual effects)
502 - AI-controlled browser environment
503 - "Fourth wall breaking" implementation
504 - Web Audio API sound generation
505 - Canvas particle system
506 - Best for: Immersive experiences, atmospheric games
507
5084. **dungeon-adventure.html** (41KB) - Turn-based Game
509 - Turn-based game with state management
510 - Character stats and inventory system
511 - Multi-turn AI dialogue with context
512 - JSON parsing for game state updates
513 - Best for: RPG games, adventure games
514
5155. **neon-gomoku.html** (24KB) - Board Game
516 - AI opponent for board games
517 - Game logic and win detection
518 - Structured AI instruction parsing
519 - Visual game board rendering
520 - Best for: Strategy games, puzzle games
521
5226. **贴吧.html** (26KB) - Content Platform
523 - Two-tier caching architecture
524 - List + detail content loading
525 - Concurrent request locking
526 - XML parsing for content structure
527 - Best for: Forums, content communities, social platforms
528
5297. **yoshiwara-chronicles-dzmm.html** (84KB) - Complete Visual Novel System (Alpine.js) ⭐
530 - **Multi-opening system** with dynamic scene switching (Night Chapter, Day Chapter)
531 - **Rich text rendering** with placeholder technique (handles nested options, dialogue quotes, italics)
532 - **Message management** (reroll/regenerate, edit, delete with context preservation)
533 - **Multi-slot save system** (3 slots with preview extraction)
534 - **Modular prompt engineering** (XML-structured with main + character + guidance + emphasis sections)
535 - **Advanced prompt techniques** (`<last_input>` emphasis, token optimization, format rules at bottom)
536 - **Streaming AI responses** with real-time display and auto-scroll
537 - **Responsive mobile design** (compressed navigation, flex-wrap buttons, adaptive spacing)
538 - **Resource reuse pattern** (GitHub Raw URLs for background images)
539 - Complete implementation of all visual novel patterns documented in this skill
540 - Best for: Visual novels, interactive fiction, narrative-driven games, Galgames
541 - **Reference project**: Based on 54-commit development of yoshiwara-chronicles
542
5438. **yoshiwara-chronicles-react** (893KB, gzip: 473KB) - React Multi-Component Version 🚀
544 - **Same project as #7**, but built with **React + TypeScript + Vite**
545 - **Component-based architecture**: 30+ modular TypeScript/TSX files
546 - **Professional codebase structure**: services/lib/contexts/types layered design
547 - **Complete DZMM API encapsulation** with TypeScript type safety
548 - **Sandbox compatibility layer**: localStorage fallback, form submission handling
549 - **Automatic API parameter validation**: maxTokens range checking, consecutive role detection
550 - **Production-ready error handling**: Detailed logging, validation, graceful degradation
551 - **Modern build pipeline**: Vite + vite-plugin-singlefile (hot reload → single HTML)
552 - **All features from Alpine.js version** plus improved maintainability
553 - Best for: Large projects (>5000 lines), team collaboration, TypeScript projects
554 - **Full source code**: https://github.com/waylon256yhw/yoshiwara-chronicles/tree/dzmm-version
555 - **Documentation**: `assets/react-examples/yoshiwara-chronicles-react.md`
556 - **Key learning**: Q11 (React/Vue migration guide), Q12 (backend integration templates)
557
558Use these as starting templates or reference implementations for specific features.
559
560## Best Practices
561
5621. **Always Initialize Properly**
563 - Wait for `dzmm:ready` event before any API call
564 - Initialize AudioContext on first user interaction (browser requirement)
565 - Show loading state during initialization
566 - Use dual detection: check `window.dzmm` directly + event listener + timeout recheck
567 - Example pattern:
568 ```javascript
569 if (window.dzmm) {
570 this.dzmmReady = true;
571 } else {
572 window.addEventListener('dzmm:ready', () => { this.dzmmReady = true; });
573 setTimeout(() => {
574 if (!this.dzmmReady && window.dzmm) this.dzmmReady = true;
575 }, 2000);
576 }
577 ```
578
5791.5. **⚠️ Resource Reuse Strategy (Critical for Migrations)**
580 - **Golden Rule**: If resources already exist, ALWAYS reference them by URL instead of recreating with code
581 - **Use GitHub Raw URLs** for images, audio, fonts from existing projects
582 - **Never simulate textures** with CSS gradients/shadows - use real image files
583 - **100% visual fidelity** vs ≤60% with code simulation
584 - Benefits: Perfect restoration, time savings, smaller file size, easier maintenance
585 - Example:
586 ```html
587 <!-- ✅ CORRECT: Direct URL reference -->
588 <div style="background-image: url('https://raw.githubusercontent.com/user/repo/main/public/image.jpg')">
589
590 <!-- ❌ WRONG: CSS simulation of textures -->
591 <div style="background: linear-gradient(...); box-shadow: inset ...">
592 ```
593 - **Resource Manager Pattern**:
594 ```javascript
595 const ASSET_BASE = 'https://raw.githubusercontent.com/user/repo/main/public';
596 const assets = {
597 backgrounds: { welcome: `${ASSET_BASE}/bg1.jpg` },
598 music: [{ src: `${ASSET_BASE}/music/track1.mp3` }]
599 };
600 ```
601 - **Migration Checklist**: All images referenced? All audio referenced? Fonts from CDN? Any simulated textures replaceable?
602
6032. **Manage Conversation History**
604 - Keep only last 10-20 messages to prevent token overflow
605 - Truncate individual messages to reasonable lengths (≤2000 chars)
606 - Use system prompts as first user message, not `role: 'system'`
607
6083. **Handle Errors Gracefully**
609 - Wrap all API calls in try-catch blocks
610 - Provide user-friendly error messages
611 - Log structured context for debugging (model, message count, error)
612
6134. **Optimize Performance**
614 - Implement debouncing for user input
615 - Use two-tier caching for content-heavy apps
616 - Add concurrent request locks to prevent duplicate calls
617 - Clean up resources (audio nodes, animation frames, particles)
618
6195. **Design Clear Prompts with Format Control**
620 - Use structured output formats (###STATE/###END, XML, or JSON)
621 - **Provide both correct AND incorrect examples in prompts**
622 - Explicitly warn AI what NOT to do (e.g., "❌ Don't put dialogue before STATE")
623 - Use clear delimiters and validate parsing
624 - Example from 恋爱游戏.html:
625 ```javascript
626 【正确示例】
627 用户:早上好
628 回复:
629 ###STATE
630 {"affection":52,"mood":"高兴"}
631 ###END
632 早上好呀!
633
634 【错误示例 - 绝对不要这样】
635 ❌ 把对话写在STATE前面
636 ❌ 不写STATE
637 ```
638
6396. **Smart State Persistence**
640 - **Exclude temporary state** from saves (disabled, loading, input)
641 - Only save game-critical data
642 - Use Object.assign() for clean state restoration
643 - Example pattern:
644 ```javascript
645 const excludeKeys = ['disabled', 'loading', 'input'];
646 const saveData = {};
647 Object.keys(this).forEach(key => {
648 if (!excludeKeys.includes(key) && typeof this[key] !== 'function') {
649 saveData[key] = this[key];
650 }
651 });
652 ```
653
6547. **Responsive Design for Mobile**
655 - Design for touch interactions first
656 - Use extensive @media queries for layout adjustments
657 - Test text readability on small screens (14-16px minimum)
658 - Ensure buttons are finger-friendly (min 44px touch targets)
659 - Hide non-essential labels on mobile to save space
660
6618. **Configuration UI Pattern**
662 - Provide initial setup screen for user customization
663 - Include game/app instructions in setup
664 - Validate inputs before allowing start
665 - Example: name input, difficulty selection, initial parameters
666
6679. **Markdown Integration (for content generators)**
668 - Load marked.js before Alpine.js
669 - Configure marked options once: `marked.setOptions({ breaks: true, gfm: true })`
670 - Render with `x-html="renderMarkdown(content)"`
671 - Style rendered HTML with specific CSS selectors (`.post-body h1`, `.post-body p`, etc.)
672
67310. **Version Your Data**
674 - Use versioned keys for KV storage (e.g., `app_state_v1`)
675 - Include timestamps for cache expiry checks
676 - Document data schema changes
677
67811. **Use Chat API for Branching Narratives**
679 - Perfect for Galgame save/load systems with multiple routes
680 - Store each player choice and story branch as separate messages
681 - Use `parentId` to create branching storylines at decision points
682 - Track current position with last message ID
683 - Load history with `timeline()` for save/load functionality
684 - Example pattern:
685 ```javascript
686 // Save choice and branch
687 const result = await dzmm.chat.insert(currentNodeId, [
688 { role: 'user', content: playerChoice },
689 { role: 'assistant', content: storyResponse }
690 ]);
691 currentNodeId = result.ids[result.ids.length - 1];
692 localStorage.setItem('savePoint', currentNodeId);
693
694 // Load save
695 const timeline = await dzmm.chat.timeline(savedNodeId);
696 const history = await dzmm.chat.list(timeline);
697 ```
698
69912. **Respect API Limits**
700 - **Concurrent requests**: Keep ≤3 simultaneous API calls
701 - **Call frequency**: Add debouncing to avoid rapid-fire requests
702 - **Message size**: Limit individual messages to reasonable lengths
703 - **Development vs Production**: Remember data persistence differs between modes
704 - Use loading states to prevent duplicate requests during processing
705
70613. **Rich Text Rendering with Placeholder Technique**
707 - **Problem**: Nested structures (like `<options>` inside AI responses) conflict with regex replacements
708 - **Solution**: Extract complex structures → process simple text → restore structures
709 - **Pattern**:
710 ```javascript
711 renderRichText(text) {
712 // 1. Extract options blocks with placeholders
713 const optionsMap = [];
714 let result = text.replace(/<options>([\s\S]*?)<\/options>/g, (match, content) => {
715 const placeholder = '___OPTIONS_' + optionsMap.length + '___';
716 optionsMap.push(content);
717 return placeholder;
718 });
719
720 // 2. Process regular text (italics, quotes, line breaks)
721 result = result
722 .replace(/\*([^*]+)\*/g, '<em>$1</em>')
723 .replace(/「([^」]+)」/g, '<span class="dialogue">「$1」</span>')
724 .replace(/\n/g, '<br>');
725
726 // 3. Restore options as HTML buttons
727 optionsMap.forEach((content, i) => {
728 const buttons = /* generate buttons from content */;
729 result = result.replace('___OPTIONS_' + i + '___', buttons);
730 });
731 return result;
732 }
733 ```
734 - **Use data attributes** to avoid HTML quote conflicts: `<button data-option="${escaped}">`
735 - **Event delegation** for dynamic buttons: Single click handler with `event.target.closest('[data-option]')`
736
73714. **Message Management Features**
738 - **Reroll (Regenerate)**: Preserve context before target message, call API with same history
739 - **Edit**: Update user message, delete all subsequent messages, auto-trigger AI response
740 - **Delete**: Slice array to remove message and everything after it
741 - **Key implementation details**:
742 ```javascript
743 // Reroll: preserve context
744 const contextMessages = this.messages.slice(0, messageIndex);
745 // Edit: delete subsequent + auto-respond
746 this.messages = this.messages.slice(0, index + 1);
747 await this.getAIResponse(editedContent, false);
748 // Delete: with confirmation
749 if (confirm('Delete this and all following messages?')) {
750 this.messages = this.messages.slice(0, index);
751 }
752 ```
753 - Use `editingIndex` and `rerollingIndex` for UI state tracking
754 - Always clean `<options>` tags from history to prevent AI format inertia
755
75615. **Multi-Opening Scene System**
757 - **Configuration**: Array of opening objects `[{ id: 'night', label: '夜之章' }]`
758 - **Content library**: Object mapping `{ night: 'content...', day: 'content...' }`
759 - **State management**: Track `selectedOpening` and `previousOpening` for cancel support
760 - **Pattern**:
761 ```javascript
762 changeOpening() {
763 if (this.messages.length > 1) {
764 if (!confirm('Switch will clear conversation. Continue?')) {
765 this.selectedOpening = this.previousOpening; // Revert
766 return;
767 }
768 }
769 this.previousOpening = this.selectedOpening;
770 this.messages = [];
771 this.messages.push({ role: 'assistant', content: this.getOpeningGreeting() });
772 }
773 ```
774 - Extensible design: Easy to add new openings to array and content object
775
77616. **Responsive Mobile Design**
777 - **Top navigation**: Use `flex-col md:flex-row` for vertical (mobile) → horizontal (desktop)
778 - **Button overflow**: Add `flex-wrap` and `gap-1.5` to allow wrapping
779 - **Text scaling**: `text-xs md:text-sm` for responsive font sizes
780 - **Decorative elements**: Hide on mobile with `hidden md:block`
781 - **Compressed spacing**: Reduce padding/margin on mobile (e.g., `py-4 → py-1.5`)
782 - **Fixed layout**: Use `h-screen` + `flex-1` + `flex-shrink-0` for header/content/footer
783 - **Touch targets**: Minimum 44px for buttons on mobile
784 - **Whitespace control**: `whitespace-nowrap` to prevent button text wrapping
785 - Test at: 375px (iPhone SE), 768px (iPad), 1920px (Desktop)
786
78717. **Advanced Prompt Engineering**
788 - **XML Structure**: Use tags like `<时代背景>`, `<创作美学>`, `<回复规范>` for clear hierarchy
789 - **Emphasis section**: Put critical format rules at BOTTOM of message array (AI remembers recent content better)
790 - **Message construction**:
791 ```javascript
792 const messages = [
793 { role: 'user', content: systemPrompt }, // Top: World/character setting
794 ...cleanedHistory, // Middle: Conversation
795 { role: 'user', content: getEmphasis() } // Bottom: Format rules (strongest)
796 ];
797 ```
798 - **<last_input> wrapper**: Emphasize most recent user input
799 ```javascript
800 for (let i = cleanedMessages.length - 1; i >= 0; i--) {
801 if (cleanedMessages[i].role === 'user') {
802 cleanedMessages[i].content = `<last_input>\n${cleanedMessages[i].content}\n</last_input>`;
803 break;
804 }
805 }
806 ```
807 - **Token optimization**: Simplify repeated tags (`<option>` → `<op>` saves ~12 chars × 3)
808 - **Clean history**: Remove `<options>` blocks from history to prevent AI format inertia
809
81018. **KV Storage Advanced Patterns**
811 - **Multi-slot saves with preview**:
812 ```javascript
813 // Save: Full game state
814 await dzmm.kv.put(`game_slot_${slotNumber}`, JSON.stringify({
815 character, messages, timestamp, ...gameState
816 }));
817
818 // Preview: Extract metadata only (don't load full messages)
819 const data = JSON.parse(result.value);
820 return {
821 characterName: data.character.name,
822 messageCount: data.messages.length,
823 lastMessage: data.messages[messages.length-1].content.slice(0, 50),
824 timestamp: new Date(data.timestamp).toLocaleString()
825 };
826 ```
827 - **Batch operations**: Use `Promise.all()` for parallel KV operations
828 - **Versioning**: Use keys like `${appName}_v2_${dataKey}` for schema upgrades
829 - **Chunking**: Split large data if hitting size limits
830 - **Caching with expiry**: Store `{ value, expiresAt }` and check timestamp on load
831
83219. **Streaming AI Response Optimization**
833 - **Real-time display**: Update UI in callback with `done === false`
834 - **Placeholder message**: Add empty message to array, update content in callback
835 - **Auto-scroll**: Use `$nextTick()` to ensure DOM updated before scrolling
836 - **Error recovery**: Remove placeholder message if API fails
837 - **Retry logic**: Implement exponential backoff (1s, 2s, 4s) for failed requests
838 - **Pattern**:
839 ```javascript
840 this.messages.push({ role: 'assistant', content: '' });
841 const idx = this.messages.length - 1;
842 await dzmm.completions({ /* ... */ }, (content, done) => {
843 this.messages[idx].content = content;
844 if (done) {
845 this.$nextTick(() => scrollToBottom());
846 }
847 });
848 ```
849
850## Writing Style Note
851
852Follow DZMM conventions:
853- Use imperative/infinitive verb forms in instructions
854- Maintain objective, instructional tone
855- Provide concrete examples with actual code
856- Reference bundled resources explicitly
857- Keep explanations concise and actionable