phase-b #1

Open
benni wants to merge 0 commits from phase-b into main
Owner
No description provided.
Die Karte ist der erste Bildschirm, alles andere liegt darunter unterhalb
des Falzes. Scrollte man dorthin, wanderte die Icon-Reihe mit dem ganzen
Vollbild-Block nach oben aus dem Sichtbereich -- eine Karte ohne sichtbare
Steuerung.

Jetzt position: sticky; top: 0 im Vollbild-Layout, mit deckendem
Hintergrund (var(--bg)), damit durchrollender Text nicht zwischen den
Knöpfen durchscheint, und zIndex 1 -- über dem Seiteninhalt, noch unter
den fixed Final-Battle-Overlays (deren zIndex 3/4).

Der Badge-Innenabstand (top/right je 6px fuer die ueberstehenden Badges)
wanderte dafür vom umgebenden Block in die Zeile selbst: Am
Abschnittsrand haette er nur im ungerollten Zustand geschützt, in der
am Viewport-Rand klebenden Zeile waeren die Badges wieder abgeschnitten.
Der Test dazu prüft jetzt die Zeile statt den Block.

Co-Authored-By: Claude Fable 5 <[email protected]>
Der Vollbild-Modus fuer Nicht-Admins skaliert die Karte auf die
Bildschirmhohe, blieb in der Breite aber im zentrierten Layout haengen:
main kappt bei 960px, und darunter kappte schon #root bei 1126px samt
Spaltenrandlinien. Auf einem breiten Monitor wirkte die "Vollbild"-Karte
wie ein schmales Band in der Mitte.

main.map-first und #root:has(.map-first) lassen jetzt beide Begrenzungen
fallen (inkl. Randlinien), sobald das Vollbild-Layout aktiv ist -- der
gemessene Container liefert der Karte danach die echte Fensterbreite.
Admins behalten das gestapelte, zentrierte Layout unveraendert.

Co-Authored-By: Claude Fable 5 <[email protected]>
Der Job trug nur die Field-Id -- ein uebrig gebliebener Job von einem
frueheren Bau auf derselben Zeile konnte einen spaeter akzeptierten Bau
vorzeitig abschliessen. Heute unerreichbar (Karten-Regeneration ersetzt
die Zeilen samt Ids komplett, und ein Tempel steht fuer immer), aber
jeder kuenftige Pfad, der eine Baustelle wiederoeffnet (etwa die
geplante Tempel-Zerstoerung), haette das Rennen wiederbelebt.

Das erwartete resolveAt reist jetzt im Job-Payload mit;
resolveBuildTemple matcht im updateMany auf genau diesen Wert statt auf
"nicht null". Absichtlich exakte Gleichheit und kein lte: now --
pg-boss feuert nach DB-Uhr, resolveAt stammt aus der App-Uhr, ein
minimaler Versatz wuerde echte Bauten sonst fuer immer verschlucken.
Payloads ohne resolveAt (vor diesem Commit eingereiht) verhalten sich
wie bisher.

Co-Authored-By: Claude Fable 5 <[email protected]>
Beide Ordner waren von Anfang an als uebergangsweise gekennzeichnet und
nannten ihre eigene Abloese-Bedingung: Phase 8a hat jetzt einen echten
eigenen Kartengenerator, dessen Platzierung (randomMaximalSpacing) aus
dem Experiment hervorgegangen ist. Das Benchmark-Ergebnis (der
Poisson-Disk-Sampler braucht fuer dieselbe Spielerzahl kleinere Karten
als das alte Verwerfungsverfahren) lebt im git-Verlauf weiter.

Verweise angepasst: ROADMAP.md beschreibt die Platzierung jetzt direkt,
CLAUDE.md listet die beiden Ordner nicht mehr, OLD-PERL.md zeigt auf die
kanonische Quelle im alten Repo statt auf die lokale Kopie.

Co-Authored-By: Claude Fable 5 <[email protected]>
Die Freigabe von main/#root max-width allein reichte nicht: #root ist
ein Spalten-Flexcontainer, und ein Flex-Item mit margin: 0 auto nimmt
sich den freien Queraum fuer die Zentrierung, statt zu strecken -- main
schrumpfte auf seine Inhaltsbreite (1167px auf einem 1440er-Fenster),
die Karte endete trotzdem wieder als schmales Band.

map-first setzt die Margins deshalb auf 0 und gibt die Groesse an den
Stretch zurueck. Nachgemessen: Karten-Container jetzt 1392px (= Fenster
minus main-Padding), Phone-Seite unveraendert voll breit.

Co-Authored-By: Claude Fable 5 <[email protected]>
mapSizeForEarthlings: n = ceil(5 * sqrt(erdlinge)), mindestens 5. Der
Faktor reproduziert die bisherige Dev-Dichte (4 Erdlinge auf Groesse 10
= 50 Felder pro Erdling); Wurzelwachstum haelt den Spielraum pro Spieler
konstant. Faktor und Minimum liegen in GAME_CONFIG, die Testvektoren
sind bewusste Anker (Umstellen des Faktors heisst, sie absichtlich zu
aendern).

Die alte 2.2-Schaetzung nach dem alten Platzierungs-Benchmark (nur
Pole+Berge, 1 Heimatstadt/Erdling) hielt der vollen Generierung nicht
stand: Auf Groesse 5 fanden 10 Heimatstaedte keinen Platz. Neu
gemessen mit Seed-Sweeps ueber den echten Generator, daher Faktor 5.

Co-Authored-By: Claude Fable 5 <[email protected]>
Die Platzierung darf legitimen Mangel produzieren (homeland()s
geometrische Regeln um Berge), aber die Zuteilung lief in
Reihenfolge in Bloecken von je zwei: Bei nur 6 von 8 platzierten
Heimatstaedten (real messbar, z.B. Seed 52 auf dem Dev-Brett) gingen
die letzten Rollen komplett leer, waehrend fruehere zwei bekamen.

Jetzt Round-Robin ueber die Rollen -- Mangel verteilt sich, niemand
geht leer, solange ueberhaupt eine Heimatstadt pro Rolle existiert.
Bei Ueberschuss weiterfrist die Kappe von zwei pro Rolle (der
Bestandstest dazu bleibt gruen).

Co-Authored-By: Claude Fable 5 <[email protected]>
Zwei Seiten derselben Kehrtwende: "Generate map" leitet die
Brettgroesse jetzt aus der tatsaechlichen Erdlings-Rollenanzahl ab
(mapSizeForEarthlings) und schreibt sie auf die Game-Zeile -- statt
DEV_MAP_EARTHLINGS fuer die Platzierung und die angebootete Groesse
fuer das Brett zu verwenden. Und die Zug-Pruefung (submit, moveAvatar)
urteilt ueber Anlieger und Wraparound gegen die gespeicherte Groesse,
nicht gegen einen vom Client geschickten Wert -- der alte gameSize-Input
war dabei mehr als nur haesslich: Mit falscher Groesse validiert der
Wraparound eines fremden Bretts den Zug.

Co-Authored-By: Claude Fable 5 <[email protected]>
getGameStatus liefert jetzt auch Game.size; die Karte wartet darauf
("Connecting..." bis zur ersten Poll) statt einen festen Wert zu
raten -- Groesse 10 war seit jeher im Client kopiert und haette nach
einer Groessenaenderung durch Karten-Generierung still falsch
weitergerendert. submit/moveAvatar schicken keinen gameSize mehr, der
Server urteilt ohnehin selbst. isNearWater nutzt denselben Torus.

Co-Authored-By: Claude Fable 5 <[email protected]>
GAME-DESIGN bekommt eine eigene Sektion "Map Generation: Board Size"
(Formel, Faktor-Herkunft, Round-Robin bei Knappheit, Server besitzt
die Geometrie); ROADMAP Phase 8a gilt als implementiert -- offen sind
nur der echte Spielstart-Trigger (Phase 10) und das Tuning der
Heimatstadt-Knappheit.

Co-Authored-By: Claude Fable 5 <[email protected]>
Bisher war Sicht rein echtzeit -- einmal ausser Reichweite war alles
wieder schwarz, und Aufklaeren hatte keinen bleibenden Wert. Neue
Tabelle ExploredField haelt pro Rolle und Koordinate einen Snapshot
des Feldes vom letzten Sichtkontakt: Gelaende, Heimatstadt, Tempel,
Besitzer. Bewusst nie Einheiten/Auftraege/Gefechte -- ein Gedachtnis
darf keine Vergangenheit als Gegenwart verkaufen.

Schreibseite (recordExploredFields, aus getGameFields' Viewer-Pfad
je Poll gerufen): neue Koordinaten als Batch-Insert mit
skipDuplicates, und ein Raw-Update frischt nur die Snapshots nach,
deren Feld jetzt sichtbar ist und von der Live-Zeile abweicht --
Aenderungen ausserhalb der eigenen Sicht lecken nie ins Gedaechtnis.
seenAt bleibt "zuerst erkundet".

Leseseite: getGameFields liefert erkundete, aktuell unsichtbare
Felder als remembered-Snapshot (nur Snapshot-Spalten, keine
Live-Daten) mit zurueck. Wieder in Sicht heisst wieder live. Ein
Nebeneffekt mit Design-Charakter: endet eine geteilte
Verbundeten-Sicht, bleiben die mitgesehenen Felder als Erinnerung
bestehen -- der Bestandstest dazu prueft jetzt genau das (Snapshot,
ohne die Einheiten des Verbundeten).

Karten-Regeneration wischt das Gedaechtnis mit dem Brett weg (das
Game ueberlebt ja); ein Dev-Reset braucht nichts, das Game-Delete
kaskadiert. Der Spalten-Guard-Test kennt den neuen Relationstyp.

Co-Authored-By: Claude Fable 5 <[email protected]>
Ein remembered-Feld (Snapshot des Erkundungs-Gedaechtnisses) rendert
seine Terrain-Daten mit opacity 0.45 -- klar erkennbar als bekannt,
aber nicht aktuell -- statt wie ein nie gesehener Hex schwarz zu
sein. Interaktiv ist es trotzdem nichts: kein Befehlspopup, kein
Einheiten-Press (isFoggedForInteraction neben isUnseen), dieselbe
Regel wie im echten Nebel -- welche Befehle ein Popup anbietet, ist
selbst Information. Ein bereits armierter Zug hinein bleibt erlaubt:
Hineinlaufen ist, wie man eine Erinnerung auffrischt.

Der Mapper in App.tsx reicht das Flag durch (die bekannten drei
Orte: db-Typ, Field-Typ, Mapper).

Co-Authored-By: Claude Fable 5 <[email protected]>
GAME-DESIGN §Visibility ersetzt das offene "ob" durch das Wie:
Snapshot-Semantik, Nur-durch-eigene-Augen-Auffrischung, Regenerations-
Wipe, remembered-Rendering und der Verbundeten-Sicht-Nebeneffekt.
ROADMAP Phase 8c entsprechend -- offen bleibt nur die OBSERVER-Sicht.

Co-Authored-By: Claude Fable 5 <[email protected]>
migrate dev im frischen Fork-Checkout hat den bekannten
Migrations-Ledger-Drift (Party-Indizes, Player.updatedAt-Default --
vgl. 1d2ae85) nicht verweigert wie auf der drifted Dev-DB, sondern
still in die Diff eingebaut: DROP INDEX Party_fieldId_layer_idx,
ALTER TABLE Player ..., CREATE INDEX Party_fieldId_idx. Auf einer
aus dem Ledger nachgebauten DB (fateshard_b) lief das durch, auf der
echten fateshard (die zum schema.prisma passt, nicht zum Ledger)
flog das DROP auf 42704 und blockierte als fehlgeschlagene Migration
beide Datenbanken.

Die Migration enthaelt jetzt nur noch ExploredField selbst; der
Ledger-Drift bleibt als eigenes, kosmetisches Thema bestehen (gleiche
Einschaetzung wie 1d2ae85). Wiederherstellung per migrate resolve
--rolled-back + deploy auf fateshard und fateshard_test, beide gruen.

Co-Authored-By: Claude Fable 5 <[email protected]>
Was B3 (Lobby/Matchmaking) schon alles vorfindet (Auth, Groessen-
formel, Generator, Bot-Fuellung samt Tick -- dessen Kickoff aber nur
im Dev-Bootstrap lebt) und welche Designfragen vor der Implementierung
geklart werden muessen: Partiegroesse/Gotterzahl, eine Lobby vs.
mehrere, Deadline-Default, Verhaeltnis zum Admin-Dev-Bootstrap,
Verhalten nach Spielende, Anmelde-UX, E-Mail-Verifizierung.

Co-Authored-By: Claude Fable 5 <[email protected]>
- "Ausloggen"-Button zusaetzlich in die Icon-Reihe ueber der Karte (beide
  Layouts, sobald eingeloggt); AuthPanel bleibt im Admin-Stapellayout unten,
  dort gibt es also beide Buttons.
- Das Vollbildlayout (Nicht-Admins mit Rolle) rendert jetzt ausschliesslich
  den Kartenscreen: Icon-Reihe, Final-Battle-Overlays, Karte und
  Befehlsfehler (actionError als Alert innerhalb des Screens). Alles darunter
  entfaellt fuer Spieler: Ueberschrift, AuthPanel, Bedienhinweis,
  "Pause game"-Knopf und das Spielende-Banner. Die Seite ist damit genau
  einen Screen hoch, scrollt nicht mehr, und die komplette Karte passt
  immer ins Browserfenster.
- Was Spieler dadurch nur noch woanders sehen: Pause-Zustand weiter ueber
  den Badge in der Icon-Reihe (der Knopf selbst ist weg), Spielende ueber
  den Event-Log-Eintrag plus automatisch aufgehendes Ergebnis-Overlay.
- Test angepasst: "Abschnitt vor Ueberschrift" ist obsolet (Spieler haben
  keine Ueberschrift mehr). Neu: reiner Spielerscreen ohne Seitenumgebung,
  Fehleranzeige innerhalb des Vollbildscreens, Row-Logout inkl.
  signOut-Aufruf, Admin-Kontrast.
- GAME-DESIGN neu: §Lobby & Joining — Spiele starten per Admin-Knopf als
  vollbotische, pausierte Partie (N Erdlinge, floor(N/2) Goetter,
  Brettgroesse wie gehabt aus der Erdlingzahl); Anmeldung/Uebernahme nimmt
  eine freie Bot-Rolle der gewuenschten Type, sonst Zwangszuweisung; nach
  Spielende macht ein Admin die naechste Partie auf; eine Lobby pro Instanz
  zunaechst, gameId-scoped fuer mehrere spaeter.
- Zwei offene Details dort notiert: wer die Pausen einer frischen Partie
  loesst (Erste-Übernahme vs. Admin), und Nickname bei Uebernahme.
- REQUIREMENTS §Authentication: Verifizierung bewusst nicht mehr als
  Lobby-Voraussetzung gerahmt; Admin-Pfad auf pro-Spiel ADMIN-Rolle +
  explizites New game umgestellt (noch nicht implementiert), Selbstversorg-
  Zuweisung fuer alle anderen beschrieben.
- ROADMAP Phase 10: offene Fragen durch Entscheidungen ersetzt, drei
  Scheiben (10a Spiel Erstellung, 10b Lobby/Uebernahme, 10c Aufraeumen).
- party_field_id_index: die Avatare-Änderung deklarierte @@index([fieldId]),
  ohne dass der alte (fieldId, layer)-Lookup-Index aus der party_layer-
  Migration je per Migration entfernt worden wäre — frische DBs wichen vom
  Schema ab und migrate dev backte den Tausch in jede neue Migration ein
  (bekannter Drift). IF EXISTS/IF NOT EXISTS: auf den bereits manuell
  angeglichenen lebenden DBs ein No-op, auf historiengetreuer Wiederholung
  die echte Änderung.
- role_type_admin: RoleType.ADMIN für die pro-Spiel-Admin-Rolle der Lobby
  (docs/GAME-DESIGN.md §Lobby & Joining); Autorisierung bleibt auf
  Player.isAdmin.
N Erdlings-Rollen + floor(N/2) Gott-Rollen (alle bot-gehalten auf je einem
Platzhalter-Player, Götter mit STARTING_MANA), die ADMIN-Rolle des
anlegenden Admins, Game-Zeile pausiert mit gestoppten Bots und Brettgröße
aus der Erdlingzahl, frisches generiertes Brett inkl. heimischer
Produktionstermine im Ergebnis. Platzhalter-Nicknames bleiben generisch,
Übernahme tauft um. Scheibe 10a-Grundlage (ROADMAP Phase 10).
Admin-gate Mutation, die createGame (Roster, Pausen, Brett) aufruft und
die heimischen Produktionstermine an den Scheduler uebergibt — gleiche
DB/Scheduler-Teilung wie dev.generateMap. Eigener gameRouter, der mit der
Lobby weiterwaechst (Auflisten/Beitreten).
Eingabefeld (Default 4, min 1) neben Generate map, Knopf legt ueber
game.create eine ganze Lobby-Partie an und setzt die Session sofort auf das
neue Spiel (inkl. Fokus-Reset wie bei Generate map). Nicht an session
gekoppelt — Partie anlegen darf keine vorhandene voraussetzen. Die
clientseitigen MyAccess/Roster-Spiegeltypen nehmen ADMIN in die
Rollentyp-Union auf (Typ-Paritaet mit dem Server).
Berichtigung zur Festlegung von heute: ungerade Erdlingzahl rundet die
Goetterzahl auf (5 Erdlinge -> 3 Goetter). Test zuerst auf die neue Regel
umgestellt und rot gezeigt, dann ceil statt floor.
joinOpenGame claimed zeilenweise und bedingt (isBot-Wache im WHERE) eine
freie Bot-Rolle der Wunsch-Type, sonst der anderen (Zwangszuweisung),
tauft sie auf den Profilnamen um und nimmt den neuesten Lobby-Spiel mit
freien Slots. Lobbys sind strukturell die Spiele mit ADMIN-Rolle — das
Dev-Fixture bleibt draußen. listOpenGames liefert frei/gesamt je Type für
den oeffentlichen Fortschritt, volle Partien bleiben sichtbar.
getLobby ohne Auth-Gate (sichtbarer Fortschritt vor dem Login), join nur
fuer eingeloggte rollenlose Nicht-Admins — Admins handeln ueber Ansicht,
Rollenhalter haben nichts zu beitreten. no-open-game als saubere
Ablehnung statt ok:false-Antwort.
LobbyPanel zeigt frei/gesamt je Rollentype (+ 'Partie voll'), rollenlose
Spieler bekommen die beiden Praeferenz-Knoepfe, Ausgeloggte nur die
Anzeige unter dem Login-Prompt. Der Join refresht den Access sofort — die
neue Rolle macht aus dem Client direkt die Vollbildkarte. Lobby-Polling
laeuft unabhaengig von der Game-Session und ueber usePolledState, damit
der Tick ohne News nichts durchreicht (pollDedup-Vertrag bleibt intakt).
Der alte 'noch keiner Rolle zugeordnet'-Wartetext ist durch die Lobby
ersetzt.
Admins bekommen neben isAdmin jetzt game (neueste ADMIN-Rollen-Partie)
bzw. null — die Grundlage fuer den Bootstrap-freien Entry-Flow. joinOpen-
Game/listOpenGames betrachten nur noch das jeweils neueste ADMIN-Rollen-
Spiel als DIE Lobby: aeltere Partien fallen aus Beitritt und Fortschritt,
statt als Ewig-Joinbare rumzustehen. Lobby-Tests lokalisiert, sodass
parallel laufende Suiten mit eigenen Lobbys sich nicht mehr in die
Quere kommen.
Der Client leitet die Admin-Session direkt aus getMyAccess' game-Feld ab
(neueste ADMIN-Rollen-Partie) statt implizit das Dev-Fixture zu
bootstrappen; ohne Partie zeigt der Kartenbereich den New-game-Leerzustand
statt ewigem Connecting. bootstrapError-Mechanik entfaellt mit dem
entfallenen Aufruf, der Server-Endpunkt bleibt als Dev/Tooling-Einstieg
bestehen. Test-Defaults auf access-getragene Sessions umgestellt.
Bootstrap-Endpunkt-Kommentar: Client ruft ihn nicht mehr, er bleibt
Dev-/Tooling-Einstieg.
Vorbereitung fuer Auto-Follow (docs/GAME-DESIGN.md §Lobby & Joining): eine
zurueckgelassene Rolle bleibt dem Spieler zugewiesen, also haelt ein Spieler ab
dem ersten Follow mehrere Rollen. Das bisherige `findFirst({ where: { playerId } })`
ohne Sortierung haette davon eine beliebige geliefert; jetzt entscheidet
`orderBy: { game: { createdAt: "desc" } }`.
Ein Spieler, dessen Rolle in einer aelteren Partie steht, wandert von selbst in
die aktuelle Lobby, mit dem Rollentyp, den er gespielt hat, als Praeferenz
(joinOpenGame uebernimmt das Claimen samt erzwungenem Typwechsel). Die
zurueckgelassene Rolle bleibt unangetastet — weiter dem Spieler zugewiesen, kein
Bot erbt seine Stellung; sie liegt einfach verwaist herum. Ein Spieler ohne
Spielerrolle (Neuling, Admin mit nur ADMIN-Rolle) wird nie gefolgt.

Zwei Vorarbeiten, damit das spaeter auf mehrere parallele Partien aufgebohrt
werden kann, statt die Ein-Lobby-Annahme aus drei Stellen herauszuoperieren:

- findCurrentLobbyGameId ist ab jetzt die einzige Stelle, die "welche Partie ist
  die Lobby" beantwortet; joinOpenGame und listOpenGames fragen sie.
- joinOpenGame und autoFollowToCurrentLobby nehmen optional die gameId der Lobby
  entgegen. Produktiv schliesst das eine Luecke — Auto-Follow loest die Lobby
  einmal auf und claimt genau dort, statt ein zweites Mal nachzuschlagen und
  moeglicherweise in einer inzwischen neu angelegten Partie zu landen. Im Test
  macht es die Faelle ueberhaupt erst deterministisch: andere Suiten legen in
  derselben DB nebenher eigene Lobby-Partien an.
Der Aufruf, den jeder Client beim Eintritt macht, zieht einen Spieler, dessen
Partie inzwischen abgeloest wurde, ohne zweiten Roundtrip in die neue Lobby.
Admins sind hier ausgenommen: sie erreichen ihre Partie ueber ihre eigene
ADMIN-Rolle, und ein Follow wuerde dem Ersteller sonst still eine Bot-Rolle
seiner frischen Partie zuweisen.

Auto-Follow geht dabei nur vorwaerts (Fund beim Verdrahten: der bestehende
Router-Test "returns the assigned role for a non-admin Player's session" wurde
rot, weil sein Spieler aus seiner eigenen, neueren Partie in eine aeltere Lobby
gezogen wurde). Entschieden wird nach Alter der Partie, nicht nach Id: wer per
assignRole von Hand in eine Partie gesetzt wurde oder im Dev-Fixture sitzt, wird
dort nicht herausgerissen, nur weil die Lobby die neueste Partie *mit
ADMIN-Rolle* ist.
Der Lobby-Poll meldet ohnehin die aktuelle Partie; weicht sie von der ab, die
diese Sitzung spielt, fragt der Client seinen Zugang neu ab — und genau dieser
Aufruf fuehrt serverseitig den Follow aus. Ohne das saesse ein Spieler bis zum
naechsten Reload in der abgeloesten Partie.

Pro Lobby wird das genau einmal versucht (Ref-Merker): ein abgelehnter Follow
— nichts frei — darf nicht jeden Poll-Tick in eine weitere Zugangsabfrage
verwandeln.
GAME-DESIGN §Lobby & Joining beschreibt die Regel (nur vorwaerts, nach Alter der
Partie; zurueckgelassene Rolle bleibt zugewiesen und unbespielt; Admins und
Erstspieler ausgenommen), REQUIREMENTS §Authentication den daraus folgenden
Zugriffsfall (mehrere Rollen pro Spieler, neueste zaehlt), ROADMAP Phase 10 den
Slice 10d samt Naht fuer mehrere parallele Lobbys.
Solange in der neuen Lobby beide Rollentypen noch einen freien Platz haben,
zieht der Follow niemanden mehr still hinueber, sondern meldet choice-pending —
der Spieler waehlt Erdling oder Gott wie jeder andere Beitretende. Erst wenn nur
noch ein Typ frei ist, gibt es nichts zu entscheiden, und der Follow nimmt ihn,
unabhaengig davon, was der Spieler vorher gespielt hat (der bisherige Typ als
Praeferenz war damit hinfaellig).

getLobbyStanding ist die eine Stelle, an der "darf dieser Spieler noch eine
Rolle in der Lobby nehmen" beantwortet wird — Eintritt und Beitritt von Hand
haengen gleichermassen daran, statt die Vorwaerts-Regel zweimal zu fuehren. Die
Zaehlung der freien Plaetze teilt sie sich mit listOpenGames (countFreeSlots).
player.getMyAccess liefert Nicht-Admins jetzt zusaetzlich lobbyChoice: steht in
der neuen Lobby noch eine Wahl offen, bleibt die alte Rolle stehen und der
Client bekommt gesagt, welche Partie zur Wahl steht.

game.join weist einen Spieler mit Rolle nicht mehr pauschal ab — genau darueber
laeuft die Wahl. Entschieden wird mit demselben getLobbyStanding, das auch der
Follow benutzt: abgewiesen wird nur, wer schon in der Lobby sitzt oder in einer
Partie, die mindestens so neu ist wie sie.
Meldet der Zugang eine offene Wahl (lobbyChoice), zeigt der Client die Lobby mit
den Praeferenz-Knoepfen statt der Karte der abgeloesten Partie — und setzt
solange keine Session, damit die alte Partie nicht im Hintergrund weitergepollt
wird. Nach dem Klick laeuft alles ueber den bestehenden Beitritts-Pfad.

Der Follow-Versuch merkt sich jetzt Lobby *und* freie Plaetze: verschwindet der
letzte freie Gott, ist die Wahl keine mehr, und genau dann lohnt die erneute
Zugangsabfrage, die den Follow dann automatisch ausfuehrt. Fehlendes
lobbyChoice-Feld wird wie null behandelt, damit der handgeschriebene
Client-Spiegel nicht an einer aelteren Antwort haengenbleibt.
GAME-DESIGN §Lobby & Joining unterscheidet jetzt die drei Faelle (Wahl offen /
nur ein Typ frei / nichts frei), REQUIREMENTS und ROADMAP ziehen nach.
This pull request is broken due to missing fork information.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin phase-b:phase-b
git switch phase-b

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff phase-b
git switch phase-b
git rebase main
git switch main
git merge --ff-only phase-b
git switch phase-b
git rebase main
git switch main
git merge --no-ff phase-b
git switch main
git merge --squash phase-b
git switch main
git merge --ff-only phase-b
git switch main
git merge phase-b
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
benni/aymargeddon!1
No description provided.