Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions docs/arnis-city-parity-todo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Arnis City Parity TODO

Goal: make Tellus generate city detail classes comparable to Arnis for the same OSM area, while keeping Tellus in charge of projection, terrain, chunk lifecycle, cache reuse, and WLB proxy routing.

Done means feature-class parity, not byte-identical `.mca` output. For example, New York should have terrain, roads, buildings, bridges/tunnels, parks/water, barriers, city props, and building details generated from OSM in-game without requiring a prewritten Arnis world.

## Ground Rules

- Keep the existing `tellus/cache/map/arnis-overpass/` raw OSM cache reusable across updates.
- Missing OSM data should try direct routes first through the WLB rule proxy; do not force paid VPN traffic.
- Add detail through neutral feature contracts first, then adapt into Tellus worldgen.
- Prefer capped, cache-first behavior for every new data family.
- Keep original Tellus Overture/PMTiles sources as fallback when OSM cache or network is missing.

## Arnis Element Inventory

Status meanings: `Done` is implemented in Tellus; `Partial` is visible but less detailed than Arnis; `Todo` is not implemented yet; `Watch` needs validation because data volume or geometry can be risky.

| Arnis module | OSM tags / behavior | Tellus status | Next task |
| --- | --- | --- | --- |
| `buildings.rs` | `building`, `building:part`, multipolygon shells, materials, roof shapes, storefront facades | Partial | Improve part stacking and Arnis-like interiors. |
| `buildings_interior.rs` | Room templates, stairs, beds, crafting/furnace/bookshelf/anvil/abandoned variants | Todo | Add opt-in simple interior pass for safe large buildings. |
| `doors.rs` | `door=*`, `entrance=*`, ground-level doors | Done | Validate snapping in dense downtown blocks. |
| `highways.rs` | `highway=*`, lanes, surface, sidewalks, zebra crossings, traffic signals, street lamps, bus stops, bridges/tunnels/layers | Partial | Tunnel portals remain; tunnel side shell/lighting exists. |
| `bridges.rs` | `bridge=*`, raised deck, ramps, edge rails/supports | Done | Validate long river bridges visually. |
| `railways.rs` | `railway=rail/light_rail/subway/tram`, slope rails, subway shells, crossing/tram-stop nodes | Partial | Surface rails and crossing/tram-stop markers exist; subway/tunnel shells remain. |
| `barriers.rs` | `barrier=*`, `fence_type`, `material`, `height`, bollard/gate nodes | Done | Validate gate replacement against dense barrier lines. |
| `amenities.rs` | parking, bicycle parking, bench, shelter, fountain, recycling, waste, vending/ATM, drinking water, fuel | Partial | Fountain/parking area shape and recycling metadata remain optional tuning. |
| `advertising.rs` | column, flag, poster box | Done | Validate density and collision. |
| `emergency.rs` | fire hydrant | Done | Validate density and underground filtering. |
| `historic.rs` | memorial, monument, wayside cross | Done | Add more subtype palettes if needed. |
| `tourisms.rs` | information boards | Done | Add map/guidepost subtype palettes if needed. |
| `man_made.rs` | pier, antenna/mast, chimney, water well, water tower | Done | Validate large towers against build height. |
| `power.rs` | power poles/towers/lines/minor lines | Done | Validate spacing and visual scale. |
| `tree.rs` | Arnis tree shapes, species/genus/leaf type | Done | Continue visual tuning for wild forests. |
| `landuse.rs` | grass, meadow, forest, orchard, farmland, cemetery, construction, traffic island, education, religious, industrial, military, railway, vineyard, brownfield, landfill, quarry | Partial | Selectors and first-pass props exist; visual density tuning remains. |
| `leisure.rs` | park, garden, nature reserve, golf/disc golf, schoolyard, playground, recreation ground, pitch, beach resort, dog park, pool, seating, water park, slipway, ice rink | Partial | Selectors and first-pass props exist; visual density tuning remains. |
| `natural.rs` | tree, wood, tree row, scrub, heath, grassland, beach/sand/dune/shoal, wetland, bare rock/scree/blockfield, mud, glacier, ridge/cliff/saddle/tundra/shrubbery | Partial | Selectors and first-pass surface/detail palettes exist; validation remains. |
| `surfaces.rs` | `surface=*` palettes for asphalt, gravel, wood, sand, tartan, grass, dirt, bricks, paving stones | Partial | Extend area/road surface palette where Tellus still falls back. |
| `waterways.rs` | river/canal/stream/ditch/drain with width and layer filters | Partial | Current light water traces exist; add width-aware channels when safe. |
| `water_areas.rs` | water multipolygons with inner islands | Partial | Current water areas exist; validate complex relation clipping. |

## P0 Data And Cache

- [x] Add neutral external feature source for roads/buildings.
- [x] Add automatic Overpass source with raw JSON cache.
- [x] Add cache estimate and capped warm-up actions to the world UI.
- [x] Preserve WLB proxy routing by using JVM networking.
- [x] Extend the neutral model to OSM line/area city details beyond roads/buildings.
- [x] Expand the Overpass query toward Arnis element families without making downloads unbounded.
- [x] Show expanded city-detail cache estimates in the UI.
- [x] Add OSM point city details for traffic signals, crossings, selected amenities, and trees.
- [x] Add OSM point city details for entrances and door nodes.
- [ ] Keep expanding cache profile in small versioned steps (`city-vN`) so raw cache remains reusable and new sidecars refresh in place.

## P1 Roads

- [x] Preserve road OSM tags on Tellus `RoadFeature`.
- [x] Use `surface=*` to distinguish paved paths and unpaved roads.
- [x] Use `lanes=*` to widen paved roads.
- [x] Render sidewalks from `sidewalk=*`.
- [x] Render dashed lane markings for multi-lane paved roads.
- [x] Add crossings and traffic signals.
- [x] Add street lamps and bus stop markers from Arnis `highways.rs`.
- [x] Add bridge edge rails beyond deck height/supports.
- [x] Add tunnel side shell and ceiling lights beyond current carving.
- [ ] Add explicit tunnel portal/headwall details at road tunnel mouths.
- [x] Add rail-related crossings.
- [x] Add rail line rendering from OSM `railway=*`.
- [x] Add barriers/guardrails/fences along OSM barrier lines.
- [x] Add barrier point nodes: bollards, blocks, gates, entrances, stiles.

## P1 Buildings

- [x] Preserve building tags through the external adapter.
- [x] Use building wall material and color tags.
- [x] Use roof material, color, shape, roof height, and roof levels.
- [x] Add entrances and doors from OSM `entrance=*` / `door=*` nodes.
- [ ] Improve building-part stacking and vertical alignment for dense downtown areas.
- [ ] Add simple Arnis-like interiors for accessible buildings.
- [x] Add OSM-aware windows/storefront variation for commercial buildings.

## P1 Areas And Surfaces

- [x] Add parking lots with surface material and painted parking markings.
- [x] Add landuse surfaces such as grass, residential, industrial, farmland, cemetery, and construction.
- [x] Add leisure surfaces such as parks, pitches, tracks, playgrounds, and gardens.
- [x] Add natural surfaces such as wood, scrub, heath, beach, wetland, rock, and scree.
- [x] Add water areas and waterways from OSM where they improve city-scale detail.
- [x] Add Arnis-style farmland crops/water points/hay bales.
- [x] Add Arnis-style cemetery graves/flowers/fence feel.
- [x] Add Arnis-style construction/quarry/brownfield/landfill clutter.
- [x] Add Arnis-style playground, pitch, pool, schoolyard, and parking-lot props.
- [x] Expand selectors for missing Arnis landuse/leisure/natural area types without making Overpass fetches unbounded.

## P2 City Props

- [x] Add amenity nodes/areas with high visual value: benches, bicycle parking, fuel, fountains, shelters.
- [x] Add tourism/historic/man_made/emergency/power/advertising feature families where Arnis renders them.
- [x] Add Arnis-style OSM natural tree nodes with species/genus/leaf-type selection.
- [x] Add tree distribution from OSM natural/landuse/leisure areas with building/road avoidance.
- [x] Replace coarse wild forest trees with the shared Arnis-style tree shapes.
- [x] Add street furniture placement that respects roads by shifting road-center OSM nodes to nearby non-road anchors.
- [ ] Add stronger building/sidewalk collision validation for street furniture after visual smoke tests.

## P3 Validation

- [ ] New York Manhattan smoke area: cache estimate, warm-up, generation, and visual pass.
- [ ] Dense European city smoke area with multipolygon buildings and narrow streets.
- [ ] Domestic-network pass: confirm direct routes are used when available and proxy/VPN only covers unreachable hosts.
- [ ] Cache-only pass: restart with `-Dtellus.arnis.overpass.network=cache-only` and confirm cached city details still render.
- [ ] Build and replace active WLB mod jar after each stable slice.
174 changes: 174 additions & 0 deletions docs/wlb-arnis-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# WLB Arnis Integration

This branch keeps the Tellus chunk generator as the owner of terrain, projection, caching, and block placement. Arnis should be integrated at the feature/rule layer, not by merging generated region files.

## Project Placement

The working copy lives under:

```text
/home/kaijie/桌面/WorkLifeBalance/你在这里搞个项目/minecraft-mods/tellus-arnis-integration
```

This matches the WorkLifeBalance workspace convention: source projects stay in `你在这里搞个项目/`, Minecraft mod projects stay in `minecraft-mods/`, and built jars are copied separately to `../../.minecraft/mods/`.

## Integration Boundary

The first stable boundary is:

```text
ExternalFeatureSource
-> ExternalRoadFeature
-> ExternalBuildingFeature
-> ExternalAreaFeature
-> ExternalLineFeature
-> GeoBounds / GeoPoint
-> ExternalFeatureAdapters
-> JsonExternalFeatureSource
-> OverpassExternalFeatureSource
```

This gives Tellus one neutral input shape for external real-world features. The first adapters can be:

- `OverpassExternalFeatureSource`: reads OSM roads/buildings/city details from Overpass with the same bbox-style data source family used by Arnis.
- `ArnisJsonFeatureSource`: reads an Arnis/exporter-produced JSON or GeoJSON feature dump for offline overrides.
- Later: `ArnisProcessFeatureSource`: runs an Arnis-side exporter as a local process for a requested bbox.

The current JSON source accepts this shape:

```json
{
"roads": [
{
"source": "arnis",
"sourceId": "road-1",
"roadClass": "MAIN",
"mode": "NORMAL",
"bridgeLevel": 0,
"highwayTag": "primary",
"points": [{"lat": 35.0, "lon": 139.0}, {"lat": 35.001, "lon": 139.001}],
"tags": {"surface": "asphalt", "lanes": "4", "sidewalk": "both"}
}
],
"buildings": [
{
"source": "arnis",
"sourceId": "building-1",
"kind": "FOOTPRINT",
"heightMeters": 8.0,
"minHeightMeters": 0.0,
"floorCount": 2,
"rings": [[
{"lat": 35.0, "lon": 139.0},
{"lat": 35.0, "lon": 139.001},
{"lat": 35.001, "lon": 139.001},
{"lat": 35.001, "lon": 139.0},
{"lat": 35.0, "lon": 139.0}
]],
"tags": {"building": "house", "building:material": "brick", "building:colour": "white", "roof:material": "tile", "roof:colour": "red"}
}
]
}
```

The same file can also include optional `areas`, `lines`, and `points` arrays for offline city-detail overrides. `areas` use `kind` values such as `PARKING`, `LANDUSE`, `LEISURE`, and `NATURAL`; `lines` use `kind` values such as `BARRIER` and `RAILWAY`; `points` use `kind` values such as `TRAFFIC_SIGNAL`, `CROSSING`, `AMENITY`, and `NATURAL`.

## Runtime File

The game-side loader now has two inputs:

1. Automatic Overpass/OSM source, enabled by default.
2. Optional local JSON override/extension file.

For normal use, no JSON file is required. When a chunk needs road/building/city-detail data, Tellus calculates the chunk's geographic bbox, fetches matching OSM `highway`, `building`, `building:part`, `amenity=parking`, selected `landuse`, `leisure`, `natural`, `barrier`, and `railway` ways/relations plus selected OSM city nodes from Overpass, caches the response under:

```text
<gameDir>/tellus/cache/map/arnis-overpass/
```

If the Overpass source returns usable features for a chunk, Tellus prefers that Arnis-style OSM source over the original Overture road/building PMTiles for that chunk. If the Overpass source returns nothing or fails, Tellus falls back to the original Overture source. Building and area relations/multipolygons are supported by merging outer/inner member way geometry into rings before handing the feature to Tellus.

Older road/building cache files remain usable. City-detail data uses a `city-v4` sidecar profile next to the existing raw tile cache. If a tile was cached before city details existed, the UI warm-up or first in-game city-detail query upgrades that tile in place instead of invalidating the whole cache. The `city-v4` profile adds Arnis-style vegetation inputs such as OSM forest/orchard landuse and extra natural area tags.

The optional local file is still supported at:

```text
<gameDir>/tellus/external-features.json
```

For the current WLB instance that means:

```text
/home/kaijie/桌面/WorkLifeBalance/.minecraft/tellus/external-features.json
```

It can also be overridden with `-Dtellus.external.features.path=/path/to/external-features.json`.

Useful runtime switches:

```text
-Dtellus.arnis.overpass.enabled=false
-Dtellus.arnis.overpass.network=cache-first
-Dtellus.arnis.overpass.network=cache-only
-Dtellus.arnis.overpass.maxNetworkTilesPerSession=96
-Dtellus.arnis.overpass.prefetchMaxTiles=32
-Dtellus.arnis.overpass.endpoints=https://overpass-api.de/api/interpreter,https://overpass.osm.ch/api/interpreter,https://overpass.kumi.systems/api/interpreter
-Dtellus.map.tile.endpoints=https://tile.openstreetmap.org/%d/%d/%d.png,https://tile.openstreetmap.de/%d/%d/%d.png
-Dtellus.external.features.prefer=false
```

Network behavior is intentionally conservative to avoid burning VPN traffic:

- `cache-first` is the default. Existing cached OSM tiles are used without network; missing tiles may be fetched.
- `cache-only` never fetches missing tiles. It only uses `<gameDir>/tellus/cache/map/arnis-overpass/`, then falls back to Overture.
- `off` disables the Overpass source.
- `maxNetworkTilesPerSession` caps missing-tile downloads per game process. The default is `96`; after that, Tellus skips more Overpass requests and falls back.
- `prefetchMaxTiles` caps each UI cache warm-up batch. The default is `32`, so the button never starts an unbounded city download.
- Overpass endpoints are tried with per-endpoint cooldown. If one public source times out or rate-limits, it is skipped for a short period instead of delaying every following tile.
- Empty Overpass responses are still treated as a completed city-detail cache entry. This prevents empty ocean or low-detail tiles from being downloaded repeatedly.
- The spawn/world map tile loader also supports multiple raster tile endpoints through `tellus.map.tile.endpoints`; tile failures are written to the Tellus traffic log.

The world customization UI has a Data Sources entry named `Test OSM connectivity`. It sends a tiny Overpass query to each configured endpoint from the current computer and reports how many endpoints are reachable plus per-endpoint timing in the tooltip. This is intended for checking whether the current network can direct-connect before spending cache/download budget.

The same Data Sources section also has `Estimate OSM cache` and `Warm missing OSM cache`. The estimate uses the current spawnpoint and the Voxy pregen radius as the target area; when Voxy pregen is disabled it estimates a conservative 96-chunk spawn radius. It reports cached/missing raw Overpass tiles and compressed cache size. The warm-up button downloads only a capped batch of missing raw OSM tiles and reuses the existing WLB `127.0.0.1:18127` rule proxy, so direct-classified sources still avoid paid VPN traffic.

## Current Arnis-Style Rules

- OSM road tags are preserved on `RoadFeature`.
- `lanes=*` and `lanes:forward/backward` widen paved roads instead of using only the Tellus road class width.
- `sidewalk=*`, `sidewalk:left`, `sidewalk:right`, and `sidewalk:both` widen paved roads and paint smooth-stone sidewalk edge strips.
- unpaved surfaces such as `gravel`, `ground`, `dirt`, `sand`, and `mud` use the dirt-path road material.
- paved `footway`, `pedestrian`, and `cycleway` features render as smooth-stone paths when they are not explicitly unpaved.
- paved roads with at least two lanes get dashed white lane markings.
- `building:material`, `facade:material`, and `material` feed the building wall palette.
- `building:colour`, `facade:colour`, and `colour` feed the building wall color palette.
- `roof:material` feeds the roof palette, `roof:colour` feeds the roof color palette, and `roof:shape` still controls flat/gabled/hipped profiles.
- `height`, `building:height`, `building:levels`, `roof:height`, and `roof:levels` feed building and roof massing. Parsed Overture building cache version was bumped so older parsed tiles without roof height metadata are rebuilt.
- `amenity=parking` areas render as paved lots with painted parking stripes.
- selected `landuse`, `leisure`, and `natural` areas render as grass, dirt/gravel construction ground, cemetery moss, pitches, tracks, playgrounds, beaches, wetlands, rock, scree, wood, scrub, and heath surfaces.
- OSM forest, orchard, wood, tree-row, scrub, heath, grassland, wetland, parks, and gardens receive deterministic Arnis-style vegetation such as trees, shrubs, ferns, dead bushes, and rocks while avoiding roads/buildings.
- selected OSM `water=*`, `natural=water`, and `waterway=*` features render lightweight water surfaces/traces for city-scale ponds, canals, streams, ditches, and drains.
- OSM `barrier=*` lines render as fences, walls, hedges, guard rails, or iron-bar barriers when they do not collide with roads/buildings.
- OSM `railway=rail|light_rail|subway|tram` lines render as rail traces where the current surface can accept them.
- OSM `highway=traffic_signals` and `highway=crossing` nodes render traffic signal props and crosswalk stripes.
- OSM `entrance=*` / `door=*` nodes try to place actual building doors by snapping to a nearby safe facade column.
- selected OSM `amenity=*` nodes render benches, bicycle parking/shelter bars, fountains, and fuel markers.
- OSM `natural=tree` nodes render Arnis-style oak/spruce/birch/dark-oak/jungle/acacia trees, selecting species from `species`, `genus`, `genus:wikidata`, and `leaf_type` tags where available.

## Why Not Merge Arnis Region Files

Arnis is an offline world writer. Tellus is a Fabric chunk generator. Their final `.mca` output cannot be safely overlaid without solving projection alignment, terrain base height, feature ordering, chunk lifecycle, and collision handling. Keeping Tellus as the block-placement owner avoids those issues.

## Development Phases

1. Add neutral feature contracts and keep existing behavior unchanged.
2. Wrap current Overture road/building features behind the neutral contracts.
3. Add an Arnis JSON/GeoJSON adapter for roads and buildings.
4. Port Arnis styling rules into Tellus profiles:
- road `surface`, `lanes`, lane markings, pedestrian paths, bridge/tunnel hints;
- building category, material palette, roof shape, doors, simple interiors.
5. Wire source selection behind settings after the adapters are validated.

## License Notes

Tellus is LGPL-3.0. Arnis is Apache-2.0. Porting algorithms and interoperating through a data format is the lowest-risk path. If code is copied directly, keep copyright notices and review compatibility before upstream submission.
Loading