diff --git a/games/mana-games/CLAUDE.md b/games/mana-games/CLAUDE.md
index 9620552cc..95c14bc9f 100644
--- a/games/mana-games/CLAUDE.md
+++ b/games/mana-games/CLAUDE.md
@@ -7,32 +7,55 @@ AI-powered browser games platform mit 22+ Spielen und KI-Spielgenerierung.
```
games/mana-games/
├── apps/
-│ ├── web/ # Astro PWA (@mana-games/web)
+│ ├── web/ # SvelteKit Web-App (@mana-games/web)
│ │ ├── src/
-│ │ │ ├── pages/ # Astro-Seiten
-│ │ │ ├── layouts/ # Layout-Komponenten
-│ │ │ ├── components/
-│ │ │ ├── data/ # Spielekatalog (games.ts)
-│ │ │ └── services/ # Stats, etc.
-│ │ └── public/
-│ │ ├── games/ # 22 HTML-Spiele
-│ │ ├── screenshots/
-│ │ └── icons/ # PWA Icons
+│ │ │ ├── routes/ # SvelteKit-Routen
+│ │ │ │ ├── (app)/ # App-Routen mit PillNavigation
+│ │ │ │ │ ├── play/[slug] # Spiel im iframe
+│ │ │ │ │ ├── create/ # AI Game Generator
+│ │ │ │ │ ├── community/ # Community-Spiele
+│ │ │ │ │ ├── stats/ # Spieler-Statistiken
+│ │ │ │ │ └── play-generated/ # Generierte Spiele
+│ │ │ │ └── (auth)/ # Login/Register
+│ │ │ └── lib/
+│ │ │ ├── components/ # Svelte 5 Komponenten
+│ │ │ ├── data/ # Local-first Store, Game-Katalog
+│ │ │ ├── stores/ # Theme, Auth, Navigation
+│ │ │ ├── services/ # Game-Kommunikation (postMessage)
+│ │ │ └── i18n/ # DE + EN Übersetzungen
+│ │ └── static/
+│ │ ├── games/ # 22 HTML-Spiele
+│ │ └── screenshots/ # Game-Thumbnails
+│ ├── web-astro/ # Alte Astro-App (Referenz, zum Löschen)
│ └── backend/ # NestJS API (@mana-games/backend)
│ └── src/
-│ ├── game-generator/ # AI-Spielgenerierung (OpenRouter)
+│ ├── game-generator/ # AI-Spielgenerierung (Gemini, Claude, GPT-4)
│ ├── game-submission/ # Community-Einreichungen (GitHub API)
│ └── health/
└── package.json # Root (mana-games)
```
+## Tech Stack
+
+| Aspekt | Technologie |
+|--------|-------------|
+| Frontend | SvelteKit 2 + Svelte 5 (Runes) |
+| Styling | Tailwind CSS 4 + @manacore/shared-tailwind |
+| Auth | @manacore/shared-auth (SSO) |
+| PWA | @vite-pwa/sveltekit + @manacore/shared-pwa |
+| State | @manacore/local-store (Dexie.js + sync) |
+| i18n | svelte-i18n (DE + EN) |
+| UI | @manacore/shared-ui (PillNav, AuthGate, etc.) |
+| Theming | @manacore/shared-theme (multi-theme) |
+| Backend | NestJS (AI-Generierung, Community) |
+
## Entwicklung
```bash
# Alles starten (Web + Backend)
pnpm mana-games:dev
-# Nur Web (Astro)
+# Nur Web (SvelteKit)
pnpm dev:mana-games:web
# Nur Backend (NestJS)
@@ -43,9 +66,23 @@ pnpm dev:mana-games:app
```
**Ports:**
-- Web: http://localhost:4321
+- Web: http://localhost:5210
- Backend: http://localhost:3011
+## Local-First Daten
+
+Stats und generierte Spiele werden in IndexedDB gespeichert (Dexie.js) mit optionalem Sync:
+
+**Collections:**
+- `gameStats` — Highscores, Spielzeit, Spiele pro Game
+- `generatedGames` — Mit KI erstellte Spiele (HTML, Prompt, Modell)
+- `favorites` — Favorisierte Spiele
+
+**Dateien:**
+- `src/lib/data/local-store.ts` — Dexie-Store Definition
+- `src/lib/data/queries.ts` — Reactive Queries (useLiveQuery)
+- `src/lib/data/games.ts` — Statischer Spielekatalog (21 Spiele)
+
## API Endpoints
| Endpoint | Method | Beschreibung |
@@ -59,10 +96,10 @@ pnpm dev:mana-games:app
```json
{
"description": "Ein Snake-Spiel im Neon-Stil",
- "mode": "create", // oder "iterate"
+ "mode": "create",
"model": "gemini-2.0-flash",
- "originalPrompt": "...", // nur bei iterate
- "currentCode": "..." // nur bei iterate
+ "originalPrompt": "...",
+ "currentCode": "..."
}
```
@@ -80,99 +117,43 @@ pnpm dev:mana-games:app
## Environment Variables
-Die Variablen werden zentral in `.env.development` verwaltet:
-
```bash
MANA_GAMES_BACKEND_PORT=3011
-
-# Google Gemini API
MANA_GAMES_GOOGLE_GENAI_API_KEY=your_key
-
-# Anthropic Claude API
MANA_GAMES_ANTHROPIC_API_KEY=your_key
-
-# Azure OpenAI API
MANA_GAMES_AZURE_OPENAI_ENDPOINT=https://your-endpoint.openai.azure.com
MANA_GAMES_AZURE_OPENAI_API_KEY=your_key
MANA_GAMES_AZURE_OPENAI_DEPLOYMENT=gpt-4o
-
-# GitHub (für Community-Einreichungen)
MANA_GAMES_GITHUB_TOKEN=your_token
MANA_GAMES_GITHUB_OWNER=tillschneider
MANA_GAMES_GITHUB_REPO=mana-games
```
-Nach Änderungen: `pnpm setup:env`
-
## Spiel hinzufügen
-1. HTML-Datei erstellen in `apps/web/public/games/spiel_name.html`
-2. Screenshot in `apps/web/public/screenshots/spiel-name.jpg`
-3. Registrieren in `apps/web/src/data/games.ts`:
-
-```typescript
-{
- id: '23',
- title: 'Spiel Titel',
- description: 'Beschreibung',
- slug: 'spiel-name',
- htmlFile: '/games/spiel_name.html',
- thumbnail: '/screenshots/spiel-name.jpg',
- tags: ['Arcade', 'Action'],
- difficulty: 'Mittel',
- complexity: 'Einfach',
- controls: 'Pfeiltasten zum Steuern'
-}
-```
+1. HTML-Datei in `apps/web/static/games/spiel_name.html`
+2. Screenshot in `apps/web/static/screenshots/spiel-name.jpg`
+3. Registrieren in `apps/web/src/lib/data/games.ts`
## Spiel-postMessage Integration
```javascript
// Beim Laden
-window.parent.postMessage({
- type: 'GAME_LOADED',
- gameId: 'spiel-slug'
-}, '*');
+window.parent.postMessage({ type: 'GAME_LOADED', gameId: 'spiel-slug' }, '*');
// Bei Score-Update
window.parent.postMessage({
- type: 'GAME_EVENT',
- gameId: 'spiel-slug',
- event: 'SCORE_UPDATE',
- data: { score: 123 }
+ type: 'GAME_EVENT', gameId: 'spiel-slug',
+ event: 'SCORE_UPDATE', data: { score: 123 }
}, '*');
// Bei Game Over
window.parent.postMessage({
- type: 'GAME_EVENT',
- gameId: 'spiel-slug',
- event: 'GAME_OVER',
- data: { score: 123 }
+ type: 'GAME_EVENT', gameId: 'spiel-slug',
+ event: 'GAME_OVER', data: { score: 123 }
}, '*');
```
-## Design
-
-**Farbschema:**
-- Primary Background: `#0a0a0a`
-- Secondary Background: `#1a1a1a`
-- Accent: `#00ff88`
-- Text: `#ffffff`
-- Border: `#2a2a2a`
-
-## PWA
-
-- Manifest: `apps/web/public/manifest.json`
-- Service Worker: `apps/web/public/sw.js`
-- Icons in `apps/web/public/icons/` (72x72 bis 512x512)
-
## Spielekatalog
-**22 Spiele** in folgenden Genres:
-- Arcade
-- Puzzle
-- Tower Defense
-- Idle/Incremental
-- Jump 'n' Run
-- Action
-- Strategie
+**21 Spiele** in folgenden Genres: Arcade, Puzzle, Tower Defense, Idle/Incremental, Jump 'n' Run, Action, Strategie
diff --git a/games/mana-games/apps/backend/src/main.ts b/games/mana-games/apps/backend/src/main.ts
index 8eab5c819..6c632accb 100644
--- a/games/mana-games/apps/backend/src/main.ts
+++ b/games/mana-games/apps/backend/src/main.ts
@@ -8,9 +8,9 @@ async function bootstrap() {
// CORS configuration
app.enableCors({
origin: [
- 'http://localhost:4321', // Astro dev
+ 'http://localhost:5210', // SvelteKit dev
+ 'http://localhost:4321', // Legacy Astro dev
'http://localhost:3000', // Alternative dev
- /\.netlify\.app$/, // Legacy Netlify
],
methods: ['GET', 'POST', 'OPTIONS'],
credentials: false,
diff --git a/games/mana-games/apps/web/.env.example b/games/mana-games/apps/web/.env.example
deleted file mode 100644
index b5ff4f29e..000000000
--- a/games/mana-games/apps/web/.env.example
+++ /dev/null
@@ -1,11 +0,0 @@
-# OpenRouter API Key
-# Get your API key from https://openrouter.ai/keys
-OPENROUTER_API_KEY=your_api_key_here
-
-# GitHub API Token (for community submissions)
-# Create a personal access token with 'repo' scope at https://github.com/settings/tokens
-GITHUB_TOKEN=your_github_token_here
-
-# GitHub Repository Settings (optional - defaults to current repo)
-GITHUB_OWNER=your_github_username
-GITHUB_REPO=mana-games
\ No newline at end of file
diff --git a/games/mana-games/apps/web/astro.config.mjs b/games/mana-games/apps/web/astro.config.mjs
deleted file mode 100644
index e762ba5cf..000000000
--- a/games/mana-games/apps/web/astro.config.mjs
+++ /dev/null
@@ -1,5 +0,0 @@
-// @ts-check
-import { defineConfig } from 'astro/config';
-
-// https://astro.build/config
-export default defineConfig({});
diff --git a/games/mana-games/apps/web/eslint.config.js b/games/mana-games/apps/web/eslint.config.js
deleted file mode 100644
index 62349efa0..000000000
--- a/games/mana-games/apps/web/eslint.config.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// @ts-check
-import {
- baseConfig,
- typescriptConfig,
- svelteConfig,
- prettierConfig,
-} from '@manacore/eslint-config';
-
-export default [
- {
- ignores: [
- 'dist/**',
- '.svelte-kit/**',
- '.astro/**',
- 'node_modules/**',
- '**/stats-integration-template.js',
- ],
- },
- ...baseConfig,
- ...typescriptConfig,
- ...svelteConfig,
- ...prettierConfig,
-];
diff --git a/games/mana-games/apps/web/package.json b/games/mana-games/apps/web/package.json
index b064a6624..a2f2309f7 100644
--- a/games/mana-games/apps/web/package.json
+++ b/games/mana-games/apps/web/package.json
@@ -1,19 +1,58 @@
{
"name": "@mana-games/web",
- "version": "1.0.0",
+ "version": "0.1.0",
"private": true,
- "type": "module",
"scripts": {
- "dev": "astro dev",
- "build": "rm -rf dist && astro build",
- "preview": "astro preview",
- "astro": "astro",
- "lint": "eslint ."
- },
- "dependencies": {
- "astro": "^5.10.1"
+ "dev": "vite dev",
+ "build": "vite build",
+ "preview": "vite preview",
+ "prepare": "svelte-kit sync || echo ''",
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
+ "lint": "eslint .",
+ "format": "prettier --write .",
+ "type-check": "svelte-kit sync && svelte-check --threshold error"
},
"devDependencies": {
- "sharp": "^0.34.2"
- }
+ "@manacore/shared-pwa": "workspace:*",
+ "@manacore/shared-vite-config": "workspace:*",
+ "@sveltejs/adapter-node": "^5.0.0",
+ "@sveltejs/kit": "^2.47.1",
+ "@sveltejs/vite-plugin-svelte": "^5.0.0",
+ "@tailwindcss/vite": "^4.1.7",
+ "@types/node": "^20.0.0",
+ "@vite-pwa/sveltekit": "^1.1.0",
+ "prettier": "^3.1.1",
+ "prettier-plugin-svelte": "^3.1.2",
+ "svelte": "^5.41.0",
+ "svelte-check": "^4.3.3",
+ "tailwindcss": "^4.1.7",
+ "tslib": "^2.4.1",
+ "typescript": "^5.9.3",
+ "vite": "^6.0.0"
+ },
+ "dependencies": {
+ "@manacore/local-store": "workspace:*",
+ "@manacore/shared-app-onboarding": "workspace:*",
+ "@manacore/shared-auth": "workspace:*",
+ "@manacore/shared-auth-stores": "workspace:*",
+ "@manacore/shared-auth-ui": "workspace:*",
+ "@manacore/shared-branding": "workspace:*",
+ "@manacore/shared-error-tracking": "workspace:*",
+ "@manacore/feedback": "workspace:*",
+ "@manacore/shared-i18n": "workspace:*",
+ "@manacore/help": "workspace:*",
+ "@manacore/shared-icons": "workspace:*",
+ "@manacore/shared-profile-ui": "workspace:*",
+ "@manacore/shared-stores": "workspace:*",
+ "@manacore/shared-tags": "workspace:*",
+ "@manacore/subscriptions": "workspace:*",
+ "@manacore/shared-tailwind": "workspace:*",
+ "@manacore/shared-theme": "workspace:*",
+ "@manacore/shared-theme-ui": "workspace:*",
+ "@manacore/shared-ui": "workspace:*",
+ "@manacore/shared-utils": "workspace:*",
+ "svelte-i18n": "^4.0.1"
+ },
+ "type": "module"
}
diff --git a/games/mana-games/apps/web/public/icons/icon-120x120.png b/games/mana-games/apps/web/public/icons/icon-120x120.png
deleted file mode 100644
index 172bbcaf2..000000000
Binary files a/games/mana-games/apps/web/public/icons/icon-120x120.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/icons/icon-128x128.png b/games/mana-games/apps/web/public/icons/icon-128x128.png
deleted file mode 100644
index 7d28b8534..000000000
Binary files a/games/mana-games/apps/web/public/icons/icon-128x128.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/icons/icon-144x144.png b/games/mana-games/apps/web/public/icons/icon-144x144.png
deleted file mode 100644
index 63165eb24..000000000
Binary files a/games/mana-games/apps/web/public/icons/icon-144x144.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/icons/icon-152x152.png b/games/mana-games/apps/web/public/icons/icon-152x152.png
deleted file mode 100644
index 4b81c5755..000000000
Binary files a/games/mana-games/apps/web/public/icons/icon-152x152.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/icons/icon-167x167.png b/games/mana-games/apps/web/public/icons/icon-167x167.png
deleted file mode 100644
index 9063b8c72..000000000
Binary files a/games/mana-games/apps/web/public/icons/icon-167x167.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/icons/icon-180x180.png b/games/mana-games/apps/web/public/icons/icon-180x180.png
deleted file mode 100644
index 81e7610cb..000000000
Binary files a/games/mana-games/apps/web/public/icons/icon-180x180.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/icons/icon-192x192.png b/games/mana-games/apps/web/public/icons/icon-192x192.png
deleted file mode 100644
index 355007c45..000000000
Binary files a/games/mana-games/apps/web/public/icons/icon-192x192.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/icons/icon-384x384.png b/games/mana-games/apps/web/public/icons/icon-384x384.png
deleted file mode 100644
index aac3099d2..000000000
Binary files a/games/mana-games/apps/web/public/icons/icon-384x384.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/icons/icon-512x512.png b/games/mana-games/apps/web/public/icons/icon-512x512.png
deleted file mode 100644
index 7195360c9..000000000
Binary files a/games/mana-games/apps/web/public/icons/icon-512x512.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/icons/icon-72x72.png b/games/mana-games/apps/web/public/icons/icon-72x72.png
deleted file mode 100644
index bc2d228cb..000000000
Binary files a/games/mana-games/apps/web/public/icons/icon-72x72.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/icons/icon-96x96.png b/games/mana-games/apps/web/public/icons/icon-96x96.png
deleted file mode 100644
index 4437e7bed..000000000
Binary files a/games/mana-games/apps/web/public/icons/icon-96x96.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/icons/icon-base.svg b/games/mana-games/apps/web/public/icons/icon-base.svg
deleted file mode 100644
index e4ff4c7d1..000000000
--- a/games/mana-games/apps/web/public/icons/icon-base.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
- MG
-
\ No newline at end of file
diff --git a/games/mana-games/apps/web/public/manifest.json b/games/mana-games/apps/web/public/manifest.json
deleted file mode 100644
index 80344cc70..000000000
--- a/games/mana-games/apps/web/public/manifest.json
+++ /dev/null
@@ -1,89 +0,0 @@
-{
- "name": "Mana Games - Spiele ohne Grenzen",
- "short_name": "Mana Games",
- "description": "Eine Sammlung kostenloser, werbefreier Web-Spiele zum Spielen, Bauen und Lernen",
- "start_url": "/",
- "display": "standalone",
- "orientation": "portrait",
- "theme_color": "#1a1a1a",
- "background_color": "#0a0a0a",
- "categories": ["games", "education", "entertainment"],
- "lang": "de",
- "dir": "ltr",
- "icons": [
- {
- "src": "/icons/icon-72x72.png",
- "sizes": "72x72",
- "type": "image/png",
- "purpose": "any maskable"
- },
- {
- "src": "/icons/icon-96x96.png",
- "sizes": "96x96",
- "type": "image/png",
- "purpose": "any maskable"
- },
- {
- "src": "/icons/icon-128x128.png",
- "sizes": "128x128",
- "type": "image/png",
- "purpose": "any maskable"
- },
- {
- "src": "/icons/icon-144x144.png",
- "sizes": "144x144",
- "type": "image/png",
- "purpose": "any maskable"
- },
- {
- "src": "/icons/icon-152x152.png",
- "sizes": "152x152",
- "type": "image/png",
- "purpose": "any maskable"
- },
- {
- "src": "/icons/icon-192x192.png",
- "sizes": "192x192",
- "type": "image/png",
- "purpose": "any maskable"
- },
- {
- "src": "/icons/icon-384x384.png",
- "sizes": "384x384",
- "type": "image/png",
- "purpose": "any maskable"
- },
- {
- "src": "/icons/icon-512x512.png",
- "sizes": "512x512",
- "type": "image/png",
- "purpose": "any maskable"
- }
- ],
- "screenshots": [
- {
- "src": "/screenshots/desktop-home.png",
- "sizes": "1280x720",
- "type": "image/png",
- "label": "Mana Games Startseite"
- },
- {
- "src": "/screenshots/mobile-home.png",
- "sizes": "750x1334",
- "type": "image/png",
- "label": "Mobile Ansicht"
- }
- ],
- "shortcuts": [
- {
- "name": "Snake Game",
- "url": "/games/snake",
- "description": "Klassisches Snake-Spiel spielen"
- },
- {
- "name": "Meine Statistiken",
- "url": "/stats",
- "description": "Spielstatistiken anzeigen"
- }
- ]
-}
diff --git a/games/mana-games/apps/web/public/offline.html b/games/mana-games/apps/web/public/offline.html
deleted file mode 100644
index c1b60aa92..000000000
--- a/games/mana-games/apps/web/public/offline.html
+++ /dev/null
@@ -1,184 +0,0 @@
-
-
-
-
-
- Offline - Mana Games
-
-
-
-
-
📡
-
Du bist offline
-
- Keine Internetverbindung gefunden. Aber keine Sorge!
- Einige Spiele, die du bereits gespielt hast, sind möglicherweise
- noch im Cache verfügbar.
-
-
- Erneut versuchen
-
-
-
-
Verfügbare Offline-Spiele
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/games/mana-games/apps/web/public/splash/splash-1125x2436.png b/games/mana-games/apps/web/public/splash/splash-1125x2436.png
deleted file mode 100644
index fbab093d6..000000000
Binary files a/games/mana-games/apps/web/public/splash/splash-1125x2436.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/splash/splash-1242x2688.png b/games/mana-games/apps/web/public/splash/splash-1242x2688.png
deleted file mode 100644
index e37234898..000000000
Binary files a/games/mana-games/apps/web/public/splash/splash-1242x2688.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/splash/splash-1536x2048.png b/games/mana-games/apps/web/public/splash/splash-1536x2048.png
deleted file mode 100644
index b7358ae1f..000000000
Binary files a/games/mana-games/apps/web/public/splash/splash-1536x2048.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/splash/splash-1668x2224.png b/games/mana-games/apps/web/public/splash/splash-1668x2224.png
deleted file mode 100644
index 7de3ee1d7..000000000
Binary files a/games/mana-games/apps/web/public/splash/splash-1668x2224.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/splash/splash-2048x2732.png b/games/mana-games/apps/web/public/splash/splash-2048x2732.png
deleted file mode 100644
index 911db7a74..000000000
Binary files a/games/mana-games/apps/web/public/splash/splash-2048x2732.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/splash/splash-640x1136.png b/games/mana-games/apps/web/public/splash/splash-640x1136.png
deleted file mode 100644
index 90997853b..000000000
Binary files a/games/mana-games/apps/web/public/splash/splash-640x1136.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/splash/splash-750x1334.png b/games/mana-games/apps/web/public/splash/splash-750x1334.png
deleted file mode 100644
index 68c9c51fa..000000000
Binary files a/games/mana-games/apps/web/public/splash/splash-750x1334.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/splash/splash-828x1792.png b/games/mana-games/apps/web/public/splash/splash-828x1792.png
deleted file mode 100644
index 4022d5a27..000000000
Binary files a/games/mana-games/apps/web/public/splash/splash-828x1792.png and /dev/null differ
diff --git a/games/mana-games/apps/web/public/sw.js b/games/mana-games/apps/web/public/sw.js
deleted file mode 100644
index 755f125f7..000000000
--- a/games/mana-games/apps/web/public/sw.js
+++ /dev/null
@@ -1,161 +0,0 @@
-const CACHE_NAME = 'mana-games-v1';
-const OFFLINE_URL = '/offline.html';
-
-// Assets, die immer gecacht werden sollen
-const STATIC_CACHE_URLS = ['/', '/offline.html', '/favicon.svg', '/manifest.json'];
-
-// Cache-Strategien für verschiedene Ressourcen
-const CACHE_STRATEGIES = {
- // Netzwerk zuerst, dann Cache (für HTML)
- networkFirst: [/\/$/, /\.html$/, /\.astro$/],
- // Cache zuerst, dann Netzwerk (für Assets)
- cacheFirst: [
- /\.css$/,
- /\.js$/,
- /\.woff2?$/,
- /\.ttf$/,
- /\.otf$/,
- /\.svg$/,
- /\.png$/,
- /\.jpg$/,
- /\.jpeg$/,
- /\.webp$/,
- /\.ico$/,
- ],
- // Nur Netzwerk (für API-Calls)
- networkOnly: [/\/api\//, /\.json$/],
-};
-
-// Service Worker Installation
-self.addEventListener('install', (event) => {
- event.waitUntil(
- caches
- .open(CACHE_NAME)
- .then((cache) => {
- console.log('Service Worker: Caching static assets');
- return cache.addAll(STATIC_CACHE_URLS);
- })
- .then(() => self.skipWaiting())
- );
-});
-
-// Service Worker Aktivierung
-self.addEventListener('activate', (event) => {
- event.waitUntil(
- caches
- .keys()
- .then((cacheNames) => {
- return Promise.all(
- cacheNames
- .filter((cacheName) => cacheName !== CACHE_NAME)
- .map((cacheName) => caches.delete(cacheName))
- );
- })
- .then(() => self.clients.claim())
- );
-});
-
-// Fetch-Event Handler
-self.addEventListener('fetch', (event) => {
- const { request } = event;
- const url = new URL(request.url);
-
- // Ignoriere Chrome Extension Requests
- if (url.protocol === 'chrome-extension:') {
- return;
- }
-
- // Bestimme die Cache-Strategie
- const strategy = getStrategy(url.pathname);
-
- if (strategy === 'networkFirst') {
- event.respondWith(networkFirst(request));
- } else if (strategy === 'cacheFirst') {
- event.respondWith(cacheFirst(request));
- } else if (strategy === 'networkOnly') {
- event.respondWith(networkOnly(request));
- } else {
- // Standard: Network First
- event.respondWith(networkFirst(request));
- }
-});
-
-// Cache-Strategien Implementierung
-async function networkFirst(request) {
- try {
- const networkResponse = await fetch(request);
- if (networkResponse.ok) {
- const cache = await caches.open(CACHE_NAME);
- cache.put(request, networkResponse.clone());
- }
- return networkResponse;
- } catch (error) {
- const cachedResponse = await caches.match(request);
- if (cachedResponse) {
- return cachedResponse;
- }
-
- // Wenn es eine Navigation ist und wir offline sind, zeige die Offline-Seite
- if (request.mode === 'navigate') {
- const offlineResponse = await caches.match(OFFLINE_URL);
- if (offlineResponse) {
- return offlineResponse;
- }
- }
-
- throw error;
- }
-}
-
-async function cacheFirst(request) {
- const cachedResponse = await caches.match(request);
- if (cachedResponse) {
- return cachedResponse;
- }
-
- try {
- const networkResponse = await fetch(request);
- if (networkResponse.ok) {
- const cache = await caches.open(CACHE_NAME);
- cache.put(request, networkResponse.clone());
- }
- return networkResponse;
- } catch (error) {
- console.error('Fetch failed:', error);
- throw error;
- }
-}
-
-async function networkOnly(request) {
- return fetch(request);
-}
-
-// Hilfsfunktion zur Bestimmung der Cache-Strategie
-function getStrategy(pathname) {
- for (const [strategy, patterns] of Object.entries(CACHE_STRATEGIES)) {
- if (patterns.some((pattern) => pattern.test(pathname))) {
- return strategy;
- }
- }
- return 'networkFirst';
-}
-
-// Message Handler für Cache-Updates
-self.addEventListener('message', (event) => {
- if (event.data && event.data.type === 'SKIP_WAITING') {
- self.skipWaiting();
- }
-
- if (event.data && event.data.type === 'CACHE_GAME') {
- const gameUrl = event.data.url;
- caches
- .open(CACHE_NAME)
- .then((cache) => cache.add(gameUrl))
- .then(() => {
- event.ports[0].postMessage({ cached: true });
- })
- .catch((error) => {
- event.ports[0].postMessage({ cached: false, error: error.message });
- });
- }
-});
diff --git a/games/mana-games/apps/web/src/app.css b/games/mana-games/apps/web/src/app.css
new file mode 100644
index 000000000..f28dfe97c
--- /dev/null
+++ b/games/mana-games/apps/web/src/app.css
@@ -0,0 +1,10 @@
+@import "tailwindcss";
+@import "@manacore/shared-tailwind/themes.css";
+
+/* Scan shared packages for Tailwind classes */
+@source "../../../../../../packages/shared-ui/src";
+@source "../../../../../../packages/shared-auth-ui/src";
+@source "../../../../../../packages/shared-branding/src";
+@source "../../../../../../packages/shared-theme-ui/src";
+@source "../../../../../../packages/shared-theme-ui/src/components";
+@source "../../../../../../packages/shared-theme-ui/src/pages";
diff --git a/games/mana-games/apps/web/src/app.html b/games/mana-games/apps/web/src/app.html
new file mode 100644
index 000000000..e31c3501d
--- /dev/null
+++ b/games/mana-games/apps/web/src/app.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+ %sveltekit.head%
+
+
+ %sveltekit.body%
+
+
diff --git a/games/mana-games/apps/web/src/components/Button.astro b/games/mana-games/apps/web/src/components/Button.astro
deleted file mode 100644
index 4895fb1fe..000000000
--- a/games/mana-games/apps/web/src/components/Button.astro
+++ /dev/null
@@ -1,188 +0,0 @@
----
-export interface Props {
- variant?: 'primary' | 'secondary' | 'accent' | 'ghost' | 'danger';
- size?: 'small' | 'medium' | 'large' | 'icon';
- href?: string;
- onclick?: string;
- id?: string;
- class?: string;
- title?: string;
- disabled?: boolean;
- type?: 'button' | 'submit' | 'reset';
-}
-
-const {
- variant = 'secondary',
- size = 'medium',
- href,
- onclick,
- id,
- class: className = '',
- title,
- disabled = false,
- type = 'button',
-} = Astro.props;
-
-const isLink = Boolean(href);
-const Component = isLink ? 'a' : 'button';
-
-const classes = ['btn', `btn-${variant}`, `btn-${size}`, className].filter(Boolean).join(' ');
-
-const props = {
- class: classes,
- ...(id && { id }),
- ...(title && { title }),
- ...(isLink ? { href } : { type, disabled }),
- ...(onclick && { onclick }),
-};
----
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/components/Footer.astro b/games/mana-games/apps/web/src/components/Footer.astro
deleted file mode 100644
index e7ae28858..000000000
--- a/games/mana-games/apps/web/src/components/Footer.astro
+++ /dev/null
@@ -1,193 +0,0 @@
----
-// Footer component with compact site navigation
----
-
-
-
-
diff --git a/games/mana-games/apps/web/src/components/GameCard.astro b/games/mana-games/apps/web/src/components/GameCard.astro
deleted file mode 100644
index 04f4a3e9f..000000000
--- a/games/mana-games/apps/web/src/components/GameCard.astro
+++ /dev/null
@@ -1,309 +0,0 @@
----
-import GameStats from './GameStats.astro';
-import Button from './Button.astro';
-
-export interface Props {
- title: string;
- description: string;
- slug: string;
- thumbnail?: string;
- tags?: string[];
- complexity?: 'Minimal' | 'Einfach' | 'Mittel' | 'Komplex';
- codeStats?: {
- total: number;
- code: number;
- comments: number;
- };
-}
-
-const { title, description, slug, thumbnail, tags = [], complexity, codeStats } = Astro.props;
----
-
-
-
-
- {
- thumbnail ? (
-
- ) : (
-
- {title.charAt(0)}
-
- )
- }
-
-
-
-
{title}
-
{description}
-
-
-
- {
- codeStats && (
-
-
- {codeStats.total} Zeilen
-
- ({codeStats.code} Code / {codeStats.comments} Kommentare)
-
-
-
- )
- }
-
-
-
-
-
-
- Code
-
- Spielen
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/components/GameStats.astro b/games/mana-games/apps/web/src/components/GameStats.astro
deleted file mode 100644
index f84e7f6e8..000000000
--- a/games/mana-games/apps/web/src/components/GameStats.astro
+++ /dev/null
@@ -1,146 +0,0 @@
----
-import { statsService } from '../services/statsService';
-
-export interface Props {
- gameId: string;
- showDetails?: boolean;
-}
-
-const { gameId, showDetails = false } = Astro.props;
-const stats = statsService.getStats(gameId);
----
-
-{
- stats && (
-
-
- {stats.highScore > 0 && (
-
- 🏆
- {stats.highScore.toLocaleString('de-DE')}
-
- )}
-
- {stats.gamesPlayed > 0 && (
-
- 🎮
- {stats.gamesPlayed}x
-
- )}
-
- {stats.totalPlayTime > 0 && (
-
- ⏱️
- {statsService.formatPlayTime(stats.totalPlayTime)}
-
- )}
-
-
- {showDetails && stats.lastPlayed && (
-
- Zuletzt gespielt: {statsService.getRelativeTime(stats.lastPlayed)}
-
- )}
-
- {showDetails && stats.achievements && stats.achievements.length > 0 && (
-
-
Achievements
-
- {stats.achievements.map((achievement) => (
-
- 🏅
- {achievement.name}
-
- ))}
-
-
- )}
-
- )
-}
-
-
diff --git a/games/mana-games/apps/web/src/components/HorizontalScroller.astro b/games/mana-games/apps/web/src/components/HorizontalScroller.astro
deleted file mode 100644
index c0ffa105e..000000000
--- a/games/mana-games/apps/web/src/components/HorizontalScroller.astro
+++ /dev/null
@@ -1,352 +0,0 @@
----
-import GameCard from './GameCard.astro';
-
-export interface Props {
- title: string;
- games: any[];
- id?: string;
-}
-
-const { title, games, id = 'scroller' } = Astro.props;
----
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/components/InstallPrompt.astro b/games/mana-games/apps/web/src/components/InstallPrompt.astro
deleted file mode 100644
index ece6b2ccb..000000000
--- a/games/mana-games/apps/web/src/components/InstallPrompt.astro
+++ /dev/null
@@ -1,183 +0,0 @@
----
-// Keine Props benötigt
----
-
-
-
-
📱
-
-
App installieren
-
Installiere Mana Games für schnelleren Zugriff!
-
-
- Installieren
- Später
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/components/MyGamesSection.astro b/games/mana-games/apps/web/src/components/MyGamesSection.astro
deleted file mode 100644
index 85220c973..000000000
--- a/games/mana-games/apps/web/src/components/MyGamesSection.astro
+++ /dev/null
@@ -1,537 +0,0 @@
----
-export interface Props {
- maxGames?: number;
-}
-
-const { maxGames = 8 } = Astro.props;
----
-
-
-
-
-
-
-
-
Lade deine Spiele...
-
-
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/layouts/Layout.astro b/games/mana-games/apps/web/src/layouts/Layout.astro
deleted file mode 100644
index efcc33870..000000000
--- a/games/mana-games/apps/web/src/layouts/Layout.astro
+++ /dev/null
@@ -1,713 +0,0 @@
----
-import Button from '../components/Button.astro';
-import InstallPrompt from '../components/InstallPrompt.astro';
-import Footer from '../components/Footer.astro';
-
-export interface Props {
- title: string;
- description?: string;
- isGamePage?: boolean;
- gameTitle?: string;
- gameSlug?: string;
- isPlayground?: boolean;
- fullWidth?: boolean;
- hideFooter?: boolean;
-}
-
-const { title, description = "Mana Games - Eine Sammlung von Web-basierten Spielen", isGamePage = false, gameTitle, gameSlug, isPlayground = false, fullWidth = false, hideFooter = false } = Astro.props;
----
-
-
-
-
-
-
-
-
-
- {title} | Mana Games
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {isGamePage ? (
-
- ) : (
-
- MANA
- GAMES
-
- )}
-
- {isGamePage ? (
-
-
- ←
-
-
-
-
- ↻
-
-
- ⛶
-
-
- {isPlayground ? (
-
- 🎮
-
- ) : (
-
- 🔧
-
- )}
-
- ) : (
-
- )}
-
-
-
-
-
-
- {!hideFooter && }
-
-
-
-
-
-
\ No newline at end of file
diff --git a/games/mana-games/apps/web/src/lib/components/GameCard.svelte b/games/mana-games/apps/web/src/lib/components/GameCard.svelte
new file mode 100644
index 000000000..a1ad111b8
--- /dev/null
+++ b/games/mana-games/apps/web/src/lib/components/GameCard.svelte
@@ -0,0 +1,54 @@
+
+
+
+ {#if game.thumbnail}
+
+
+
+ {:else}
+
+ 🎮
+
+ {/if}
+
+
+
+
+ {game.title}
+
+
+ {game.difficulty}
+
+
+
+
+ {game.description}
+
+
+
+ {#each game.tags.slice(0, 3) as tag}
+
+ {tag}
+
+ {/each}
+
+
+
diff --git a/games/mana-games/apps/web/src/lib/components/skeletons/AppLoadingSkeleton.svelte b/games/mana-games/apps/web/src/lib/components/skeletons/AppLoadingSkeleton.svelte
new file mode 100644
index 000000000..cc9f6e177
--- /dev/null
+++ b/games/mana-games/apps/web/src/lib/components/skeletons/AppLoadingSkeleton.svelte
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+ {#each Array(6) as _}
+
+ {/each}
+
+
+
+
+
diff --git a/games/mana-games/apps/web/src/lib/components/skeletons/index.ts b/games/mana-games/apps/web/src/lib/components/skeletons/index.ts
new file mode 100644
index 000000000..f09e744bb
--- /dev/null
+++ b/games/mana-games/apps/web/src/lib/components/skeletons/index.ts
@@ -0,0 +1 @@
+export { default as AppLoadingSkeleton } from './AppLoadingSkeleton.svelte';
diff --git a/games/mana-games/apps/web/src/data/games.ts b/games/mana-games/apps/web/src/lib/data/games.ts
similarity index 78%
rename from games/mana-games/apps/web/src/data/games.ts
rename to games/mana-games/apps/web/src/lib/data/games.ts
index 24a0c5208..d3cf640dc 100644
--- a/games/mana-games/apps/web/src/data/games.ts
+++ b/games/mana-games/apps/web/src/lib/data/games.ts
@@ -14,7 +14,6 @@ export interface Game {
code: number;
comments: number;
};
- // Community game fields
community?: boolean;
author?: string;
submittedAt?: string;
@@ -33,11 +32,7 @@ export const games: Game[] = [
difficulty: 'Einfach',
complexity: 'Komplex',
controls: 'Pfeiltasten oder WASD zum Steuern',
- codeStats: {
- total: 604,
- code: 338,
- comments: 192,
- },
+ codeStats: { total: 604, code: 338, comments: 192 },
},
{
id: '2',
@@ -51,11 +46,7 @@ export const games: Game[] = [
difficulty: 'Mittel',
complexity: 'Mittel',
controls: 'A/D oder Pfeiltasten zum Bewegen, Leertaste zum Schießen',
- codeStats: {
- total: 436,
- code: 348,
- comments: 32,
- },
+ codeStats: { total: 436, code: 348, comments: 32 },
},
{
id: '3',
@@ -69,11 +60,7 @@ export const games: Game[] = [
difficulty: 'Schwer',
complexity: 'Mittel',
controls: 'Klicke für Gravitationspunkte, Leertaste für Partikel',
- codeStats: {
- total: 426,
- code: 348,
- comments: 21,
- },
+ codeStats: { total: 426, code: 348, comments: 21 },
},
{
id: '4',
@@ -87,11 +74,7 @@ export const games: Game[] = [
difficulty: 'Einfach',
complexity: 'Einfach',
controls: 'Mausbewegung zum Steuern des Paddles',
- codeStats: {
- total: 437,
- code: 289,
- comments: 87,
- },
+ codeStats: { total: 437, code: 289, comments: 87 },
},
{
id: '5',
@@ -105,11 +88,7 @@ export const games: Game[] = [
difficulty: 'Mittel',
complexity: 'Komplex',
controls: 'WASD oder Pfeiltasten zum Bewegen',
- codeStats: {
- total: 832,
- code: 644,
- comments: 69,
- },
+ codeStats: { total: 832, code: 644, comments: 69 },
},
{
id: '6',
@@ -123,11 +102,7 @@ export const games: Game[] = [
difficulty: 'Mittel',
complexity: 'Komplex',
controls: 'A, S, D, F Tasten im Rhythmus drücken',
- codeStats: {
- total: 741,
- code: 584,
- comments: 56,
- },
+ codeStats: { total: 741, code: 584, comments: 56 },
},
{
id: '7',
@@ -140,11 +115,7 @@ export const games: Game[] = [
difficulty: 'Einfach',
complexity: 'Minimal',
controls: 'Klicke auf das rote Quadrat',
- codeStats: {
- total: 111,
- code: 88,
- comments: 23,
- },
+ codeStats: { total: 111, code: 88, comments: 23 },
},
{
id: '8',
@@ -158,11 +129,7 @@ export const games: Game[] = [
difficulty: 'Einfach',
complexity: 'Minimal',
controls: 'Klicke die Farben in der richtigen Reihenfolge',
- codeStats: {
- total: 86,
- code: 86,
- comments: 0,
- },
+ codeStats: { total: 86, code: 86, comments: 0 },
},
{
id: '9',
@@ -176,11 +143,7 @@ export const games: Game[] = [
difficulty: 'Einfach',
complexity: 'Minimal',
controls: 'Klicke wenn der Bildschirm grün wird',
- codeStats: {
- total: 78,
- code: 78,
- comments: 0,
- },
+ codeStats: { total: 78, code: 78, comments: 0 },
},
{
id: '10',
@@ -194,35 +157,27 @@ export const games: Game[] = [
difficulty: 'Mittel',
complexity: 'Mittel',
controls: 'WASD oder Pfeiltasten zum Fliegen, Leertaste für Boost',
- codeStats: {
- total: 485,
- code: 428,
- comments: 57,
- },
+ codeStats: { total: 485, code: 428, comments: 57 },
},
{
id: '11',
title: 'Fish Catcher',
description:
- 'Fange Fische mit deinem Boot! Verschiedene Fischarten bringen unterschiedliche Punkte. Sammle Power-ups für größere Netze und Boni.',
+ 'Fange Fische mit deinem Boot! Verschiedene Fischarten bringen unterschiedliche Punkte.',
slug: 'fish-catcher',
htmlFile: '/games/fish_catcher.html',
thumbnail: '/screenshots/fish-catcher.jpg',
tags: ['Arcade', 'Familie', 'Entspannend'],
difficulty: 'Einfach',
complexity: 'Einfach',
- controls: 'A/D oder Pfeiltasten zum Bewegen, Maus für sanfte Steuerung',
- codeStats: {
- total: 362,
- code: 321,
- comments: 41,
- },
+ controls: 'A/D oder Pfeiltasten zum Bewegen',
+ codeStats: { total: 362, code: 321, comments: 41 },
},
{
id: '12',
title: 'Balloon Pop',
description:
- 'Platze bunte Ballons bevor sie entkommen! Verschiedene Ballonarten, Power-ups und Combo-System für maximalen Spaß.',
+ 'Platze bunte Ballons bevor sie entkommen! Verschiedene Ballonarten, Power-ups und Combo-System.',
slug: 'balloon-pop',
htmlFile: '/games/balloon_pop.html',
thumbnail: '/screenshots/balloon-pop.jpg',
@@ -230,11 +185,7 @@ export const games: Game[] = [
difficulty: 'Einfach',
complexity: 'Einfach',
controls: 'Maus zum Klicken auf Ballons',
- codeStats: {
- total: 398,
- code: 351,
- comments: 47,
- },
+ codeStats: { total: 398, code: 351, comments: 47 },
},
{
id: '13',
@@ -243,34 +194,24 @@ export const games: Game[] = [
'Entschlüssele durcheinandergewürfelte Wörter! Mit 5 Kategorien, Combo-System und steigender Schwierigkeit.',
slug: 'word-scramble',
htmlFile: '/games/word_scramble.html',
- thumbnail: '/screenshots/word-scramble.jpg',
tags: ['Puzzle', 'Wortspiel', 'Bildung'],
difficulty: 'Mittel',
complexity: 'Mittel',
controls: 'Tastatur zum Eingeben, Maus zum Klicken auf Buchstaben',
- codeStats: {
- total: 850,
- code: 720,
- comments: 130,
- },
+ codeStats: { total: 850, code: 720, comments: 130 },
},
{
id: '14',
title: 'Memory Card Match',
description:
- 'Das klassische Memory-Spiel! Finde alle Kartenpaare mit Emojis. Drei Schwierigkeitsstufen für jeden Spieler.',
+ 'Das klassische Memory-Spiel! Finde alle Kartenpaare mit Emojis. Drei Schwierigkeitsstufen.',
slug: 'memory-card-match',
htmlFile: '/games/memory_card_match.html',
- thumbnail: '/screenshots/memory-card-match.jpg',
tags: ['Gedächtnis', 'Kartenspiel', 'Familie'],
difficulty: 'Einfach',
complexity: 'Einfach',
controls: 'Maus zum Aufdecken der Karten',
- codeStats: {
- total: 415,
- code: 350,
- comments: 0,
- },
+ codeStats: { total: 415, code: 350, comments: 0 },
},
{
id: '15',
@@ -279,106 +220,76 @@ export const games: Game[] = [
'Drift durch die Kurven und stelle Bestzeiten auf! Mit realistischer Drift-Physik und Nitro-Boost.',
slug: 'turbo-racer',
htmlFile: '/games/turbo_racer.html',
- thumbnail: '/screenshots/turbo-racer.jpg',
tags: ['Rennen', 'Action', 'Arcade'],
difficulty: 'Mittel',
complexity: 'Mittel',
controls: 'WASD oder Pfeiltasten zum Fahren, Leertaste für Boost',
- codeStats: {
- total: 680,
- code: 620,
- comments: 60,
- },
+ codeStats: { total: 680, code: 620, comments: 60 },
},
{
id: '16',
title: 'Card Stack Rush',
description:
- 'Sortiere Karten blitzschnell auf die richtigen Stapel! Mit wechselnden Regeln, Combo-System und Zeitdruck.',
+ 'Sortiere Karten blitzschnell auf die richtigen Stapel! Mit wechselnden Regeln und Combo-System.',
slug: 'card-stack-rush',
htmlFile: '/games/card_stack_rush.html',
- thumbnail: '/screenshots/card-stack-rush.jpg',
tags: ['Kartenspiel', 'Geschwindigkeit', 'Arcade'],
difficulty: 'Mittel',
complexity: 'Einfach',
controls: 'Drag & Drop oder Klicken zum Platzieren',
- codeStats: {
- total: 520,
- code: 480,
- comments: 0,
- },
+ codeStats: { total: 520, code: 480, comments: 0 },
},
{
id: '17',
title: 'Flappy Mana',
description:
- 'Fliege durch Röhren und sammle Punkte! Ein Flappy Bird Klon mit Partikeleffekten und Highscore-System.',
+ 'Fliege durch Röhren und sammle Punkte! Ein Flappy Bird Klon mit Partikeleffekten.',
slug: 'flappy-mana',
htmlFile: '/games/flappy_mana.html',
- thumbnail: '/screenshots/flappy-mana.jpg',
tags: ['Arcade', 'Geschicklichkeit', 'Endless'],
difficulty: 'Mittel',
complexity: 'Einfach',
controls: 'Klick oder Leertaste zum Fliegen',
- codeStats: {
- total: 450,
- code: 430,
- comments: 20,
- },
+ codeStats: { total: 450, code: 430, comments: 20 },
},
{
id: '18',
title: 'Mana Runner',
description:
- 'Laufe und springe durch magische Welten! Sammle Mana-Kristalle, weiche Hindernissen aus und schalte den Doppelsprung frei.',
+ 'Laufe und springe durch magische Welten! Sammle Mana-Kristalle und weiche Hindernissen aus.',
slug: 'mana-runner',
htmlFile: '/games/mana_runner.html',
- thumbnail: '/screenshots/mana-runner.jpg',
tags: ['Jump n Run', 'Arcade', 'Endless'],
difficulty: 'Mittel',
complexity: 'Mittel',
controls: 'Leertaste zum Springen, Doppelsprung nach 10 Kristallen',
- codeStats: {
- total: 600,
- code: 580,
- comments: 20,
- },
+ codeStats: { total: 600, code: 580, comments: 20 },
},
{
id: '19',
title: 'Mana Defense',
description:
- 'Verteidige deinen Mana-Kristall! Baue Türme, plane deine Strategie und überlebe 20 Wellen von Gegnern.',
+ 'Verteidige deinen Mana-Kristall! Baue Türme, plane deine Strategie und überlebe 20 Wellen.',
slug: 'mana-defense',
htmlFile: '/games/mana_defense.html',
- thumbnail: '/screenshots/mana-defense.jpg',
tags: ['Tower Defense', 'Strategie', 'Aufbau'],
difficulty: 'Schwer',
complexity: 'Komplex',
controls: 'Maus zum Platzieren, 1-3 für Turmauswahl, S zum Verkaufen',
- codeStats: {
- total: 900,
- code: 850,
- comments: 50,
- },
+ codeStats: { total: 900, code: 850, comments: 50 },
},
{
id: '20',
title: 'Mana Factory',
description:
- 'Baue die größte Mana-Produktionsanlage! Ein Idle-Game mit Upgrades, Prestige-System und exponentiellem Wachstum.',
+ 'Baue die größte Mana-Produktionsanlage! Ein Idle-Game mit Upgrades und Prestige-System.',
slug: 'mana-factory',
htmlFile: '/games/mana_factory.html',
- thumbnail: '/screenshots/mana-factory.jpg',
tags: ['Idle', 'Incremental', 'Aufbau'],
difficulty: 'Einfach',
complexity: 'Mittel',
controls: 'Maus zum Klicken und Kaufen',
- codeStats: {
- total: 800,
- code: 750,
- comments: 50,
- },
+ codeStats: { total: 800, code: 750, comments: 50 },
},
{
id: '21',
@@ -387,15 +298,28 @@ export const games: Game[] = [
'Klassisches Tetris-Gameplay! Stapele fallende Blöcke, vervollständige Reihen und erreiche den höchsten Score.',
slug: 'puzzle-blocks',
htmlFile: '/games/puzzle_blocks.html',
- thumbnail: '/screenshots/puzzle-blocks.jpg',
tags: ['Puzzle', 'Klassiker', 'Arcade'],
difficulty: 'Mittel',
complexity: 'Einfach',
controls: '← → zum Bewegen, ↑ zum Drehen, ↓ schneller fallen, Space für Harddrop',
- codeStats: {
- total: 450,
- code: 420,
- comments: 30,
- },
+ codeStats: { total: 450, code: 420, comments: 30 },
},
];
+
+export function getGameBySlug(slug: string): Game | undefined {
+ return games.find((g) => g.slug === slug);
+}
+
+export function getGamesByTag(tag: string): Game[] {
+ return games.filter((g) => g.tags.includes(tag));
+}
+
+export function getAllTags(): string[] {
+ const tagSet = new Set();
+ for (const game of games) {
+ for (const tag of game.tags) {
+ tagSet.add(tag);
+ }
+ }
+ return [...tagSet].sort();
+}
diff --git a/games/mana-games/apps/web/src/lib/data/guest-seed.ts b/games/mana-games/apps/web/src/lib/data/guest-seed.ts
new file mode 100644
index 000000000..221cf78d6
--- /dev/null
+++ b/games/mana-games/apps/web/src/lib/data/guest-seed.ts
@@ -0,0 +1 @@
+// No guest seed data needed — games are static HTML files, stats build up from play
diff --git a/games/mana-games/apps/web/src/lib/data/local-store.ts b/games/mana-games/apps/web/src/lib/data/local-store.ts
new file mode 100644
index 000000000..d172c2da5
--- /dev/null
+++ b/games/mana-games/apps/web/src/lib/data/local-store.ts
@@ -0,0 +1,55 @@
+import { createLocalStore, type BaseRecord } from '@manacore/local-store';
+
+// ─── Types ──────────────────────────────────────────────────
+
+export interface LocalGameStats extends BaseRecord {
+ gameId: string;
+ highScore: number;
+ lastScore: number;
+ gamesPlayed: number;
+ totalPlayTime: number;
+ lastPlayed: string;
+}
+
+export interface LocalGeneratedGame extends BaseRecord {
+ title: string;
+ description: string;
+ htmlCode: string;
+ prompt: string;
+ model: string;
+ iterationCount: number;
+}
+
+export interface LocalFavorite extends BaseRecord {
+ gameId: string;
+}
+
+// ─── Store ──────────────────────────────────────────────────
+
+const SYNC_SERVER_URL = import.meta.env.PUBLIC_SYNC_SERVER_URL || 'http://localhost:3050';
+
+export const gamesStore = createLocalStore({
+ appId: 'mana-games',
+ collections: [
+ {
+ name: 'gameStats',
+ indexes: ['gameId', 'highScore'],
+ },
+ {
+ name: 'generatedGames',
+ indexes: ['title'],
+ },
+ {
+ name: 'favorites',
+ indexes: ['gameId'],
+ },
+ ],
+ sync: {
+ serverUrl: SYNC_SERVER_URL,
+ },
+});
+
+// Typed collection accessors
+export const gameStatsCollection = gamesStore.collection('gameStats');
+export const generatedGameCollection = gamesStore.collection('generatedGames');
+export const favoriteCollection = gamesStore.collection('favorites');
diff --git a/games/mana-games/apps/web/src/lib/data/queries.ts b/games/mana-games/apps/web/src/lib/data/queries.ts
new file mode 100644
index 000000000..65cde2135
--- /dev/null
+++ b/games/mana-games/apps/web/src/lib/data/queries.ts
@@ -0,0 +1,24 @@
+import { useLiveQueryWithDefault } from '@manacore/local-store/svelte';
+import {
+ gameStatsCollection,
+ generatedGameCollection,
+ favoriteCollection,
+ type LocalGameStats,
+ type LocalGeneratedGame,
+ type LocalFavorite,
+} from './local-store';
+
+export function useAllGameStats() {
+ return useLiveQueryWithDefault(async () => gameStatsCollection.getAll(), [] as LocalGameStats[]);
+}
+
+export function useAllGeneratedGames() {
+ return useLiveQueryWithDefault(async () => {
+ const games = await generatedGameCollection.getAll();
+ return games.reverse();
+ }, [] as LocalGeneratedGame[]);
+}
+
+export function useAllFavorites() {
+ return useLiveQueryWithDefault(async () => favoriteCollection.getAll(), [] as LocalFavorite[]);
+}
diff --git a/games/mana-games/apps/web/src/lib/i18n/index.ts b/games/mana-games/apps/web/src/lib/i18n/index.ts
new file mode 100644
index 000000000..99d8bb6c8
--- /dev/null
+++ b/games/mana-games/apps/web/src/lib/i18n/index.ts
@@ -0,0 +1,38 @@
+import { browser } from '$app/environment';
+import { init, register, locale, waitLocale } from 'svelte-i18n';
+
+export const supportedLocales = ['de', 'en'] as const;
+export type SupportedLocale = (typeof supportedLocales)[number];
+
+const defaultLocale = 'de';
+
+register('de', () => import('./locales/de.json'));
+register('en', () => import('./locales/en.json'));
+
+function getInitialLocale(): SupportedLocale {
+ if (browser) {
+ const stored = localStorage.getItem('mana_games_locale');
+ if (stored && supportedLocales.includes(stored as SupportedLocale)) {
+ return stored as SupportedLocale;
+ }
+ const browserLang = navigator.language.split('-')[0];
+ if (supportedLocales.includes(browserLang as SupportedLocale)) {
+ return browserLang as SupportedLocale;
+ }
+ }
+ return defaultLocale;
+}
+
+init({
+ fallbackLocale: defaultLocale,
+ initialLocale: getInitialLocale(),
+});
+
+export function setLocale(newLocale: SupportedLocale) {
+ locale.set(newLocale);
+ if (browser) {
+ localStorage.setItem('mana_games_locale', newLocale);
+ }
+}
+
+export { waitLocale };
diff --git a/games/mana-games/apps/web/src/lib/i18n/locales/de.json b/games/mana-games/apps/web/src/lib/i18n/locales/de.json
new file mode 100644
index 000000000..55092c71c
--- /dev/null
+++ b/games/mana-games/apps/web/src/lib/i18n/locales/de.json
@@ -0,0 +1,66 @@
+{
+ "app": {
+ "name": "Mana Games",
+ "loading": "Wird geladen..."
+ },
+ "nav": {
+ "home": "Spiele",
+ "create": "Erstellen",
+ "community": "Community",
+ "stats": "Statistiken",
+ "settings": "Einstellungen"
+ },
+ "home": {
+ "title": "Browser-Spiele",
+ "subtitle": "22+ Spiele direkt im Browser spielen",
+ "search": "Spiel suchen...",
+ "noResults": "Keine Spiele gefunden",
+ "allGames": "Alle Spiele",
+ "favorites": "Favoriten",
+ "recentlyPlayed": "Zuletzt gespielt"
+ },
+ "game": {
+ "play": "Spielen",
+ "difficulty": "Schwierigkeit",
+ "controls": "Steuerung",
+ "tags": "Tags",
+ "stats": "Statistiken",
+ "highScore": "Highscore",
+ "gamesPlayed": "Spiele gespielt",
+ "totalPlayTime": "Gesamtspielzeit",
+ "lastPlayed": "Zuletzt gespielt",
+ "back": "Zurück",
+ "fullscreen": "Vollbild",
+ "editor": "Code ansehen"
+ },
+ "create": {
+ "title": "Spiel erstellen",
+ "subtitle": "Beschreibe dein Spiel und lass es von KI generieren",
+ "prompt": "Was für ein Spiel soll erstellt werden?",
+ "promptPlaceholder": "Ein Neon-Snake-Spiel mit Partikeleffekten...",
+ "generate": "Generieren",
+ "generating": "Generiere Spiel...",
+ "model": "KI-Modell",
+ "iterate": "Verbessern",
+ "save": "Speichern",
+ "preview": "Vorschau"
+ },
+ "stats": {
+ "title": "Deine Statistiken",
+ "totalGames": "Gespielte Spiele",
+ "totalTime": "Gesamtspielzeit",
+ "favoriteGame": "Lieblingsspiel",
+ "noStats": "Noch keine Statistiken. Spiele ein paar Spiele!"
+ },
+ "difficulty": {
+ "Einfach": "Einfach",
+ "Mittel": "Mittel",
+ "Schwer": "Schwer"
+ },
+ "time": {
+ "justNow": "Gerade eben",
+ "minutesAgo": "Vor {minutes} Minuten",
+ "hoursAgo": "Vor {hours} Stunden",
+ "daysAgo": "Vor {days} Tagen"
+ }
+}
diff --git a/games/mana-games/apps/web/src/lib/i18n/locales/en.json b/games/mana-games/apps/web/src/lib/i18n/locales/en.json
new file mode 100644
index 000000000..9c7a22192
--- /dev/null
+++ b/games/mana-games/apps/web/src/lib/i18n/locales/en.json
@@ -0,0 +1,66 @@
+{
+ "app": {
+ "name": "Mana Games",
+ "loading": "Loading..."
+ },
+ "nav": {
+ "home": "Games",
+ "create": "Create",
+ "community": "Community",
+ "stats": "Statistics",
+ "settings": "Settings"
+ },
+ "home": {
+ "title": "Browser Games",
+ "subtitle": "22+ games to play right in your browser",
+ "search": "Search games...",
+ "noResults": "No games found",
+ "allGames": "All Games",
+ "favorites": "Favorites",
+ "recentlyPlayed": "Recently Played"
+ },
+ "game": {
+ "play": "Play",
+ "difficulty": "Difficulty",
+ "controls": "Controls",
+ "tags": "Tags",
+ "stats": "Statistics",
+ "highScore": "High Score",
+ "gamesPlayed": "Games Played",
+ "totalPlayTime": "Total Play Time",
+ "lastPlayed": "Last Played",
+ "back": "Back",
+ "fullscreen": "Fullscreen",
+ "editor": "View Code"
+ },
+ "create": {
+ "title": "Create Game",
+ "subtitle": "Describe your game and let AI generate it",
+ "prompt": "What kind of game should be created?",
+ "promptPlaceholder": "A neon snake game with particle effects...",
+ "generate": "Generate",
+ "generating": "Generating game...",
+ "model": "AI Model",
+ "iterate": "Improve",
+ "save": "Save",
+ "preview": "Preview"
+ },
+ "stats": {
+ "title": "Your Statistics",
+ "totalGames": "Games Played",
+ "totalTime": "Total Play Time",
+ "favoriteGame": "Favorite Game",
+ "noStats": "No statistics yet. Play some games!"
+ },
+ "difficulty": {
+ "Einfach": "Easy",
+ "Mittel": "Medium",
+ "Schwer": "Hard"
+ },
+ "time": {
+ "justNow": "Just now",
+ "minutesAgo": "{minutes} minutes ago",
+ "hoursAgo": "{hours} hours ago",
+ "daysAgo": "{days} days ago"
+ }
+}
diff --git a/games/mana-games/apps/web/src/lib/services/game-communication.ts b/games/mana-games/apps/web/src/lib/services/game-communication.ts
new file mode 100644
index 000000000..5ce7836f3
--- /dev/null
+++ b/games/mana-games/apps/web/src/lib/services/game-communication.ts
@@ -0,0 +1,114 @@
+import { gameStatsCollection, type LocalGameStats } from '$lib/data/local-store';
+
+export interface GameMessage {
+ type: 'GAME_EVENT' | 'GAME_LOADED' | 'GAME_ENDED';
+ gameId: string;
+ event?: string;
+ data?: Record;
+}
+
+export function initGameCommunication(gameSlug: string) {
+ let gameStartTime: number | null = null;
+
+ async function getOrCreateStats(gameId: string): Promise {
+ const all = await gameStatsCollection.getAll();
+ return all.find((s) => s.gameId === gameId) || null;
+ }
+
+ async function updateGameStats(gameId: string, update: Partial) {
+ const existing = await getOrCreateStats(gameId);
+
+ if (existing) {
+ await gameStatsCollection.update(existing.id, {
+ ...update,
+ lastPlayed: new Date().toISOString(),
+ });
+ } else {
+ await gameStatsCollection.insert({
+ gameId,
+ highScore: 0,
+ lastScore: 0,
+ gamesPlayed: 0,
+ totalPlayTime: 0,
+ lastPlayed: new Date().toISOString(),
+ ...update,
+ });
+ }
+ }
+
+ function handleMessage(event: MessageEvent) {
+ if (event.origin !== window.location.origin) return;
+
+ const message = event.data as GameMessage;
+ if (!message.type || message.gameId !== gameSlug) return;
+
+ switch (message.type) {
+ case 'GAME_LOADED':
+ gameStartTime = Date.now();
+ getOrCreateStats(gameSlug).then((stats) => {
+ updateGameStats(gameSlug, {
+ gamesPlayed: (stats?.gamesPlayed || 0) + 1,
+ });
+ });
+ break;
+
+ case 'GAME_EVENT':
+ handleGameEvent(gameSlug, message.event!, message.data);
+ break;
+
+ case 'GAME_ENDED':
+ if (gameStartTime) {
+ const playTime = Math.floor((Date.now() - gameStartTime) / 1000);
+ getOrCreateStats(gameSlug).then((stats) => {
+ updateGameStats(gameSlug, {
+ totalPlayTime: (stats?.totalPlayTime || 0) + playTime,
+ });
+ });
+ gameStartTime = null;
+ }
+ break;
+ }
+ }
+
+ function handleBeforeUnload() {
+ if (gameStartTime) {
+ const playTime = Math.floor((Date.now() - gameStartTime) / 1000);
+ getOrCreateStats(gameSlug).then((stats) => {
+ updateGameStats(gameSlug, {
+ totalPlayTime: (stats?.totalPlayTime || 0) + playTime,
+ });
+ });
+ }
+ }
+
+ window.addEventListener('message', handleMessage);
+ window.addEventListener('beforeunload', handleBeforeUnload);
+
+ return () => {
+ window.removeEventListener('message', handleMessage);
+ window.removeEventListener('beforeunload', handleBeforeUnload);
+ };
+
+ async function handleGameEvent(
+ gameId: string,
+ event: string,
+ data: Record | undefined
+ ) {
+ if (!data) return;
+
+ switch (event) {
+ case 'SCORE_UPDATE':
+ case 'GAME_OVER': {
+ const score = data.score as number;
+ if (score) {
+ const stats = await getOrCreateStats(gameId);
+ await updateGameStats(gameId, {
+ lastScore: score,
+ highScore: Math.max(score, stats?.highScore || 0),
+ });
+ }
+ break;
+ }
+ }
+ }
+}
diff --git a/games/mana-games/apps/web/src/lib/stores/auth.svelte.ts b/games/mana-games/apps/web/src/lib/stores/auth.svelte.ts
new file mode 100644
index 000000000..060eba973
--- /dev/null
+++ b/games/mana-games/apps/web/src/lib/stores/auth.svelte.ts
@@ -0,0 +1,5 @@
+import { createManaAuthStore } from '@manacore/shared-auth-stores';
+
+export const authStore = createManaAuthStore({
+ devBackendPort: 3011,
+});
diff --git a/games/mana-games/apps/web/src/lib/stores/navigation.ts b/games/mana-games/apps/web/src/lib/stores/navigation.ts
new file mode 100644
index 000000000..cf9f78ecb
--- /dev/null
+++ b/games/mana-games/apps/web/src/lib/stores/navigation.ts
@@ -0,0 +1,5 @@
+import { createSimpleNavigationStores } from '@manacore/shared-stores';
+
+export const { isNavCollapsed } = createSimpleNavigationStores({
+ storageKey: 'mana-games',
+});
diff --git a/games/mana-games/apps/web/src/lib/stores/theme.svelte.ts b/games/mana-games/apps/web/src/lib/stores/theme.svelte.ts
new file mode 100644
index 000000000..a6469410b
--- /dev/null
+++ b/games/mana-games/apps/web/src/lib/stores/theme.svelte.ts
@@ -0,0 +1,6 @@
+import { createThemeStore } from '@manacore/shared-theme';
+
+export const theme = createThemeStore({
+ appId: 'mana-games',
+ defaultVariant: 'lume',
+});
diff --git a/games/mana-games/apps/web/src/lib/stores/user-settings.svelte.ts b/games/mana-games/apps/web/src/lib/stores/user-settings.svelte.ts
new file mode 100644
index 000000000..adee3724a
--- /dev/null
+++ b/games/mana-games/apps/web/src/lib/stores/user-settings.svelte.ts
@@ -0,0 +1,18 @@
+import { browser } from '$app/environment';
+import { createUserSettingsStore } from '@manacore/shared-theme';
+import { authStore } from './auth.svelte';
+
+function getAuthUrl(): string {
+ if (browser && typeof window !== 'undefined') {
+ const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string })
+ .__PUBLIC_MANA_CORE_AUTH_URL__;
+ if (injectedUrl) return injectedUrl;
+ }
+ return import.meta.env.DEV ? 'http://localhost:3001' : '';
+}
+
+export const userSettings = createUserSettingsStore({
+ appId: 'mana-games',
+ authUrl: getAuthUrl,
+ getAccessToken: () => authStore.getAccessToken(),
+});
diff --git a/games/mana-games/apps/web/src/pages/about.astro b/games/mana-games/apps/web/src/pages/about.astro
deleted file mode 100644
index e7512cf4f..000000000
--- a/games/mana-games/apps/web/src/pages/about.astro
+++ /dev/null
@@ -1,684 +0,0 @@
----
-import Layout from '../layouts/Layout.astro';
-import Button from '../components/Button.astro';
-import { games } from '../data/games';
-
-// Statistiken berechnen
-const totalGames = games.length;
-const totalLines = games.reduce((sum, game) => sum + (game.codeStats?.total || 0), 0);
-const genres = [...new Set(games.flatMap((game) => game.tags))].length;
-const complexityBreakdown = {
- Minimal: games.filter((g) => g.complexity === 'Minimal').length,
- Einfach: games.filter((g) => g.complexity === 'Einfach').length,
- Mittel: games.filter((g) => g.complexity === 'Mittel').length,
- Komplex: games.filter((g) => g.complexity === 'Komplex').length,
-};
----
-
-
-
-
-
-
- Mehr als nur
- Spiele
-
-
Eine Plattform für Kreativität, Lernen und Spaß
-
-
-
-
-
-
-
-
-
-
🎮
-
Spielen ohne Grenzen
-
- Keine Downloads, keine Installationen. Einfach spielen - direkt im Browser, auf jedem
- Gerät.
-
-
-
-
🎨
-
Kreativität fördern
-
- Jedes Spiel ist ein Kunstwerk aus Code. Von minimalistisch bis komplex - wir zeigen die
- Vielfalt der Spieleentwicklung.
-
-
-
-
📚
-
Lernen durch Code
-
- Unsere Spiele sind vollständig dokumentiert und dienen als Lernressource für angehende
- Entwickler.
-
-
-
-
-
-
-
-
-
-
{totalGames}
-
Spiele
-
und es werden mehr
-
-
-
{totalLines.toLocaleString('de-DE')}
-
Zeilen Code
-
handgeschrieben
-
-
-
{genres}
-
Genres
-
für jeden Geschmack
-
-
-
100%
-
Open Source
-
lerne vom Code
-
-
-
-
-
-
-
-
-
-
Komplexität unserer Spiele
-
- {
- Object.entries(complexityBreakdown).map(([level, count]) => (
-
-
- {count}
-
-
{level}
-
- ))
- }
-
-
-
-
Beliebte Kategorien
-
- 🕹️ Arcade
- 🧩 Puzzle
- 🚀 Action
- 🎵 Rhythmus
- 🏃 Jump'n'Run
- 🗼 Tower Defense
-
-
- Von klassischen Arcade-Spielen wie Snake bis zu innovativen Physik-Puzzles wie Gravity
- Painter - unsere Sammlung wächst stetig. Jedes Spiel ist mit Liebe zum Detail entwickelt
- und optimiert für flüssige Performance auf allen Geräten.
-
-
-
-
-
-
-
-
-
-
-
- HTML5
-
-
Canvas API
-
Flüssige 60 FPS Grafiken direkt im Browser
-
-
-
- JS
-
-
Vanilla JavaScript
-
Keine Dependencies, pure Performance
-
-
-
- PWA
-
-
Progressive Web App
-
Installierbar, offline spielbar
-
-
-
- 📱
-
-
Responsive Design
-
Perfekt auf jedem Bildschirm
-
-
-
-
-
-
-
-
Unsere Philosophie
-
- "Spiele sollten mehr sein als nur Unterhaltung. Sie sind interaktive Kunst, technische
- Meisterwerke und Lernwerkzeuge in einem."
-
-
-
-
✨
-
-
Qualität vor Quantität
-
Jedes Spiel wird sorgfältig entwickelt und getestet
-
-
-
-
🌍
-
-
Zugänglichkeit für alle
-
Kostenlos, werbefrei und ohne versteckte Kosten
-
-
-
-
💡
-
-
Innovation fördern
-
Neue Spielkonzepte und kreative Mechaniken
-
-
-
-
-
-
-
-
-
-
Werde Teil der Community
-
- Hast du Ideen für neue Spiele? Möchtest du zur Plattform beitragen? Oder einfach nur
- Feedback geben? Wir freuen uns von dir zu hören!
-
-
- Spiele entdecken
- Deine Statistiken
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/pages/agb.astro b/games/mana-games/apps/web/src/pages/agb.astro
deleted file mode 100644
index bb9a8a034..000000000
--- a/games/mana-games/apps/web/src/pages/agb.astro
+++ /dev/null
@@ -1,472 +0,0 @@
----
-import Layout from '../layouts/Layout.astro';
-import Button from '../components/Button.astro';
----
-
-
-
-
-
-
- Inhaltsverzeichnis
-
- Geltungsbereich
- Nutzung der Plattform
- Registrierung und Nutzerkonto
- Nutzergenierte Inhalte
- Verhaltensregeln
- Geistiges Eigentum
- Haftungsausschluss
- Datenschutz
- Änderungen der AGB
- Schlussbestimmungen
-
-
-
-
- § 1 Geltungsbereich
-
-
- (1) Diese Allgemeinen Geschäftsbedingungen (nachfolgend "AGB") gelten für die Nutzung der
- Website mana-games.netlify.app (nachfolgend "Plattform") und alle darauf angebotenen Dienste
- und Spiele.
-
-
-
- (2) Mit der Nutzung der Plattform akzeptieren Sie diese AGB. Wenn Sie mit diesen Bedingungen
- nicht einverstanden sind, nutzen Sie bitte unsere Dienste nicht.
-
-
-
- (3) Die Plattform richtet sich an Nutzer aller Altersgruppen. Für minderjährige Nutzer
- gelten zusätzlich unsere Jugendschutzbestimmungen .
-
-
-
-
- § 2 Nutzung der Plattform
-
-
- (1) Die Nutzung der Plattform und der darauf angebotenen Spiele ist grundsätzlich kostenlos
- und ohne Registrierung möglich.
-
-
-
- (2) Wir gewähren Ihnen ein nicht-exklusives, nicht übertragbares, widerrufliches Recht zur
- persönlichen Nutzung der Plattform und der Spiele.
-
-
-
-
Erlaubte Nutzung umfasst:
-
- Spielen aller verfügbaren Spiele
- Erstellen eigener Spiele mit dem KI-Generator
- Speichern von Spielständen im lokalen Browser-Speicher
- Teilen von Links zu Spielen
-
-
-
-
-
Nicht erlaubt ist:
-
- Kommerzielle Nutzung ohne ausdrückliche Genehmigung
- Automatisierte Zugriffe (Bots, Scraping)
- Umgehung von Sicherheitsmaßnahmen
- Verbreitung von Schadsoftware
-
-
-
-
-
- § 3 Registrierung und Nutzerkonto
-
-
- (1) Aktuell ist keine Registrierung für die Nutzung der Plattform erforderlich. Alle Daten
- werden lokal in Ihrem Browser gespeichert.
-
-
-
- (2) Sollten wir in Zukunft Nutzerkonten einführen, werden wir Sie rechtzeitig informieren
- und separate Bedingungen dafür bereitstellen.
-
-
-
-
- § 4 Nutzergenierte Inhalte
-
-
- (1) Mit unserem KI-Generator können Sie eigene Spiele erstellen. Diese werden ausschließlich
- lokal in Ihrem Browser gespeichert.
-
-
-
- (2) Sie sind für die von Ihnen erstellten Inhalte selbst verantwortlich und stellen sicher,
- dass diese:
-
-
-
- Keine Rechte Dritter verletzen
- Keine illegalen Inhalte enthalten
- Nicht diskriminierend, beleidigend oder anstößig sind
- Keine Gewaltverherrlichung oder extremistische Inhalte beinhalten
- Jugendschutzbestimmungen einhalten
-
-
-
- (3) Wir behalten uns vor, bei Kenntnis von rechtswidrigen Inhalten entsprechende Maßnahmen
- zu ergreifen.
-
-
-
-
- § 5 Verhaltensregeln
-
-
-
-
✅ Erwünschtes Verhalten
-
- Respektvoller Umgang mit anderen Nutzern
- Konstruktives Feedback
- Melden von Bugs und Problemen
- Teilen von kreativen Ideen
-
-
-
-
-
❌ Unerwünschtes Verhalten
-
- Spam oder Werbung
- Hacking-Versuche
- Verbreitung falscher Informationen
- Belästigung anderer Nutzer
-
-
-
-
-
-
- § 6 Geistiges Eigentum
-
-
- (1) Alle Rechte an der Plattform, dem Design, den offiziellen Spielen und dem Quellcode
- liegen bei uns bzw. unseren Lizenzgebern.
-
-
-
- (2) Die Plattform ist Open Source. Details zur Lizenzierung finden Sie auf unserer
- Copyright-Seite .
-
-
-
- (3) An den von Ihnen mit dem KI-Generator erstellten Spielen räumen Sie uns ein einfaches,
- nicht-exklusives Nutzungsrecht ein, sofern Sie diese öffentlich teilen.
-
-
-
-
- § 7 Haftungsausschluss
-
-
-
- (1) Die Nutzung der Plattform erfolgt auf eigene Gefahr. Wir übernehmen keine Gewähr für
- die ständige Verfügbarkeit, Fehlerfreiheit oder Vollständigkeit der angebotenen Dienste.
-
-
-
-
- (2) Wir haften nur für Schäden, die durch vorsätzliches oder grob fahrlässiges Verhalten
- unsererseits entstehen. Die Haftung für leichte Fahrlässigkeit ist ausgeschlossen, soweit
- keine wesentlichen Vertragspflichten verletzt werden.
-
-
-
- (3) Für Datenverluste, insbesondere von lokal gespeicherten Spielständen oder selbst
- erstellten Spielen, übernehmen wir keine Haftung. Wir empfehlen regelmäßige Backups
- wichtiger Daten.
-
-
- (4) Die Haftung für mittelbare und Folgeschäden ist ausgeschlossen.
-
-
-
- § 8 Datenschutz
-
-
- Der Schutz Ihrer Daten ist uns wichtig. Einzelheiten zur Datenverarbeitung finden Sie in
- unserer Datenschutzerklärung .
-
-
-
-
- § 9 Änderungen der AGB
-
-
- (1) Wir behalten uns vor, diese AGB jederzeit zu ändern. Änderungen werden auf der Plattform
- bekannt gegeben.
-
-
-
- (2) Die weitere Nutzung der Plattform nach Bekanntgabe von Änderungen gilt als Zustimmung zu
- den geänderten Bedingungen.
-
-
-
-
- § 10 Schlussbestimmungen
-
-
- (1) Es gilt das Recht der Bundesrepublik Deutschland unter Ausschluss des UN-Kaufrechts.
-
-
-
- (2) Sollten einzelne Bestimmungen dieser AGB unwirksam sein oder werden, berührt dies die
- Wirksamkeit der übrigen Bestimmungen nicht.
-
-
-
- (3) Gerichtsstand für alle Streitigkeiten aus diesem Vertragsverhältnis ist, soweit
- gesetzlich zulässig, [Ihr Ort].
-
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/pages/community.astro b/games/mana-games/apps/web/src/pages/community.astro
deleted file mode 100644
index 880487d17..000000000
--- a/games/mana-games/apps/web/src/pages/community.astro
+++ /dev/null
@@ -1,356 +0,0 @@
----
-import Layout from '../layouts/Layout.astro';
-import GameCard from '../components/GameCard.astro';
-import { games } from '../data/games';
-
-// Filter community games
-const communityGames = games.filter((game) => 'community' in game && game.community === true);
-
-// Try to load additional community games from JSON file
-let additionalCommunityGames = [];
-// TODO: When community-games.json exists, load it here
-// For now, we'll just use an empty array until the first game is submitted
-
-// Combine all community games
-const allCommunityGames = [...communityGames, ...additionalCommunityGames];
----
-
-
-
-
-
-
-
- {
- allCommunityGames.length > 0 ? (
-
-
Eingereichte Spiele
-
- {allCommunityGames.map((game) => (
-
- ))}
-
-
- ) : (
-
- )
- }
-
-
-
🔄 In Prüfung
-
Diese Spiele werden gerade von unserem Team geprüft:
-
-
Lade ausstehende Einreichungen...
-
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/pages/copyright.astro b/games/mana-games/apps/web/src/pages/copyright.astro
deleted file mode 100644
index 88d6fc8e4..000000000
--- a/games/mana-games/apps/web/src/pages/copyright.astro
+++ /dev/null
@@ -1,719 +0,0 @@
----
-import Layout from '../layouts/Layout.astro';
-import Button from '../components/Button.astro';
----
-
-
-
-
-
-
-
-
🌟
-
-
100% Open Source
-
- Mana Games ist ein Open-Source-Projekt. Der gesamte Quellcode ist öffentlich verfügbar
- und kann frei verwendet, modifiziert und weitergegeben werden.
-
-
- 📦
- Zum GitHub Repository
-
-
-
-
-
-
- Projekt-Lizenz
-
-
-
-
-
-
Copyright (c) 2024 [Ihr Name]
-
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this
- software and associated documentation files (the "Software"), to deal in the Software
- without restriction, including without limitation the rights to use, copy, modify,
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to the following
- conditions:
-
-
-
- The above copyright notice and this permission notice shall be included in all copies or
- substantial portions of the Software.
-
-
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
- INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
- OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-
-
-
-
-
Was bedeutet das für Sie?
-
- ✅ Sie können den Code frei verwenden
- ✅ Sie können den Code modifizieren
- ✅ Sie können den Code in kommerziellen Projekten nutzen
- ✅ Sie können den Code weitergeben
- ⚠️ Keine Garantie oder Haftung
- 📋 Copyright-Hinweis muss erhalten bleiben
-
-
-
-
-
-
- Spiele-Lizenzen
-
-
-
-
Offizielle Spiele
-
- Alle offiziellen Spiele auf unserer Plattform unterliegen ebenfalls der MIT-Lizenz. Sie
- können den Code jedes Spiels frei verwenden, studieren und modifizieren.
-
-
-
-
-
Nutzer-generierte Spiele
-
- Spiele, die mit unserem KI-Generator erstellt werden, gehören dem jeweiligen Ersteller.
- Die Ersteller können selbst entscheiden, unter welcher Lizenz sie ihre Spiele
- veröffentlichen möchten.
-
-
-
-
-
-
- Verwendete Technologien & Bibliotheken
-
-
-
-
Framework & Build-Tools
-
-
-
-
-
- TypeScript
- v5.x
-
-
-
-
-
-
-
-
Deployment & Hosting
-
-
-
-
-
-
-
-
- Assets & Medien
-
-
-
-
Icons & Emojis
-
- Wir verwenden System-Emojis, die je nach Betriebssystem unterschiedlich dargestellt
- werden können. Diese sind gemeinfrei oder unterliegen den jeweiligen Systemlizenzen.
-
-
-
-
-
Schriftarten
-
- Wir nutzen System-Schriftarten für optimale Performance und Lesbarkeit. Keine externen
- Schriftarten werden geladen.
-
-
-
-
-
Grafiken
-
- Alle Spielgrafiken werden programmatisch mit Canvas API erstellt. Es werden keine
- externen Bilddateien in den Spielen verwendet.
-
-
-
-
-
-
- Beitragen zum Projekt
-
-
-
Wie Sie beitragen können
-
-
-
-
1
-
-
Fork erstellen
-
Erstellen Sie einen Fork des Repositories auf GitHub
-
-
-
-
-
2
-
-
Änderungen vornehmen
-
Entwickeln Sie Ihre Features oder Bugfixes
-
-
-
-
-
3
-
-
Pull Request
-
Reichen Sie einen Pull Request mit Ihren Änderungen ein
-
-
-
-
-
-
- Wichtig: Mit dem Einreichen eines Pull Requests stimmen Sie zu, dass Ihre
- Beiträge unter der MIT-Lizenz veröffentlicht werden.
-
-
-
-
-
-
- Namensnennung & Credits
-
-
-
Hauptentwickler
-
-
[Ihr Name]
-
Projektinitiator & Hauptentwickler
-
-
-
Contributors
-
- Eine vollständige Liste aller Contributors finden Sie auf unserer
-
- GitHub Contributors-Seite
-
-
-
-
Besonderer Dank
-
- An die Open-Source-Community für ihre großartigen Tools
- An alle Spieler, die uns Feedback geben
- An alle Contributors, die das Projekt verbessern
-
-
-
-
-
- Rechtliche Hinweise
-
-
-
-
Markenrechte
-
- "Mana Games" ist eine eingetragene Marke. Die Verwendung des Namens bedarf unserer
- ausdrücklichen Genehmigung.
-
-
-
-
-
Haftungsausschluss
-
- Die Software wird "wie besehen" ohne jegliche Garantie bereitgestellt. Details finden
- Sie in der MIT-Lizenz.
-
-
-
-
-
Externe Links
-
Wir übernehmen keine Verantwortung für die Inhalte verlinkter externer Websites.
-
-
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/pages/create.astro b/games/mana-games/apps/web/src/pages/create.astro
deleted file mode 100644
index 0685dfa84..000000000
--- a/games/mana-games/apps/web/src/pages/create.astro
+++ /dev/null
@@ -1,1651 +0,0 @@
----
-import Layout from '../layouts/Layout.astro';
----
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
KI generiert dein Spiel... (kann 10-20 Sekunden dauern)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
🎮 Hier erscheint dein generiertes Spiel
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/pages/datenschutz.astro b/games/mana-games/apps/web/src/pages/datenschutz.astro
deleted file mode 100644
index e1727041e..000000000
--- a/games/mana-games/apps/web/src/pages/datenschutz.astro
+++ /dev/null
@@ -1,445 +0,0 @@
----
-import Layout from '../layouts/Layout.astro';
-import Button from '../components/Button.astro';
----
-
-
-
-
-
-
- 1. Datenschutz auf einen Blick
-
-
-
Allgemeine Hinweise
-
- Die folgenden Hinweise geben einen einfachen Überblick darüber, was mit Ihren
- personenbezogenen Daten passiert, wenn Sie diese Website besuchen. Personenbezogene Daten
- sind alle Daten, mit denen Sie persönlich identifiziert werden können.
-
-
-
-
-
🛡️
-
-
Ihre Daten sind bei uns sicher
-
- Wir erheben nur minimal notwendige Daten. Keine Tracker, keine Werbung, keine
- versteckten Datensammlungen. Ihre Privatsphäre ist uns wichtig.
-
-
-
-
-
-
- 2. Datenerfassung auf dieser Website
-
- Wer ist verantwortlich für die Datenerfassung?
-
- Die Datenverarbeitung auf dieser Website erfolgt durch den Websitebetreiber. Die
- Kontaktdaten können Sie dem Abschnitt „Hinweis zur verantwortlichen Stelle" in dieser
- Datenschutzerklärung entnehmen.
-
-
- Wie erfassen wir Ihre Daten?
-
- Ihre Daten werden zum einen dadurch erhoben, dass Sie uns diese mitteilen. Hierbei kann es
- sich z.B. um Daten handeln, die Sie in ein Kontaktformular eingeben.
-
-
- Andere Daten werden automatisch oder nach Ihrer Einwilligung beim Besuch der Website durch
- unsere IT-Systeme erfasst. Das sind vor allem technische Daten (z.B. Internetbrowser,
- Betriebssystem oder Uhrzeit des Seitenaufrufs).
-
-
- Wofür nutzen wir Ihre Daten?
-
- Ein Teil der Daten wird erhoben, um eine fehlerfreie Bereitstellung der Website zu
- gewährleisten. Andere Daten können zur Analyse Ihres Nutzerverhaltens verwendet werden.
-
-
-
-
- 3. Hosting und Content Delivery Networks (CDN)
-
-
-
Netlify
-
- Wir hosten unsere Website bei Netlify. Anbieter ist die Netlify, Inc., 2325 3rd Street,
- Suite 296, San Francisco, CA 94107, USA.
-
-
- Beim Besuch unserer Website erfasst Netlify verschiedene Logfiles inklusive Ihrer
- IP-Adressen. Details entnehmen Sie der Datenschutzerklärung von Netlify:
-
- https://www.netlify.com/privacy/
-
-
-
- Die Verwendung von Netlify erfolgt auf Grundlage von Art. 6 Abs. 1 lit. f DSGVO. Wir haben
- ein berechtigtes Interesse an einer möglichst zuverlässigen Darstellung unserer Website.
-
-
-
-
-
- 4. Allgemeine Hinweise und Pflichtinformationen
-
- Datenschutz
-
- Die Betreiber dieser Seiten nehmen den Schutz Ihrer persönlichen Daten sehr ernst. Wir
- behandeln Ihre personenbezogenen Daten vertraulich und entsprechend den gesetzlichen
- Datenschutzvorschriften sowie dieser Datenschutzerklärung.
-
-
- Hinweis zur verantwortlichen Stelle
- Die verantwortliche Stelle für die Datenverarbeitung auf dieser Website ist:
-
-
-
- Speicherdauer
-
- Soweit innerhalb dieser Datenschutzerklärung keine speziellere Speicherdauer genannt wurde,
- verbleiben Ihre personenbezogenen Daten bei uns, bis der Zweck für die Datenverarbeitung
- entfällt.
-
-
-
-
- 5. Datenerfassung auf dieser Website
-
- Server-Log-Dateien
-
- Der Provider der Seiten erhebt und speichert automatisch Informationen in so genannten
- Server-Log-Dateien, die Ihr Browser automatisch an uns übermittelt. Dies sind:
-
-
- Browsertyp und Browserversion
- Verwendetes Betriebssystem
- Referrer URL
- Hostname des zugreifenden Rechners
- Uhrzeit der Serveranfrage
- IP-Adresse
-
- Eine Zusammenführung dieser Daten mit anderen Datenquellen wird nicht vorgenommen.
-
- Progressive Web App (PWA)
-
- Diese Website kann als Progressive Web App (PWA) installiert werden. Bei der Installation
- werden folgende Daten lokal auf Ihrem Gerät gespeichert:
-
-
- App-Manifest und Icons
- Service Worker für Offline-Funktionalität
- Spielstände und Einstellungen (im localStorage)
-
-
- Diese Daten verbleiben ausschließlich auf Ihrem Gerät und werden nicht an uns oder Dritte
- übertragen.
-
-
-
-
- 6. Analyse-Tools und Werbung
-
-
-
✅
-
-
Keine Analyse-Tools
-
- Wir verwenden keine Analyse-Tools wie Google Analytics oder ähnliche Dienste. Ihre
- Nutzung unserer Website wird nicht getrackt oder analysiert.
-
-
-
-
-
-
🚫
-
-
Keine Werbung
-
- Unsere Website ist komplett werbefrei. Wir verwenden keine Werbenetzwerke oder
- Display-Werbung jeglicher Art.
-
-
-
-
-
-
- 7. Plugins und Tools
-
- Keine externen Plugins
-
- Wir verwenden keine Social Media Plugins, keine eingebetteten Videos von Drittanbietern und
- keine externen Schriftarten. Alle Ressourcen werden direkt von unserem Server ausgeliefert.
-
-
-
-
- 8. Ihre Rechte
-
- Sie haben folgende Rechte:
-
-
-
Auskunftsrecht
-
Sie können Auskunft über Ihre gespeicherten personenbezogenen Daten verlangen.
-
-
-
Berichtigung
-
Sie können die Berichtigung unrichtiger Daten verlangen.
-
-
-
Löschung
-
Sie können die Löschung Ihrer personenbezogenen Daten verlangen.
-
-
-
Einschränkung
-
Sie können die Einschränkung der Verarbeitung verlangen.
-
-
-
Widerspruch
-
Sie können der Verarbeitung Ihrer Daten widersprechen.
-
-
-
Datenübertragbarkeit
-
Sie haben das Recht auf Datenübertragbarkeit.
-
-
-
-
-
- 9. Änderungen
-
- Wir behalten uns vor, diese Datenschutzerklärung anzupassen, damit sie stets den aktuellen
- rechtlichen Anforderungen entspricht oder um Änderungen unserer Leistungen in der
- Datenschutzerklärung umzusetzen, z.B. bei der Einführung neuer Services. Für Ihren erneuten
- Besuch gilt dann die neue Datenschutzerklärung.
-
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/pages/games/[slug].astro b/games/mana-games/apps/web/src/pages/games/[slug].astro
deleted file mode 100644
index 1434c2e84..000000000
--- a/games/mana-games/apps/web/src/pages/games/[slug].astro
+++ /dev/null
@@ -1,1101 +0,0 @@
----
-import Layout from '../../layouts/Layout.astro';
-import Button from '../../components/Button.astro';
-import { games } from '../../data/games';
-
-export function getStaticPaths() {
- return games.map((game) => ({
- params: { slug: game.slug },
- props: { game },
- }));
-}
-
-const { game } = Astro.props;
----
-
-
-
-
-
-
-
-
-
-
-
-
-
📊 Deine Statistiken
-
-
-
-
-
{game.title}
-
{game.description}
-
-
-
-
Steuerung
-
{game.controls}
-
-
-
-
Details
-
-
- {game.tags.map((tag) => (
- {tag}
- ))}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/games/mana-games/apps/web/src/pages/games/[slug]/playground.astro b/games/mana-games/apps/web/src/pages/games/[slug]/playground.astro
deleted file mode 100644
index eb9adfddf..000000000
--- a/games/mana-games/apps/web/src/pages/games/[slug]/playground.astro
+++ /dev/null
@@ -1,427 +0,0 @@
----
-import Layout from '../../../layouts/Layout.astro';
-import { games } from '../../../data/games';
-
-export function getStaticPaths() {
- return games.map((game) => ({
- params: { slug: game.slug },
- props: { game },
- }));
-}
-
-const { game } = Astro.props;
----
-
-
-
-
-
-
-
Code wird geladen...
-
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/pages/impressum.astro b/games/mana-games/apps/web/src/pages/impressum.astro
deleted file mode 100644
index e4bfe3a50..000000000
--- a/games/mana-games/apps/web/src/pages/impressum.astro
+++ /dev/null
@@ -1,432 +0,0 @@
----
-import Layout from '../layouts/Layout.astro';
-import Button from '../components/Button.astro';
----
-
-
-
-
-
-
- Verantwortlich für den Inhalt
-
-
-
-
-
-
- Umsatzsteuer-ID
- Umsatzsteuer-Identifikationsnummer gemäß §27 a Umsatzsteuergesetz:
-
- DE[IHRE-UST-ID]
-
-
- Falls Sie keine Umsatzsteuer-ID haben, können Sie diesen Abschnitt entfernen.
-
-
-
-
- Verantwortlich für den Inhalt nach § 55 Abs. 2 RStV
-
-
[Ihr Name]
-
[Ihre Adresse]
-
[PLZ und Ort]
-
-
-
-
- EU-Streitschlichtung
-
- Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit:
-
-
- Unsere E-Mail-Adresse finden Sie oben im Impressum.
-
-
-
- Verbraucherstreitbeilegung / Universalschlichtungsstelle
-
- Wir sind nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer
- Verbraucherschlichtungsstelle teilzunehmen.
-
-
-
-
- Haftungsausschluss (Disclaimer)
-
- Haftung für Inhalte
-
- Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte auf diesen Seiten nach
- den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter
- jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen
- oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen.
-
-
- Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den
- allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst
- ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden
- von entsprechenden Rechtsverletzungen werden wir diese Inhalte umgehend entfernen.
-
-
- Haftung für Links
-
- Unser Angebot enthält Links zu externen Websites Dritter, auf deren Inhalte wir keinen
- Einfluss haben. Deshalb können wir für diese fremden Inhalte auch keine Gewähr übernehmen.
- Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der
- Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf
- mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung
- nicht erkennbar.
-
-
- Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete
- Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von
- Rechtsverletzungen werden wir derartige Links umgehend entfernen.
-
-
- Urheberrecht
-
- Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem
- deutschen Urheberrecht. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der
- Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen der schriftlichen Zustimmung
- des jeweiligen Autors bzw. Erstellers. Downloads und Kopien dieser Seite sind nur für den
- privaten, nicht kommerziellen Gebrauch gestattet.
-
-
- Soweit die Inhalte auf dieser Seite nicht vom Betreiber erstellt wurden, werden die
- Urheberrechte Dritter beachtet. Insbesondere werden Inhalte Dritter als solche
- gekennzeichnet. Sollten Sie trotzdem auf eine Urheberrechtsverletzung aufmerksam werden,
- bitten wir um einen entsprechenden Hinweis. Bei Bekanntwerden von Rechtsverletzungen werden
- wir derartige Inhalte umgehend entfernen.
-
-
-
-
- Open Source Hinweis
-
-
💻
-
-
Diese Website ist Open Source
-
- Der Quellcode dieser Website ist öffentlich verfügbar. Sie finden das Repository auf:
-
-
- 📦
- GitHub Repository
-
-
-
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/pages/index.astro b/games/mana-games/apps/web/src/pages/index.astro
deleted file mode 100644
index 43f65844c..000000000
--- a/games/mana-games/apps/web/src/pages/index.astro
+++ /dev/null
@@ -1,765 +0,0 @@
----
-import Layout from '../layouts/Layout.astro';
-import GameCard from '../components/GameCard.astro';
-import MyGamesSection from '../components/MyGamesSection.astro';
-import HorizontalScroller from '../components/HorizontalScroller.astro';
-import { games } from '../data/games';
-
-// Filtere offizielle Spiele (ohne community flag)
-const officialGames = games.filter((game) => !game.community);
-
-// Kategorisiere Spiele nach Genres für verschiedene Scroller
-const arcadeGames = officialGames.filter((game) => game.tags.includes('Arcade'));
-const puzzleGames = officialGames.filter((game) => game.tags.includes('Puzzle'));
-const actionGames = officialGames.filter(
- (game) =>
- game.tags.includes('Action') ||
- game.tags.includes('Shooter') ||
- game.tags.includes('Jump n Run')
-);
-
-// Sortiere nach Beliebtheit/Komplexität
-const featuredGames = [...officialGames].slice(0, 8);
----
-
-
-
-
-
-
- Spiele
- ohne Grenzen
-
-
-
-
-
-
-
-
-
- {officialGames.length}
- Spiele
-
-
-
- 100%
- Kostenlos
-
-
-
- 100%
- Werbefrei
-
-
-
- 📊
- Meine Stats
-
-
-
-
-
-
-
-
-
-
-
- {
- arcadeGames.length > 0 && (
-
- )
- }
-
- {
- puzzleGames.length > 0 && (
-
- )
- }
-
- {
- actionGames.length > 0 && (
-
- )
- }
-
-
-
-
-
- {
- officialGames.map((game, index) => (
-
-
-
- ))
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/pages/jugendschutz.astro b/games/mana-games/apps/web/src/pages/jugendschutz.astro
deleted file mode 100644
index 6deb86dd9..000000000
--- a/games/mana-games/apps/web/src/pages/jugendschutz.astro
+++ /dev/null
@@ -1,601 +0,0 @@
----
-import Layout from '../layouts/Layout.astro';
-import Button from '../components/Button.astro';
----
-
-
-
-
-
-
-
-
- Bei Mana Games liegt uns die Sicherheit und das Wohlbefinden junger Spieler besonders am
- Herzen. Unsere Plattform ist so gestaltet, dass Kinder und Jugendliche sicher und
- altersgerecht spielen können.
-
-
-
-
-
- Unsere Jugendschutz-Prinzipien
-
-
-
-
🎮
-
Altersgerechte Inhalte
-
- Alle unsere Spiele sind familienfreundlich und enthalten keine Gewalt, explizite Inhalte
- oder verstörende Elemente.
-
-
-
-
-
🚫
-
Keine Werbung
-
- Unsere Plattform ist komplett werbefrei. Kinder werden nicht mit kommerziellen Inhalten
- oder In-App-Käufen konfrontiert.
-
-
-
-
-
🔒
-
Datenschutz
-
- Wir sammeln keine persönlichen Daten von Kindern. Alle Spielstände werden nur lokal im
- Browser gespeichert.
-
-
-
-
-
💬
-
Kein Chat
-
- Es gibt keine Chat-Funktionen oder soziale Features, die eine Kontaktaufnahme zwischen
- Nutzern ermöglichen.
-
-
-
-
-
-
- Altersempfehlungen
-
-
-
-
0-6 Jahre
-
Vorschulalter
-
Einfache Spiele mit großen Buttons und klaren visuellen Elementen:
-
- Memory-Spiele
- Einfache Puzzle
- Farb- und Formspiele
-
-
-
-
-
6-12 Jahre
-
Grundschulalter
-
Spiele die Geschicklichkeit und logisches Denken fördern:
-
- Jump'n'Run Spiele
- Einfache Strategiespiele
- Lernspiele
-
-
-
-
-
12+ Jahre
-
Jugendliche
-
Komplexere Spiele mit anspruchsvollen Herausforderungen:
-
- Tower Defense
- Komplexe Puzzle
- Strategiespiele
-
-
-
-
-
-
- Hinweise für Eltern
-
-
-
-
🕐 Spielzeiten begrenzen
-
- Auch wenn unsere Spiele pädagogisch wertvoll sind, empfehlen wir altersgerechte
- Bildschirmzeiten einzuhalten.
-
-
-
- 3-6 Jahre: max. 30 Minuten täglich
-
-
- 6-9 Jahre: max. 1 Stunde täglich
-
-
- 10+ Jahre: max. 2 Stunden täglich
-
-
-
-
-
-
👨👩👧 Gemeinsam spielen
-
- Nutzen Sie die Gelegenheit, mit Ihren Kindern gemeinsam zu spielen. Das fördert nicht
- nur die Bindung, sondern ermöglicht auch Gespräche über das Spielerlebnis.
-
-
-
-
-
🎯 Altersgerechte Auswahl
-
Achten Sie auf die Komplexitätsstufen unserer Spiele:
-
- Minimal - Für die Kleinsten
- Einfach - Ab Grundschulalter
- Mittel - Für erfahrene Spieler
- Komplex - Herausfordernd
-
-
-
-
-
-
- KI-Generator und Jugendschutz
-
-
-
-
Sichere KI-Nutzung
-
Unser KI-Spielegenerator verfügt über eingebaute Sicherheitsmechanismen:
-
- Filterung ungeeigneter Begriffe und Themen
- Automatische Prüfung generierter Inhalte
- Keine Generierung von gewalttätigen oder ungeeigneten Spielen
-
-
-
-
-
⚠️ Empfehlung
-
- Wir empfehlen, dass Kinder unter 12 Jahren den KI-Generator nur unter Aufsicht von
- Erwachsenen nutzen.
-
-
-
-
-
-
- Technische Schutzmaßnahmen
-
-
-
-
🌐
-
-
Keine externen Links
-
Unsere Spiele enthalten keine Links zu externen Websites.
-
-
-
-
-
📵
-
-
Offline spielbar
-
Nach dem ersten Laden können alle Spiele offline gespielt werden.
-
-
-
-
-
🔐
-
-
Lokale Datenspeicherung
-
Alle Daten bleiben auf dem Gerät des Nutzers.
-
-
-
-
-
-
- Kontakt und Meldungen
-
-
-
-
-
- Weitere Ressourcen
-
-
-
Hilfreiche Links für Eltern:
-
-
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/pages/mitmachen.astro b/games/mana-games/apps/web/src/pages/mitmachen.astro
deleted file mode 100644
index 37005f562..000000000
--- a/games/mana-games/apps/web/src/pages/mitmachen.astro
+++ /dev/null
@@ -1,644 +0,0 @@
----
-import Layout from '../layouts/Layout.astro';
-import Button from '../components/Button.astro';
----
-
-
-
-
-
-
- Werde Teil der
- Community
-
-
Gemeinsam erschaffen wir die Zukunft des Web-Gaming
-
-
-
-
-
-
-
-
- Mana Games ist mehr als nur eine Spielesammlung – es ist eine wachsende Community von
- Entwicklern, Kreativen und Gaming-Enthusiasten. Deine Ideen und Beiträge können Teil
- dieser Vision werden.
-
-
-
-
-
-
-
-
-
-
-
-
-
Spielideen einreichen
-
- Du hast eine geniale Spielidee? Teile sie mit uns! Wir sind immer auf der Suche nach
- innovativen Konzepten, die Spaß machen und gleichzeitig technisch interessant sind.
-
-
- Neue Gameplay-Mechaniken
- Kreative Themes und Settings
- Innovative Steuerungskonzepte
-
-
-
-
-
-
-
Code & Entwicklung
-
- Als Open-Source-Projekt freuen wir uns über Code-Beiträge jeder Art. Ob Bug-Fixes,
- Performance-Optimierungen oder neue Features – jeder Beitrag zählt.
-
-
- JavaScript/HTML5 Canvas Expertise
- Performance-Optimierungen
- Bug-Fixes und Verbesserungen
-
-
-
-
-
-
-
-
-
Design & Grafik
-
- Hilf uns dabei, Mana Games noch schöner zu machen! Von Spiel-Assets über
- UI-Verbesserungen bis hin zu komplett neuen visuellen Konzepten.
-
-
- Pixel Art & Sprites
- UI/UX Verbesserungen
- Visuelle Effekte & Animationen
-
-
-
-
-
-
-
-
-
-
-
-
🏆
-
Anerkennung
-
Dein Name in den Credits und der Contributors-Liste
-
-
-
📚
-
Lernerfahrung
-
Arbeite mit modernen Web-Technologien und lerne von der Community
-
-
-
🌍
-
Reichweite
-
Deine Arbeit wird von Spielern weltweit gesehen und gespielt
-
-
-
🤝
-
Netzwerk
-
Verbinde dich mit gleichgesinnten Entwicklern und Kreativen
-
-
-
-
-
-
-
-
-
-
✅
-
-
Qualität über Quantität
-
Wir legen Wert auf durchdachte, gut implementierte Beiträge
-
-
-
-
🎯
-
-
Performance im Fokus
-
Spiele müssen flüssig auf allen Geräten laufen
-
-
-
-
🌟
-
-
Kreativität fördern
-
Neue Ideen und innovative Ansätze sind immer willkommen
-
-
-
-
👥
-
-
Respektvolle Community
-
Ein freundlicher und konstruktiver Umgang miteinander
-
-
-
-
-
-
-
-
-
-
- Arbeite mit modernen Web-Technologien und erweitere deine Fähigkeiten:
-
-
-
- HTML5 Canvas
- Grafik-Engine
-
-
- JavaScript ES6+
- Programmierung
-
-
- Astro
- Framework
-
-
- PWA
- App-Technologie
-
-
-
-
-
-
-
-
-
Bereit durchzustarten?
-
- Egal ob du Entwickler, Designer oder einfach voller Ideen bist – wir freuen uns auf deinen
- Beitrag zur Mana Games Community!
-
-
-
- GitHub Repository
-
- Kontakt aufnehmen
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/pages/play-generated.astro b/games/mana-games/apps/web/src/pages/play-generated.astro
deleted file mode 100644
index bc05d5e29..000000000
--- a/games/mana-games/apps/web/src/pages/play-generated.astro
+++ /dev/null
@@ -1,397 +0,0 @@
----
-import Layout from '../layouts/Layout.astro';
----
-
-
-
-
-
-
-
-
-
-
-
-
❌ Spiel konnte nicht geladen werden
-
Das gesuchte Spiel wurde nicht gefunden.
-
Zurück zur Startseite
-
-
-
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/pages/stats.astro b/games/mana-games/apps/web/src/pages/stats.astro
deleted file mode 100644
index 5a1879fc9..000000000
--- a/games/mana-games/apps/web/src/pages/stats.astro
+++ /dev/null
@@ -1,1515 +0,0 @@
----
-import Layout from '../layouts/Layout.astro';
-import { games } from '../data/games';
----
-
-
-
-
Meine Spielstatistiken
-
-
-
-
Lade Statistiken...
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/pages/submit.astro b/games/mana-games/apps/web/src/pages/submit.astro
deleted file mode 100644
index ac928afa2..000000000
--- a/games/mana-games/apps/web/src/pages/submit.astro
+++ /dev/null
@@ -1,754 +0,0 @@
----
-import Layout from '../layouts/Layout.astro';
----
-
-
-
-
-
-
-
-
📋 Richtlinien für Einreichungen
-
- Das Spiel muss in einer einzelnen HTML-Datei funktionieren
- Keine externen Abhängigkeiten (CDNs sind erlaubt)
- Maximale Dateigröße: 1MB für HTML, 500KB für Screenshot
- Das Spiel muss familienfreundlich sein
- Kein urheberrechtlich geschütztes Material
- Das Spiel sollte die postMessage API für Score-Integration nutzen
-
-
-
-
-
-
-
Validierungsergebnisse
-
-
-
-
-
-
-
-
-
diff --git a/games/mana-games/apps/web/src/routes/(app)/+layout.svelte b/games/mana-games/apps/web/src/routes/(app)/+layout.svelte
new file mode 100644
index 000000000..31f297173
--- /dev/null
+++ b/games/mana-games/apps/web/src/routes/(app)/+layout.svelte
@@ -0,0 +1,292 @@
+
+
+
+
+
+
+
+
+
+
+ {@render children()}
+
+
+
+
(commandBarOpen = false)}
+ onSearch={handleCommandBarSearch}
+ onSelect={handleCommandBarSelect}
+ quickActions={commandBarQuickActions}
+ placeholder="Spiel suchen..."
+ emptyText="Keine Ergebnisse"
+ searchingText="Suche..."
+ />
+
+
+ (showGuestWelcome = false)}
+ onLogin={() => goto('/login')}
+ onRegister={() => goto('/register')}
+ locale={($locale || 'de') === 'de' ? 'de' : 'en'}
+ />
+
+ {#if authStore.isAuthenticated}
+
+ {/if}
+
+
+
+
diff --git a/games/mana-games/apps/web/src/routes/(app)/+page.svelte b/games/mana-games/apps/web/src/routes/(app)/+page.svelte
new file mode 100644
index 000000000..ff7e4f615
--- /dev/null
+++ b/games/mana-games/apps/web/src/routes/(app)/+page.svelte
@@ -0,0 +1,83 @@
+
+
+
+ {$_('app.name')} - {$_('home.title')}
+
+
+
+
+
{$_('home.title')}
+
{$_('home.subtitle')}
+
+
+
+
+
+
+
+ (selectedTag = null)}
+ >
+ {$_('home.allGames')}
+
+ {#each allTags as tag}
+ (selectedTag = selectedTag === tag ? null : tag)}
+ >
+ {tag}
+
+ {/each}
+
+
+ {#if filteredGames().length === 0}
+
+
{$_('home.noResults')}
+
+ {:else}
+
+ {#each filteredGames() as game (game.id)}
+
+ {/each}
+
+ {/if}
+
diff --git a/games/mana-games/apps/web/src/routes/(app)/community/+page.svelte b/games/mana-games/apps/web/src/routes/(app)/community/+page.svelte
new file mode 100644
index 000000000..54e1bd776
--- /dev/null
+++ b/games/mana-games/apps/web/src/routes/(app)/community/+page.svelte
@@ -0,0 +1,27 @@
+
+
+
+ {$_('nav.community')} - Mana Games
+
+
+
+
+
{$_('nav.community')}
+
+ Von der Community erstellte Spiele. Reiche dein eigenes Spiel ein!
+
+
+
+
+
🎮
+
Noch keine Community-Spiele vorhanden.
+
+ Erstelle das erste Spiel!
+
+
+
diff --git a/games/mana-games/apps/web/src/routes/(app)/create/+page.svelte b/games/mana-games/apps/web/src/routes/(app)/create/+page.svelte
new file mode 100644
index 000000000..77a866143
--- /dev/null
+++ b/games/mana-games/apps/web/src/routes/(app)/create/+page.svelte
@@ -0,0 +1,211 @@
+
+
+
+ {$_('create.title')} - Mana Games
+
+
+
+
+
{$_('create.title')}
+
{$_('create.subtitle')}
+
+
+
+
+
+
+
+ {$_('create.prompt')}
+
+
+
+
+
+
+ {$_('create.model')}
+
+
+ {#each models as model}
+
+ {model.label} ({model.provider} - {model.speed})
+
+ {/each}
+
+
+
+ {#if error}
+
+ {error}
+
+ {/if}
+
+
+
+ {#if isGenerating}
+
+ ⚡
+ {$_('create.generating')}
+
+ {:else if iterationCount > 0}
+ {$_('create.iterate')}
+ {:else}
+ {$_('create.generate')}
+ {/if}
+
+
+ {#if generatedHtml}
+
+ {$_('create.save')}
+
+
+ Neu
+
+ {/if}
+
+
+ {#if iterationCount > 0}
+
+ Iteration {iterationCount} · Beschreibe Änderungen im Prompt-Feld
+
+ {/if}
+
+
+
+
+ {#if generatedHtml}
+
+ {:else}
+
+
+
🎮
+
{$_('create.preview')}
+
+
+ {/if}
+
+
+
diff --git a/games/mana-games/apps/web/src/routes/(app)/play-generated/+page.svelte b/games/mana-games/apps/web/src/routes/(app)/play-generated/+page.svelte
new file mode 100644
index 000000000..f5baec300
--- /dev/null
+++ b/games/mana-games/apps/web/src/routes/(app)/play-generated/+page.svelte
@@ -0,0 +1,84 @@
+
+
+
+ Generierte Spiele - Mana Games
+
+
+
+
+
Generierte Spiele
+
Deine mit KI erstellten Spiele
+
+
+ {#if generatedGames.value.length === 0}
+
+
✨
+
Noch keine generierten Spiele.
+
+ Erstelle dein erstes Spiel!
+
+
+ {:else}
+
+
+ {#each generatedGames.value as game (game.id)}
+
(selectedGameId = game.id)}
+ class="w-full text-left rounded-lg border p-3 transition-colors {selectedGameId ===
+ game.id
+ ? 'border-primary bg-primary/5'
+ : 'border-border bg-card hover:bg-muted/50'}"
+ >
+ {game.title}
+
+ {game.model} · {game.iterationCount} Iterationen
+
+
+ {/each}
+
+
+
+ {#if selectedGame}
+
+ {selectedGame.title}
+ deleteGame(selectedGame!.id)}
+ class="text-xs text-red-400 hover:text-red-300 transition-colors"
+ >
+ Löschen
+
+
+
+ {:else}
+
+
Wähle ein Spiel aus der Liste
+
+ {/if}
+
+
+ {/if}
+
diff --git a/games/mana-games/apps/web/src/routes/(app)/play/[slug]/+page.svelte b/games/mana-games/apps/web/src/routes/(app)/play/[slug]/+page.svelte
new file mode 100644
index 000000000..80291f7d7
--- /dev/null
+++ b/games/mana-games/apps/web/src/routes/(app)/play/[slug]/+page.svelte
@@ -0,0 +1,132 @@
+
+
+
+ {game?.title || 'Spiel'} - Mana Games
+
+
+{#if game}
+
+
+
+
+
+ {$_('game.fullscreen')}
+
+
+
+
+
+
+
+
+
+
+
{game.title}
+
{game.description}
+
+
+
+ {$_('game.difficulty')}
+ {game.difficulty}
+
+
+ {$_('game.controls')}
+ {game.controls}
+
+
+
+
+ {#each game.tags as tag}
+
+ {tag}
+
+ {/each}
+
+
+
+ {#if stats}
+
+
{$_('game.stats')}
+
+
+ {$_('game.highScore')}
+ {stats.highScore.toLocaleString()}
+
+
+ {$_('game.gamesPlayed')}
+ {stats.gamesPlayed}
+
+
+ {$_('game.totalPlayTime')}
+ {formatPlayTime(stats.totalPlayTime)}
+
+
+
+ {/if}
+
+
+{:else}
+
+
Spiel nicht gefunden.
+
Zurück zur Übersicht
+
+{/if}
diff --git a/games/mana-games/apps/web/src/routes/(app)/stats/+page.svelte b/games/mana-games/apps/web/src/routes/(app)/stats/+page.svelte
new file mode 100644
index 000000000..33a588a8e
--- /dev/null
+++ b/games/mana-games/apps/web/src/routes/(app)/stats/+page.svelte
@@ -0,0 +1,95 @@
+
+
+
+ {$_('stats.title')} - Mana Games
+
+
+
+
{$_('stats.title')}
+
+ {#if allStats.value.length === 0}
+
+
📊
+
{$_('stats.noStats')}
+
+ {:else}
+
+
+
{totalGamesPlayed}
+
{$_('stats.totalGames')}
+
+
+
{formatPlayTime(totalPlayTime)}
+
{$_('stats.totalTime')}
+
+
+
{favoriteGame()?.title || '-'}
+
{$_('stats.favoriteGame')}
+
+
+
+
+
+
+
+ Spiel
+ {$_('game.highScore')}
+ {$_('game.gamesPlayed')}
+ {$_('game.totalPlayTime')}
+
+
+
+ {#each sortedStats as stat (stat.id)}
+
+ {getGameTitle(stat.gameId)}
+ {stat.highScore.toLocaleString()}
+ {stat.gamesPlayed}
+ {formatPlayTime(stat.totalPlayTime)}
+
+ {/each}
+
+
+
+ {/if}
+
diff --git a/games/mana-games/apps/web/src/routes/+layout.svelte b/games/mana-games/apps/web/src/routes/+layout.svelte
new file mode 100644
index 000000000..f599b48aa
--- /dev/null
+++ b/games/mana-games/apps/web/src/routes/+layout.svelte
@@ -0,0 +1,39 @@
+
+
+
+
+{#if $isLocaleLoading || loading}
+
+{:else}
+
+ {@render children()}
+
+{/if}
diff --git a/games/mana-games/apps/web/src/routes/+layout.ts b/games/mana-games/apps/web/src/routes/+layout.ts
new file mode 100644
index 000000000..ad6cddb06
--- /dev/null
+++ b/games/mana-games/apps/web/src/routes/+layout.ts
@@ -0,0 +1,2 @@
+// Disable SSR — all data is local-first (IndexedDB + mana-sync)
+export const ssr = false;
diff --git a/games/mana-games/apps/web/src/scripts/game-communication.ts b/games/mana-games/apps/web/src/scripts/game-communication.ts
deleted file mode 100644
index 7140205fa..000000000
--- a/games/mana-games/apps/web/src/scripts/game-communication.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { statsService } from '../services/statsService';
-
-export interface GameMessage {
- type: 'GAME_EVENT' | 'GAME_LOADED' | 'GAME_ENDED';
- gameId: string;
- event?: string;
- data?: any;
-}
-
-export function initGameCommunication(gameSlug: string) {
- let gameStartTime: number | null = null;
-
- window.addEventListener('message', (event) => {
- if (event.origin !== window.location.origin) return;
-
- const message = event.data as GameMessage;
- if (!message.type || message.gameId !== gameSlug) return;
-
- switch (message.type) {
- case 'GAME_LOADED':
- gameStartTime = Date.now();
- statsService.incrementGamesPlayed(gameSlug);
- break;
-
- case 'GAME_EVENT':
- handleGameEvent(gameSlug, message.event!, message.data);
- break;
-
- case 'GAME_ENDED':
- if (gameStartTime) {
- const playTime = Math.floor((Date.now() - gameStartTime) / 1000);
- statsService.addPlayTime(gameSlug, playTime);
- gameStartTime = null;
- }
- break;
- }
- });
-
- window.addEventListener('beforeunload', () => {
- if (gameStartTime) {
- const playTime = Math.floor((Date.now() - gameStartTime) / 1000);
- statsService.addPlayTime(gameSlug, playTime);
- }
- });
-}
-
-function handleGameEvent(gameId: string, event: string, data: any) {
- switch (event) {
- case 'SCORE_UPDATE':
- if (data.score) {
- statsService.updateStats(gameId, {
- lastScore: data.score,
- });
- }
- break;
-
- case 'ACHIEVEMENT_UNLOCKED':
- if (data.achievement) {
- statsService.unlockAchievement(gameId, data.achievement);
- }
- break;
-
- case 'GAME_OVER':
- if (data.score) {
- statsService.updateStats(gameId, {
- lastScore: data.score,
- });
- }
- break;
- }
-}
diff --git a/games/mana-games/apps/web/src/scripts/stats-integration-template.js b/games/mana-games/apps/web/src/scripts/stats-integration-template.js
deleted file mode 100644
index a71d33cf9..000000000
--- a/games/mana-games/apps/web/src/scripts/stats-integration-template.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// Template für Stats-Integration in Spiele
-// Dieses Template zeigt, wie man die Stats-Integration in ein Spiel einbaut
-
-// 1. Game ID definieren (muss mit dem Slug in games.ts übereinstimmen)
-const GAME_ID = 'dein-spiel-slug';
-
-// 2. Beim Spielstart senden
-window.addEventListener('load', () => {
- window.parent.postMessage(
- {
- type: 'GAME_LOADED',
- gameId: GAME_ID,
- },
- '*'
- );
-});
-
-// 3. Bei Score-Updates senden
-function updateScore(newScore) {
- score = newScore;
- // UI Update...
-
- window.parent.postMessage(
- {
- type: 'GAME_EVENT',
- gameId: GAME_ID,
- event: 'SCORE_UPDATE',
- data: { score: score },
- },
- '*'
- );
-}
-
-// 4. Bei Game Over senden
-function gameOver() {
- // Game Over Logik...
-
- window.parent.postMessage(
- {
- type: 'GAME_EVENT',
- gameId: GAME_ID,
- event: 'GAME_OVER',
- data: { score: finalScore },
- },
- '*'
- );
-
- // Achievement Beispiele
- if (score >= 100) {
- window.parent.postMessage(
- {
- type: 'GAME_EVENT',
- gameId: GAME_ID,
- event: 'ACHIEVEMENT_UNLOCKED',
- data: {
- achievement: {
- id: 'first-100',
- name: 'Erste 100',
- description: '100 Punkte erreicht!',
- },
- },
- },
- '*'
- );
- }
-}
-
-// 5. Optional: Bei Spielende/Verlassen
-window.addEventListener('beforeunload', () => {
- window.parent.postMessage(
- {
- type: 'GAME_ENDED',
- gameId: GAME_ID,
- },
- '*'
- );
-});
diff --git a/games/mana-games/apps/web/src/services/statsService.ts b/games/mana-games/apps/web/src/services/statsService.ts
deleted file mode 100644
index f51431a6a..000000000
--- a/games/mana-games/apps/web/src/services/statsService.ts
+++ /dev/null
@@ -1,192 +0,0 @@
-export interface GameStats {
- gameId: string;
- highScore: number;
- lastScore: number;
- gamesPlayed: number;
- totalPlayTime: number;
- lastPlayed: string;
- achievements?: Achievement[];
-}
-
-export interface Achievement {
- id: string;
- name: string;
- description: string;
- unlockedAt?: string;
-}
-
-export interface GlobalStats {
- totalGamesPlayed: number;
- totalPlayTime: number;
- favoriteGame?: string;
- lastPlayedGame?: string;
- gamesWithStats: number;
-}
-
-class StatsService {
- private readonly STATS_KEY = 'mana-games-stats';
-
- private getStoredStats(): Record {
- if (typeof window === 'undefined') return {};
-
- try {
- const stored = localStorage.getItem(this.STATS_KEY);
- return stored ? JSON.parse(stored) : {};
- } catch (error) {
- console.error('Error reading stats:', error);
- return {};
- }
- }
-
- private saveStats(stats: Record): void {
- if (typeof window === 'undefined') return;
-
- try {
- localStorage.setItem(this.STATS_KEY, JSON.stringify(stats));
- } catch (error) {
- console.error('Error saving stats:', error);
- }
- }
-
- getStats(gameId: string): GameStats | null {
- const allStats = this.getStoredStats();
- return allStats[gameId] || null;
- }
-
- updateStats(gameId: string, update: Partial): void {
- const allStats = this.getStoredStats();
- const currentStats = allStats[gameId] || {
- gameId,
- highScore: 0,
- lastScore: 0,
- gamesPlayed: 0,
- totalPlayTime: 0,
- lastPlayed: new Date().toISOString(),
- achievements: [],
- };
-
- allStats[gameId] = {
- ...currentStats,
- ...update,
- gameId,
- lastPlayed: new Date().toISOString(),
- };
-
- if (update.lastScore && update.lastScore > currentStats.highScore) {
- allStats[gameId].highScore = update.lastScore;
- }
-
- this.saveStats(allStats);
- }
-
- getAllStats(): Record {
- return this.getStoredStats();
- }
-
- getGlobalStats(): GlobalStats {
- const allStats = this.getStoredStats();
- const statsArray = Object.values(allStats);
-
- if (statsArray.length === 0) {
- return {
- totalGamesPlayed: 0,
- totalPlayTime: 0,
- gamesWithStats: 0,
- };
- }
-
- const totalGamesPlayed = statsArray.reduce((sum, stat) => sum + stat.gamesPlayed, 0);
- const totalPlayTime = statsArray.reduce((sum, stat) => sum + stat.totalPlayTime, 0);
-
- const favoriteGame = statsArray.reduce((fav, stat) =>
- !fav || stat.gamesPlayed > fav.gamesPlayed ? stat : fav
- ).gameId;
-
- const lastPlayedGame = statsArray.reduce((last, stat) =>
- !last || new Date(stat.lastPlayed) > new Date(last.lastPlayed) ? stat : last
- ).gameId;
-
- return {
- totalGamesPlayed,
- totalPlayTime,
- favoriteGame,
- lastPlayedGame,
- gamesWithStats: statsArray.length,
- };
- }
-
- incrementGamesPlayed(gameId: string): void {
- const stats = this.getStats(gameId) || {
- gameId,
- highScore: 0,
- lastScore: 0,
- gamesPlayed: 0,
- totalPlayTime: 0,
- lastPlayed: new Date().toISOString(),
- };
-
- this.updateStats(gameId, {
- gamesPlayed: stats.gamesPlayed + 1,
- });
- }
-
- addPlayTime(gameId: string, seconds: number): void {
- const stats = this.getStats(gameId) || {
- gameId,
- highScore: 0,
- lastScore: 0,
- gamesPlayed: 0,
- totalPlayTime: 0,
- lastPlayed: new Date().toISOString(),
- };
-
- this.updateStats(gameId, {
- totalPlayTime: stats.totalPlayTime + seconds,
- });
- }
-
- unlockAchievement(gameId: string, achievement: Achievement): void {
- const stats = this.getStats(gameId);
- if (!stats) return;
-
- const achievements = stats.achievements || [];
- const exists = achievements.find((a) => a.id === achievement.id);
-
- if (!exists) {
- achievements.push({
- ...achievement,
- unlockedAt: new Date().toISOString(),
- });
-
- this.updateStats(gameId, { achievements });
- }
- }
-
- formatPlayTime(seconds: number): string {
- const hours = Math.floor(seconds / 3600);
- const minutes = Math.floor((seconds % 3600) / 60);
-
- if (hours > 0) {
- return `${hours}h ${minutes}m`;
- }
- return `${minutes}m`;
- }
-
- getRelativeTime(dateString: string): string {
- const date = new Date(dateString);
- const now = new Date();
- const diffMs = now.getTime() - date.getTime();
- const diffMins = Math.floor(diffMs / 60000);
- const diffHours = Math.floor(diffMs / 3600000);
- const diffDays = Math.floor(diffMs / 86400000);
-
- if (diffMins < 1) return 'Gerade eben';
- if (diffMins < 60) return `Vor ${diffMins} Minuten`;
- if (diffHours < 24) return `Vor ${diffHours} Stunden`;
- if (diffDays < 7) return `Vor ${diffDays} Tagen`;
-
- return date.toLocaleDateString('de-DE');
- }
-}
-
-export const statsService = new StatsService();
diff --git a/games/mana-games/apps/web/public/favicon.svg b/games/mana-games/apps/web/static/favicon.png
similarity index 100%
rename from games/mana-games/apps/web/public/favicon.svg
rename to games/mana-games/apps/web/static/favicon.png
diff --git a/games/mana-games/apps/web/public/games/asteroid_dash.html b/games/mana-games/apps/web/static/games/asteroid_dash.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/asteroid_dash.html
rename to games/mana-games/apps/web/static/games/asteroid_dash.html
diff --git a/games/mana-games/apps/web/public/games/balloon_pop.html b/games/mana-games/apps/web/static/games/balloon_pop.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/balloon_pop.html
rename to games/mana-games/apps/web/static/games/balloon_pop.html
diff --git a/games/mana-games/apps/web/public/games/bounce_catch_tutorial.html b/games/mana-games/apps/web/static/games/bounce_catch_tutorial.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/bounce_catch_tutorial.html
rename to games/mana-games/apps/web/static/games/bounce_catch_tutorial.html
diff --git a/games/mana-games/apps/web/public/games/card_stack_rush.html b/games/mana-games/apps/web/static/games/card_stack_rush.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/card_stack_rush.html
rename to games/mana-games/apps/web/static/games/card_stack_rush.html
diff --git a/games/mana-games/apps/web/public/games/click_race.html b/games/mana-games/apps/web/static/games/click_race.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/click_race.html
rename to games/mana-games/apps/web/static/games/click_race.html
diff --git a/games/mana-games/apps/web/public/games/color_memory.html b/games/mana-games/apps/web/static/games/color_memory.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/color_memory.html
rename to games/mana-games/apps/web/static/games/color_memory.html
diff --git a/games/mana-games/apps/web/public/games/fish_catcher.html b/games/mana-games/apps/web/static/games/fish_catcher.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/fish_catcher.html
rename to games/mana-games/apps/web/static/games/fish_catcher.html
diff --git a/games/mana-games/apps/web/public/games/flappy_mana.html b/games/mana-games/apps/web/static/games/flappy_mana.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/flappy_mana.html
rename to games/mana-games/apps/web/static/games/flappy_mana.html
diff --git a/games/mana-games/apps/web/public/games/game-stats-example.html b/games/mana-games/apps/web/static/games/game-stats-example.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/game-stats-example.html
rename to games/mana-games/apps/web/static/games/game-stats-example.html
diff --git a/games/mana-games/apps/web/public/games/gravity_painter.html b/games/mana-games/apps/web/static/games/gravity_painter.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/gravity_painter.html
rename to games/mana-games/apps/web/static/games/gravity_painter.html
diff --git a/games/mana-games/apps/web/public/games/mana_defense.html b/games/mana-games/apps/web/static/games/mana_defense.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/mana_defense.html
rename to games/mana-games/apps/web/static/games/mana_defense.html
diff --git a/games/mana-games/apps/web/public/games/mana_factory.html b/games/mana-games/apps/web/static/games/mana_factory.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/mana_factory.html
rename to games/mana-games/apps/web/static/games/mana_factory.html
diff --git a/games/mana-games/apps/web/public/games/mana_runner.html b/games/mana-games/apps/web/static/games/mana_runner.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/mana_runner.html
rename to games/mana-games/apps/web/static/games/mana_runner.html
diff --git a/games/mana-games/apps/web/public/games/memory_card_match.html b/games/mana-games/apps/web/static/games/memory_card_match.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/memory_card_match.html
rename to games/mana-games/apps/web/static/games/memory_card_match.html
diff --git a/games/mana-games/apps/web/public/games/neon_maze_runner.html b/games/mana-games/apps/web/static/games/neon_maze_runner.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/neon_maze_runner.html
rename to games/mana-games/apps/web/static/games/neon_maze_runner.html
diff --git a/games/mana-games/apps/web/public/games/puzzle_blocks.html b/games/mana-games/apps/web/static/games/puzzle_blocks.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/puzzle_blocks.html
rename to games/mana-games/apps/web/static/games/puzzle_blocks.html
diff --git a/games/mana-games/apps/web/public/games/reaction_test.html b/games/mana-games/apps/web/static/games/reaction_test.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/reaction_test.html
rename to games/mana-games/apps/web/static/games/reaction_test.html
diff --git a/games/mana-games/apps/web/public/games/rhythm_defender.html b/games/mana-games/apps/web/static/games/rhythm_defender.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/rhythm_defender.html
rename to games/mana-games/apps/web/static/games/rhythm_defender.html
diff --git a/games/mana-games/apps/web/public/games/snake_game.html b/games/mana-games/apps/web/static/games/snake_game.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/snake_game.html
rename to games/mana-games/apps/web/static/games/snake_game.html
diff --git a/games/mana-games/apps/web/public/games/space_defender_game.html b/games/mana-games/apps/web/static/games/space_defender_game.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/space_defender_game.html
rename to games/mana-games/apps/web/static/games/space_defender_game.html
diff --git a/games/mana-games/apps/web/public/games/turbo_racer.html b/games/mana-games/apps/web/static/games/turbo_racer.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/turbo_racer.html
rename to games/mana-games/apps/web/static/games/turbo_racer.html
diff --git a/games/mana-games/apps/web/public/games/word_scramble.html b/games/mana-games/apps/web/static/games/word_scramble.html
similarity index 100%
rename from games/mana-games/apps/web/public/games/word_scramble.html
rename to games/mana-games/apps/web/static/games/word_scramble.html
diff --git a/games/mana-games/apps/web/public/screenshots/asteroid-dash.jpg b/games/mana-games/apps/web/static/screenshots/asteroid-dash.jpg
similarity index 100%
rename from games/mana-games/apps/web/public/screenshots/asteroid-dash.jpg
rename to games/mana-games/apps/web/static/screenshots/asteroid-dash.jpg
diff --git a/games/mana-games/apps/web/public/screenshots/balloon-pop.jpg b/games/mana-games/apps/web/static/screenshots/balloon-pop.jpg
similarity index 100%
rename from games/mana-games/apps/web/public/screenshots/balloon-pop.jpg
rename to games/mana-games/apps/web/static/screenshots/balloon-pop.jpg
diff --git a/games/mana-games/apps/web/public/screenshots/bounce-catch.jpg b/games/mana-games/apps/web/static/screenshots/bounce-catch.jpg
similarity index 100%
rename from games/mana-games/apps/web/public/screenshots/bounce-catch.jpg
rename to games/mana-games/apps/web/static/screenshots/bounce-catch.jpg
diff --git a/games/mana-games/apps/web/public/screenshots/click-race.jpg b/games/mana-games/apps/web/static/screenshots/click-race.jpg
similarity index 100%
rename from games/mana-games/apps/web/public/screenshots/click-race.jpg
rename to games/mana-games/apps/web/static/screenshots/click-race.jpg
diff --git a/games/mana-games/apps/web/public/screenshots/color-memory.jpg b/games/mana-games/apps/web/static/screenshots/color-memory.jpg
similarity index 100%
rename from games/mana-games/apps/web/public/screenshots/color-memory.jpg
rename to games/mana-games/apps/web/static/screenshots/color-memory.jpg
diff --git a/games/mana-games/apps/web/public/screenshots/fish-catcher.jpg b/games/mana-games/apps/web/static/screenshots/fish-catcher.jpg
similarity index 100%
rename from games/mana-games/apps/web/public/screenshots/fish-catcher.jpg
rename to games/mana-games/apps/web/static/screenshots/fish-catcher.jpg
diff --git a/games/mana-games/apps/web/public/screenshots/gravity-painter.jpg b/games/mana-games/apps/web/static/screenshots/gravity-painter.jpg
similarity index 100%
rename from games/mana-games/apps/web/public/screenshots/gravity-painter.jpg
rename to games/mana-games/apps/web/static/screenshots/gravity-painter.jpg
diff --git a/games/mana-games/apps/web/public/screenshots/neon-maze-runner.jpg b/games/mana-games/apps/web/static/screenshots/neon-maze-runner.jpg
similarity index 100%
rename from games/mana-games/apps/web/public/screenshots/neon-maze-runner.jpg
rename to games/mana-games/apps/web/static/screenshots/neon-maze-runner.jpg
diff --git a/games/mana-games/apps/web/public/screenshots/reaction-test.jpg b/games/mana-games/apps/web/static/screenshots/reaction-test.jpg
similarity index 100%
rename from games/mana-games/apps/web/public/screenshots/reaction-test.jpg
rename to games/mana-games/apps/web/static/screenshots/reaction-test.jpg
diff --git a/games/mana-games/apps/web/public/screenshots/rhythm-defender.jpg b/games/mana-games/apps/web/static/screenshots/rhythm-defender.jpg
similarity index 100%
rename from games/mana-games/apps/web/public/screenshots/rhythm-defender.jpg
rename to games/mana-games/apps/web/static/screenshots/rhythm-defender.jpg
diff --git a/games/mana-games/apps/web/public/screenshots/snake.jpg b/games/mana-games/apps/web/static/screenshots/snake.jpg
similarity index 100%
rename from games/mana-games/apps/web/public/screenshots/snake.jpg
rename to games/mana-games/apps/web/static/screenshots/snake.jpg
diff --git a/games/mana-games/apps/web/public/screenshots/space-defenders.jpg b/games/mana-games/apps/web/static/screenshots/space-defenders.jpg
similarity index 100%
rename from games/mana-games/apps/web/public/screenshots/space-defenders.jpg
rename to games/mana-games/apps/web/static/screenshots/space-defenders.jpg
diff --git a/games/mana-games/apps/web/svelte.config.js b/games/mana-games/apps/web/svelte.config.js
new file mode 100644
index 000000000..f290ef5a6
--- /dev/null
+++ b/games/mana-games/apps/web/svelte.config.js
@@ -0,0 +1,21 @@
+import adapter from '@sveltejs/adapter-node';
+import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
+
+/** @type {import('@sveltejs/kit').Config} */
+const config = {
+ preprocess: vitePreprocess(),
+
+ kit: {
+ adapter: adapter({
+ out: 'build',
+ }),
+ prerender: {
+ handleHttpError: ({ path, message }) => {
+ if (path === '/favicon.png') return;
+ throw new Error(message);
+ },
+ },
+ },
+};
+
+export default config;
diff --git a/games/mana-games/apps/web/tsconfig.json b/games/mana-games/apps/web/tsconfig.json
index a9210e68f..a8f10c8e3 100644
--- a/games/mana-games/apps/web/tsconfig.json
+++ b/games/mana-games/apps/web/tsconfig.json
@@ -1,5 +1,14 @@
{
- "extends": "astro/tsconfigs/strict",
- "include": [".astro/types.d.ts", "**/*"],
- "exclude": ["dist"]
+ "extends": "./.svelte-kit/tsconfig.json",
+ "compilerOptions": {
+ "allowJs": true,
+ "checkJs": true,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "resolveJsonModule": true,
+ "skipLibCheck": true,
+ "sourceMap": true,
+ "strict": true,
+ "moduleResolution": "bundler"
+ }
}
diff --git a/games/mana-games/apps/web/vite.config.ts b/games/mana-games/apps/web/vite.config.ts
new file mode 100644
index 000000000..d4e6c2a84
--- /dev/null
+++ b/games/mana-games/apps/web/vite.config.ts
@@ -0,0 +1,33 @@
+import { sveltekit } from '@sveltejs/kit/vite';
+import { defineConfig } from 'vite';
+import { SvelteKitPWA } from '@vite-pwa/sveltekit';
+import { createPWAConfig } from '@manacore/shared-pwa';
+import { MANACORE_SHARED_PACKAGES, getBuildDefines } from '@manacore/shared-vite-config';
+
+export default defineConfig({
+ plugins: [
+ sveltekit(),
+ SvelteKitPWA(
+ createPWAConfig({
+ name: 'Mana Games - Browser-Spiele',
+ shortName: 'Mana Games',
+ description: 'AI-powered Browser-Games Plattform',
+ themeColor: '#00ff88',
+ preset: 'minimal',
+ })
+ ),
+ ],
+ server: {
+ port: 5210,
+ strictPort: true,
+ },
+ ssr: {
+ noExternal: [...MANACORE_SHARED_PACKAGES],
+ },
+ optimizeDeps: {
+ exclude: [...MANACORE_SHARED_PACKAGES],
+ },
+ define: {
+ ...getBuildDefines(),
+ },
+});