Arnis

repository·main·Indexed 12 days ago

https://github.com/louis-e/arnis

A tool for generating realistic Minecraft Java Edition (1.17+) and Bedrock Edition worlds using real-world geospatial and elevation data from OpenStreetMap and Overture Maps. It features a GUI and a CLI for creating detailed representations of cities, hometowns, and natural landscapes, with support for custom scales, interior generation, and vegetation tiers.

Tokens
15.1K
Snippets
57
Records
76
Agent score
97%

What's inside Arnis

  1. Overview of Arnis

    main

    Arnis is a tool that generates complex and accurate Minecraft Java Edition (1.17+) and Bedrock Edition worlds based on real-world geography, topography, and architecture. It processes geospatial data from OpenStreetMap and elevation data to create detailed representations of terrain and buildings.

    Key Features:

    • Generates hometowns, cities, and natural landscapes.
    • Uses OpenStreetMap (OSM) for architecture and roads.
    • Uses elevation data for realistic terrain.
    • Supports both GUI and Command Line interfaces.

    Note: For mobile generation or larger map sizes, use MapSmith.

  2. Understand tree pack size tiers and height constraints

    main

    Arnis organizes tree packs into size tiers based on their height (measured in blocks). When building, any trees taller than 40 blocks are dropped.

    Height Tiers:

    • small: $\le$ 6 blocks
    • medium: 7-12 blocks
    • big: 13-20 blocks
    • tall: 21-28 blocks
    • giant: 29-40 blocks

    Metrics: Counts are provided as SPECIES (distinct species) / SCHEMS (variants).

    Rendering Note: Tier toggles are managed via the Meld 'Trees' card. The giant tier is OFF by default and only renders at a 1:1 scale. The tall tier is considered rare.

  3. Build and run Arnis via Command Line

    main

    Arnis can be built and run using cargo. You can choose between a GUI build or a headless command-line build.

    GUI Build

    To launch the graphical interface:

    cargo run --release

    Command Line Build

    To run a headless generation with specific parameters:

    cargo run --release --no-default-features -- --output-dir="C:/YOUR_PATH/.minecraft/saves/worldname" --bbox="min_lat,min_lng,max_lat,max_lng"

    Run with Nix

    If you are using Nix, you can run the program directly:

    nix run github:louis-e/arnis -- --output-dir=YOUR_PATH/.minecraft/saves/worldname --bbox="min_lat,min_lng,max_lat,max_lng"
  4. Use Arnis via the GUI

    main

    The Graphical User Interface (GUI) allows for an interactive world generation experience:

    1. Select Area: Use the rectangle tool on the map to choose your desired geographic area.
    2. Select World: Choose your target Minecraft world.
    3. Customize Settings: Adjust parameters such as world scale, spawn point, or building interior generation.
    4. Generate: Click Start Generation to begin the process.
  5. Supported World Formats

    main

    Arnis supports three primary world formats. The format is determined by the CLI flags provided:

    • Java Edition: The default format. Creates a new world in the specified directory. Supports an optional --disable-height-limit flag to install a tall-world datapack (requires Minecraft 1.21.4+).
    • Bedrock Edition: Triggered via --bedrock. Generates a .mcworld file. The output directory defaults to the user's Bedrock output directory if --path is not provided.
    • Luanti (formerly Minetest): Triggered via --luanti. Creates a world in the Luanti worlds directory. Supports specific game logic via the --luanti-game option (e.g., Mineclonia).
  6. How ElevationProvider selection works

    main

    When selecting an elevation provider, Arnis uses several signals from the ElevationProvider trait:

    1. Coverage: The system checks coverage_bboxes() to see if the requested area is supported. If coverage_bboxes() returns None, the provider is treated as a global fallback.
    2. Acceptance: The accepts(&LLBBox) method allows a provider to decline a request. This is useful for rate-limited providers that may want to reject oversized bounding boxes, allowing the selector to fall through to the next available candidate.
    3. Resolution Ranking: Providers are ranked based on the value returned by native_resolution_m(). A lower value (higher resolution) is preferred.
  7. Merge sections with different authority rules

    main

    The world editor provides three distinct strategies for merging sections, depending on whether the data is considered 'authoritative' or part of a 'halo' (non-authoritative) zone:

    1. merge_section_write_if_air: Used for halo data. It only writes to the destination if the current block is AIR. It does not perform coordinate checks.
    2. merge_section_auth_overwrite_nonair: Used when a section is within an authoritative tile but the destination already contains halo data.
      • Non-AIR blocks from the authoritative tile always overwrite the destination.
      • If the authoritative tile has AIR at a position, the existing halo data is preserved.
    3. merge_section_with_auth_check: The slow path for partial overlaps. It performs per-block coordinate checks against authoritative bounds (auth_min_x, auth_min_x, etc.). A block is written if it is within the authoritative bounds OR if the destination cell is currently AIR.
  8. How Arnis works: Core Workflow

    main

    Arnis is a tool for generating Minecraft-style worlds (Java, Bedrock, or Luanti) from real-world geographic data. The generation process follows these high-level stages:

    1. Bounding Box Resolution: Determines the geographic area to process. Precedence: explicit --bbox > local .osm/.xml file < <bounds> element in OSM data < node-coordinate extent.
    2. Data Fetching: Parallel fetching of OpenStreetMap (OSM) data via Overpass, Overture Maps building data, and terrain/land-cover data.
    3. Data Parsing & Merging: OSM data is parsed and merged with Overture building footprints. Elements are sorted by priority.
    4. Land Cover Repair: OSM water overrides and bridge-shadow repairs are applied to the terrain data.
    5. Map Transformation: Applies transformations like rotation and coordinate projection.
    6. World Generation: Converts the processed geographic and object data into the target world format (Java Anvil, Bedrock .mcworld, or Luanti worlds).
  9. How water distance is computed

    main

    The compute_water_distance function generates a distance-to-shore field using a multi-source Breadth-First Search (BFS).

    This is used for shoreline blending (e.g., assigning sand surfaces to land cells adjacent to water). The resulting grid values are:

    • 0: Non-water cell (or unreachable water).
    • 1: Water cell on the shore (adjacent to non-water or the grid edge).
    • 2+: Water cell $N$ blocks from the nearest shore.

    The depth is capped at 15 to prevent excessive computation for large bodies of water.

  10. Understand Generation Modes in Arnis

    main

    Arnis uses GenerationMode to determine how terrain and objects (from OpenStreetMap or Overture Maps) are composed. You can control this via the --mode flag.

    • geo-terrain (Default): Combines real elevation data with OSM/Overture objects. This is the standard 'realistic' mode.
    • geo-only: Places OSM/Overture objects on a flat ground plane. Use this if you want objects without elevation changes.
    • terrain-only: Generates real elevation terrain but skips all OSM and Overture objects entirely. This mode always requires a --bbox argument, even if you provide a --file.

    Note: The legacy --terrain flag is a no-op that defaults to geo-terrain behavior to maintain compatibility with older scripts.

    # Example: Generate only terrain without any OSM objects
    arnis --bbox 1,2,3,4 --mode terrain-only --output-dir ./my_world
    
    # Example: Generate objects on flat ground
    arnis --bbox 1,2,3,4 --mode geo-only --output-dir ./my_world
  11. Use SparseBytes for efficient Parquet row-group downloads

    main

    The SparseBytes struct implements a memory-efficient way to read Parquet files by only storing pre-fetched byte ranges. This is designed for scenarios where you want to download only the file footer and specific row groups (e.g., ~4-5 MB) instead of the entire partition file (e.g., ~580 MB).

    Workflow:

    1. Initialize with SparseBytes::new(file_size).
    2. Use add_range(offset, data) to add fetched chunks.
    3. Call finalize() to sort the ranges by offset.
    4. The struct implements ChunkReader, allowing it to be used with Parquet readers to access only the cached segments via get_read or get_bytes.
    struct SparseBytes {
        file_size: u64,
        ranges: Vec<(u64, bytes::Bytes)>,
    }
  12. 3DMR client cache location

    main

    The 3DMR client uses an on-disk cache for both .json metadata and .glb files. The cache directory is determined as follows:

    • It attempts to use the standard system cache directory via the dirs crate, appending the subdirectory arnis/3dmr.
    • If a system cache directory cannot be determined, it defaults to ./.arnis_3dmr_cache in the current working directory.