Spiele entwickeln
Erstelle ein spielbares, korrektes Browser-Spiel – keinen statischen Screenshot. Ein Spiel ist einfach eine React-Route mit einem <canvas> (oder <Canvas> für R3F) plus DOM-Overlay-UI. Gestalte das Overlay (Startbildschirm, HUD, Menüs) mit dem design-ui-Skill; dieses Skill besitzt die Spielschleife und die Welt.
Steuerung / invertiertes A/D: öffne .grok/skills/controls/SKILL.md bevor du WASD, Lenk- oder Flug-Input schreibst. Fahrzeug-/Flug-Demos liefern oft A/D vertauscht, wenn du nur diese Datei oder ein einzelnes Genre-Playbook liest.
Hinweis zum Umfang – Einzelspieler, Bots oder kleine P2P-Koop:
- Liefere standardmäßig Einzelspieler oder Einzelspieler + KI/Bots aus.
- Koop / lockere Echtzeit für 2–8 Spieler (gemeinsame Cursor, Partyspiele, lockere Action unter Freunden) wird unterstützt – nutze das
multiplayer-p2p-Skill (WebRTC-Mesh, signalisiert unter/api/rtc). Lies zuerst sein Vertrauensmodell. - P2P ist derzeit die einzige unterstützte Mehrspieler-Option. Baue keine halbfertigen Sockets, die sich nicht verbinden können.
Referenzen (bei Bedarf laden):
controls-Skill (../controls/) – erforderlich für Bewegung/Lenkung/Flug: spielersichtbares A/D, Anti-Pattern für invertierte Lenkung, Flug-Querruder, verbindlicher Selbsttest +window.__controlsTest. Nicht optional für Fahrzeuge/Flugzeuge.references/threejs-foundational.md– die tiefgehende 3D/Loop/Perf-Referenz. Für 3D lesen.references/3d-libs.md– Nutzung von three.js + @react-three/fiber + drei + rapier.threejs-Skill (../threejs/) – offizielles vollständiges Three.js + TSL-API-Dump (llms-full.txt). Für fortgeschrittene Materialien/Shader/WebGPU/Loader laden; nicht für einfache 2D-Canvas-Spiele.references/babylon.md– Babylon.js, die Alternative mit vielen integrierten Funktionen für 3D-Engines.references/phaser.md– Phaser 3, die Standard-Engine für 2D-Spiele.references/ecs-architecture.md– Entity-Component-System-Struktur für größere Spiele.references/genres/*.md– Genre-spezifische Playbooks (fps, platformer-2d, racing-kart, puzzle-match3-tetris, voxel-minecraft, endless-runner, topdown-twin-stick, tower-defense, board-card-chess). Genre-Dateien ersetzen nicht dascontrols-Skill.references/game-feel-juice.md,input.md,audio.md,collision-physics.md,save-persistence.md,procedural-generation.md,ai-pathfinding.md.game-asset-core(+game-animation-frames/game-tilesets/game-character-consistency/game-ui-icons) – engine-bereite 2D-Kunst-Standards und Überprüfung beim Generieren von Sprites, Sheets, Tiles oder UI (siehe §6).
Wähle die spezifische Genre-/Themenreferenz für den Bau aus; diese Datei ist der universelle Kern für Schleife/Welt. Eingabezeichen → controls.** 2D-Spielgrafik → game-asset-core.
1. Spielschleife & Timing (das #1-Korrektheitsproblem)
- Treibe die Schleife mit der RAF-Schleife der Engine an (
renderer.setAnimationLoop, R3FuseFrameoderrequestAnimationFramefür 2D-Canvas). NiemalssetInterval/setTimeout/Date.now()für Spiel-Timing. - Skaliere ALLE Bewegungen/Animationen mit der Delta-Zeit (Sekunden), damit die Geschwindigkeit bildwiederholratenunabhängig ist (60 Hz vs. 144 Hz). Berechne das Delta einmal pro Frame und verwende es wieder.
- three.js: verwende
THREE.Timer(nichtClock–Clock.getDelta()liefert bei einem zweiten Aufruf im selben Frame ~0, ein klassischer Freeze-Bug).
- three.js: verwende
- Begrenze das Delta (
min(delta, 0.1)), damit ein im Hintergrund geöffneter Tab nichts herumteleportiert. - Fester Zeitschritt für Physik/Gameplay: akkumuliere Delta und simuliere in festen Schritten (z.B. 1/60), während du mit der Anzeigefrequenz renderst – verhindert Tunneling und Nichtdeterminismus.
2. Steuerung (an das controls-Skill delegieren)
Öffne .grok/skills/controls/SKILL.md, bevor du irgendeinen WASD-/Lenk-/Flug-Code implementierst. Dieses Skill ist die Quelle der Wahrheit für:
- Spielersichtbares A = links / D = rechts (Verfolgungskamera, während Vorwärtsbewegung)
- Warum
KeyA → steer−+yaw += steer * +rateinvertiert (häufigster Bug) - Fahrzeug vs. FPS (Strafe ≠ Lenkung), Querruder bei Starrflüglern, Heli-/Drohnen-Hinweise
- Verbindlicher Selbsttest +
window.__controlsTest-Sonde
Behandle genres/racing-kart.md nicht als den einzigen Ort, an dem Lenkungszeichen leben – Flugzeuge, Jetskis und Mechas öffnen es nie.
Kurze Erinnerung (volle Details in controls):
// Fahrzeug-Gierkörper (Verfolgungskamera): A muss das Gieren mit dieser Basis erhöhen
forward = (-sin(yaw), 0, -cos(yaw))
// KeyA → steer = +1; yaw += steer * turnRate * speedFactor * dt
// FALSCH (liefert invertiert): KeyA → steer = -1; yaw += steer * turnRate * dt
- Zeigersperre: Mausblick nur – implementiere WASD selbst; Klick-zum-Spielen-Overlay; beim Sperren ausblenden.
- Verfolge Tasten mit gehaltenem Zustand + dt; vereinheitliche Geräte über
references/input.md. - Abschluss: führe die Checkliste des
controls-Skills aus. Nur ein Screenshot ist für Fahrzeuge/Flüge unzureichend.
3. 3D-Orientierung & Weltobjekte (die „seitwärts/rückwärts“-Bugs)
- three.js ist rechtshändig, +Y oben: +X rechts, +Y oben, +Z auf den Betrachter zu. Netze zeigen in +Z; Kameras schauen in −Z (der klassische „Kamera rückwärts“-Fehler).
- Grundelemente wie
Cone/Cylinderzeigen standardmäßig in +Y → rotiere, um eine Spitze an der Vorderseite auszurichten (geo.rotateX(Math.PI/2)). - Ausrichten eines Netzes, um in
forwardzu zeigen (Netze zeigen in +Z): Der einfachste korrekte Weg istmesh.lookAt(mesh.position.clone().add(forward)). Um die Basis von Hand zu erstellen, setze die +Z-Spalte aufforwardund wähle die x-Achse, die eine korrekte rechtshändige Rotation ergibt (det = +1):xAxis = normalize(cross(up, forward)), dannmakeBasis(xAxis, up, forward). Beachte, dass diescross(up, forward)ist – nicht das Bewegungs-right = cross(forward, up)aus §2. Das Zielen auf +Z (anstatt auf das −Z einer Kamera) kehrt das Vorzeichen der x-Achse um, sodassxAxis × up = forwardgilt; die Achse bleibt rechtshändig (keine Spiegelung). Verwende nichtmakeBasis(xAxis, up, -forward)für ein Netz – das zielt auf −forward (die Kamera-Konvention) ab, sodass das Netz rückwärts zeigt. - Ausrichten einer Kamera, um entlang
forwardzu schauen (Kameras schauen in −Z): setze die +Z-Spalte auf-forward–xAxis = normalize(cross(forward, up)), dannmakeBasis(xAxis, up, -forward)(oder einfachcamera.lookAt(target)). - Behalte ein konsistentes
upin der Welt bei, damit Objekte aufrecht bleiben; rotiere nur flache Grundelemente, um sie aufrecht zu stellen. - Überprüfe die Orientierung von glTF-Importen; debugge mit
AxesHelper/ArrowHelper. Selbsttest für Aufrechtigkeit: Charaktere stehen auf der Bodenebene, liegen nicht oder sind eingesunken.
4. Kamera muss mit Bewegung übereinstimmen
- Behalte ein dediziertes
moveForward/moveRightfür Bewegungen bei, das einmal berechnet und niemals durch Kamera-Code verändert wird (Alias eines gemeinsam genutzten temporären Vektors führt dazu, dass Kamera und Bewegung nicht übereinstimmen – ein reproduzierbarer Bug). - Dritte-Person-Verfolgung:
desired = playerPos + up*height + moveForward*(-followDist); interpoliere die Kamera dorthin (verwende exp-basierte Glättung, Delta-skaliert),lookAt(player). - Debug-Reihenfolge „Ebene isolieren“: (1) Tasten werden registriert → (2) Bewegungszeichen sind korrekt → (3) Kamera stimmt überein. In dieser Reihenfolge beheben.
5. Performance
- Minimiere Draw Calls (
renderer.info.render.calls, Ziel <100): teile Materialien,InstancedMesh/BatchedMeshfür wiederholte Objekte, Atlanten. - Gib GPU-Ressourcen selbst frei (
geometry/material/texture.dispose()) bei Levelwechsel – three.js räumt sie nicht auf. Pools für Kugeln/Gegner/Partikel. - Keine Pro-Frame-Allokationen (temporäre Vektoren wiederverwenden). Texturen komprimieren; LOD für Entfernung.
6. Assets (die generierte-Foto-Falle vermeiden)
- Interaktive 3D-Elemente (Waffen-Viewmodels, Charaktere, Requisiten, Projektile) → baue aus 3D-Geometrie / glTF, nicht aus einem generierten Bild. Ein flaches fotorealistisches JPG einer Waffe in der Hand, das als FPS-Viewmodel verwendet wird, sieht falsch aus, kann nicht animiert werden und (JPG hat keinen Alpha-Kanal) rendert als schwarze Box. Verparente ein echtes 3D-Viewmodel an die Kamera als Overlay-Render-Layer.
- Reserve die Bildgenerierung für flache 2D-Assets (Texturen, Himmel/Menü-Hintergründe, 2D-Sprites, UI-Kunst). Verwende niemals ein generiertes Foto als 3D-Netz, Viewmodel oder Charakterersatz – baue diese in 3D-Geometrie / glTF. Setze
crossOrigin="anonymous"auf Bilder, die auf Canvas/Texturen gezeichnet werden. Siehe dasimagine-grok-build-Skill (nur 2D – Bildwerkzeuge können kein echtes 3D erzeugen). - Engine-bereite Spielgrafik-Doktrin → öffne
game-asset-core(../game-asset-core/) für Standards + Blindüberprüfung + Wiederholungsdisziplin, dann die passenden Spezialisten:game-animation-frames(Schleifen-/Bewegungsgesetze),game-tilesets,game-character-consistency,game-ui-icons. Dies sind QC/Doktrin, nicht die Export-Pipeline. Liefere keine Strichmännchen-Platzhalter aus, wenn echte Grafiken erwartet werden. - 2D-Spiel-Sprites / Animations-Sheets → führe
generate2dspriteaus (.grok/skills/generate2dsprite/SKILL.md): solide#FF00FFmagentaimagine_text_to_image-Sheets + Chroma-Nachbearbeitungsskripte (Magenta ist für den Prozessor erforderlich). Verdrahte transparente PNGs/GIFs in Canvas/Phaser. Wende trotzdemgame-asset-corean (+ Animations-/Charakter-Spezialisten, wenn relevant). - 2D-Karten / Level / Prop-Pakete → öffne
generate2dmap(.grok/skills/generate2dmap/SKILL.md). Bevorzuge nur das Fundament + separate Props/Kollision für spielbare Karten. Browser-Standard:raw_canvas/ Phaser. Tilebarer Boden/Wände → auchgame-tilesetsfür 2×2-Nahtprüfungen. - Optionale dichtere Fortbewegung → führe
video2dspriteaus (Grokimagine_image_to_video+ Sandbox-Skripte; Magenta-Basis). Bevorzugegenerate2dspritefür klare Produktions-Helden. Verwendegame-animation-framesfür Schleifen-/Flip-Test-Gesetze; bevorzugevideo2dspritegegenüber ad-hoc ffmpeg-only-Ernte in dieser Sandbox.
7. Audio, Speichern, Spielgefühl
- Audio: entsperre
AudioContextbei der ersten Benutzeraktion (Tippen zum Starten), sonst ist iOS stumm; setze beivisibilitychangefort. (references/audio.md) - Speichern:
localStorage/IndexedDB mit einemversion-Feld + Migrationen. - Spielgefühl: Bildschirmwackeln, Treffer-Stopp, abgefederte Tweens, Partikel – günstig, enorme Steigerung der wahrgenommenen Qualität. Halte Präsentation getrennt von der Simulation.
8. Mobilgeräte
- Unterscheide Canvas-Puffergröße von CSS-Größe; respektiere
devicePixelRatio. touch-action: none, Letterbox-Fit auf eine Basisauflösung, behandle Orientierung.- Touch-Steuerung (virtueller Joystick + Aktionsknöpfe), ≥44px Ziele.
Stack / Engine-Wahl
- 3D → three.js, idealerweise über @react-three/fiber + drei (passt zur React-App; drei bietet Zeigersperre/Steuerung/Loader) + @react-three/rapier für Physik/Charakter-Controller. Siehe
references/3d-libs.md. - 2D → natives Canvas 2D reicht für Snake/Tetris/Flappy/Plattformer; greife nur zu Phaser, wenn das Genre es benötigt.
- Diese Spiel-Abhängigkeiten sind nicht vorinstalliert –
npm installsie (und stelle sicher, dass sie inpackage.jsonlanden, damit der Vercel-Build sie hat).
Abschlusskriterien (vor „fertig“)
- Wird ohne Konsolenfehler geladen; sichtbares Gameplay (kein leeres Canvas).
- Selbsttest des
controls-Skills bestanden (A = links / D = rechts von der Verfolgungskamera aus bei Vorwärtsbewegung; ein Zeichen umdrehen, wenn invertiert). Nicht nur Screenshot. - Selbsttests für 3D-Aufrechtigkeit und Kameraübereinstimmung bestanden (§3, §4).
- Läuft auf mobilen Viewports mit Touch-Steuerung.
- Production Build (
npm run build) rendert die gebaute Ausgabe, nicht nur Dev. - Share / X-Karte: öffne das
og-Skill – benutzerdefiniertespublic/og.jpgund"type": "x:game"insrc/lib/og/site.json. X verwendetog:type="x:game", um die Unfurl als Spielkarte darzustellen; verwendetwitter:cardoder erfindex:typenicht dafür.browser-smoke/brand-checkwarnen, wenn Canvas-Apps dassite.json-Feld auslassen.