A networked 3D virtual world built with Rust and Bevy. https://cartopolis.org
  • Rust 92.6%
  • TypeScript 4.9%
  • CSS 0.6%
  • Shell 0.5%
  • HTML 0.5%
  • Other 0.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
viberfox-agent 1ba25f569d
All checks were successful
CI / test cartopolis (push) Successful in 17m28s
CI / wasm & android targets (push) Successful in 2m36s
perf(web): keep parsing off the browser's main thread
In the web build the IoTaskPool is the page's main thread: every future
runs there between frames, and so did the CPU work those futures did
after a fetch. Over Groningen a basemap tile spent 3–6 s getting its
payload and 0.3–0.4 s being drawn and compressed; the payload's steps
only advance in the gaps between frames, which ran 0.3–1.9 s during a
cold load on the Deck.

- workers::compute runs a closure on the worker pool and awaits the
  answer on the web, and runs it in place natively, where the io pool is
  sixteen real threads.
- CellSource parses through it, which covers the BGT paving (3.8 MB on
  a dense cell), the crops and the roof colours; so do load_bag_cell and
  load_berths (the buildings file is 1.9 MB) and the land-cover parse
  every basemap tile waits for.
- lod22 fetched and parsed its street tile on the main thread before
  handing the cell to a worker; it now hands the bytes over and parses
  on the worker.
- parse_shared held one lock across every parse, so the workers took
  turns, and the main thread, which spins on a contended lock rather
  than parking, froze for as long as any worker's unrelated parse took.
  Each source now has its own slot: different sources parse in
  parallel, the same one is still parsed once. A test holds that.

The "tile fill" log line gains stages_ms, each tile's mean payload,
worker wait, draw and pack times since the last line.
2026-10-13 19:39:17 +00:00
.cargo feat(perf): fly scenarios N times and report median and range (#295) 2026-09-30 09:47:37 +00:00
.claude/skills docs: say node, not slot, for midas build nodes 2026-10-13 13:16:03 +00:00
.forgejo/workflows feat(web): Community | World | Admin in one page, and remove the autopilot 2026-10-11 18:46:29 +00:00
assets feat(brand): the pin on a street plan replaces the tower cluster 2026-10-10 18:35:31 +00:00
crates perf(web): keep parsing off the browser's main thread 2026-10-13 19:39:17 +00:00
deploy feat(web): Community | World | Admin in one page, and remove the autopilot 2026-10-11 18:46:29 +00:00
docs docs: note the RTK receiver, its caster and its safety gates 2026-10-13 21:11:58 +02:00
tools fix(web): give the browser's shared fetch limit room for the basemap 2026-10-12 18:54:03 +00:00
.git-blame-ignore-revs build: gate rustfmt in CI, and keep git blame readable across the reformat 2026-08-06 17:20:50 +02:00
.gitattributes refactor(brand): rename viberfox to cartopolis, cool the surface ramp 2026-08-11 17:52:22 +00:00
.gitignore refactor(brand): rename viberfox to cartopolis, cool the surface ramp 2026-08-11 17:52:22 +00:00
AGENTS.md docs: add a contributor guide and point the entry points at it 2026-07-27 23:52:47 +02:00
Cargo.lock feat(nav): take the position from an external RTK receiver 2026-10-13 21:11:58 +02:00
Cargo.toml feat(gnss): add a crate for an external RTK receiver 2026-10-13 21:11:58 +02:00
CHANGELOG.md docs(changelog): note the tarmac that stopped being drawn on the squares 2026-09-12 12:42:23 +00:00
CLAUDE.md docs: note the RTK receiver, its caster and its safety gates 2026-10-13 21:11:58 +02:00
LICENSE refactor(brand): rename viberfox to cartopolis, cool the surface ramp 2026-08-11 17:52:22 +00:00
LICENSE-APACHE feat(android): behave like an app the system can suspend, and answer Back 2026-08-10 22:27:18 +00:00
LICENSE-MIT refactor(brand): rename viberfox to cartopolis, cool the surface ramp 2026-08-11 17:52:22 +00:00
LICENSE-THIRD-PARTY.md feat(satellites): draw every satellite round the globe, and follow one 2026-10-08 23:35:56 +00:00
README.md docs(readme): cut it down to bullets 2026-09-27 20:26:38 +00:00

Cartopolis

A social map of the real world: see how a place is built, and talk about it with the people who are there.

Groningen city centre, built from open public data

A walkable 3D copy of the real world, built from open public data and shared between everyone looking at it. Runs in the browser, on the desktop and on Android. Free, open source, self-hostable.

Public infrastructure

  • Built from the registers — buildings from BAG and 3DBAG, ground from AHN, street trees, lighting and paving from the national and municipal object registers, PDOK aerial photography, live transit.
  • Every building has a card — year built, use, units, floor area, status, monument listing, addresses. Walk in and its storeys are there.
  • The world around it — real sun, real weather, routing on foot, by bike or by car, and one continuous space from a doorway to orbit.

Sharing a place

  • Talk where you stand — avatars, local chat scoped by distance, proximity voice, world chat, end-to-end encrypted private chats.
  • Point at it — a link opens your exact view in the browser or the app; saved places with photos and map pins.
  • Put something there — place and script objects and 3D models, swap a building for an IFC model, export and import content over an HTTP API.
  • Moderation — blocking, reporting and account deletion, enforced on the server; a web console for accounts and data pipelines.

For residents, communities, municipalities and governments, and planners and architects.

Screenshots

Bird's-eye over Groningen's canal ring The southern ring road in its cut beside DUO
Canal ring Ring road tunnel by DUO
The main station and rail yard from above The Grote Markt and the Martinitoren
Main station and rail yard Grote Markt and Martinitoren
Forum Groningen beside the Martinitoren The town hall selected, with its register card
Forum Groningen Building card: the town hall
Groningen from 3 km south-west The whole city from 1.2 km up
Groningen from 3 km The city from 1.2 km up
Eemshaven's harbour basins and wind turbines Eemshaven from over the Wadden Sea
Eemshaven Eemshaven from the Wadden Sea
Two people meeting on the Grote Markt Earth from orbit
Meeting on the Grote Markt Earth from orbit

Generated with cargo shots from docs/shots.toml.

Where it works

Map, sky, weather, routing and the shared world: anywhere on Earth. Register detail (measured buildings and their records, relief, street objects, aerial photos, transit): the Netherlands, plus municipal data where a city publishes it. Elsewhere the ground is flat and buildings come from OpenStreetMap. Each register is one pipeline in crates/atlas.

Written in Rust on Bevy.

Try it

  • Browser — cartopolis.org. Needs WebGPU.
  • Desktop — Linux and Windows on the releases page, or build from source (macOS too). Published binaries need AVX2 and FMA (~2013+).
  • Android — APK at cartopolis.org/apk (arm64, Android 9+). The full client, least tested of the three (notes).

Running from source

cargo run -p cartopolis

Starts offline. Sign in to a server from ☰ ▸ Sign in….

cargo run -p cartopolis -- --connect <host>        # split mode: connect to a live sim (TLS)
cargo run -p cartopolis -- --offline               # no sim: single user, no auth or persistence
cargo run -p cartopolis_simulator                  # the sim server, standalone

Needs Rust, a C compiler and a GPU driver; see the development guide. Run git lfs install before cloning — assets are in Git LFS and some are compiled in.

Documentation

  • User manual — controls, getting around, authoring, the developer panel.
  • Changelog — what changed, per release.
  • Development guide — prerequisites, dev loop, tests, code map, conventions, CI.
  • Server guide — deploying the sim and the self-hosted geo services.
  • docs/notes/ — constraints and measurements; CLAUDE.md Known issues is the trap list.

Architecture

Crate Role
cartopolis_core Shared protocol types and tile/coordinate math
cartopolis_geo Bevy-free map geodata: MVT decode, road classes, tree scatter, the routing graph
cartopolis_e2ee End-to-end encrypted private chats (MLS); the server relays sealed bytes it cannot open
cartopolis_simulator The shared-world server (Tokio + SQLite): avatars, chat, voice, objects, accounts; no Bevy
cartopolis_atlas The register pipelines (BAG, 3DBAG, AHN, BGT, …), the terrain server and the operator web console
cartopolis Bevy client — rendering, ECS systems, UI
cartopolis_android The Android app shell around the client
big_space Vendored floating-origin fork, for planet-scale coordinates

Licence

Source: MIT OR Apache-2.0 (LICENSE). Data, avatars and font carry their own terms; LICENSE-THIRD-PARTY.md is the canonical notice list (the credits below mirror it — add new sources there).

Credits

  • Engine — built with Bevy.
  • Floating origin — big_space by Aevyrie, MIT OR Apache-2.0. Vendored here as a fork ported to the Bevy release we track.
  • Avatar characters — Quaternius Ultimate Modular Men/Women, CC0. Consider supporting the work on Patreon.
  • Map data — © OpenStreetMap contributors, under the ODbL. Building detail and POIs come from Overpass, place search and reverse geocoding from Nominatim — both self-hosted, and usable against the public instances under the OSMF usage policies.
  • Vector tiles — VersaTiles, in the Shortbread schema. Self-hosted mirror of their OSM-derived planet build.
  • Buildings (LoD2.2) — 3DBAG by the 3D geoinformation group, TU Delft, CC BY 4.0 — derived from the Kadaster's BAG registry and AHN, both via PDOK. Netherlands only.
  • Aerial photography — Beeldmateriaal Nederland, served as Luchtfoto RGB by PDOK, CC BY 4.0. Netherlands only.
  • Street objects — street trees, lighting and containers from gemeente Groningen open data, CC BY 4.0. Groningen only.
  • Elevation — AHN height rasters (DTM/DSM), served by PDOK, CC0. Netherlands only.
  • Public transport — live departures and vehicle positions from OVapi, the open key-free feed of Dutch NDOV operator data. Netherlands only.
  • Weather — forecasts from MET Norway, CC BY 4.0, and global cloud cover from the NOAA Global Forecast System, public domain.
  • Night sky — star positions and magnitudes from the HYG Database v4.1 by David Nash, CC BY-SA 4.0 — a compilation of the Hipparcos, Yale Bright Star and Gliese catalogs.
  • Type — Plus Jakarta Sans by Tokotype, SIL Open Font License 1.1.