diff --git a/CLAUDE.md b/CLAUDE.md index b2c9b78..d89c2a1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -51,12 +51,21 @@ Drei Wächter prüfen das. `core/clippy.toml` sperrt Pfade wie `std::collections - Alle Texte, die Spieler sehen, stehen in `game/i18n/texts.csv` (Deutsch und Englisch) und werden über `tr()` geholt. - Tests, die Dateien schreiben, nutzen `TestFiles.temporary_dir()` (Ordner unter `user://tests`), nie die echten Dateien des Spielers. - Godot erzeugt beim Import zu jedem Skript eine `.uid`-Datei. Sie gehört ins Archiv. Der Ordner `game/.godot/` gehört nicht hinein. -- Das Netzwerk liegt in `game/scripts/net_link.gd` (ENet, Port 24680) und `game/scripts/session_link.gd`. Nachrichten des Kerns gehen zuverlässig und in Reihenfolge über Kanal 0, Positionen der Figuren unzuverlässig, aber geordnet über Kanal 1; ENet drosselt sie nie. Eine Verbindung, deren Pakete unbeantwortet bleiben, gilt nach höchstens `NetLink.TIMEOUT_MSEC` als verloren. `NetLink.close_peer` schließt eine Verbindung mit `peer_disconnect_later`, damit wartende Nachrichten wie eine Ablehnung noch ankommen. +- Das Netzwerk liegt in `game/scripts/net_link.gd` (ENet, Port 24680) und `game/scripts/session_link.gd`. Nachrichten des Kerns gehen zuverlässig und in Reihenfolge über Kanal 0, Positionen der Figuren unzuverlässig, aber geordnet über Kanal 1; ENet drosselt sie nie. Eine Verbindung, deren Pakete unbeantwortet bleiben, gilt nach etwa `NetLink.TIMEOUT_MSEC` als verloren; ENet prüft die Grenze nur, wenn eine Wiederholung fällig ist. `NetLink.close_peer` schließt eine Verbindung mit `peer_disconnect_later`, damit wartende Nachrichten wie eine Ablehnung noch ankommen. - Nur der Host speichert. Laden mit F9 geht nur ohne geöffnete Welt („Allein spielen“). - Eine Pause beginnt nur ohne Gäste und lässt sich immer beenden. Nimmt der Host einen Gast an, endet sie; eine bloße Verbindung ohne Gruß beendet sie nicht. - Hält der Kern mit einem internen Fehler an, schließt ein Host seine Welt für Gäste, und ein Gast kehrt ins Menü zurück. Eine angehaltene Sitzung hinterlässt keine Aufzeichnung. - Tests mit Netzwerk lauschen nur auf `127.0.0.1` und lassen das System den Port wählen (Port 0), damit sie nie an einem belegten Port scheitern. +## Grafik + +- Alles auf dem Spielfeld zeichnet `Art` (`game/scripts/art/art.gd`), jedes Ding unter einer Kennung wie `terrain/soft_rock`. Andere Skripte zeichnen keine eigenen Formen oder Farben aufs Spielfeld; ausgenommen sind Texte wie die Namen über den Figuren. +- Die Grafik ist Pixelgrafik aus Code (Konzept 7.4): 16 × 16 Pixel pro Kachel, schräg von vorn gesehen. `PixelStyle` (`game/scripts/art/pixel_style.gd`) zeichnet jede Kennung Pixel für Pixel in ein kleines Bild und hebt es auf. Die Stile `WarmStyle`, `PastelStyle` und `GlowStyle` wählen nur Palette, Umrisse und Leuchten; Warm ist der Standard. F2 wechselt im Spiel, „Stilproben ansehen“ im Menü öffnet die Vitrine, und das Spiel merkt sich die Wahl. +- Eine neue Kennung braucht eine Zeichnung in `PixelStyle` und ihre Farben in jeder Palette; sonst zeichnet `ArtStyle` nur einen Platzhalter. `game/tests/test_art.gd` lässt jeden Stil jede Kennung zeichnen. +- Damit die Pixel scharf bleiben, stellt `project.godot` die Texturfilterung auf „Nearest“ und rastet 2D-Transformationen auf ganze Bildschirmpixel ein. Die Kamera vergrößert ganzzahlig (`CAMERA_ZOOM` in `main.gd`), und die Stile setzen ihre Bilder auf ganze Pixel. +- Ein Bild `game/art/.png` ersetzt die Zeichnung seiner Kennung, ohne dass sich Code ändert. So kann ein Artist Grafik austauschen. Ein solches Bild ist ein einzelnes festes Bild; Kachelränder und Bewegung zeichnet bisher nur der Code. +- Die Karte zeichnet in Blöcken von 16 × 16 Kacheln (`MapView`); nach einem Treffer werden nur die Blöcke um die Kachel neu gezeichnet. Jede Kachel kennt ihre Nachbarn (`TileShape`), damit Felsmassen außen rund und innen geschlossen sind und zum offenen Boden hin ihre Vorderkante zeigen. + ## Prüfen Vor jedem Commit müssen alle Befehle fehlerfrei laufen: @@ -76,10 +85,10 @@ Der Test `game/tests/test_two_instances.gd` startet einen zweiten Godot-Prozess Schlägt `core/tests/golden.rs` fehl, haben sich Regeln oder ein Format geändert. Sind Speicherstände, Aufzeichnungen oder Nachrichten betroffen, erhöhst du die Versionskonstante, die die Fehlermeldung nennt (`SNAPSHOT_VERSION`, `RECORDING_VERSION` oder `PROTOCOL_VERSION`). Erst danach passt du den festgeschriebenen Wert bewusst an. -Für Änderungen am Aussehen gibt es ein Werkzeug, das kurz ein Fenster öffnet und ein Bildschirmfoto speichert: +Für Änderungen am Aussehen gibt es ein Werkzeug, das kurz ein Fenster öffnet und ein Bildschirmfoto speichert. `--style=NAME` wählt einen Stil, `--showcase` zeigt die Vitrine statt des Spiels: ```bash -godot --path game -s res://tools/screenshot.gd -- +godot --path game -s res://tools/screenshot.gd -- [--style=NAME] [--showcase] ``` ## Spielen @@ -97,6 +106,7 @@ Argumente hinter `play.bat` gehen an das Spiel: | `--solo`, `--host` | Startet ohne Menü allein beziehungsweise mit offener Welt | | `--port=PORT` | Port einer offenen Welt | | `--join=ADRESSE` | Tritt ohne Menü einem Host bei; die Adresse darf auf `:PORT` enden | +| `--style=NAME` | Zeichnet im Stil `warm`, `pastel` oder `glow` statt im zuletzt gewählten | `play-zweites-fenster.bat` startet ein zweites Fenster mit dem Profil `zweites-fenster`. Die Datei reicht weitere Argumente ebenfalls an das Spiel weiter, etwa `--name=Zweiter`. diff --git a/docs/playtests/m1d.md b/docs/playtests/m1d.md new file mode 100644 index 0000000..6ef49cb --- /dev/null +++ b/docs/playtests/m1d.md @@ -0,0 +1,39 @@ +# Probelauf M1d: Stilproben + +M1d zeichnet das Spielfeld als Pixelgrafik aus Code, im Stil klassischer Farmspiele, aber eigenständig. Es gibt drei Abwandlungen: Warm, Pastell und Glimmen. Nach der ersten Probe war Warm dein Favorit; jetzt siehst du die Stile im Spiel und in Bewegung. Das beantwortet die Prüffrage von Meilenstein 1: „Welche der drei Stilproben soll es sein?“ Die Vitrine zeigt dazu Dinge aus späteren Meilensteinen, die es zum Spielen noch nicht gibt. + +## So siehst du die Proben + +1. Doppelklick auf `play.bat`. +2. Im Menü auf „Stilproben ansehen“. Die Vitrine zeigt + - toten und lebendigen Boden, + - Lebensmoos, + - eine Ranke, die Steine trägt, + - eine wachsende Faserpflanze, + - ein hüpfendes Weidetier, + - eine erwachende Ruine, + - zwei Spielfiguren. + + Mit 1, 2 und 3 oder den Knöpfen unten wechselst du den Stil, mit Esc oder „Zurück“ geht es ins Menü. +3. Im Spiel wechselt F2 den Stil. Lauf herum, schlag Stein und sieh dir Fels, Figur, Zielmarke und Splitter an. Das Spiel merkt sich den zuletzt gewählten Stil. +4. Zu zweit wie in M1c: Die Namen über den Figuren sind jetzt scharf, und dein eigener Schlag zeigt seine Splitter sofort, auch als Gast. + +So sehen die drei Proben aus: + +| Warm | Pastell | Glimmen | +|---|---|---| +| ![Warm, Vitrine](m1d/warm-vitrine.png) | ![Pastell, Vitrine](m1d/pastell-vitrine.png) | ![Glimmen, Vitrine](m1d/glimmen-vitrine.png) | +| ![Warm, Spiel](m1d/warm-karte.png) | ![Pastell, Spiel](m1d/pastell-karte.png) | ![Glimmen, Spiel](m1d/glimmen-karte.png) | + +## Fragen + +1. Bleibt es bei Warm, oder gefällt dir im Spiel ein anderer Stil besser? +2. Was gefällt dir an deinem Favoriten am besten, und was stört dich daran? +3. Gibt es an den anderen beiden etwas, das du übernehmen möchtest, etwa das Leuchten des Lebendigen aus Glimmen? +4. Erkennst du auf einen Blick, was Boden, weicher Fels und harter Fels ist? Und was lebendiger Boden ist? +5. Wirkt das Lebendige lebendig: das Moos, die Ranke, die wachsende Pflanze, das Tier, die erwachende Ruine? Oder wirkt es nüchtern? +6. Ist die Bewegung angenehm: Laufen, Wiegen, Wachsen und Hüpfen? Oder ist es zu viel oder zu wenig? +7. Findest du deine Figur sofort, auch neben anderen? Sind Figuren und Dinge groß genug? +8. Wirkt ein Schlag als Gast jetzt sofort, und sind die Namen über den Figuren scharf? + +Antworte formlos im Chat oder als Kommentar in Gitea. diff --git a/docs/playtests/m1d/glimmen-karte.png b/docs/playtests/m1d/glimmen-karte.png new file mode 100644 index 0000000..a54c5fd Binary files /dev/null and b/docs/playtests/m1d/glimmen-karte.png differ diff --git a/docs/playtests/m1d/glimmen-vitrine.png b/docs/playtests/m1d/glimmen-vitrine.png new file mode 100644 index 0000000..3049f21 Binary files /dev/null and b/docs/playtests/m1d/glimmen-vitrine.png differ diff --git a/docs/playtests/m1d/pastell-karte.png b/docs/playtests/m1d/pastell-karte.png new file mode 100644 index 0000000..ca72b1a Binary files /dev/null and b/docs/playtests/m1d/pastell-karte.png differ diff --git a/docs/playtests/m1d/pastell-vitrine.png b/docs/playtests/m1d/pastell-vitrine.png new file mode 100644 index 0000000..037299b Binary files /dev/null and b/docs/playtests/m1d/pastell-vitrine.png differ diff --git a/docs/playtests/m1d/warm-karte.png b/docs/playtests/m1d/warm-karte.png new file mode 100644 index 0000000..3c1355f Binary files /dev/null and b/docs/playtests/m1d/warm-karte.png differ diff --git a/docs/playtests/m1d/warm-vitrine.png b/docs/playtests/m1d/warm-vitrine.png new file mode 100644 index 0000000..5bd35c0 Binary files /dev/null and b/docs/playtests/m1d/warm-vitrine.png differ