managarten/NewAppIdeas/Roblox Reimagined/MVP-Voxel-Platform.md
Till JS 5589765180 feat(manavoxel): scaffold 2D pixel platform MVP (Phase 0)
Add ManaVoxel — a 2D top-down pixel platform for creating and programming
miniature worlds in the browser. This commit includes:

- SvelteKit + PixiJS 8 web app with chunk-based tilemap renderer
- Game engine: camera (scroll/zoom), input (keyboard/mouse/touch), player with
  AABB collision, editor/play mode toggle
- Pixel editor tools: brush, eraser, flood fill, pipette, box fill, line
  (Bresenham), undo/redo stack
- Shared types package: materials, areas, items, network protocol, inventory
- Demo world generator with terrain, buildings, trees
- Material palette UI with 15 materials, keyboard shortcuts
- Comprehensive design documents (Roblox analysis, tech stack options,
  voxel resolution analysis, 2D alternative comparison, full project plan)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 08:57:08 +02:00

42 KiB
Raw Permalink Blame History

Voxel Platform MVP: Design & Technische Architektur

Eine reine Voxel-Welt, in der alles im Spiel erschaffen und programmiert wird


Inhaltsverzeichnis

  1. Die Vision
  2. Voxel-Rendering: Techniken & Tradeoffs
  3. Voxel-Resolution: Optionen & adaptive Skalierung
  4. Der In-Game Voxel-Editor
  5. Programmierbare Items & Artefakte
  6. MVP-Definition: Was ist das Minimum?
  7. Technische Architektur des MVP
  8. Gefahren, Schwierigkeiten & Mitigationen
  9. Datenmodell
  10. Build-Plan

1. Die Vision

Was macht diese Plattform einzigartig?

Roblox:     Entwickler bauen Games in einem externen Editor (Roblox Studio)
            → Spieler spielen die fertigen Games

Minecraft:  Spieler bauen Strukturen aus vordefinierten Bloecken
            → Bloecke haben keine programmierbare Logik (ohne Mods)

Unsere Plattform:
            Alles entsteht IM SPIEL -- in einem Voxel-Editor
            → Spieler FORMEN Items/Objekte aus Voxeln (wie digitale Toepferei)
            → Spieler PROGRAMMIEREN diese Items (Trigger, Effekte, Verhalten)
            → Spieler TEILEN ihre Kreationen (Marketplace, Cross-Game)
            → Spieler SPIELEN in Welten aus diesen Kreationen

Der Kern-Loop:

Erschaffen (Voxel-Editor)
     │
     ▼
Programmieren (Visual Scripting / Code)
     │
     ▼
Testen (sofort spielbar)
     │
     ▼
Teilen (Marketplace, andere Welten)
     │
     ▼
Entdecken & Spielen
     │
     └──→ zurueck zu Erschaffen (inspiriert durch Entdecktes)

2. Voxel-Rendering: Techniken & Tradeoffs

Die vier gaengigen Ansaetze

1. Greedy Meshing (Minecraft-Ansatz)

Voxel-Daten (3D-Array)          Optimiertes Mesh
┌─┬─┬─┬─┐                      ┌───────────┐
│█│█│█│█│  benachbarte gleiche  │           │
├─┼─┼─┼─┤  Flaechen werden  →  │  1 Quad   │
│█│█│█│█│  zu einem Quad        │  statt 8  │
├─┼─┼─┼─┤  zusammengefasst     │           │
│ │ │ │ │                       └───────────┘
└─┴─┴─┴─┘
  • Wie es funktioniert: Voxel-Daten werden pro Chunk (z.B. 16x16x16) durchlaufen. Benachbarte Voxel gleichen Typs werden zu einem einzelnen Quad (Rechteck) zusammengefasst. Nur sichtbare Flaechen werden gerendert (Flaechen zwischen zwei soliden Bloecken werden weggelassen).
  • Performance: Exzellent. Reduziert Triangle-Count um 80-95%. Minecraft-artige Welten mit Millionen Bloecken laufen auf Handys.
  • Qualitaet: Blockig. Alle Kanten sind rechtwinklig. Klassischer "Voxel-Look".
  • Empfehlung: Bester Startpunkt fuer MVP. Bewaehrt, schnell, einfach zu implementieren.

2. Marching Cubes / Surface Nets (glatte Voxel)

Voxel-Daten (SDF/Dichte)       Glattes Mesh
┌─┬─┬─┬─┐                     ╭───────────╮
│▓│█│█│▓│  Isosurface wird    │           │
├─┼─┼─┼─┤  extrahiert und  →  │  Glattes  │
│█│█│█│█│  als Dreiecksmesh    │   Mesh    │
├─┼─┼─┼─┤  gerendert          │           │
│▓│▓│▓│▓│                     ╰───────────╯
└─┴─┴─┴─┘
  • Wie es funktioniert: Statt diskreter Bloecke speichert jeder Voxel einen Dichte-Wert (Signed Distance Field). Marching Cubes extrahiert eine Isosurface als Dreiecksmesh.
  • Performance: Langsamer als Greedy Meshing. Mehr Dreiecke, komplexere Mesh-Generierung.
  • Qualitaet: Glatte, organische Formen. Terrain wie in No Man's Sky, Deep Rock Galactic.
  • Empfehlung: Fuer Phase 2 (Terrain-Sculpting). Nicht fuer MVP.

3. Sparse Voxel Octree (SVO) + Ray Marching

Octree-Struktur                    GPU Ray Marching
┌───────────┐                      Kamera → Strahl →
│     ┌─┬─┐ │                     Octree traversieren →
│     │█│ │ │  Leere Bereiche     Farbe + Normal zurueck
│     ├─┼─┤ │  werden nicht    →
│     │ │█│ │  gespeichert         Kein Mesh noetig!
│     └─┴─┘ │
└───────────┘
  • Wie es funktioniert: Voxel-Daten werden in einem Octree gespeichert (jeder Knoten teilt sich in 8 Kinder). GPU-Compute-Shader schiesst Strahlen durch den Octree und findet Voxel-Treffer.
  • Performance: GPU-intensiv, aber skaliert besser bei hoher Resolution. Kein Mesh-Generation-Bottleneck.
  • Qualitaet: Kann extrem hohe Resolutionen rendern. Teardown nutzt dies (2cm Voxel, 500M+ Voxel).
  • Empfehlung: Langfristig interessant, aber zu komplex fuer MVP. Braucht tiefes GPU-Wissen.

4. Hybrid: Greedy Mesh + Octree LOD

Nah:  Greedy Meshing (volle Resolution, wenige Chunks)
       │
Mittel: Octree LOD Level 1 (halbe Resolution, mehr Chunks)
       │
Fern:  Octree LOD Level 2 (viertel Resolution, Horizont)
       │
Sehr fern: Impostors oder gar nicht rendern
  • Wie es funktioniert: Nahbereich wird klassisch mit Greedy Meshing gerendert. Entfernte Chunks werden in niedrigerer Resolution gerendert (Octree-LOD). Sehr entfernte Bereiche werden als 2D-Impostors oder gar nicht angezeigt.
  • Performance: Best of both worlds. Nah: hohe Qualitaet. Fern: niedrige Kosten.
  • Empfehlung: Ziel-Architektur. Greedy Mesh fuer MVP, Octree-LOD in Phase 2.

Empfehlung fuer unseren Stack

Phase 1 (MVP):     Greedy Meshing + Chunk-System (16³ oder 32³)
Phase 2:           + Octree-LOD fuer Fernbereich
Phase 3:           + Optional: SVO Ray Marching fuer Ultra-Detail-Modus

3. Voxel-Resolution: Optionen & adaptive Skalierung

Resolution-Stufen

Resolution Voxelgroesse Vergleich Voxel pro m³ Speicher/Chunk (32³)
Low (Minecraft) 1.0 m Minecraft-Bloecke 1 ~32 KB
Medium 0.5 m LEGO-artig 8 ~256 KB
High 0.25 m Detaillierter 64 ~2 MB
Very High 0.1 m Trove/Hytale-aehnlich 1.000 ~32 MB
Ultra (Teardown) 0.02 m Fotorealistisch zerstoerbar 125.000 nicht praktikabel als Array

Empfehlung: 0.25m Basis-Resolution mit adaptiver Skalierung

Warum 0.25m (25cm)?

  • Detailliert genug fuer erkennbare Items: Ein Schwert ist ~4-6 Voxel breit, ein Charakter ~7 Voxel breit, ~24 hoch
  • Blocky genug fuer charmante Aesthetik (MagicaVoxel-Style)
  • Performant genug fuer Browser/Mobile
  • Editierbar -- einzelne Voxel sind gross genug zum Anklicken/Platzieren
  • Ein 32³-Chunk deckt 8m x 8m x 8m ab -- ein Raum, ein kleines Haus

Alternative: 0.125m (12.5cm, 8 Voxel pro Meter)

  • Doppelte Detail-Stufe, aber 8x mehr Daten
  • Fuer Items/Artefakte im Editor (Zoom-Modus), nicht fuer ganze Welten

Adaptive Skalierung pro Geraet

┌─────────────────────────────────────────────────────┐
│           RENDERING QUALITY TIERS                    │
│                                                      │
│  Tier 1: High-End Desktop (RTX 3060+)               │
│  ├─ View Distance: 256m (32 Chunks)                  │
│  ├─ Voxel Resolution: 0.25m (volle Basis)            │
│  ├─ LOD: 3 Stufen                                    │
│  ├─ Schatten: Ja (Shadow Maps)                       │
│  ├─ AO: Screen-Space Ambient Occlusion               │
│  └─ Max Voxel im Sichtfeld: ~2M                     │
│                                                      │
│  Tier 2: Mid-Range Desktop / Tablet                  │
│  ├─ View Distance: 128m (16 Chunks)                  │
│  ├─ Voxel Resolution: 0.25m (nah), 0.5m (fern)      │
│  ├─ LOD: 2 Stufen                                    │
│  ├─ Schatten: Vereinfacht                            │
│  ├─ AO: Voxel-basiert (precomputed)                  │
│  └─ Max Voxel im Sichtfeld: ~800K                   │
│                                                      │
│  Tier 3: Low-End / Mobile                            │
│  ├─ View Distance: 64m (8 Chunks)                    │
│  ├─ Voxel Resolution: 0.5m (nah), 1.0m (fern)       │
│  ├─ LOD: 1 Stufe                                     │
│  ├─ Schatten: Nein (nur Ambient)                     │
│  ├─ AO: Nein                                         │
│  └─ Max Voxel im Sichtfeld: ~200K                   │
│                                                      │
│  Automatische Erkennung:                             │
│  - WebGPU Adapter Limits (max texture size, etc.)    │
│  - FPS-Monitoring: Tier runterstufen bei <30fps      │
│  - User Override moeglich                            │
└─────────────────────────────────────────────────────┘

Wie funktioniert LOD fuer Voxel?

Chunk auf LOD 0 (volle Resolution, 0.25m):
┌─┬─┬─┬─┬─┬─┬─┬─┐
│A│A│B│B│A│A│C│C│
├─┼─┼─┼─┼─┼─┼─┼─┤
│A│A│B│B│A│A│C│C│
├─┼─┼─┼─┼─┼─┼─┼─┤
│D│D│D│D│E│E│E│E│
├─┼─┼─┼─┼─┼─┼─┼─┤
│D│D│D│D│E│E│E│E│
└─┴─┴─┴─┴─┴─┴─┴─┘

Chunk auf LOD 1 (halbe Resolution, 0.5m):
┌───┬───┬───┬───┐
│ A │ B │ A │ C │  ← 2x2 Voxel → 1 Voxel
├───┼───┼───┼───┤     (dominanter Typ gewinnt)
│ D │ D │ E │ E │
└───┴───┴───┴───┘

Chunk auf LOD 2 (viertel Resolution, 1.0m):
┌───────┬───────┐
│   A   │   A   │  ← 4x4 Voxel → 1 Voxel
├───────┼───────┤
│   D   │   E   │
└───────┴───────┘

LOD-Meshes werden vorberechnet wenn der Chunk sich aendert und gecached. Der Uebergang zwischen LOD-Stufen nutzt ein "Skirt" (ueberlappende Kante) um Luecken zu vermeiden.

Dual-Resolution fuer Items vs. Welt

WELT-VOXEL: 0.25m Resolution
├── Terrain, Gebaeude, Landschaft
├── Grosse Strukturen
└── Immer Greedy Meshing + LOD

ITEM-VOXEL: 0.0625m (6.25cm) Resolution -- 4x feiner!
├── Schwerter, Werkzeuge, Schmuck, Ruenen
├── Kleine detaillierte Objekte
├── Im Voxel-Editor: Zoom auf Item-Grid
└── Als Mesh gerendert (einmal generiert, wiederverwendet)

Warum zwei Resolutionen?

Ein Schwert bei 0.25m waere ~4 Voxel lang -- zu grob. Bei 0.0625m ist es ~16 Voxel lang und kann echte Details haben (Klinge, Griff, Verzierung). Die Item-Meshes werden einmal generiert und als regulaere 3D-Objekte in der Welt platziert -- kein Performance-Unterschied zum Rendern normaler Meshes.


4. Der In-Game Voxel-Editor

Editor-Modi

┌─────────────────────────────────────────────────────┐
│                 VOXEL EDITOR                         │
│                                                      │
│  [Welt-Modus]  [Item-Modus]  [Charakter-Modus]     │
│                                                      │
│  ┌─────────────────────────────────────────────┐    │
│  │                                             │    │
│  │         3D Viewport                         │    │
│  │         (Bevy Renderer)                     │    │
│  │                                             │    │
│  │    Voxel-Cursor zeigt Platzierungsort       │    │
│  │                                             │    │
│  └─────────────────────────────────────────────┘    │
│                                                      │
│  Werkzeuge:                                          │
│  [Pinsel] [Radierer] [Fuellen] [Pipette]            │
│  [Box] [Kugel] [Linie] [Spiegeln]                   │
│  [Kopieren] [Einfuegen] [Undo] [Redo]               │
│                                                      │
│  Palette:                                            │
│  [█ Stein] [█ Holz] [█ Glas] [█ Metall] [█ ...]    │
│  [█ Custom Farbe/Material]                           │
│                                                      │
│  Eigenschaften (rechte Seite):                       │
│  ┌─────────────────────┐                             │
│  │ Material: Stein     │                             │
│  │ Farbe: #8B7355      │                             │
│  │ Transparenz: 0%     │                             │
│  │ Leuchten: Nein      │                             │
│  │ Physik: Solid       │                             │
│  │ Sound: stone_hit    │                             │
│  └─────────────────────┘                             │
└─────────────────────────────────────────────────────┘

Welt-Modus (0.25m Voxel)

  • Terrain formen, Gebaeude bauen, Landschaften gestalten
  • Grosse Pinsel (1-10 Voxel Radius)
  • Terrain-Tools: Erhoehen, Absenken, Glaeetten, Malen
  • Prefab-System: Gespeicherte Strukturen wiederverwenden
  • Kollaborativ -- mehrere Creator gleichzeitig (CRDT via mana-sync)

Item-Modus (0.0625m Voxel)

  • Feindetailliertes Sculpting fuer Items, Werkzeuge, Artefakte
  • 32x32x32 Grid (= 2m x 2m x 2m reale Groesse) oder kleiner
  • MagicaVoxel-aehnliche UX: Rotation, Schicht-fuer-Schicht-Editing
  • Anchor Points: Wo das Item gehalten/getragen/platziert wird
  • Hit Box: Kollisionsbereich definieren
  • Animation Frames: Mehrere Zustaende fuer animierte Items (optional)

Charakter-Modus (0.0625m oder 0.125m)

  • Avatar-Koerper aus Voxeln gestalten
  • Vordefinierte Skelett-Struktur (Kopf, Torso, Arme, Beine)
  • Voxel werden ans Skelett gebunden (Rigging)
  • Animations-Preview mit Standard-Animationen (Laufen, Springen, Idle)

Editor-UX: Touch/Mobile-tauglich

Desktop:                          Mobile/Tablet:
- Mausrad: Zoom                   - Pinch: Zoom
- Rechtsklick: Orbit              - 2-Finger-Drag: Orbit
- Linksklick: Platzieren          - Tap: Platzieren
- Shift+Klick: Loeschen           - Long Press: Loeschen
- Ctrl+Z: Undo                    - Shake/Button: Undo
- Tastatur: Tool-Shortcuts        - Toolbar unten

5. Programmierbare Items & Artefakte

Das Property-System

Jedes Voxel-Item bekommt ein Component-basiertes Property-System (ECS-nativ):

Schwert "Flammenklinge" (Voxel-Item)
│
├── VoxelData           → 32x8x2 Voxel-Grid (Klinge + Griff)
├── ItemInfo            → Name, Beschreibung, Icon, Creator
├── Holdable            → Anchor: rechte Hand, Offset, Rotation
├── MeleeDamage         → Basis: 10, Typ: Slash
├── ElementalEffect     → Feuer, Staerke: 5, Partikel: flame_burst
├── Durability          → Max: 100, Aktuell: 100, RepairCost: 5 Mana
├── Rarity              → Legendary (goldener Rahmen)
├── Tradeable           → true, MinPrice: 50 Mana
├── OnHit               → Script: "spawn_fire_particles(target)"
├── OnEquip             → Script: "player.glow(orange)"
└── CustomProperties    → { "forged_by": "alice", "enchant_level": 3 }

Drei Programmier-Ebenen

Ebene 1: Property Sliders (fuer alle, ab 6 Jahre)

┌─────────────────────────────────────────┐
│  ITEM EIGENSCHAFTEN                      │
│                                          │
│  Schaden:     [████████░░] 80            │
│  Reichweite:  [██░░░░░░░░] 20            │
│  Geschwind.:  [██████░░░░] 60            │
│  Haltbarkeit: [██████████] 100           │
│                                          │
│  Element:     [🔥 Feuer ▼]              │
│  Sound:       [⚔️ Schwert-Treffer ▼]    │
│  Partikel:    [✨ Funkenspur ▼]         │
│  Seltenheit:  [⭐ Legendaer ▼]          │
│                                          │
│  [Testen]  [Speichern]                   │
└─────────────────────────────────────────┘

Kein Code, keine Logik. Einfach Werte einstellen. Das Item "funktioniert" sofort mit Standard-Verhalten basierend auf den Werten.

Ebene 2: Trigger-Action System (ab 8-10 Jahre)

┌─────────────────────────────────────────┐
│  VERHALTEN EDITOR                        │
│                                          │
│  WENN [Spieler beruehrt ▼]              │
│    DANN [Spieler bekommt Item ▼]         │
│                                          │
│  WENN [Item benutzt wird ▼]             │
│    DANN [Feuerball schiessen ▼]          │
│    UND  [Sound abspielen: boom ▼]        │
│    UND  [5 Schaden an Ziel ▼]            │
│    WARTE [0.5 Sekunden]                  │
│    DANN [Partikel an Ziel ▼]             │
│                                          │
│  WENN [Haltbarkeit = 0 ▼]              │
│    DANN [Item zerstoeren ▼]              │
│    UND  [Sound: glass_break ▼]           │
│                                          │
│  [+ Neue Regel]  [Testen]  [Speichern]  │
└─────────────────────────────────────────┘

Verfuegbare Trigger:

  • Spieler beruehrt / betritt Bereich / verlaesst Bereich
  • Item wird benutzt (Primaer / Sekundaer)
  • Item wird aufgenommen / abgelegt / geworfen
  • Timer (alle X Sekunden)
  • HP unter/ueber X
  • Tageszeit / Wetter
  • Anderes Item in der Naehe
  • Custom Event (von anderen Items ausgeloest)

Verfuegbare Aktionen:

  • Schaden/Heilen
  • Partikel/Sound/Licht abspielen
  • Spieler teleportieren / pushen / verlangsamen
  • Item spawnen / zerstoeren
  • Voxel setzen / loeschen (Welt veraendern!)
  • Nachricht anzeigen
  • Variable setzen / abfragen
  • Custom Event senden

Ebene 3: TypeScript-Scripting (ab 12+ Jahre, Creator)

// sword_flame.ts -- Kompiliert zu WASM, laeuft in Sandbox

import { onHit, onEquip, spawn, damage, particles } from '@platform/api';

// Wird aufgerufen wenn das Schwert trifft
onHit((event) => {
	const target = event.target;

	// Basis-Schaden
	damage(target, 10 + this.properties.enchantLevel * 2);

	// Feuer-Effekt
	particles.spawn('fire_burst', target.position, {
		count: 20,
		lifetime: 0.5,
		color: '#ff4400',
	});

	// Feuer-DoT (Damage over Time)
	target.addEffect('burning', {
		damage: 2,
		interval: 1.0,
		duration: 3.0,
	});

	// Haltbarkeit reduzieren
	this.durability -= 1;
	if (this.durability <= 0) {
		this.destroy();
		particles.spawn('shatter', this.position);
	}
});

onEquip((player) => {
	player.setGlow({ color: '#ff6600', intensity: 0.5 });
});

Wie die drei Ebenen zusammenspielen

Ebene 1 (Sliders) ──kompiliert──→ Standard-Trigger-Actions
                                        │
Ebene 2 (Trigger-Action) ──kompiliert──→ TypeScript
                                              │
Ebene 3 (TypeScript) ──kompiliert──→ WASM (Wasmtime Sandbox)

Alles wird zu WASM. Ebene 1 und 2 sind nur UX-Schichten ueber dem gleichen System. Ein Kind, das mit Slidern anfaengt, kann spaeter die generierten Trigger-Actions sehen und modifizieren -- und irgendwann den TypeScript-Code direkt schreiben. Nahtloser Lernpfad.

Cross-Game Item-Portabilitaet

Item "Flammenklinge" existiert als:
├── VoxelData (Aussehen) → Reist immer mit
├── ItemInfo (Metadaten) → Reist immer mit
├── Platform Properties  → Vom Game interpretiert
│   ├── Rarity: Legendary
│   ├── Element: Fire
│   └── BaseDamage: 10
└── Game-spezifische Scripts → NUR im Ursprungs-Game

In Game A (Fantasy RPG):
  → Schwert macht 10 Schaden + Feuer-DoT
  → Scripts laufen wie vom Creator definiert

In Game B (Parkour):
  → Schwert ist kosmetisch (kein Kampfsystem)
  → Wird als Avatar-Accessoire angezeigt
  → Rarity bestimmt visuellen Glow-Effekt

In Game C (Trading Card Game):
  → Schwert-Voxelmodell wird als Karten-Illustration genutzt
  → Properties (Damage, Element) werden als Kartenwerte interpretiert

Regel: Platform-Properties reisen. Game-spezifische Scripts bleiben im Ursprungs-Game. Jedes Game entscheidet selbst, wie es Platform-Properties interpretiert.


6. MVP-Definition: Was ist das Minimum?

MVP = "Eine Welt, ein Editor, Items programmieren, zusammen spielen"

WAS IM MVP IST:                         WAS NICHT IM MVP IST:

✅ Voxel-Welt (0.25m, flat terrain)     ❌ Terrain-Generation (Perlin Noise)
✅ Welt-Editor (platzieren/loeschen)    ❌ Marching Cubes / glatte Voxel
✅ Item-Editor (0.0625m, detailliert)   ❌ Charakter-Editor (Standard-Avatar)
✅ Property Sliders (Ebene 1)           ❌ TypeScript-Scripting (Ebene 3)
✅ Trigger-Action (Ebene 2)             ❌ Cross-Game Items
✅ Multiplayer (2-20 Spieler)           ❌ Matchmaking (manuelle Server)
✅ Basis-Physik (Gravitation, Kollision)❌ Voxel-Destruction-Physik
✅ Inventar (Items aufheben/tragen)     ❌ Marketplace (manuelles Teilen)
✅ Login (mana-auth)                    ❌ Economy (kein Mana im MVP)
✅ Offline-Editor (Dexie.js)            ❌ Voice Chat
✅ Guest Mode                           ❌ AI NPCs
✅ Basis-Beleuchtung (Ambient + Sun)    ❌ Dynamische Schatten
✅ 5-10 Basis-Materialien               ❌ Custom Materialien
✅ Speichern/Laden (Local-First)        ❌ Versionierung

MVP User Stories

Als Spieler kann ich:

  1. Eine Voxel-Welt betreten (Browser, kein Download)
  2. Bloecke platzieren und loeschen (Welt-Editor)
  3. Ein Item im Voxel-Editor formen (z.B. ein Schwert)
  4. Dem Item Eigenschaften geben (Schaden, Element, Sound)
  5. Dem Item Verhalten geben ("Wenn benutzt → Feuerball")
  6. Das Item in mein Inventar nehmen und benutzen
  7. Die Welt mit Freunden teilen (Link → Multiplayer)
  8. Offline im Editor arbeiten und spaeter synchronisieren
  9. Als Gast spielen ohne Account

Als Creator kann ich: 10. Eine komplette Spielwelt bauen (Terrain + Gebaeude + Items) 11. Items mit komplexen Trigger-Action-Ketten programmieren 12. Die Welt veroeffentlichen (andere koennen beitreten)


7. Technische Architektur des MVP

Chunk-System

Welt = Grid aus Chunks

Chunk (32 x 32 x 32 Voxel = 8m x 8m x 8m bei 0.25m Resolution):
┌──────────────────────────────────┐
│ header:                           │
│   position: (cx, cy, cz)         │
│   dirty: bool                    │
│   mesh: Option<GpuMesh>          │
│   lod_meshes: [Option<GpuMesh>]  │
│                                   │
│ data:                             │
│   voxels: [u16; 32*32*32]        │  ← 64 KB pro Chunk
│          (material_id + flags)    │
│                                   │
│   palette: [(Color, MaterialType)]│  ← Chunk-lokale Palette
│          (max 256 Eintraege)      │
└──────────────────────────────────┘

Speicher pro Chunk: ~64 KB (Voxel) + ~1-10 KB (Palette) + Mesh (variabel)
100 Chunks geladen: ~8 MB Voxel-Daten + ~50 MB Meshes = ~58 MB
→ Passt problemlos in Browser-WASM-Memory

Voxel-Daten-Encoding

Jeder Voxel = 16 Bit (u16):

Bits 0-7:   Material-Index (256 Materialien pro Chunk-Palette)
Bit  8:     Transparent (ja/nein)
Bit  9:     Emissive (leuchtet ja/nein)
Bits 10-11: Rotation (0°, 90°, 180°, 270° -- fuer nicht-symmetrische Bloecke)
Bits 12-15: Reserved (Custom Flags, Zustaende)

Material 0 = Luft (leer)

Alternative fuer hoehere Vielfalt: u32 (4 Bytes pro Voxel)
→ 128 KB pro 32³ Chunk, 16M Farben, mehr Flags
→ Empfehlung: Mit u16 starten, u32 wenn noetig

Mesh-Generation Pipeline (WebGPU Compute)

Chunk aendert sich (Voxel gesetzt/geloescht)
       │
       ▼
Greedy Meshing Algorithmus (CPU oder GPU Compute)
       │
       ├── Fuer jede der 6 Richtungen (+X, -X, +Y, -Y, +Z, -Z):
       │   1. Scanne Schicht fuer Schicht
       │   2. Finde zusammenhaengende Rechtecke gleichen Materials
       │   3. Erzeuge ein Quad pro Rechteck
       │
       ▼
Vertex Buffer (Position, Normal, UV, Color, AO)
       │
       ▼
Upload zu GPU → Rendern

Performance-Ziel: <5ms pro Chunk-Remesh (damit Echtzeit-Editing fluessig)

Bevy ECS Architektur

// Kern-Components fuer das Voxel-System

// Ein Chunk in der Welt
struct Chunk {
    position: IVec3,           // Chunk-Koordinaten
    voxels: [u16; 32*32*32],   // Voxel-Daten
    palette: Vec<Material>,     // Chunk-lokale Material-Palette
    dirty: bool,                // Mesh muss neu generiert werden
}

// Ein Voxel-Item (im Inventar oder in der Welt)
struct VoxelItem {
    voxels: Vec<u16>,          // Item-Voxel-Daten (variable Groesse)
    dimensions: UVec3,          // z.B. 16x32x4
    resolution: f32,            // 0.0625 fuer Items
    anchor: Vec3,               // Haltepunkt
    hitbox: Aabb,               // Kollisionsbox
}

// Properties eines Items
struct ItemProperties {
    name: String,
    damage: Option<f32>,
    element: Option<Element>,
    durability: Option<(f32, f32)>,  // (aktuell, max)
    rarity: Rarity,
    custom: HashMap<String, Value>,
}

// Trigger-Action-Behavior
struct ItemBehavior {
    triggers: Vec<Trigger>,     // Wann
    actions: Vec<Action>,       // Was passiert
    wasm_module: Option<WasmModule>,  // Kompiliertes Script
}

// Spieler
struct Player {
    inventory: Vec<Entity>,     // Item-Entities
    held_item: Option<Entity>,  // Aktuell gehaltenes Item
    position: Vec3,
    health: f32,
}

Netzwerk-Protokoll fuer Voxel-Sync

CHUNK SYNC (Unreliable, haeufig):

Client verbindet sich:
1. Server sendet alle Chunks im Radius (komprimiert)
   - RLE (Run-Length Encoding) + LZ4: ~64 KB Chunk → ~2-10 KB komprimiert
   - Bei 100 Chunks: ~200 KB - 1 MB Initial-Load

2. Spieler bewegt sich:
   - Server sendet neue Chunks am Rand
   - Client entlaedt Chunks ausserhalb des Radius

3. Voxel-Aenderung:
   Client → Server: SetVoxel { chunk: (2,0,1), pos: (15,3,7), material: 42 }
   Server validiert (Berechtigung? Physik OK?)
   Server → Alle Clients im Bereich: VoxelChanged { ... }

   Batching: Mehrere Aenderungen pro Frame zusammenfassen

ITEM SYNC (Reliable, bei Aenderung):

Item erstellt/modifiziert:
   Client → Server: CreateItem { voxel_data, properties, behavior }
   Server validiert (WASM-Script sicher? Properties in Bounds?)
   Server speichert → PostgreSQL + mana-sync
   Server → Relevante Clients: ItemCreated { ... }

Kompression: Voxel-Daten klein halten

Rohe Chunk-Daten: 32³ × 2 Bytes = 65.536 Bytes (64 KB)

RLE (Run-Length Encoding):
  [0,0,0,0,0,5,5,5,0,0] → [(0,5), (5,3), (0,2)]
  Typisch 60-90% Reduktion fuer natuerliche Welten

LZ4 (schnelle Kompression):
  Nach RLE nochmal ~50% Reduktion
  Dekompression: ~2 GB/s (vernachlaessigbar)

Typische komprimierte Chunk-Groesse:
  Leerer Chunk (nur Luft):    ~10 Bytes
  Flaches Terrain:            ~500 Bytes - 2 KB
  Komplexes Gebaeude:         ~5-15 KB
  Maximal gefuellter Chunk:   ~30 KB

Netzwerk-Budget pro Spieler:
  100 Chunks geladen × 5 KB = ~500 KB Initialtransfer
  Laufend: ~1-5 KB/s fuer Aenderungen
  → Trivial fuer jede Internetverbindung

Local-First: Offline Voxel-Editor

Dexie.js Schema:

worlds: {
  id: string,
  name: string,
  seed: number,
  created: Date,
  modified: Date,
  settings: WorldSettings
}

chunks: {
  id: string,              // world_id + chunk_position
  worldId: string,
  position: [number, number, number],
  voxelData: Uint8Array,   // Komprimiert (RLE + LZ4)
  palette: Material[],
  version: number,         // Fuer Sync-Konflikte
  modified: Date
}

items: {
  id: string,
  worldId: string,
  voxelData: Uint8Array,   // Komprimiertes Item-Grid
  dimensions: [number, number, number],
  properties: ItemProperties,
  behavior: TriggerAction[],
  script?: string,         // TypeScript-Quellcode
  wasmBinary?: Uint8Array, // Kompiliertes WASM
  modified: Date
}

inventory: {
  id: string,
  playerId: string,
  itemId: string,
  slot: number,
  quantity: number
}

Sync via mana-sync:
  - Chunks: Field-Level LWW (wie bestehende Collections)
  - Items: Ganzes Item synct (Items sind klein genug)
  - Konflikte: Letzter Schreiber gewinnt (LWW) -- fuer Voxel OK
    (Alternative: CRDT per Voxel -- overkill fuer MVP)

8. Gefahren, Schwierigkeiten & Mitigationen

Technische Gefahren

1. Mesh-Generation-Performance

Problem: Jedes Mal wenn ein Spieler einen Block setzt, muss der Chunk-Mesh neu generiert werden. Greedy Meshing fuer 32³ = 32.768 Voxel braucht ~2-10ms auf CPU. Bei schnellem Bauen (10 Bloecke/Sekunde) wird das zum Bottleneck.

Mitigation:

  • Mesh-Generation in Web Worker (separater Thread)
  • Dirty-Flag-System: Nur geaenderte Chunks remeshen
  • Doppel-Buffering: Alten Mesh anzeigen waehrend neuer generiert wird
  • GPU Compute Meshing (WebGPU): ~10x schneller als CPU, aber komplexer zu implementieren
  • Rate Limiting: Max 2-3 Chunk-Remeshes pro Frame

2. Memory auf Mobile/Low-End

Problem: 100 Chunks × (64 KB Voxel + 200 KB Mesh) = ~26 MB nur fuer sichtbare Welt. Dazu kommen Engine, UI, WASM-Runtime. Mobile Browser haben oft nur 200-500 MB WASM-Memory.

Mitigation:

  • Weniger Chunks auf Mobile laden (8 statt 32 Radius)
  • Komprimierte Voxel-Daten (RLE), nur dekomprimieren wenn gebraucht
  • Mesh-LOD: Entfernte Chunks haben einfachere Meshes
  • Chunk-Eviction: LRU-Cache, aelteste Chunks entladen
  • Memory-Budget-System: Automatisch Qualitaet reduzieren bei Speicherdruck

3. Netzwerk-Bandbreite bei vielen Aenderungen

Problem: 20 Spieler bauen gleichzeitig → hunderte Voxel-Aenderungen/Sekunde → Bandbreite explodiert.

Mitigation:

  • Delta-Compression: Nur geaenderte Voxel senden, nicht ganze Chunks
  • Batching: Aenderungen pro Tick zusammenfassen (16ms-Fenster)
  • Priorisierung: Nahe Aenderungen zuerst, ferne spaeter
  • Rate Limit pro Spieler: Max 30 Voxel-Aenderungen/Sekunde
  • Area of Interest: Nur Aenderungen im sichtbaren Bereich empfangen

4. WASM-Script-Sicherheit

Problem: User-Scripts koennten Endlosschleifen haben, zu viel Memory nutzen, oder unerwartete Interaktionen zwischen Items verursachen.

Mitigation:

  • Fuel Metering: Max 10.000 Instructions pro Item-Tick
  • Memory Limit: 4 MB pro Script (ein Item braucht typisch <100 KB)
  • Timeout: Script wird nach 5ms abgebrochen
  • Capability System: Scripts koennen nur deklarierte APIs nutzen
  • Sandboxed Side Effects: damage() geht nicht direkt → wird als Event an Server gesendet, Server validiert
  • Anti-Spam: Max 10 Events pro Script pro Sekunde

5. Voxel-Physik ist schwer

Problem: Wenn ein Spieler Bloecke unter einem Gebaeude entfernt, sollte es einstuerzen? Strukturelle Integritaet ist ein extrem schwieriges Problem (O(n) Floodfill bei jeder Aenderung).

Mitigation fuer MVP:

  • Keine strukturelle Integritaet im MVP. Bloecke schweben, wie in Minecraft Creative Mode.
  • Items haben Schwerkraft (fallen, wenn nicht auf einem Block)
  • Spieler haben Schwerkraft
  • Phase 2: Optionale "Gravity" Flag pro Chunk → einfacher Floodfill
  • Phase 3: Echte strukturelle Integritaet (wie Valheim/Teardown) -- grosser Engineering-Aufwand

6. Cross-Platform Rendering-Konsistenz

Problem: Ein Item sieht auf Desktop anders aus als auf Mobile (verschiedene LOD-Stufen, Beleuchtung).

Mitigation:

  • Items werden mit fester Resolution gerendert (immer 0.0625m, kein LOD fuer Items)
  • Nur Welt-Chunks bekommen LOD
  • Beleuchtung: Ambient + einfache Directional Light → sieht ueberall gleich aus
  • Optional: Item-Preview als 2D-Sprite cachen (fuer Inventar-Anzeige)

Design-Gefahren

7. "Minecraft-Klon"-Wahrnehmung

Problem: Jedes Voxel-Game wird sofort mit Minecraft verglichen.

Differenzierung:

  • Programmierbare Items -- das hat Minecraft nicht (ohne Mods)
  • In-Game Item-Editor mit hoher Resolution -- kein externes Tool
  • Trigger-Action-System -- nicht nur Bauen, sondern Verhalten definieren
  • Cross-Game Items -- Items reisen zwischen Welten
  • Browser-nativ -- kein Download
  • Aesthetik: MagicaVoxel-Style statt Minecraft-Bloecke (0.25m statt 1m, Farben statt Texturen)

8. Zu komplex fuer Kinder

Problem: Drei Programmier-Ebenen + Voxel-Editor + 3D-Navigation = Ueberforderung.

Mitigation:

  • Onboarding-Tutorial: Geführtes Erstes Item bauen → Property Slider → Benutzen → Wow-Moment
  • Templates: Vorgefertigte Items zum Modifizieren (einfacher als from scratch)
  • Progressive Disclosure: Trigger-Actions erst zeigen wenn Sliders gemeistert
  • TypeScript erst fuer angemeldete Creator (nicht im Guest Mode)

9. Moderation von Voxel-Inhalten

Problem: Spieler bauen unangemessene Formen aus Voxeln (wie Roblox's "Condo Games"-Problem, aber mit Voxeln).

Mitigation:

  • Voxel-Modell → Render zu Bild → Vision-Classifier (bestehende AI-Pipeline)
  • Community-Reporting
  • Automatische Scans bei Veroeffentlichung
  • Spaeter: Behavioral Analysis (welche Spieler besuchen welche Welten)

10. Performance-Erwartungen im Browser

Problem: Browser-Spiele werden als "langsam" wahrgenommen. WebGPU ist neu.

Realitaet:

  • WebGPU + WASM ist 80-90% von nativem Performance
  • Voxel-Rendering ist GPU-freundlich (einfache Geometrie, wenig Overdraw)
  • Minecraft Java Edition laeuft auf aelterer Technik und ist beliebter als Bedrock
  • Ziel: 60fps auf Mid-Range Desktop, 30fps auf Mid-Range Mobile

9. Datenmodell

PostgreSQL Schema (Server-Side)

-- Welten
CREATE TABLE worlds (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    creator_id UUID NOT NULL REFERENCES users(id),
    name TEXT NOT NULL,
    description TEXT,
    settings JSONB DEFAULT '{}',
    is_published BOOLEAN DEFAULT false,
    max_players INTEGER DEFAULT 20,
    created_at TIMESTAMPTZ DEFAULT now(),
    updated_at TIMESTAMPTZ DEFAULT now()
);

-- Chunks (komprimierte Voxel-Daten)
CREATE TABLE chunks (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    world_id UUID NOT NULL REFERENCES worlds(id) ON DELETE CASCADE,
    position_x INTEGER NOT NULL,
    position_y INTEGER NOT NULL,
    position_z INTEGER NOT NULL,
    voxel_data BYTEA NOT NULL,          -- RLE + LZ4 komprimiert
    palette JSONB DEFAULT '[]',
    version INTEGER DEFAULT 1,
    updated_at TIMESTAMPTZ DEFAULT now(),
    UNIQUE(world_id, position_x, position_y, position_z)
);
CREATE INDEX idx_chunks_world ON chunks(world_id);

-- Items (Voxel-Kreationen)
CREATE TABLE items (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    creator_id UUID NOT NULL REFERENCES users(id),
    name TEXT NOT NULL,
    description TEXT,
    voxel_data BYTEA NOT NULL,          -- Komprimiertes Voxel-Grid
    dimensions SMALLINT[3] NOT NULL,     -- z.B. {16, 32, 4}
    resolution REAL DEFAULT 0.0625,
    properties JSONB DEFAULT '{}',
    behavior JSONB DEFAULT '[]',         -- Trigger-Action-Regeln
    wasm_binary BYTEA,                   -- Kompiliertes Script
    rarity TEXT DEFAULT 'common',
    is_published BOOLEAN DEFAULT false,
    thumbnail_url TEXT,                   -- Gerendertes Preview-Bild
    created_at TIMESTAMPTZ DEFAULT now(),
    updated_at TIMESTAMPTZ DEFAULT now()
);

-- Inventar
CREATE TABLE inventories (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    player_id UUID NOT NULL REFERENCES users(id),
    item_id UUID NOT NULL REFERENCES items(id),
    world_id UUID REFERENCES worlds(id), -- NULL = globales Inventar
    slot INTEGER,
    quantity INTEGER DEFAULT 1,
    instance_data JSONB DEFAULT '{}',    -- Haltbarkeit etc. pro Instanz
    UNIQUE(player_id, item_id, world_id, slot)
);

-- Materialien (globaler Katalog)
CREATE TABLE materials (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    color TEXT NOT NULL,                 -- Hex
    type TEXT DEFAULT 'solid',           -- solid, transparent, liquid, emissive
    texture_url TEXT,
    properties JSONB DEFAULT '{}'
);

Dexie.js Schema (Client-Side, Local-First)

const db = new Dexie('voxel-platform');

db.version(1).stores({
	worlds: 'id, creatorId, name, isPublished, updatedAt',
	chunks: 'id, worldId, [worldId+posX+posY+posZ], updatedAt',
	items: 'id, creatorId, name, rarity, isPublished, updatedAt',
	inventories: 'id, playerId, itemId, worldId',
	materials: 'id, name, type',
});

10. Build-Plan

Phase 0: Voxel Engine Proof of Concept (6-8 Wochen)

Woche 1-2: Bevy + wgpu im Browser
  □ Bevy-Projekt aufsetzen, WASM-Build, WebGPU-Rendering im Browser
  □ Einfache Kamera-Steuerung (Orbit + WASD)

Woche 3-4: Chunk-System + Greedy Meshing
  □ Chunk-Datenstruktur (32³, u16-Voxel)
  □ Greedy Meshing Algorithmus implementieren
  □ 5 Basis-Materialien (Stein, Holz, Gras, Wasser, Sand)
  □ Flat-World-Generator (eine Ebene Gras)

Woche 5-6: Voxel-Editing
  □ Raycast: Mausklick → welcher Voxel?
  □ Platzieren (Linksklick) + Loeschen (Rechtsklick)
  □ Material-Palette UI (Svelte Overlay)
  □ Undo/Redo Stack

Woche 7-8: Basis-Physik + Spieler
  □ Spieler-Capsule mit Gravitation
  □ AABB-Kollision mit Voxel-Welt
  □ Springen, Laufen
  □ First-Person + Third-Person Kamera

Ergebnis: Minecraft Creative Mode im Browser, 60fps, Offline-faehig

Phase 1: Item-System (6-8 Wochen)

Woche 9-10: Item Voxel-Editor
  □ Separater Editor-Modus (0.0625m Grid)
  □ 32x32x32 Voxel-Grid fuer Items
  □ Rotieren, Spiegeln, Schicht-Editing
  □ Item speichern (Dexie.js)

Woche 11-12: Property System
  □ Component-basierte Properties (ECS)
  □ Property-Slider-UI (Svelte)
  □ 10 Standard-Properties (Damage, Element, Durability, ...)
  □ Item im Inventar anzeigen

Woche 13-14: Trigger-Action System
  □ Trigger-Action Editor UI (Svelte)
  □ 10 Trigger-Typen + 15 Action-Typen
  □ Trigger-Action → WASM Kompilierung
  □ WASM-Sandbox (Wasmtime) Integration

Woche 15-16: Items in der Welt
  □ Item in der Hand halten (Third Person)
  □ Item benutzen (Primary/Secondary Action)
  □ Items auf den Boden legen / aufheben
  □ Partikel + Sound-Effekte

Ergebnis: Spieler baut Schwert im Editor, gibt ihm Feuer-Schaden,
          benutzt es in der Welt → Partikel fliegen

Phase 2: Multiplayer (4-6 Wochen)

Woche 17-18: Go Game Server
  □ Bevy headless Server (Rust Binary)
  □ Go-Orchestrator spawnt Server-Prozesse
  □ WebTransport (Quinn) Verbindung Browser ↔ Server

Woche 19-20: Voxel-Sync
  □ Chunk-Sync bei Verbindung (komprimiert)
  □ Delta-Sync bei Voxel-Aenderungen
  □ Server-autoritatives Voxel-Editing
  □ Andere Spieler sehen + sich bewegen sehen

Woche 21-22: Multiplayer Items + Polish
  □ Inventar-Sync
  □ Item-Interaktionen zwischen Spielern
  □ Chat (Text, einfach)
  □ Welt-Link teilen (mana.how/world/abc123)

Ergebnis: 2-20 Spieler in einer geteilten Voxel-Welt,
          bauen zusammen, benutzen selbst-programmierte Items

Phase 3: Platform (4-6 Wochen)

Woche 23-24: Auth + Persistence
  □ mana-auth Integration (Login/Register/Guest)
  □ Welten in PostgreSQL speichern
  □ Local-First Sync (Dexie.js ↔ mana-sync ↔ PostgreSQL)
  □ Welt-Liste (eigene + oeffentliche)

Woche 25-26: Discovery + Social
  □ Welt veroeffentlichen
  □ Welt-Suche (Meilisearch)
  □ Spieler-Profil (erstellte Welten, Items)
  □ Favoriten

Woche 27-28: Polish + Performance
  □ LOD fuer entfernte Chunks
  □ Performance-Tiers (Desktop/Mobile)
  □ Onboarding Tutorial
  □ Bug Fixes, Edge Cases

Ergebnis: MVP! Browser-basierte Voxel-Plattform mit Login,
          Welt-Erstellung, Item-Programmierung, Multiplayer.

Gesamtzeit: ~28 Wochen (7 Monate)

Monat 1-2:   Voxel Engine im Browser (Bauen + Physik)
Monat 3-4:   Item-Editor + Programmierung
Monat 5-6:   Multiplayer + Sync
Monat 7:     Platform-Features + Polish

Zusammenfassung: Was macht dieses MVP besonders?

1. ALLES IM SPIEL     — Kein externer Editor, kein Download, kein SDK
2. PROGRAMMIERBARE     — Items sind nicht nur Deko, sie haben Verhalten
   ITEMS                 (Slider → Trigger-Actions → TypeScript → WASM)
3. ZWEI RESOLUTIONEN   — Welt: 0.25m (Minecraft+), Items: 0.0625m (MagicaVoxel)
4. BROWSER-FIRST       — Ein Link, sofort spielen, kein Install
5. OFFLINE-FAEHIG      — Editor funktioniert ohne Internet (Local-First)
6. ADAPTIVE QUALITAET  — Desktop: 256m Sichtweite, Mobile: 64m, Auto-Anpassung
7. NAHTLOSER LERNPFAD  — Kind startet mit Slidern, lernt Trigger-Actions,
                         entdeckt irgendwann TypeScript

Der Kern-Differentiator gegenueber Minecraft: Items haben Verhalten. Der Kern-Differentiator gegenueber Roblox: Alles entsteht in-game, aus Voxeln, ohne externen Editor.


Erstellt: 28. Maerz 2026