From 0f41d375e7847cc7652041db8192356d6e2b7ea6 Mon Sep 17 00:00:00 2001 From: team3 Date: Sat, 29 Aug 2026 11:42:30 +0200 Subject: [PATCH] first commit --- README.md | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..b038957 --- /dev/null +++ b/README.md @@ -0,0 +1,102 @@ +# Elements Autochess + +Auto-Battler nach TFT-Vorbild in Godot 4.7, in 3D. +Primitive Assets: Hexfelder sind Zylinder mit 6 Segmenten, Einheiten sind +Würfel (Tank), Kegel (DPS) und Kugeln (Heiler). Alles wird im Code erzeugt. + +## Starten + + godot --path . scenes/Main.tscn + +## Steuern + +- Shop-Karte anklicken = kaufen. Neutrale Avatare fragen dabei nach der + Spezialisierung, Element-Avatare kommen fertig. +- Die Bank sind die 9 Hexplätze vor dem eigenen Spielfeld, ebenfalls in 3D. +- Avatare per Drag & Drop verschieben: Bank -> Feld, Feld -> Bank, Feld -> Feld + und Bank -> Bank. Ist das Ziel belegt, tauschen die beiden die Plätze. +- Klick ohne Ziehen = auswählen. Info rechts, dort auch `Aufwerten`. +- Rechtsklick auf dem Feld = zurück auf die Bank, auf der Bank = verkaufen. +- Klicks treffen über einen Strahl von der Kamera auf die Feldebene. +- `D` neu würfeln, `Leertaste` Kampf starten / überspringen, `Esc` Auswahl lösen + +## Regeln + +| Anforderung | Umsetzung | +| --- | --- | +| 1-Star bis 3-Star, zweimal aufwertbar | `Avatar.star`, `Data.MAX_STAR` | +| Tank / DPS / Heiler | `Data.Role`, eigene Werte und Fähigkeiten | +| Spezialisierung beim Kauf | Popup beim Kauf eines neutralen Avatars | +| Weitere Spezialisierung beim Aufwerten | Popup beim Upgrade, bis zu 3 Elemente | +| Shop startet elementlos | `PlayerState.unlocked` beginnt leer | +| Aufgestellte Elemente kommen in den Shop | `PlayerState.unlock()` beim Aufstellen | +| Mein Shop zeigt nur meine Elemente und Neutral | `PlayerState.shop_elements()` je Spieler | +| Neutrale Chance -25% je aufgestelltem Element | `Data.neutral_chance()`, multiplikativ | +| Bank ist 3D am Spielfeld | `BoardView3D.bench_pos()`, 9 Hexplätze | +| Avatare zwischen Bank und Board verschieben | `PlayerState.move_slot()` | +| Drag & Drop | `Main._begin_drag()` / `_end_drag()`, Avatar klebt flach am Zeiger | +| Aufwertung zeigt, was sich ändert | Popup nennt die neue Fähigkeit, je Auswahl eine Zeile | +| Zinsen je 10 Gold bis 50 Gold | `Data.interest()`, max +5 | +| Neutral 1 Gold, Element 2 Gold | `Data.PRICE_NONE` / `PRICE_ELEMENT` | +| 1-Star Feuer + 2 Feuer = 2-Star | `Avatar.upgrade_cost()` | +| 2-Star Feuer/Wind + 3 Feuer + 3 Wind = 3-Star | `Avatar.upgrade_cost()` | +| Stats und Fähigkeiten pro Stufe | `Data.STAR_MULT`, `Avatar.ability_text()`, `Combat._cast()` | +| Elemente kombinierbar wie Traits | `Data.ELEMENT_TRAITS`, `Data.COMBO_TRAITS` | +| 5 Gold pro Runde, 1 für Sieg, mehr bei Serie | `PlayerState.round_income()` | +| 100 Leben | `Data.START_HP` | +| Begrenzte Elementmenge für alle Spieler | `Pool.element_left`, 180 pro Element | +| 7 Bots | `Game.BOT_NAMES`, `BotAI` | +| Keine Items | nicht vorhanden | + +Nicht in den Anforderungen, aber nötig: die Kaderplätze wachsen mit der Runde +(`Data.team_slots()`, 3 bis 9). Der neutrale Avatar selbst ist unbegrenzt. Knapp ist +das Element, das man ihm beim Kauf gibt: das zieht einen Platz aus dem geteilten Vorrat. + +Die 180 pro Element sind gemessen, nicht geraten: bei 30 war jedes Element nach +gut der Hälfte der Partie leer, bei 160 lief in 1 von 12 Partien schon um Runde 15 +eines leer. Bei 180 hält der Vorrat eine ganze Partie, der Tiefstand liegt aber +noch bei rund einem Achtel. + +Die Neutral-Chance ist multiplikativ (0,75 hoch Anzahl Elemente) statt in +Prozentpunkten. So verschwindet Neutral nie ganz: ohne eigene Elemente 100%, +mit einem 75%, mit sechs noch 18%. + +## Elemente und Traits + +Feuer, Wasser, Wind, Blitz, Erde, Eis. Stufen bei 2 / 4 / 6 Einheiten. +Kombinationen (beide Elemente ab 2 Einheiten): Feuersturm, Frost, Magnetsturm, +Magma, Sturmfront, Dampf. + +## Aufbau + + scripts/core/ Data, Avatar, Pool, ShopEntry, PlayerState, Hex, Combat, BotAI, Game + scripts/ui/ Main (Szene + Bedienung), BoardView3D (Arena), HudOverlay, UiKit + scenes/Main.tscn + tests/ sim_test.gd (kopflos), Probe2, Probe3, CamCal + +`Combat` ist reine Logik und wird in Schritten gerechnet. Bot-Kämpfe laufen sofort +durch (`run_to_end`), der eigene Kampf wird pro Frame gesteppt. + +Die Darstellung hängt nicht an der Logik: `BoardView3D` liest nur `Game`. +Lebens- und Manabalken zeichnet `HudOverlay` in 2D über die projizierten +Weltpositionen, damit sie in jeder Entfernung lesbar bleiben. + +`Main._fit_camera()` rechnet Abstand und Blickpunkt so aus, dass das Spielfeld +genau in die freie Bildmitte passt. Links stehen Elemente, Einheit und Rundenlog, +rechts die Spielerliste, unten der Shop. Das läuft bei jeder Fenstergröße neu. + +## Tests + +Kernlogik ohne Fenster: + + godot --headless --path . --script tests/sim_test.gd + +UI-Durchläufe mit Screenshots (Ordner als Argument): + + godot --path . tests/probe2.tscn -- /pfad/zu/screenshots # 3-Star, Spielende, Neustart + godot --path . tests/probe3.tscn -- /pfad/zu/screenshots # echte Maus- und Tastatureingaben + godot --path . tests/camcal.tscn -- /pfad/zu/screenshots # Kamerabild und Trefferprüfung + +`probe3` schickt Klicks und Drags über `Viewport.push_input` wie ein Nutzer und +prüft danach den Zustand. `camcal` prüft, dass alle 28 Felder und 9 Bankplätze +unter ihrer eigenen Bildschirmposition auch getroffen werden.