Repository navigation
Installation
| Component | Version |
|---|---|
| Server | Paper 1.21.8 (see gradle.properties in the repo for the exact target) |
| Runtime | Java 21 |
| TerraForge data | Prepared locally — see Data Sources |
| Optional | Towny / NewTowny, BlueMap |
Download TerraForge-<version>.jar and terraforge-cli-<version>.jar from the
latest release, or build them from source:
./gradlew :terraforge-plugin:shadowJar
cp terraforge-plugin/build/libs/TerraForge-*.jar server/plugins/Start the server once. TerraForge writes plugins/TerraForge/terraforge.yml and logs its banner:
====================================
TerraForge - Real Earth Engine
====================================
World: earth
Scale: 1.0 blocks/km (1000 m per block)
Projection: Equirectangular -- exact north-south distance, standard parallel 51.00 degrees
Origin: 51.000000, 10.000000
Vertical: sea-level 63, exaggeration 1.0, 1.0 m/block
Test region: central-europe [47.0000,5.0000 -> 55.5000,15.5000]
Towny: ENABLED
BlueMap: NOT INSTALLED (integration skipped)
Natural-only: ENABLED
====================================
Nothing is downloaded at runtime — every dataset is prepared offline with the CLI:
java -jar terraforge-cli-<version>.jar prepare-region \
--lat-min 47.0 --lat-max 55.5 --lon-min 5.0 --lon-max 15.5 \
-i ./source-data \
-o ./server/plugins/TerraForgeprepare-region expects one directory per dataset under -i. A missing directory means "no such
data yet" — it is reported and skipped, not treated as an error.
source-data/
├── dem/ *.hgt SRTM tiles
├── landcover/ *.asc Arc/Info ASCII grids
├── boundaries/ *.geojson countries and first-level regions
├── cities/ *.txt GeoNames tab-separated export
└── water/ *.geojson natural water polygons
Everything is clipped to the bounding box, so a planet-wide gazetteer produces a regional
database. The whole import runs in one transaction — a broken source file leaves the database
exactly as it was. Re-running the command refuses to overwrite prepared data unless you pass
--replace.
Resulting layout:
plugins/TerraForge/
├── terraforge.yml
├── terraforge.db countries, regions, cities, water bodies
├── data/
│ ├── dem/ N47E005.tfdem, ...
│ └── landcover/ *.tflc
└── cache/
Verify before starting:
java -jar terraforge-cli.jar info -c server/plugins/TerraForge/terraforge.ymlSee Data Sources and DEM Pipeline for which datasets to download and how to prepare each one.
Add to bukkit.yml:
worlds:
earth:
generator: TerraForgeOr, with Multiverse:
/mv create earth normal -g TerraForge
The world name must match world.name in terraforge.yml.
/earth info server-wide configuration
/earth whereami your country, region, nearest city, lat/lon, elevation
/earth teleport city Frankfurt
/earth teleport country DE
Country and city names complete with Tab, as do the subcommands of teleport,
pregenerate, towny, cache and debug. Names containing a space are not offered — Bukkit
splits arguments on spaces — but typing them out still works.
While debugging terrain, /earth debug prints a one-off report for the block you are standing on
and /earth debug overlay follows you in the action bar. The overlay needs both debug.enabled
and debug.per-player in terraforge.yml; the repeating task exists only while somebody has it on.
See the full Commands reference for everything else.
Both are detected at runtime. Install them, restart, and the banner reports ENABLED. Neither is
required — a missing plugin is logged and skipped. See Towny Integration and
BlueMap Integration.
- Stop the server.
- Replace the jar.
- Start. New config keys are added with their defaults; unknown keys are ignored, so older files keep working.
Do not change
scale,earth.origin,projectionorterrain.*on a world that already has generated chunks — new chunks would not line up with old ones.
Next: Data Sources · Configuration
TerraForge is MIT-licensed and community-maintained. Ships no geodata — see Data Sources for licensing. Found an error on this page? Suggest a fix via a pull request or open a documentation issue.
Getting started
Going deeper
Integrations
Help