Skip to content

Arnis v2.7.0-meld.1

Choose a tag to compare

@Teddy563 Teddy563 released this 04 May 21:51
· 338 commits to main since this release

Arnis Meld Fork

A fork of louis-e/arnis v2.7.0 that unlocks country-scale Minecraft world generation. Without any of the new flags, the binary behaves identically to upstream — every addition is opt-in.

What this patch adds

Five new flags that let you stitch many Arnis runs into one giant Minecraft world:

--master-origin-lat / --master-origin-lng

Pin every tile to a shared global origin point. Without this, two adjacent runs both write to r.0.0.mca and overwrite each other. With it, every tile lands at its correct globally-aligned region file, so you can render Romania (or any country) one chunk at a time and have it all line up.

--elevation-min / --elevation-max

Lock the elevation-to-Y mapping to a fixed range. Upstream auto-fits each tile to its local terrain, which means the same hill ends up at different Y heights in adjacent tiles → visible seams. Survey your whole region's elevation once, pass the same min/max to every run, and heights match across borders.

--tile-invariant-rendering [SEED]

Makes every stochastic decision in building rendering deterministic across runs and across adjacent tiles.

  • --tile-invariant-rendering (no value) → seed = 1
  • --tile-invariant-rendering 1 / 42 / etc. → explicit seed (any non-zero u64)
  • omitted → upstream behaviour (process-local thread RNG)

What gets seeded:

  • 10 building decisions per element: wall, floor, window, accent, vertical-window, accent-roof, accent-lines, vertical-accent, gabled, chimney
  • 3 wall-block selectors that previously called rand::rng() directly: get_building_wall_block_for_color, get_fallback_building_block, get_castle_wall_block (now have _seeded variants taking &mut impl Rng)
  • Pre-clip building metrics (unclipped_bounds, unclipped_polygon_area on ProcessedWay) drive every dimension/diagonality/skyscraper decision so a building straddling two tiles renders identically in both

Two runs passing the same SEED produce byte-identical building palettes regardless of which tile rendered which OSM element first. Two runs with different seeds produce different (but each internally deterministic) palettes.

--overpass-url

Point Arnis at a self-hosted Overpass mirror (or a comma-separated failover chain). Public mirrors throttle hard at ~2 connections per IP — running 12+ parallel workers for a country-scale job hits 90% failure rate. With a local Docker Overpass, that goes to zero.

--road-detail max | clean | compact

Controls how road detail is rendered to fight visual noise from OSM road features stacking onto the same blocks. Three modes, each tuned for a different render scale:

  • max (default) — upstream byte-identical. Full multi-lane width, dense lanes-1 dashed dividers, all footways/crossings rendered. Best at scale ≥ 1.0 with sparse OSM data; visual escape hatch when clean produces a look you don't like.
  • clean — for scale ≥ 0.7. Caps lane dividers to {1, 2}: lanes ≤ 4 gets one centre stripe, lanes ≥ 5 gets twin centre stripes 1 block apart (reads as a divided highway). Suppresses dividers on service / service=parking_aisle / pedestrian-grade highways and on roads narrower than 4 blocks. Same OSM coverage as max, just the divider geometry is cleaner.
  • compact — for scale < 0.7. Single centre stripe regardless of OSM lanes, dash period floored at 4-on/4-off (was halved with scale → checker noise), drops pedestrian highway types entirely AND trims them from the Overpass query (~30–50% smaller payload).

Multi-tile schedulers (Meld) auto-resolve based on project scale: compact below 0.7, clean above. Pin per-project to override.

The earlier none value was removed in favour of these three; for terrain-only worlds, omit --road-detail and pre-filter OSM input.

Visual cleanup

Independent of the multi-tile flags, this release fixes rendering issues at lower scales:

  • Crosswalks now use a 2-on/2-off stripe pattern (was 1/1, which collapsed into a solid white bar from any distance) and stay inside the footway bounding box instead of bleeding onto adjacent sidewalks.
  • Lane dividers are gated by lane count and road type — narrow service roads, parking aisles, and pedestrian highways no longer get painted dividers, and wide boulevards get a clean twin-stripe instead of 4–7 evenly-spread lines.
  • Lane dividers width-gate — roads narrower than 4 blocks total (most service streets, narrow turn lanes, one-way alleys) skip the centre stripe entirely in clean and compact. A 3-block road has only 1 cell either side of centre, so a dashed centre stripe leaves no visible asphalt — looks like a single-block dashed path, not a road.
  • Parking lots use black concrete for driving lanes and gray for parking spaces; the parking renderer's overwrite whitelist now includes WHITE_CONCRETE, so road dividers painted on cells before the parking flood-fill pass get correctly erased. Render order: highways at data_processing.rs:172 → amenities at :197.
  • Building tile invariance — the 3 wall-block helpers (get_building_wall_block_for_color, get_fallback_building_block, get_castle_wall_block) no longer call rand::rng() directly, so buildings straddling tile boundaries pick the same blocks in both tiles.

Combined example: country-scale Romania run

arnis \
  --bbox 44.40,26.05,44.45,26.10 \
  --output-dir /path/to/master_world \
  --scale 0.5 \
  --master-origin-lat 45.9432 --master-origin-lng 24.9668 \
  --elevation-min -440 --elevation-max 2157 \
  --tile-invariant-rendering 1 \
  --overpass-url http://localhost:12345/api/interpreter \
  --road-detail compact

Every tile lands at a globally-correct .mca index, terrain heights align across boundaries, building palettes match across tile seams via the seeded RNG streams, OSM data fetches from a self-hosted Overpass mirror at zero rate-limit, and pedestrian-grade road noise is suppressed at the chosen scale.

Compatibility

  • Drops in as a binary swap (arnis-windows.exe) — no scheduler-side config needed.
  • Single-tile users who don't pass any new flags get upstream-byte-identical output.
  • World save format unchanged (same Java / Bedrock writers as upstream).
  • All changes are additive — any patch in this fork should land cleanly on louis-e/arnis main if accepted upstream.

Companion: Meld scheduler

This binary is designed to drop into Teddy563/meld, a Python scheduler that automates country-scale generation by computing per-tile bboxes, surveying global elevation once, holding the master-origin invariant, and emitting all the new flags automatically. Standalone CLI use works fine too.

Build provenance

  • Source: Teddy563/arnis @ d07412e
  • Toolchain: Rust stable
  • Profile: cargo build --release
  • Binary size: 37,291,008 bytes
  • Platform: Windows x64

Verifying the binary

arnis --help | grep -E "master-origin|elevation-min|elevation-max|tile-invariant-rendering|overpass-url|road-detail"

Expect seven flags in the output.


License: Apache-2.0 (inherited from upstream).
Credits: Upstream Arnis by @louis-e and contributors. Meld fork patches by @Teddy563.