managarten/NewAppIdeas/Roblox Reimagined/PROJEKT-PLAN-2D.md
Till JS 22a73943e1 chore: complete ManaCore → Mana rename (docs, go modules, plists, images)
Final cleanup of references missed in previous rename commits:

- Dockerfiles: PUBLIC_MANA_CORE_AUTH_URL → PUBLIC_MANA_AUTH_URL
- Go modules: github.com/manacore/* → github.com/mana/* (7 go.mod files)
- launchd plists: com.manacore.* → com.mana.* (14 files renamed + content)
- Image assets: *_Manacore_AI_Credits* → *_Mana_AI_Credits* (11 files)
- .env.example files: ManaCore brand strings → Mana
- .prettierignore: stale apps/manacore/* paths → apps/mana/*
- Markdown docs (CLAUDE.md, /docs/*): mana-core-auth → mana-auth, etc.

Excluded from rename: .claude/, devlog/, manascore/ (historical content),
client testimonials, blueprints, npm package refs (@mana-core/*).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 12:26:10 +02:00

930 lines
41 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ManaVoxel 2D: Der Projektplan
## Top-Down Pixel-Plattform mit Zoom-Stufen -- von der Weltkarte bis zum Item-Detail
---
## 1. Die Vision: Fraktaler Zoom
Das Spiel funktioniert wie Google Maps fuer Spielwelten: Je naeher man zoomt, desto mehr Detail erscheint. Jede Zoom-Stufe hat ihre eigene Pixel-Resolution und ihren eigenen Gameplay-Fokus.
```
ZOOM OUT ──────────────────────────────────────────── ZOOM IN
Weltkarte Region Stadt/Dorf Strasse Innenraum Detail
(spaeter) (spaeter) (spaeter) (MVP) (MVP) (MVP)
🗺️ 🏔️ 🏘️ 🚶 🏠 🔍
1 Pixel 1 Pixel 1 Pixel 1 Pixel 1 Pixel 1 Pixel
= 100m = 10m = 1m = 10cm = 5cm = 1cm
```
### Was der Spieler erlebt
```
Spaeter (Post-MVP):
Weltkarte aufmachen → "Ich sehe Kontinente, Ozeane, Staedte als Punkte"
In eine Stadt klicken → "Ich sehe Strassen, Gebaeude von oben, Plaetze"
MVP:
In eine Strasse gehen → "Ich laufe durch die Strasse, sehe Haeuser,
Laternen, andere Spieler, NPCs"
In ein Haus gehen → "Ich bin drin. Moebel, Treppen, Teppiche.
Ich gehe nach oben -- zweites Stockwerk."
Ein Item anschauen → "Ich oeffne den Detail-View. Jeder Pixel
des Schwerts ist sichtbar. Gravuren, Farben."
```
---
## 2. Die sechs Zoom-Stufen
### Uebersicht
| Stufe | Name | Pixel = | Sichtfeld | Gameplay | Phase |
|-------|------|---------|-----------|----------|-------|
| 1 | Weltkarte | 100m | Ganze Welt | Navigation, Strategie | Spaeter |
| 2 | Region | 10m | ~5km × 5km | Reisen, Ueberblick | Spaeter |
| 3 | Stadt/Dorf | 1m | ~500m × 500m | Erkunden, Orientierung | Spaeter |
| 4 | **Strasse** | **10cm** | **~50m × 30m** | **Laufen, Interaktion, Kampf** | **MVP** |
| 5 | **Innenraum** | **5cm** | **~20m × 15m** | **Erkunden, Einrichten, Raetsel** | **MVP** |
| 6 | **Detail** | **1cm** | **~2m × 1.5m** | **Items/Chars betrachten, editieren** | **MVP** |
### Stufe 4: Strasse (10cm) -- Der Hauptspiel-View
```
┌─────────────────────────────────────────────────────────────┐
│ │
│ ██████████ ████████████ ███████████████ │
│ █ Baecker █ █ Schmiede █ █ Taverne █ │
│ █ [Tuer] █ █ [Tuer] █ █ [Tuer] █ │
│ ██████████ ████████████ ███████████████ │
│ │
│ 🌳 🪑 ⚒️ 🌳 💡 │
│ │
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ░░░░░░░░░░░░░░░░░ STRASSE ░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ │
│ 🧑 (Spieler) 🧙 (NPC) 🐕 (Tier) │
│ │
│ ██████████ ████████████ │
│ █ Haus A █ █ Haus B █ 🌳 🌳 │
│ █ [Tuer] █ █ [Tuer] █ │
│ ██████████ ████████████ │
│ │
└─────────────────────────────────────────────────────────────┘
Resolution: 1 Pixel = 10cm
Sichtfeld: ~50m × 30m (500 × 300 Pixel auf Screen bei 1:1)
Gerendert: Skaliert auf Display-Resolution (z.B. 1920×1080)
Der Spieler sieht: Gebaeude von oben, Strassen, Baeume, andere Spieler
Der Spieler kann: Laufen, mit Tueren interagieren (→ Innenraum),
NPCs ansprechen, Items aufheben, kaempfen
```
**Welt-Daten bei 10cm:**
- Eine Strasse (50m × 30m): 500 × 300 = 150.000 Pixel = 300 KB roh, ~15 KB komprimiert
- Ein Stadtviertel (200m × 200m): 2.000 × 2.000 = 4M Pixel = 8 MB roh, ~400 KB komprimiert
- Layer: Boden, Objekte, Dach/Decke (3 Layer) = ×3
### Stufe 5: Innenraum (5cm) -- Haeuser und Dungeons
```
┌─────────────────────────────────────────────────────────────┐
│ │
│ ████████████████████████████████████████████████████████ │
│ █ █ │
│ █ ┌────────┐ ┌──────────────┐ ┌───────────┐ █ │
│ █ │ Regal │ │ │ │ Kamin │ █ │
│ █ │ ▪▪▪▪▪ │ │ Tisch │ │ 🔥 │ █ │
│ █ │ ▪▪▪▪▪ │ │ ▫ ▫ ▫ ▫ │ │ │ █ │
│ █ │ ▪▪▪▪▪ │ │ │ └───────────┘ █ │
│ █ └────────┘ └──────────────┘ █ │
│ █ █ │
│ █ 🪑 🪑 🧑 ┌──────────────┐ █ │
│ █ (Spieler) │ Truhe 🔒 │ █ │
│ █ │ ▪▪▪▪▪▪▪▪▪ │ █ │
│ █ ┌──────────┐ └──────────────┘ █ │
│ █ │ Bett │ 🕯️ █ │
│ █ │ ░░░░░░ │ █ │
│ █ │ ░░░░░░ │ [Treppe ↑ OG] █ │
│ █ └──────────┘ █ │
│ █ █ │
│ ████████████░░░░████████████████████████████████████████ █
│ (Tuer → Strasse) │
└─────────────────────────────────────────────────────────────┘
Resolution: 1 Pixel = 5cm (doppelt so detailliert wie Strasse!)
Sichtfeld: ~20m × 15m (400 × 300 Pixel bei 1:1)
Der Spieler sieht: Moebel im Detail, Buchruecken im Regal,
Muster auf Teppichen, Kerzenflammen
Der Spieler kann: Moebel platzieren, Truhen oeffnen, Treppen steigen,
Items untersuchen (→ Detail-View)
```
**Stockwerke:**
```
Stockwerk-System (Layer-basiert):
OG: [Schlafzimmer] [Bad] [Balkon] ← Layer 2
─────────────────────────────
EG: [Wohnzimmer] [Kueche] [Flur] ← Layer 1 (Standard)
─────────────────────────────
UG: [Keller] [Geheimraum] ← Layer 0
Spieler geht auf Treppe → Fade-Transition → anderer Layer sichtbar
Aktuelles Stockwerk: Volle Opacity
Anderes Stockwerk: Ausgeblendet oder 20% Opacity als Schatten
```
**Welt-Daten bei 5cm:**
- Ein Raum (8m × 6m): 160 × 120 = 19.200 Pixel = 38 KB roh
- Ein ganzes Haus (20m × 15m, 3 Stockwerke): 400 × 300 × 3 = 360.000 Pixel = 720 KB roh, ~35 KB komprimiert
- Trivial!
### Stufe 6: Detail-View (1cm) -- Items und Charaktere
```
┌─────────────────────────────────────────────────────────────┐
│ │
│ DETAIL VIEW: "Flammenklinge" [X Zurueck]│
│ │
│ ┌────────────────────────────────┐ ┌───────────────────┐ │
│ │ │ │ Eigenschaften: │ │
│ │ ░░▓░░ │ │ │ │
│ │ ░▓█▓░ │ │ Schaden: 80 │ │
│ │ ░▓███▓░ │ │ Element: Feuer │ │
│ │ ░▓█████▓░ │ │ Haltb.: 95/100 │ │
│ │ ░▓███▓░ │ │ Seltenheit: Leg. │ │
│ │ ░▓█▓░ │ │ │ │
│ │ ░▓░ │ │ Verhalten: │ │
│ │ ░▓░ │ │ ┌────────────────┐│ │
│ │ ░▓░ │ │ │WENN benutzt ││ │
│ │ ░▓░ │ │ │DANN Feuerball ││ │
│ │ ░▓▓▓░ │ │ │UND 10 Schaden ││ │
│ │ ░▓▓▓▓▓░ │ │ └────────────────┘│ │
│ │ ░▓█▓░ │ │ │ │
│ │ ░▓░ │ │ [Bearbeiten] │ │
│ │ ░▓░ │ │ [Duplizieren] │ │
│ │ │ │ [Teilen] │ │
│ └────────────────────────────────┘ └───────────────────┘ │
│ │
│ Canvas: 64 × 128 Pixel bei 1cm │
│ Erstellt von: alice | Trades: 47 | Likes: 312 │
│ │
└─────────────────────────────────────────────────────────────┘
Resolution: 1 Pixel = 1cm
Canvas: 64 × 128 (oder frei waehlbar bis 128 × 128)
Items: Schwert, Trank, Ring, Buch, Schluessel...
Charaktere: Avatar von allen Seiten, mit Zubehoer
Moebel: Stuhl, Tisch, Lampe im Detail
Hier wird auch EDITIERT:
→ Sprite-Editor oeffnet sich im gleichen View
→ Pixel fuer Pixel zeichnen
→ Properties und Verhalten zuweisen
```
**Welt-Daten bei 1cm:**
- Ein Item (64 × 128): 8.192 Pixel = 16 KB roh, ~2 KB komprimiert
- 100 Items im Inventar: ~200 KB komprimiert
- Trivial!
---
## 3. Wie die Stufen verbunden sind
### Uebergaenge (MVP)
```
STRASSE (10cm)
│ Spieler geht auf Tuer-Pixel
│ → Fade/Slide-Transition (~0.3s)
INNENRAUM (5cm)
│ Spieler geht auf Treppe
│ → Fade (~0.2s) → anderes Stockwerk
│ Spieler interagiert mit Item/Moebel
│ → Detail-Panel oeffnet sich (Slide-In)
DETAIL VIEW (1cm)
│ [X] oder Escape → zurueck zum Innenraum
INNENRAUM
│ Spieler geht auf Tuer → zurueck zur Strasse
STRASSE
```
### Uebergaenge (Spaeter)
```
WELTKARTE (100m/px) → Klick auf Stadt → STADT (1m/px)
STADT (1m/px) → Klick auf Strasse/Laufen → STRASSE (10cm/px)
STRASSE (10cm/px) → Tuer → INNENRAUM (5cm/px)
INNENRAUM (5cm/px) → Item anklicken → DETAIL (1cm/px)
Jede Stufe ist ein eigener "Raum" mit eigenen Daten.
Uebergaenge sind wie Tuer-Portale in Zelda: Fade → Neuer Raum laedt.
```
### Daten-Hierarchie
```
World
├── (spaeter) regions[]
│ ├── (spaeter) towns[]
│ │ ├── streets[] ← MVP: Hier startet der Spieler
│ │ │ ├── tiles (10cm) ← Pixel-Grid der Strasse
│ │ │ ├── entities[] ← NPCs, Items, Spieler
│ │ │ └── portals[] ← Tueren zu Innenraeumen
│ │ │ └── interior
│ │ │ ├── floors[] ← Stockwerke
│ │ │ │ └── tiles (5cm)
│ │ │ ├── furniture[] ← Moebel (platzierte Items)
│ │ │ └── entities[]
│ │ └── portals[] ← Strasse-zu-Strasse-Verbindungen
│ └── connections[] ← Region-zu-Region
└── items[] ← Globaler Item-Katalog (1cm Sprites)
```
---
## 4. Resolution & Memory: Die Zahlen
### Pro Zoom-Stufe
| Stufe | Pixel/m | Typische Area | Pixel total | RAM (3 Layer) | Komprimiert |
|-------|---------|--------------|-------------|---------------|-------------|
| Strasse | 10 | 50m × 30m | 150K | 900 KB | ~50 KB |
| Innenraum | 20 | 20m × 15m × 3 Etagen | 540K | 3.2 MB | ~160 KB |
| Detail-Item | 100 | 0.64m × 1.28m | 8K | 16 KB | ~2 KB |
### Eine komplette Spielwelt (MVP)
```
Ein Dorf mit 5 Strassen und 20 Haeusern:
Strassen: 5 × 50 KB = 250 KB
Innenraeume: 20 × 160 KB = 3.2 MB
Items: 200 × 2 KB = 400 KB
Entities: 100 × 1 KB = 100 KB
────────────────────────────────────
TOTAL: ~4 MB komprimiert
→ Laedt in <1 Sekunde
→ Passt 100× in den Browser-Speicher
→ Netzwerk-Transfer: trivial
```
### Spaetere Stufen (Post-MVP)
```
Stadt-View hinzufuegen:
Eine Stadt (500m × 500m bei 1m/px): 500 × 500 = 250K Pixel = 500 KB roh
Komprimiert: ~25 KB
→ Trivial
Region-View:
Eine Region (5km × 5km bei 10m/px): 500 × 500 = 250K Pixel = 500 KB
→ Trivial
Weltkarte:
Eine Welt (50km × 50km bei 100m/px): 500 × 500 = 250K Pixel = 500 KB
→ Trivial
ALLE Zoom-Stufen zusammen: <10 MB. Kein Problem.
```
---
## 5. Technischer Stack
### Architektur
```
╔═══════════════════════════════════════════════════════════╗
║ BROWSER (PixiJS + Svelte 5 + Dexie.js) ║
║ ║
║ ┌──────────────────────────┐ ┌───────────────────────┐ ║
║ │ PixiJS 8 (WebGL/WebGPU) │ │ Svelte 5 UI │ ║
║ │ │ │ │ ║
║ │ TilemapRenderer │ │ HUD / Inventar │ ║
║ │ → Strasse (10cm Layer) │ │ Dialog-System │ ║
║ │ → Innenraum (5cm Layer) │ │ Pixel-Editor │ ║
║ │ SpriteRenderer │ │ Sprite-Editor │ ║
║ │ → Entities, Items │ │ Property Sliders │ ║
║ │ LightingSystem │ │ Trigger-Action Builder │ ║
║ │ → 2D Raycasts │ │ Code Editor (Monaco) │ ║
║ │ ParticleSystem │ │ Chat, Social │ ║
║ │ TransitionManager │ │ Marketplace │ ║
║ │ → Zoom-Stufen-Wechsel │ │ Minimap │ ║
║ └─────────────┬────────────┘ └──────────┬────────────┘ ║
║ │ │ ║
║ ┌─────────────▼───────────────────────────▼────────────┐║
║ │ Dexie.js (IndexedDB) -- Local-First ║║
║ │ Streets, Interiors, Items, Inventory (alles offline!) ║║
║ └───────────────────────┬──────────────────────────────┘║
╚══════════════════════════╪════════════════════════════════╝
│ WebSocket + REST
╔══════════════════════════╪════════════════════════════════╗
║ GAME SERVER (Go) ║
║ ║
║ ┌───────────────────────────────────────────────────┐ ║
║ │ mana-game-server (Go) │ ║
║ │ │ ║
║ │ 1 Goroutine pro aktive Strasse/Innenraum │ ║
║ │ Welt-State: map[AreaID]*Area (Pixel-Grid + Entities)│ ║
║ │ Physik: 2D AABB Collision (simple, custom) │ ║
║ │ Scripting: wazero (WASM) fuer Item-Scripts │ ║
║ │ Networking: coder/websocket │ ║
║ │ Tick Rate: 20 Hz (50ms, wie Minecraft) │ ║
║ └───────────────────────────────────────────────────┘ ║
║ ║
║ ┌───────────────────────────────────────────────────┐ ║
║ │ mana-area-manager (Go) │ ║
║ │ Laedt/entlaedt Areas on-demand │ ║
║ │ Routet Spieler zwischen Areas │ ║
║ │ Managed Uebergaenge (Strasse ↔ Innenraum) │ ║
║ └───────────────────────────────────────────────────┘ ║
╠═══════════════════════════════════════════════════════════╣
║ BESTEHENDE SERVICES (unveraendert) ║
║ mana-auth │ mana-credits │ mana-sync │ mana-notify ║
║ mana-user │ mana-sub │ mana-analytics │ mana-search ║
║ mana-llm │ mana-image-gen │ mana-stt │ mana-tts ║
╠═══════════════════════════════════════════════════════════╣
║ DATA ║
║ PostgreSQL │ TigerBeetle │ Dragonfly │ MinIO │ Dexie.js ║
║ + Meilisearch │ + ClickHouse (spaeter) ║
╠═══════════════════════════════════════════════════════════╣
║ INFRA (Self-Hosted, Mac Mini) ║
║ Forgejo │ Grafana │ Loki │ GlitchTip │ Cloudflare Tunnel║
╚═══════════════════════════════════════════════════════════╝
```
### Warum dieser Stack?
| Entscheidung | Begruendung |
|-------------|-------------|
| **PixiJS 8** statt Phaser/Three.js | Schnellster 2D-Renderer, WebGPU-ready, kein Framework-Overhead |
| **Svelte 5** fuer UI | Bestehende Expertise, 19 Apps, Runes |
| **Go** Game Server | Goroutines = 1 pro Area, bestehende Expertise, kein Rust noetig |
| **wazero** fuer Scripts | WASM in Go, kein CGo, sandboxed |
| **WebSocket** statt WebTransport | Reicht fuer 2D (keine unreliable datagrams noetig bei 20Hz) |
| **Dexie.js** Local-First | Bestehend, 19 Apps, Offline-Editor |
| **TigerBeetle** Economy | Double-Entry, 70% Creator Share |
| **Dragonfly** statt Redis | Drop-in Upgrade, multi-threaded |
### Rendering-Architektur (PixiJS)
```
PixiJS Application
├── Stage
│ ├── WorldContainer (aktuelle Zoom-Stufe)
│ │ ├── BackgroundLayer (Tilemap: Boden, Wasser, Gras)
│ │ ├── ObjectLayer (Tilemap: Waende, Moebel, Baeume)
│ │ ├── EntityLayer (Sprites: Spieler, NPCs, Items)
│ │ ├── EffectLayer (Partikel, Projectiles)
│ │ └── LightLayer (2D Lighting Overlay)
│ │
│ ├── UIContainer (Svelte-managed, HTML Overlay)
│ │ ├── HUD (HP, Mana, Minimap)
│ │ ├── Inventar
│ │ ├── Dialog-Fenster
│ │ └── Editor-Panels
│ │
│ └── TransitionOverlay (Fade/Slide bei Zoom-Wechsel)
└── Ticker (60fps Game Loop)
├── InputSystem (Keyboard, Mouse, Touch)
├── PhysicsSystem (2D AABB, simple)
├── AnimationSystem (Sprite Frames)
├── ScriptSystem (WASM Trigger-Evaluation)
├── NetworkSystem (WebSocket Sync)
└── RenderSystem (PixiJS Draw)
```
### Layer-System fuer Stockwerke
```
Innenraum mit 3 Stockwerken:
Layer 0 (Keller):
├── floor_tiles (5cm) Steinboden
├── wall_tiles (5cm) Waende
├── objects[] Truhen, Faesser
└── entities[] Ratten, Spinnen
Layer 1 (Erdgeschoss): ← Spieler ist hier
├── floor_tiles (5cm) Holzboden
├── wall_tiles (5cm) Waende mit Fenstern
├── objects[] Moebel, Kamin
└── entities[] NPC, Katze
Layer 2 (Obergeschoss):
├── floor_tiles (5cm) Teppich
├── wall_tiles (5cm) Waende
├── objects[] Bett, Schrank
└── entities[] -
Rendering:
Aktueller Layer: 100% Opacity, voll interaktiv
Layer darüber: Nicht sichtbar (oder 10% als Schatten)
Layer darunter: Nicht sichtbar (oder 10% als Schatten)
Treppe: Special Tile das bei Betreten den Layer wechselt
```
---
## 6. Der Area-Editor
### Strassen-Editor (10cm)
```
┌─────────────────────────────────────────────────────┐
│ STRASSEN-EDITOR: "Marktplatz" [▶ Testen]│
├─────────────────────────────────────────────────────┤
│ Werkzeuge: │
│ [Pinsel][Radierer][Fuellen][Box][Auswahl] │
│ [Tuer platzieren][NPC platzieren][Item platzieren] │
├─────────────────────────────────────────────────────┤
│ │
│ ██████████ ████████████ ██████████ │
│ █ Shop A █ █ Brunnen █ █ Shop B █ │
│ █ 🚪 █ █ 💧 █ █ 🚪 █ │
│ ██████████ ████████████ ██████████ │
│ │
│ 💡 🌳 🌳 💡 │
│ │
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ░░░░░░░░░░░░░ KOPFSTEINPFLASTER ░░░░░░░░░░░░░ │
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ │
├─────────────────────────────────────────────────────┤
│ Layer: [Boden ▼] Palette: [█ Stein][█ Holz][...] │
│ Groesse: 50m × 30m Pixel: 500 × 300 │
└─────────────────────────────────────────────────────┘
🚪 = Tuer-Portal (verlinkt zu einem Innenraum)
💡 = Laterne (Lichtquelle, Item mit Leucht-Property)
🌳 = Baum (Objekt-Sprite)
💧 = Brunnen (interaktives Objekt)
```
### Innenraum-Editor (5cm)
```
┌─────────────────────────────────────────────────────┐
│ INNENRAUM-EDITOR: "Schmiede EG" [▶ Testen] │
├─────────────────────────────────────────────────────┤
│ Werkzeuge: │
│ [Pixel][Radierer][Fuellen][Moebel platzieren] │
│ [Stockwerk: EG ▼] [+ Stockwerk] [Treppe setzen] │
├─────────────────────────────────────────────────────┤
│ │
│ ████████████████████████████████████████████████ │
│ █ █ │
│ █ [Amboss] [Schmelzofen] █ │
│ █ █ │
│ █ [Werkbank mit Werkzeug] █ │
│ █ █ │
│ █ 🔥 (Feuer, leuchtet) █ │
│ █ █ │
│ █ [Waffenstaender] [Regal mit Erzen] █ │
│ █ █ │
│ █ [Treppe ↑ OG] █ │
│ ████████████░░░░░░░░████████████████████████████ │
│ Tuer → Strasse │
├─────────────────────────────────────────────────────┤
│ Layer: [Objekte ▼] Stockwerk: [EG ▼] │
│ Groesse: 12m × 8m Pixel: 240 × 160 │
└─────────────────────────────────────────────────────┘
```
### Sprite-Editor (1cm) -- Items & Charaktere
```
┌────────────────────────────────────────────────────────┐
│ SPRITE-EDITOR: "Flammenschwert" [X Zurueck] │
├────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────┐ ┌────────────────────────┐ │
│ │ │ │ Werkzeuge: │ │
│ │ Pixel-Canvas │ │ [Pinsel 1px] │ │
│ │ 64 × 128 bei 1cm │ │ [Pinsel 3px] │ │
│ │ │ │ [Radierer] │ │
│ │ (Schwert-Form │ │ [Fuellen] │ │
│ │ wird hier │ │ [Pipette] │ │
│ │ Pixel fuer │ │ [Spiegeln H/V] │ │
│ │ Pixel gemalt) │ │ [Drehen 90°] │ │
│ │ │ │ │ │
│ │ │ │ Palette: │ │
│ │ │ │ [█][█][█][█][█][█][+] │ │
│ │ │ │ │ │
│ └──────────────────────┘ │ Animation: │ │
│ │ Frame: [1/4] │ │
│ Vorschau: │ [◀][▶][+ Frame] │ │
│ ┌──────┐ ┌──────┐ │ [▶ Abspielen] │ │
│ │ 1x │ │ 2x │ │ │ │
│ │ 🗡️ │ │ 🗡️ │ │ Anchor: [Mitte-Unten ▼] │ │
│ └──────┘ └──────┘ │ Hitbox: [Auto ▼] │ │
│ └────────────────────────┘ │
├────────────────────────────────────────────────────────┤
│ [Properties] [Verhalten] [Testen] [Speichern] │
└────────────────────────────────────────────────────────┘
```
---
## 7. Programmierbare Items (gleich wie 3D)
Identisches 3-Ebenen-System:
```
Ebene 1: Sliders (ab 6 Jahre) → Werte einstellen
Ebene 2: Trigger-Actions (ab 8) → WENN X DANN Y
Ebene 3: TypeScript (ab 12+) → Voller Code → WASM
Alle kompilieren zu WASM → laufen in wazero auf dem Go-Server.
```
### 2D-spezifische Trigger & Actions
**Trigger:**
- Spieler beruehrt / betritt Bereich / verlaesst Bereich
- Spieler interagiert (Klick / Taste)
- Timer (alle X Sekunden)
- Tageszeit / Wetter
- HP/Mana unter/ueber X
- Anderes Item in Radius
- Spieler betritt Stockwerk / Area
- NPC-Dialog-Option gewaehlt
**Actions:**
- Schaden / Heilen
- Partikel (2D) / Sound abspielen
- Pixel setzen / loeschen (Welt veraendern!)
- Tuer oeffnen / schliessen
- Licht ein/aus / Farbe aendern
- Teleport (innerhalb Area oder zu anderer Area)
- Nachricht / Dialog anzeigen
- Variable setzen / abfragen
- Item geben / nehmen
- NPC bewegen / Animation abspielen
- Kamera-Effekt (Shake, Zoom, Flash)
---
## 8. Multiplayer
### Area-basiertes Multiplayer
```
Jede Area (Strasse oder Innenraum) ist eine eigene Server-Instanz.
Spieler A ist auf Strasse "Marktplatz":
→ Verbunden mit Goroutine "marktplatz_001"
→ Sieht andere Spieler auf dem Marktplatz
→ Sieht NICHT Spieler in Haeusern
Spieler A geht in die Schmiede:
→ Wechselt zu Goroutine "schmiede_eg_001"
→ Sieht Spieler in der Schmiede
→ Marktplatz-Goroutine laeuft weiter (fuer andere Spieler)
Server-Architektur:
mana-game-server (Go)
├── World "bobs-village"
│ ├── Area "marktplatz" → Goroutine (5 Spieler)
│ ├── Area "schmiede_eg" → Goroutine (2 Spieler)
│ ├── Area "schmiede_og" → Goroutine (0 → suspended)
│ ├── Area "taverne_eg" → Goroutine (3 Spieler)
│ └── Area "taverne_keller" → Goroutine (1 Spieler)
└── World "alices-dungeon"
├── Area "eingang" → Goroutine (4 Spieler)
└── Area "bosskammer" → Goroutine (4 Spieler)
```
**Vorteile dieses Ansatzes:**
- Jede Area ist klein (~50 KB State) → tausende koennen gleichzeitig laufen
- Leere Areas werden suspendiert (0 CPU)
- Spieler sehen nur relevante andere Spieler
- Kein kompliziertes Interest Management (Area = Interest Boundary)
- Go-Goroutines sind perfekt dafuer (~4 KB Stack pro Goroutine)
### Bandbreite pro Spieler
```
Area-Wechsel: ~50-200 KB (komprimierte Area laden)
Laufend:
Spieler-Positionen: 20Hz × ~20 Bytes × Spieler-in-Area = ~2 KB/s
Pixel-Aenderungen: ~0.5 KB/s
Chat + Events: ~0.5 KB/s
Total: ~3 KB/s pro Spieler
→ Mac Mini mit 100 Mbit/s Upload: ~3.000 gleichzeitige Spieler
```
---
## 9. Datenmodell
### PostgreSQL
```sql
-- Welten
CREATE TABLE worlds (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
creator_id UUID NOT NULL,
name TEXT NOT NULL,
description TEXT,
is_published BOOLEAN DEFAULT false,
play_count INTEGER DEFAULT 0,
settings JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- Areas (Strassen, Innenraeume)
CREATE TABLE areas (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
world_id UUID NOT NULL REFERENCES worlds(id) ON DELETE CASCADE,
name TEXT NOT NULL,
type TEXT NOT NULL, -- 'street', 'interior', 'dungeon'
resolution REAL NOT NULL, -- 0.10 oder 0.05
width INTEGER NOT NULL, -- in Pixeln
height INTEGER NOT NULL,
floors INTEGER DEFAULT 1, -- Anzahl Stockwerke
pixel_data BYTEA NOT NULL, -- Komprimiert (alle Layer)
palette JSONB DEFAULT '[]',
entities JSONB DEFAULT '[]', -- NPCs, Items, Lichtquellen
portals JSONB DEFAULT '[]', -- Tueren zu anderen Areas
spawn_point JSONB, -- Wo Spieler erscheinen
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- Items (Sprites + Properties + Behavior)
CREATE TABLE items (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
creator_id UUID NOT NULL,
name TEXT NOT NULL,
description TEXT,
sprite_data BYTEA NOT NULL, -- PNG oder Roh-Pixel komprimiert
sprite_width INTEGER NOT NULL,
sprite_height INTEGER NOT NULL,
animation_frames INTEGER DEFAULT 1,
resolution REAL DEFAULT 0.01, -- 1cm fuer Items
properties JSONB DEFAULT '{}',
behavior JSONB DEFAULT '[]',
script TEXT,
wasm_binary BYTEA,
rarity TEXT DEFAULT 'common',
capabilities TEXT[] DEFAULT '{}',
is_published BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ DEFAULT now()
);
-- Portale (Verbindungen zwischen Areas)
CREATE TABLE portals (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
from_area_id UUID NOT NULL REFERENCES areas(id),
to_area_id UUID NOT NULL REFERENCES areas(id),
from_position JSONB NOT NULL, -- {x, y, floor}
to_position JSONB NOT NULL, -- {x, y, floor}
requires_key UUID REFERENCES items(id) -- Optional: Item zum Oeffnen
);
-- Inventar
CREATE TABLE inventories (
player_id UUID NOT NULL,
item_id UUID NOT NULL,
slot INTEGER NOT NULL,
quantity INTEGER DEFAULT 1,
instance_data JSONB DEFAULT '{}',
PRIMARY KEY (player_id, item_id, slot)
);
```
### Dexie.js (Client-Side)
```typescript
const db = new Dexie('manavoxel');
db.version(1).stores({
worlds: 'id, creatorId, name, isPublished, updatedAt',
areas: 'id, worldId, name, type, updatedAt',
items: 'id, creatorId, name, rarity, updatedAt',
portals: 'id, fromAreaId, toAreaId',
inventories: '[playerId+itemId+slot], playerId',
settings: 'key'
});
```
---
## 10. Build-Plan
### Phase 0: Proof of Concept (2 Wochen)
```
Woche 1: PixiJS + Tilemap
□ PixiJS 8 + SvelteKit Setup
□ Tilemap-Renderer (10cm, 500 × 300)
□ Kamera: Scroll + Zoom
□ 10 Materialien (Stein, Holz, Gras, Wasser, Sand, ...)
□ Pixel-Editor: Setzen/Loeschen/Fuellen
□ Undo/Redo
Woche 2: Spieler + Physik
□ Charakter-Sprite (Standard, 4 Richtungen)
□ 2D AABB Kollision mit Tilemap
□ Laufen in 8 Richtungen
□ Tueren: Portal zu anderem Tilemap (Innenraum-Prototyp)
Ergebnis: Zelda-aehnlich im Browser, Welt editierbar, Tuer fuehrt in Raum
```
### Phase 1: Zoom-Stufen + Editor (3 Wochen)
```
Woche 3: Innenraum (5cm)
□ Innenraum-Renderer (5cm Tilemap, 3 Layer fuer Stockwerke)
□ Treppen (Layer-Wechsel mit Transition)
□ Moebel als platzierbare Objekte
□ Portal-System: Strasse ↔ Innenraum
Woche 4: Detail-View + Sprite-Editor
□ Detail-View Panel (Svelte, 1cm Canvas)
□ Sprite-Editor (Pixel-fuer-Pixel, 64×128)
□ Farb-Palette, Pinsel, Spiegeln
□ Animation Frames (Spritesheet)
□ "Als Item speichern"
Woche 5: Items in der Welt
□ Item im Inventar (Svelte UI)
□ Item in der Hand halten
□ Item in der Welt ablegen / aufheben
□ Moebel platzieren (Innenraum einrichten)
Ergebnis: Strasse → Haus betreten → Moebel platzieren →
Item zeichnen → in die Welt bringen
```
### Phase 2: Programmierung (3 Wochen)
```
Woche 6: Property Sliders
□ Property-Panel (Svelte): Schaden, Element, Haltbarkeit...
□ Standard-Verhalten pro Property-Kombination
□ Item benutzen → Effekt sichtbar (Partikel, Sound)
Woche 7: Trigger-Actions
□ Trigger-Action Builder UI (Svelte)
□ 10 Trigger + 15 Actions
□ Trigger-Action → TypeScript → WASM Compilation
□ wazero Sandbox auf Go-Server
Woche 8: Interaktive Welt
□ Items interagieren mit Welt (Pixel zerstoeren, setzen)
□ Items interagieren miteinander (Events)
□ NPCs (einfach: feste Position, Dialog bei Interaktion)
□ Licht-System (2D Raycast, optional)
Ergebnis: Spieler baut Schwert → gibt ihm Feuer → benutzt es →
Pixel-Explosion an der Wand → Geheimgang dahinter!
```
### Phase 3: Multiplayer (3 Wochen)
```
Woche 9: Go Game Server
□ mana-game-server (Go)
□ Area-basiertes Multiplayer (1 Goroutine pro Area)
□ WebSocket (coder/websocket)
□ Pixel-Sync (Delta-Kompression)
Woche 10: Multiplayer-Sync
□ Spieler-Positionen
□ Area-Wechsel (Spieler geht in Haus → verschwindet auf Strasse)
□ Item-Sync + Inventar
□ Server-autoritative Validierung
Woche 11: Social Features
□ Text-Chat (per Area)
□ Emotes
□ PvP (Items benutzen gegen andere Spieler)
□ Welt-Link teilen
Ergebnis: 2-20 Spieler im gleichen Dorf, betreten Haeuser,
kaempfen, handeln, chatten
```
### Phase 4: Platform (3 Wochen)
```
Woche 12: Auth + Persistence
□ mana-auth Integration
□ Welten in PostgreSQL speichern
□ Local-First (Dexie.js ↔ mana-sync)
□ Guest Mode
□ Offline-Editor
Woche 13: Discovery + Economy
□ Welt veroeffentlichen
□ Welt-Suche (Meilisearch)
□ TigerBeetle: Mana-Waehrung
□ Item-Marketplace (einfach)
□ Creator-Profil
Woche 14: Polish + Launch
□ Onboarding Tutorial ("Baue dein erstes Haus")
□ Welt-Templates (Dorf, Dungeon, Arena, Haus)
□ Mobile Touch-Steuerung
□ Performance-Optimierung
□ Bug Fixes
Ergebnis: MVP FERTIG! Spielbare 2D-Plattform im Browser.
```
### Timeline
```
Woche 1 2 3 4 5 6 7 8 9 10 11 12 13 14
[PoC ][Zoom+Editor ][Programmier.][Multiplayer][Platform ]
Monat 1 2 3 3.5
MVP spielbar nach: ~14 Wochen (3.5 Monate)
```
### Post-MVP Roadmap
```
Phase 5 (Monat 4-5): AI + Voice
□ AI NPCs (mana-llm, Dialog-System)
□ Voice Chat (mana-stt + WebRTC)
□ AI Palette-Generierung (mana-image-gen)
□ TypeScript Scripting (Ebene 3)
Phase 6 (Monat 5-6): Advanced World
□ Tag/Nacht-Zyklus
□ Wetter (Regen-Pixel, Schnee)
□ Erweiterte Physik (Wasser fliessen, Sand fallen)
□ Voxel-Destruction (Krater, Truemmer)
Phase 7 (Monat 6-8): Zoom-Out-Stufen
□ Stadt-View (1m/px) -- Strassen verbinden
□ Region-View (10m/px) -- Staedte verbinden
□ Weltkarte (100m/px) -- Ueberblick
Phase 8 (Monat 8+): Scale + Community
□ Gilden / Gruppen
□ Events / Wettbewerbe
□ Advanced Economy (Handel, Auktionen)
□ Cross-Game Items
□ Community-Moderation-Tools
```
---
## 11. Zusammenfassung
```
PROJEKT: ManaVoxel 2D
ANSICHT: Top-Down, 6 Zoom-Stufen
RESOLUTION: Strasse 10cm, Innenraum 5cm, Items 1cm
STACK: PixiJS 8 + Svelte 5 + Go Server + Dexie.js
SPRACHEN: TypeScript (90%) + Go (10%)
MVP: 14 Wochen (3.5 Monate)
FEATURES MVP: Strasse + Innenraum + Stockwerke + Item-Editor
+ 3 Programmier-Ebenen + Multiplayer + Economy
+ Local-First + Guest Mode + Offline-Editor
SPAETER: Stadt-View, Region, Weltkarte, AI NPCs, Voice
HOSTING: Mac Mini (Self-Hosted) + Cloudflare
ECONOMY: TigerBeetle, 70% Creator Revenue
WIEDERVERW.: 14 bestehende Services direkt nutzbar
NEUER CODE: ~15.000-25.000 Zeilen TypeScript + ~5.000 Zeilen Go
```
---
*Erstellt: 28. Maerz 2026*
*Projekt: ManaVoxel 2D -- Teil des Mana-Oekosystems*