docs: Entwurf für Flamingo Park nach OpenStreetMap
Teil 1 von zwei: Der Park bekommt die echten Wege, Felder, Plätze, Pool, Parkplatz und Gebäude, eingepasst nach Variante D, dazu die Jefferson Avenue als gerade Verlängerung nach Süden. Umsetzung in der Extraktion. Teil 2 (Bordstein, Gehweg, amerikanische Markierungen) bekommt einen eigenen Entwurf. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fb38652e7f
commit
c278ad3d9d
1 file changed
+341
@@ -0,0 +1,341 @@
|
||||
# Flamingo Park nach OpenStreetMap — Entwurf
|
||||
|
||||
**Datum:** 2026-09-15
|
||||
**Zusammenhang:** Der Nutzer will, dass Straßen und Wege nicht mehr zackig sind und dass Flamingo Park (Miami Beach) im Spiel dieselben Wege hat wie in Wirklichkeit. Vorlagen im Gespräch: ein Google-Maps-Ausschnitt (15th Street bis 11th Street, Michigan Ave bis Meridian Ave) mit einem roten Strich über der 11th Street auf der Linie der Jefferson Avenue, und ein Screenshot aus dem Spiel mit den zackigen Straßen am Nordrand des Parks.
|
||||
**Aufteilung, vom Nutzer entschieden:** **Teil 1** (dieser Entwurf) baut den Park neu, noch mit flachen Flächen wie bisher. **Teil 2** ist ein eigenes Konzept für die Straßen: gerade Kanten, Bordstein, Gehweg und amerikanische Markierungen, mit den Kits `modular_city_road_pack__game_ready` und `modular_sidewalk_curb_kit` (beide noch nicht versioniert im Repo-Wurzelordner).
|
||||
**Baut auf:** `docs/superpowers/specs/2026-09-12-leonida-vice-slice-design.md` (Extraktion, Chunk-Format), `2026-09-13-minimap-design.md` (`overview.py`), `2026-09-14-hood-yard-design.md` und `2026-09-14-tribuene-design.md` (Orte, Satellitenanker). Die Feinkalibrierung (`2026-09-13-feinkalibrierung-design.md`) ist geplant, aber nicht umgesetzt; es gibt keine `corrections.toml`.
|
||||
|
||||
## Ziel
|
||||
|
||||
Flamingo Park zeigt im Spiel die echte Anlage: alle Wege, Sportfelder, Plätze, Pool, Parkplatz und Gebäude, eingepasst in die Parkfläche des Spiels, mit glatten Wegkanten. Die Jefferson Avenue führt vom Park geradeaus nach Süden. Tribüne und Hood Yard bleiben, wo sie sind. 3D-Welt, Kollision, Minimap, Palmen und Laternen zeigen dieselbe Anlage, und jeder spätere Lauf der Extraktion erzeugt sie wieder.
|
||||
|
||||
## Befund (gemessen)
|
||||
|
||||
### Warum Wege zackig sind
|
||||
|
||||
`road_polygons` in `tools/extract/leonida/vectors.py` fasst die Klassen `strasse`, `weg` und `spekulativ` zu einer Maske zusammen, schließt sie mit `disk(3)`, verfolgt die Kontur auf dem 1-px/m-Raster und vereinfacht nur um 0,8 m. Jede schräge Kante wird zur Treppe. Straßen und Wege sind danach eine Klasse (`roads` ohne `class`) und bekommen dasselbe Material (`asphalt_02`).
|
||||
|
||||
### Park im Spiel
|
||||
|
||||
Gemessen an `public/data/vice-a/map.png`: Geraden durch die Innenkanten der vier umgebenden Straßen, Restfehler unter 0,7 m.
|
||||
|
||||
| Kante | Gerade (Welt) |
|
||||
|---|---|
|
||||
| West (Michigan Ave) | x = 1475,6 − 0,0870 · y |
|
||||
| Ost (Meridian Ave) | x = 1718,0 − 0,0840 · y |
|
||||
| Nord | y = 951,1 + 0,0891 · x |
|
||||
| Süd (11th Street) | y = 575,7 + 0,0584 · x |
|
||||
|
||||
- **Ecken:** SW (1418,3 | 658,6), SE (1661,5 | 672,8), NE (1626,0 | 1096,0), NW (1382,1 | 1074,2).
|
||||
- **Maße:** 243,6 m entlang der Südkante, 417,2 m entlang der Westkante, etwa 5° gegen den Uhrzeigersinn gedreht. Die Nordkante steigt mit 5,1° stärker als die Südkante mit 3,3°. Die Straßen ringsum sind rund 15 m breit.
|
||||
- **Inhalt heute:**
|
||||
- Baseball- und Fußballfeld sowie ein drittes Feld als `park`.
|
||||
- Querweg mit Kreisel bei y ≈ 890 und ein Nord-Süd-Weg bis zur 11th Street, beide als `roads`.
|
||||
- Zwei kleine Gebäude bei (1450 | 905) und (1477 | 918), dazu Palmen.
|
||||
|
||||
### Echter Park (OpenStreetMap, Abruf 2026-09-15)
|
||||
|
||||
- **Umriss:** Park-Polygon ist way 76684242 („Flamingo Park“).
|
||||
- **Lokales Maß:** Meter um den Bezugspunkt 25,7840° N, −80,1375° O, mit 111 320 m je Breitengrad und 100 238 m je Längengrad.
|
||||
- **Innenkante zwischen Michigan und Meridian Ave:**
|
||||
- SE (113,0 | −227,1) und NE (97,9 | 284,3) sind Eckpunkte des Polygons.
|
||||
- SW (−87,5 | −233,2) ist der Schnittpunkt von West- und Südkante.
|
||||
- NW (−102,9 | 281,0) ist der Punkt der Westkante auf Höhe der NE-Ecke. Der Zipfel hinter der Tribüne bleibt weg.
|
||||
- Maße: 200,6 × 514,4 m.
|
||||
- **Nicht im Spielpark:** der Parkplatz nördlich der Felder, der bis zur 15th Street reicht, und das Stadion westlich der Michigan Ave.
|
||||
- **Inhalt nach Einpassung**, gezählt vor dem Zuschneiden an den Rändern:
|
||||
- **Wege:** rund 25 Fußwege, zusammen knapp 2 km. Zwei davon heißen „Flamingo Park Path (13th St)“ und „Flamingo Park Path (Jefferson Ave)“. Dazu eine Parkplatzgasse (`highway=service`).
|
||||
- **Sportflächen** (`leisure=pitch`): 2 × Baseball, Fußball, Basketball, Tennis (`surface=clay`, 8 600 m²) und 4 × Racquet.
|
||||
- **Weitere Flächen:** `dog_park`, `playground`, `sports_centre` (eingezäunt, `sport=multi`), 2 Becken (`leisure=swimming_pool`) und 1 Parkplatz mit 2 880 m².
|
||||
- **Gebäude:** 14 Stück, 7 davon mit `height` zwischen 0,0 und 12,2 m.
|
||||
|
||||
### Einpassung
|
||||
|
||||
Der echte Park ist schmaler und länger als der im Spiel. Vier Varianten, gemessen mit affiner Näherung. Der Abstand gibt an, wie weit die echte Tribüne (OSM way 436030691) von der Tribünenmitte im Spiel (1405 | 1058,6) landet und wie weit die echten Kleinbauten vom Hood Yard (1489 | 1067,5).
|
||||
|
||||
| Variante | quer | längs | Abstand zum Westrand | Tribüne | Hood Yard |
|
||||
|---|---|---|---|---|---|
|
||||
| A: echte Proportionen | 0,811 | 0,811 | 40,5 m | 32,2 m | 14,4 m |
|
||||
| B: ganz ausgefüllt | 1,214 | 0,811 | 0 m | 1,8 m | 13,6 m |
|
||||
| C: Mittelweg, mittig | 1,0 | 0,811 | 21,5 m | 16,3 m | 14,0 m |
|
||||
| **D: Mittelweg, an Tribüne ausgerichtet** | **1,0** | **0,811** | **6,3 m** | **1,3 m** | **1,2 m** |
|
||||
|
||||
Bei D bleibt östlich der Anlage ein 37 m breiter Rasenstreifen.
|
||||
|
||||
### Südlich des Parks
|
||||
|
||||
- Der Jefferson-Weg endet nach Einpassung (D) bei (1516,5 | 662) an der 11th Street.
|
||||
- Rund 30 m westlich liegt eine schmale, zackige Gasse. Ihre Mittellinie läuft 1484/652 → 1487/616 → 1488/578 → 1495/536 → 1497/468 → 1501/461 → 1502/446 → 1505/381 → 1508/367 → 1510/333.
|
||||
- Sie endet an einer Querstraße mit der Mittellinie 1440/327 → 1510/332 → 1551/333.
|
||||
- Auf der Linie des Jefferson-Wegs stehen zwei Gebäude, beide `source: "district"`:
|
||||
- x 1494,5–1531 · y 614,5–640,5, 20,9 m hoch
|
||||
- x 1506,5–1556,5 · y 393,5–458,5, 24,9 m hoch
|
||||
|
||||
### Die beiden Kits, für Teil 2 festgehalten
|
||||
|
||||
- **`modular_city_road_pack__game_ready`** (Salah3D, CC BY 4.0):
|
||||
- Spielzeugmaßstab: Fahrbahn 4,2 m für zwei Spuren, Gehwegstreifen 0,25 m, Stufe 3 cm.
|
||||
- Markierungen fest in 512-px-Texturen: gelbe Randlinien, weiße gestrichelte Mitte, Zebrastreifen. Das ist kein amerikanisches Schema.
|
||||
- **`modular_sidewalk_curb_kit`** (Just8, CC BY 4.0):
|
||||
- Amerikanischer Bordstein mit Rinne, etwa 0,85 × 0,15 m, 3-m-Module, Ecken und ein Gully-Gitter.
|
||||
- 2K-Texturen mit Normal-Map.
|
||||
- Die Gehwegfläche trägt nur eine Platzhalter-Textur („Tri-plannar Sidewalk texture“).
|
||||
|
||||
## Entscheidungen des Nutzers
|
||||
|
||||
| Frage | Entscheidung |
|
||||
|---|---|
|
||||
| Aufteilung | Teil 1: Park. Teil 2: Straßenkonzept mit den Kits |
|
||||
| Umfang im Park | Wege und Felder, dazu Plätze, Pool und Parkplatz als Flächen an ihren echten Stellen |
|
||||
| Einpassung | Variante D: Breite 1:1, Länge 0,811, an Tribüne und Hood Yard ausgerichtet |
|
||||
| Roter Strich | eine fehlende Verbindung vom Park über die 11th Street nach Süden |
|
||||
| Gebäude | die echten aus OpenStreetMap als Kästen, die zwei alten Kästen entfallen |
|
||||
| Umsetzung | in der Extraktion (Weg 1), nicht zur Laufzeit und nicht als Nachbearbeitung der Chunks |
|
||||
| Jefferson Avenue | gerade Verlängerung des Parkwegs bis zur nächsten Querstraße |
|
||||
| Abschnitte Daten und Einpassung, Inhalt, Darstellung, Ablauf und Prüfung | bestätigt |
|
||||
|
||||
## Daten
|
||||
|
||||
### OSM-Abruf (`tools/extract/osm.py`)
|
||||
|
||||
- Neues Skript, das von Hand aufgerufen wird: `cd tools/extract && uv run python osm.py`.
|
||||
- Es fragt die Overpass-API (`https://overpass-api.de/api/interpreter`, POST, User-Agent wie `tiles.py`) für den Kasten 25,7765–25,7885° N, −80,1425 bis −80,1325° O ab. Abgefragt werden Wege mit `highway`, `leisure`, `amenity=parking` und `building`, jeweils mit Geometrie.
|
||||
- Es behält nur, was der Park braucht, und schreibt `tools/extract/data/osm/flamingo-park.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"source": "https://www.openstreetmap.org",
|
||||
"license": "ODbL 1.0, © OpenStreetMap-Mitwirkende",
|
||||
"fetched": "2026-09-15T20:28:44Z",
|
||||
"elements": [ { "id": 198107995, "tags": { "highway": "footway", "name": "..." }, "geometry": [[25.78190, -80.13764], ...] } ]
|
||||
}
|
||||
```
|
||||
|
||||
- `run.py` liest nur diese Datei und braucht kein Netz. Ein neuer Abruf ist eine bewusste Handlung mit eigenem Commit.
|
||||
|
||||
### Parkdatei (`tools/extract/data/flamingo-park.toml`)
|
||||
|
||||
Alles, was von Hand entschieden ist. Die Werte unten sind die Werte der Umsetzung; nur `offset_u` wird beim Umsetzen mit der bilinearen Umrechnung neu eingestellt (siehe Einpassung).
|
||||
|
||||
```toml
|
||||
# Flamingo Park nach OpenStreetMap. Spec: docs/superpowers/specs/2026-09-15-flamingo-park-design.md
|
||||
osm = "osm/flamingo-park.json"
|
||||
|
||||
[fit]
|
||||
# Innenkante des echten Parks, Breite/Länge in Grad
|
||||
real = { sw = [25.781905, -80.138373], se = [25.781960, -80.136373], ne = [25.786554, -80.136523], nw = [25.786524, -80.138527] }
|
||||
# Innenkante der Straßen um den Park im Spiel, Welt-x/Welt-y wie auf der Minimap
|
||||
game = { sw = [1418.3, 658.6], se = [1661.5, 672.8], ne = [1626.0, 1096.0], nw = [1382.1, 1074.2] }
|
||||
scale_u = 1.0 # quer wie in echt
|
||||
offset_u = 6.3 # Meter vom Westrand; echte Tribüne und Kleinbauten auf Tribüne und Hood Yard
|
||||
|
||||
[[anchor]] # Prüfung der Einpassung, höchstens 1,5 m Abweichung
|
||||
name = "Tribüne"
|
||||
real = [25.786336, -80.138358] # Mitte von OSM way 436030691
|
||||
game = [1405.0, 1058.6] # Tribünen-Spec: Mitte der echten Tribüne im Spiel
|
||||
[[anchor]]
|
||||
name = "Hood Yard"
|
||||
real = [25.786407, -80.137540] # Übergang Container/Schuppen laut Hood-Yard-Spec
|
||||
game = [1489.0, 1067.5]
|
||||
|
||||
[[keepout]] # Außenmaße aus src/world/places.js
|
||||
name = "tribuene"
|
||||
at = [1409.9, 1051.1]
|
||||
rotation = 45
|
||||
bounds = { min_x = -20.8, max_x = 20.8, min_z = -14.82, max_z = 0.8 }
|
||||
[[keepout]]
|
||||
name = "hood-yard"
|
||||
at = [1489.0, 1067.5]
|
||||
rotation = 0
|
||||
bounds = { min_x = -17.15, max_x = 17.0, min_z = -13.4, max_z = 8.6 }
|
||||
|
||||
[paths]
|
||||
main_width = 6.0 # "Flamingo Park Path (13th St)", "Flamingo Park Path (Jefferson Ave)"
|
||||
width = 3.0 # alle übrigen Fußwege
|
||||
service_width = 6.0 # Parkplatzgasse und Zufahrt
|
||||
|
||||
[buildings]
|
||||
default_height = 4.0 # wenn OSM keine Höhe hat
|
||||
|
||||
[street] # Jefferson Avenue südlich des Parks
|
||||
from = [1516.5, 664.0]
|
||||
to = [1545.2, 334.2]
|
||||
width = 12.0
|
||||
remove_buildings = [[1513.0, 628.0], [1532.0, 426.0]]
|
||||
# Gassenstreifen zwischen den Kanten von 11th Street und der Querstraße bei y ≈ 332, samt der
|
||||
# ausgerundeten Ecken an beiden Einmündungen. Wird beim Planen einmal aus den Chunk-Daten gemessen.
|
||||
alley_cut = [[x, y], ...]
|
||||
```
|
||||
|
||||
**Prüfregeln beim Einlesen:** Fehlt ein Pflichtfeld, hat ein Feld den falschen Typ, fehlt die OSM-Datei oder ist eine Breite oder Höhe ≤ 0, bricht `run.py` mit einer Meldung ab, die Datei und Feld nennt. Fehlt die OSM-Datei, nennt die Meldung den Aufruf von `osm.py`.
|
||||
|
||||
## Einpassung
|
||||
|
||||
- **Echte Lage:** Jeder OSM-Punkt wird zuerst in lokale Meter umgerechnet (Bezugspunkt und Maß wie im Befund). Danach bekommt er Parkkoordinaten (s, t), mit der Umkehrung der bilinearen Abbildung über die vier echten Ecken: s läuft von West nach Ost, t von Süd nach Nord. Das echte Parkviereck ist s, t ∈ [0, 1].
|
||||
- **Lage im Spiel:** Quer wird s zu s' = (offset_u + scale_u · s · B_echt) / B_Spiel umgerechnet, mit B_echt = 200,6 m und B_Spiel = 243,6 m, jeweils entlang der Südkante. Längs bleibt t. Der Spielpunkt ist die bilineare Abbildung von (s', t) über die vier Spielecken. Die Nordkante des Parks folgt so auch der schrägen Nordkante im Spiel.
|
||||
- **Länge:** Sie ergibt sich aus den Ecken, 417,2 / 514,4 ≈ 0,811.
|
||||
- **`offset_u`:** Der Wert wird so gewählt, dass beide Anker aus der Parkdatei höchstens 1,5 m neben ihrer Spielposition landen. Die 6,3 m aus dem Befund sind mit affiner Näherung gemessen, die Umsetzung stellt den Wert bilinear neu ein.
|
||||
- **Zuschneiden:** Wege werden am echten Parkviereck abgeschnitten. Endet ein Weg danach höchstens 5 m vor dessen West- oder Ostrand, läuft er im Spiel in seiner letzten Richtung bis an die Straßenkante weiter. Flächen und Gebäude zählen nur, wenn ihr Mittelpunkt im echten Parkviereck liegt.
|
||||
|
||||
## Anwendung in der Pipeline (`tools/extract/leonida/park.py`)
|
||||
|
||||
**Zeitpunkt:** in `run.py` nach Land, Belägen, Straßen, Mittellinien, Gebäuden mit Höhen und Palmen, vor den Chunk-Nutzlasten. So sehen Chunk-Dateien, Kollision, Minimap und Landemaske das Ergebnis.
|
||||
|
||||
**Sicherheitsprüfung vorab:** Jede Spielecke aus der Parkdatei muss höchstens 2 m neben einer Straßenfläche liegen. Sonst hat sich die Extraktion geändert, und der Lauf bricht mit einer Meldung ab.
|
||||
|
||||
### Schritt 1: Jefferson Avenue
|
||||
|
||||
1. **Gebäude:** Jedes Gebäude, in dem ein Punkt aus `remove_buildings` liegt, entfällt.
|
||||
2. **Gasse:**
|
||||
- Das Vieleck `alley_cut` wird aus der Straßenfläche geschnitten. Es reicht von der Kante der 11th Street bis zur Kante der Querstraße bei y ≈ 332 und schließt die ausgerundeten Ecken der Einmündungen ein, aber keine Fahrbahn der Querstraßen.
|
||||
- Die Mittellinienstücke in `alley_cut` entfallen.
|
||||
3. **Neue Straße:**
|
||||
- Ein Rechteck von `width` Breite von `from` nach `to` wird mit der Straßenfläche vereinigt, `bridge = false`. Die Querstraßen sind danach durchgehend.
|
||||
- Dazu kommt eine Mittellinie von `from` nach `to`.
|
||||
4. **Frei gewordene Flächen:** Die Grundrisse und `alley_cut`, soweit sie nicht unter der neuen Straße liegen, werden als `urban` mit der Stadtfläche vereinigt.
|
||||
5. **Palmen:** Palmen auf der neuen Straße oder näher als 1,5 m an ihr entfallen.
|
||||
|
||||
### Schritt 2: Park
|
||||
|
||||
Das Parkpolygon ist das Viereck aus den Spielecken.
|
||||
|
||||
**Entfernen**
|
||||
- Straßenflächen werden am Parkpolygon abgeschnitten, Mittellinien ebenso. Stücke unter 1 m entfallen.
|
||||
- Beläge (`sand`, `park`, `urban`) werden am Parkpolygon abgeschnitten.
|
||||
- Gebäude mit mehr als der Hälfte ihrer Fläche im Park entfallen.
|
||||
- Palmen im Park entfallen.
|
||||
|
||||
**Einsetzen**, in dieser Reihenfolge:
|
||||
|
||||
| Ergebnis | Aus OpenStreetMap | Chunk-Ziel |
|
||||
|---|---|---|
|
||||
| Rasen | das ganze Parkpolygon | `surfaces`, `park` |
|
||||
| Felder | `pitch` mit `sport` baseball oder soccer | `surfaces`, `field` |
|
||||
| Plätze | `pitch` mit tennis, basketball oder racquet, dazu `sports_centre` | `surfaces`, `court` |
|
||||
| Pool | `swimming_pool` | `surfaces`, `pool` |
|
||||
| Parkplatz | `amenity=parking` | `surfaces`, `parking` |
|
||||
| Spielplatz | `playground` | `surfaces`, `sand` |
|
||||
| Hundewiese | `dog_park` | bleibt Rasen |
|
||||
| Parkplatzgasse und Zufahrt | `highway=service`, `service_width` breit | `roads`, ohne Mittellinie |
|
||||
| Wege | übrige `highway`-Wege, 6 m (benannte Hauptwege) oder 3 m breit | neue Liste `paths` |
|
||||
| Gebäude | `building`, Höhe aus `height`, sonst `default_height` | `buildings`, `source: "osm"`, `speculative: false` |
|
||||
|
||||
- **Wege:** Alle Wege werden gepuffert (runde Ecken und Enden) und zu einer Fläche vereinigt. Kreuzungen und Kurven haben dadurch glatte Kanten.
|
||||
- **Gebäude, die entfallen:** OSM-Gebäude mit `height` = 0 (Dächer ohne Wände, heute ein Pavillon auf einem Weg) und Gebäude, die eine Sperrfläche berühren (heute die echte Tribüne und ein Schuppen im Hood Yard). Es bleiben 11 von 14.
|
||||
- **Sperrflächen:** Die Rechtecke aus `keepout` werden aus Feldern, Plätzen, Pool, Parkplatz und Wegen ausgeschnitten. Trifft das einen Weg, gibt der Lauf eine Warnung aus.
|
||||
- **Palmen:**
|
||||
- Dieselbe Regel wie `palm_points` für Parks: fester Seed, ein Versuch je 250 m².
|
||||
- Sie gilt auf dem Rasen ohne Felder, Plätze, Pool, Parkplatz und Spielplatz.
|
||||
- Gesperrt sind Straßen, Gebäude, Wege und Sperrflächen, jeweils mit 6 m Abstand (`PALM_CLEARANCE`).
|
||||
- **Laternen:** Im Park entstehen keine. Die Mittellinien der alten Parkwege sind entfernt, die neuen Wege haben keine.
|
||||
|
||||
## Chunk-Format
|
||||
|
||||
- **`paths`:** neue Liste je Chunk, `[{ "poly": rings }]`, chunk-lokal wie `roads`, mit Löchern.
|
||||
- **`surfaces`:** vier neue Arten `field`, `court`, `pool` und `parking`.
|
||||
- **`buildings`:** neuer Wert `source: "osm"`.
|
||||
- **`manifest.json`:** `attribution` wird um den Satz „Flamingo Park: © OpenStreetMap-Mitwirkende (ODbL).“ ergänzt. `buildAttribution` in `src/ui/hud.js` übernimmt ihn ohne Änderung.
|
||||
- **Recht:** Die Chunk-Dateien enthalten danach OSM-Daten. Solange das Projekt privat bleibt, genügt die Namensnennung. Bei einer Veröffentlichung müssten die Parkdaten unter ODbL stehen; wegen GTA ist eine Veröffentlichung ohnehin eine eigene Frage.
|
||||
|
||||
## Darstellung im Browser
|
||||
|
||||
- **`src/world/geometry.js`:**
|
||||
- `SURFACE_KINDS` wird zu `sand`, `park`, `urban`, `field`, `court`, `pool` und `parking`.
|
||||
- `buildChunkGeometry` baut zusätzlich `paths` als flache Fläche auf `ROAD_OFFSET`.
|
||||
- **`src/world/materials.js`:**
|
||||
- Neue Schlüssel in `MATERIAL_KEYS`:
|
||||
|
||||
| Schlüssel | Material |
|
||||
|---|---|
|
||||
| `paths` | Textur `concrete_pavement` |
|
||||
| `field` | Textur `leafy_grass` mit grünerer Tönung, im Browser abgestimmt |
|
||||
| `court` | einfarbig grüngrau, ohne Textur |
|
||||
| `pool` | einfarbig blau, ohne Textur |
|
||||
| `parking` | Textur `asphalt_02` mit `ROAD_TINT`, als eigenes Material |
|
||||
|
||||
- `POLYGON_OFFSET_ORDER` wird zu `ground`, `urban`, `park`, `sand`, `field`, `court`, `pool`, `parking`, `paths`, `roads`.
|
||||
- Die Regel, dass jeder Schlüssel eine Textur hat, gilt künftig nur für texturierte Schlüssel. `court` und `pool` stehen in einer eigenen Farbliste.
|
||||
- **`src/world/streaming.js`:** `DECALS` bekommt `paths`, `field`, `court`, `pool` und `parking`. Das sind reine Auflagen ohne eigene Kollision, wie heute Straßen und Beläge. Die Landplatte trägt, Gebäude kollidieren wie alle anderen. Man läuft also auch über den Pool.
|
||||
- **`tools/assets/textures.mjs`:** `SLUGS` bekommt `concrete_pavement` (Poly Haven, CC0, 1k). Die Textur ist auch für die Gehwege in Teil 2 gedacht.
|
||||
- **Kosten:** Bis zu fünf Draw Calls mehr, nur in den Chunks von Park und Jefferson Avenue (J6, K6, J7, K7, J8, K8, J9, K9).
|
||||
|
||||
## Minimap (`tools/extract/overview.py`)
|
||||
|
||||
- `SURFACE` bekommt Farben für `field`, `court`, `pool` und `parking`, `parking` in der Straßenfarbe.
|
||||
- Eine neue Ebene für `paths` wird zwischen Belägen und Straßen gezeichnet, in hellem Beige.
|
||||
- `map.png`, `map-walkable.png` und `map.json` werden neu erzeugt. In der Begehbarkeitsmaske ändern sich nur die Gebäude, weil Beläge, Wege und Straßen schon heute nicht zählen.
|
||||
|
||||
## Ablauf
|
||||
|
||||
1. **Branch:** Die Arbeit läuft auf `leonida/flamingo-park`, `main` bleibt bis zur Abnahme unberührt.
|
||||
2. **Pipeline auf Windows nachbauen:**
|
||||
- `cd tools/extract && uv sync`. `uv` lädt dafür Python 3.12 und die Pakete aus `uv.lock`.
|
||||
- Danach `uv run python run.py` mit unverändertem Code.
|
||||
- Verglichen werden alle Chunk-Dateien und `manifest.json` als geparstes JSON, dazu `map.png` und `map-walkable.png` Pixel für Pixel sowie `map.json`.
|
||||
- Weicht etwas ab, geht es erst weiter, wenn die Ursache geklärt und mit dem Nutzer entschieden ist.
|
||||
3. **OSM-Daten:** `osm.py` schreiben, einmal abrufen, dazu `flamingo-park.toml` anlegen.
|
||||
4. **Pipeline:** `park.py` testgetrieben bauen, dann in `run.py` einbinden.
|
||||
5. **Browser:** Geometrie, Materialien und Streaming testgetrieben erweitern.
|
||||
6. **Textur, Minimap und Namensnennung.**
|
||||
7. **Abschluss:** vollständiger Lauf, alle Tests, Sichtprüfung.
|
||||
|
||||
## Tests
|
||||
|
||||
### pytest (`tools/extract/tests/test_park.py`)
|
||||
|
||||
- **Einpassung:**
|
||||
- Südkante (t = 0) und Nordkante (t = 1) des echten Parks landen auf Süd- und Nordkante im Spiel.
|
||||
- s = 0 landet `offset_u` Meter östlich der Westkante.
|
||||
- Beide Anker liegen höchstens 1,5 m neben ihrer Spielposition.
|
||||
- **Zuschneiden und Verlängern:**
|
||||
- Ein Weg über den echten Parkrand endet an der Kante.
|
||||
- Ein Weg, der 3 m vor dem Westrand endet, reicht bis an die Straßenkante.
|
||||
- **Entfernen:**
|
||||
- Eine Straße, die in den Park ragt, endet an der Parkkante, ihre Mittellinie ebenso.
|
||||
- Gebäude, Beläge und Palmen im Park entfallen, außerhalb bleiben sie.
|
||||
- Ein Gebäude halb außerhalb bleibt stehen, eines zu 60 % im Park entfällt.
|
||||
- **Wege:** Ein einzelner Weg ist 3 m breit, ein benannter Hauptweg 6 m. Zwei kreuzende Wege ergeben eine einzige Fläche.
|
||||
- **Gebäude:** Die Höhe kommt aus `height`, sonst gilt `default_height`. Höhe 0 und Berührung einer Sperrfläche lassen das Gebäude entfallen.
|
||||
- **Sperrflächen:** Darin liegen danach keine Wege, Gebäude und Palmen, und Felder sind dort ausgeschnitten.
|
||||
- **Palmen:** keine auf Wegen, Feldern, Plätzen, Pool, Parkplatz oder Spielplatz, keine näher als 6 m an Straßen, Gebäuden, Wegen oder Sperrflächen. Gleicher Seed ergibt gleiche Palmen.
|
||||
- **Jefferson Avenue:**
|
||||
- Die Straße ist mit Mittellinie da, die beiden Gebäude sind weg.
|
||||
- `alley_cut` gehört nicht mehr zur Straßenfläche, die Fahrbahnen der Querstraßen bleiben unversehrt.
|
||||
- Frei gewordene Flächen sind `urban`.
|
||||
- **Parkdatei:** Jeder Formfehler bricht mit Dateiname und Feld ab. Liegt eine Spielecke weiter als 2 m von einer Straße, bricht der Lauf ab.
|
||||
- **`test_emit.py`:** Das Schema enthält `paths` und die neuen Flächenarten.
|
||||
- **`test_overview.py`:** Wege und neue Flächenarten erscheinen im Kartenbild, die eingecheckten Kartendateien passen zu den eingecheckten Chunks.
|
||||
|
||||
### vitest
|
||||
|
||||
- **`tests/geometry.test.js`:** `paths` und die neuen Flächenarten werden gebaut, Flächen zeigen nach oben.
|
||||
- **`tests/materials.test.js`:** Neue Schlüssel und neue Reihenfolge, streng steigende Versätze. `court` und `pool` stehen in der Farbliste.
|
||||
- **`tests/streaming.test.js`:** Die neuen Schichten landen in der Szene, aber nicht in der Kollisionsgruppe.
|
||||
- **`tests/placesSite.test.js`:** Mit den neuen Daten bleibt der Test grün. Neu: Unter Tribüne und Hood Yard liegt kein Punkt einer `paths`-Fläche.
|
||||
- **Neuer Datentest:** Die `keepout`-Einträge in `flamingo-park.toml` stimmen in `at`, `rotation` und `bounds` mit `PLACES` überein. Der Test liest die wenigen Felder aus der TOML-Datei.
|
||||
- **Startpunkt:** `SPAWN` in `src/main.js` (1600 | 690) liegt danach im Park. Ein Datentest prüft, dass er auf Land und in keinem Gebäude liegt; die vier Fahrzeugpunkte liegen weiter auf einer Straßenfläche.
|
||||
|
||||
### Sichtprüfung
|
||||
|
||||
- **Karte:** Minimap-Ausschnitt des Parks neben dem OSM-Bild, Vorher-Nachher.
|
||||
- **Browser:**
|
||||
- Draufsicht auf den Park, Blick entlang des 13th-St-Wegs und die Jefferson Avenue von der 11th Street aus.
|
||||
- Tribüne und Hood Yard stehen an ihren Feldern.
|
||||
- Die Konsole zeigt keine Fehler, Bildrate und Draw Calls im Park werden festgehalten.
|
||||
|
||||
## Fehlerfälle und Risiken
|
||||
|
||||
- **Windows baut die Chunks nicht gleich:** Das zeigt Schritt 2 des Ablaufs. Dann erst die Ursache klären und mit dem Nutzer entscheiden, bevor Daten ersetzt werden.
|
||||
- **Die Extraktion ändert die Straßen um den Park:** Die Sicherheitsprüfung der Ecken bricht den Lauf ab, die Ecken in der Parkdatei werden neu gemessen.
|
||||
- **Einpassung wirkt im Spiel anders als auf der Karte**, etwa zu kleine Felder: Die Werte in der Parkdatei werden nachgestellt, mit Vorher-Nachher-Bild.
|
||||
- **Farben und Tönung passen nicht:** Das wird im Browser abgestimmt, nicht still.
|
||||
- **OpenStreetMap ändert sich:** Der Stand liegt im Repo, ein neuer Abruf ist ein eigener Commit.
|
||||
- **Orte werden verschoben:** Der Datentest zu den Sperrflächen schlägt an.
|
||||
- **Pool ist nur eine Fläche:** bewusst so, ein Becken wäre eine eigene Aufgabe.
|
||||
|
||||
## Nicht Teil dieser Arbeit
|
||||
|
||||
- Bordsteine, Gehwege und Straßenmarkierungen sowie die beiden Kits: Teil 2, mit eigenem Entwurf.
|
||||
- Laternen an Parkwegen, Zäune, Netze, Feldlinien, Poolbecken, Infield-Sand der Baseballfelder.
|
||||
- Bäume außer Palmen, andere Parks.
|
||||
- Die allgemeine Feinkalibrierung (`corrections.toml`).
|
||||
Reference in new issue
Block a user