2 * Heightmap image source:
3 * Imagery by Jesse Allen, NASA's Earth Observatory,
4 * using data from the General Bathymetric Chart of the Oceans (GEBCO)
5 * produced by the British Oceanographic Data Centre.
6 * https://visibleearth.nasa.gov/view.php?id=73934
8 * Licensing: Public Domain, https://visibleearth.nasa.gov/useterms.php
10 * The heightmap image is reproduced using:
11 * wget https://eoimages.gsfc.nasa.gov/images/imagerecords/73000/73934/gebco_08_rev_elev_C2_grey_geo.tif
12 * lat=-3.177437; lon=35.574687; width=0.7
13 * lat1=$(bc <<< ";scale=5;$lat-$width/2"); lon1=$(bc <<< ";scale=5;$lon+$width/2"); lat2=$(bc <<< ";scale=5;$lat+$width/2"); lon2=$(bc <<< ";scale=5;$lon-$width/2")
14 * gdal_translate -projwin $lon2 $lat2 $lon1 $lat1 gebco_08_rev_elev_C2_grey_geo.tif ngorongoro.tif
15 * convert ngorongoro.tif -resize 512 -contrast-stretch 0 ngorongoro.png
16 * No further changes should be applied to the image to keep it easily interchangeable.
19 Engine.LoadLibrary("rmgen");
20 Engine.LoadLibrary("rmgen-common");
21 Engine.LoadLibrary("rmgen2");
22 Engine.LoadLibrary("rmbiome");
24 function* GenerateMap()
26 setBiome("generic/savanna");
28 g_Terrains.roadWild = "savanna_riparian_dry";
29 g_Terrains.road = "road2";
31 g_Gaia.metalLarge = "gaia/ore/savanna_large";
32 g_Gaia.metalSmall = "gaia/ore/tropical_small";
33 g_Gaia.fish = "gaia/fish/tilapia";
34 g_Gaia.tree1 = "gaia/tree/baobab";
35 g_Gaia.tree2 = "gaia/tree/baobab";
36 g_Gaia.tree3 = "gaia/tree/baobab";
37 g_Gaia.tree4 = "gaia/tree/baobab";
38 g_Gaia.tree5 = "gaia/tree/baobab";
40 g_Decoratives.grass = "actor|props/flora/grass_savanna.xml";
41 g_Decoratives.grassShort = "actor|props/flora/grass_soft_dry_tuft_a.xml";
42 g_Decoratives.rockLarge = "actor|geology/stone_savanna_med.xml";
43 g_Decoratives.rockMedium = "actor|geology/stone_savanna_med.xml";
44 g_Decoratives.bushMedium = "actor|props/flora/bush_desert_dry_a.xml";
45 g_Decoratives.bushSmall = "actor|props/flora/bush_dry_a.xml";
47 const heightScale = num => num * mapSettings.Size / 320;
49 const heightHighlands = heightScale(45);
50 const heightEden = heightScale(60);
51 const heightMax = 150;
53 function setBiomeLowlands()
55 g_Gaia.mainHuntableAnimal = "gaia/fauna_giraffe";
56 g_Gaia.secondaryHuntableAnimal = "gaia/fauna_zebra";
58 g_Terrains.mainTerrain = "savanna_riparian_bank";
59 g_Terrains.forestFloor1 = "savanna_dirt_rocks_b";
60 g_Terrains.forestFloor2 = "savanna_dirt_rocks_c";
61 g_Terrains.tier1Terrain = "savanna_dirt_rocks_a";
62 g_Terrains.tier2Terrain = "savanna_grass_a";
63 g_Terrains.tier3Terrain = "savanna_grass_b";
64 g_Terrains.tier4Terrain = "savanna_forest_floor_a";
67 function setBiomeHighlands()
70 g_Gaia.mainHuntableAnimal = "gaia/fauna_lioness";
71 g_Gaia.secondaryHuntableAnimal = "gaia/fauna_lion";
73 g_Terrains.mainTerrain = "savanna_grass_a_wetseason";
74 g_Terrains.forestFloor1 = "savanna_grass_a";
75 g_Terrains.forestFloor2 = "savanna_grass_b";
76 g_Terrains.tier1Terrain = "savanna_grass_a_wetseason";
77 g_Terrains.tier2Terrain = "savanna_grass_b_wetseason";
78 g_Terrains.tier3Terrain = "savanna_shrubs_a_wetseason";
79 g_Terrains.tier4Terrain = "savanna_shrubs_b";
82 function setBiomeEden()
84 g_Gaia.mainHuntableAnimal = "gaia/fauna_rhinoceros_white";
85 g_Gaia.secondaryHuntableAnimal = "gaia/fauna_elephant_african_bush";
88 globalThis.g_Map = new RandomMap(0, g_Terrains.mainTerrain);
89 const mapCenter = g_Map.getCenter();
91 initTileClasses(["eden", "highlands"]);
93 g_Map.LoadHeightmapImage("ngorongoro.png", 0, heightMax);
96 g_Map.log("Smoothing heightmap");
98 new MapBoundsPlacer(),
99 new SmoothingPainter(1, scaleByMapSize(0.1, 0.5), 1));
102 g_Map.log("Marking land");
104 new MapBoundsPlacer(),
105 new TileClassPainter(g_TileClasses.land));
108 g_Map.log("Marking eden");
110 new DiskPlacer(fractionToTiles(0.14), mapCenter),
111 new TileClassPainter(g_TileClasses.eden),
112 new HeightConstraint(-Infinity, heightEden));
115 g_Map.log("Marking highlands");
117 new MapBoundsPlacer(),
118 new TileClassPainter(g_TileClasses.highlands),
120 new HeightConstraint(heightHighlands, Infinity),
121 avoidClasses(g_TileClasses.eden, 0)
125 g_Map.log("Painting cliffs");
127 new MapBoundsPlacer(),
129 new TerrainPainter(g_Terrains.cliff),
130 new TileClassPainter(g_TileClasses.mountain),
132 new SlopeConstraint(2, Infinity));
137 g_Map.log("Placing players");
138 const [playerIDs, playerPosition] = createBases(
139 ...playerPlacementRandom(
143 g_TileClasses.mountain, 5,
144 g_TileClasses.highlands, 5,
145 g_TileClasses.eden, 5),
146 stayClasses(g_TileClasses.land, defaultPlayerBaseRadius())
150 g_Map.log("Flatten the initial CC area");
151 for (const position of playerPosition)
153 new ClumpPlacer(diskArea(defaultPlayerBaseRadius() * 0.8), 0.95, 0.6, Infinity,
155 new SmoothElevationPainter(ELEVATION_SET, g_Map.getHeight(position), 6));
158 g_Map.log("Render lowlands");
162 "func": addLayeredPatches,
164 g_TileClasses.dirt, 5,
165 g_TileClasses.forest, 2,
166 g_TileClasses.mountain, 2,
167 g_TileClasses.player, 12,
168 g_TileClasses.eden, 2,
169 g_TileClasses.highlands, 2
176 "func": addDecoration,
178 g_TileClasses.forest, 2,
179 g_TileClasses.mountain, 2,
180 g_TileClasses.player, 12,
181 g_TileClasses.eden, 2,
182 g_TileClasses.highlands, 2
190 addElements(shuffleArray([
192 "func": addSmallMetal,
194 g_TileClasses.berries, 5,
195 g_TileClasses.forest, 3,
196 g_TileClasses.mountain, 6,
197 g_TileClasses.player, 30,
198 g_TileClasses.rock, 20,
199 g_TileClasses.metal, 10,
200 g_TileClasses.eden, 2,
201 g_TileClasses.highlands, 2
211 g_TileClasses.berries, 5,
212 g_TileClasses.forest, 3,
213 g_TileClasses.mountain, 6,
214 g_TileClasses.player, 30,
215 g_TileClasses.rock, 20,
216 g_TileClasses.metal, 10,
217 g_TileClasses.eden, 2,
218 g_TileClasses.highlands, 2
222 "amounts": ["scarce"]
227 g_TileClasses.berries, 5,
228 g_TileClasses.forest, 8,
229 g_TileClasses.metal, 3,
230 g_TileClasses.mountain, 6,
231 g_TileClasses.player, 20,
232 g_TileClasses.rock, 3,
233 g_TileClasses.eden, 2,
234 g_TileClasses.highlands, 2
237 "mixes": ["similar"],
238 "amounts": ["normal"]
242 addElements(shuffleArray([
246 g_TileClasses.animals, 20,
247 g_TileClasses.forest, 2,
248 g_TileClasses.metal, 2,
249 g_TileClasses.mountain, 6,
250 g_TileClasses.player, 20,
251 g_TileClasses.rock, 2,
252 g_TileClasses.eden, 2,
253 g_TileClasses.highlands, 2
256 "mixes": ["similar"],
262 g_TileClasses.animals, 20,
263 g_TileClasses.forest, 2,
264 g_TileClasses.metal, 2,
265 g_TileClasses.mountain, 6,
266 g_TileClasses.player, 20,
267 g_TileClasses.rock, 2,
268 g_TileClasses.eden, 2,
269 g_TileClasses.highlands, 2
276 "func": addStragglerTrees,
278 g_TileClasses.berries, 5,
279 g_TileClasses.forest, 4,
280 g_TileClasses.metal, 2,
281 g_TileClasses.mountain, 6,
282 g_TileClasses.player, 12,
283 g_TileClasses.rock, 2,
284 g_TileClasses.eden, 2,
285 g_TileClasses.highlands, 2
294 g_Map.log("Render highlands");
298 "func": addLayeredPatches,
300 g_TileClasses.forest, 2,
301 g_TileClasses.mountain, 2,
302 g_TileClasses.player, 12
304 "stay": [g_TileClasses.highlands, 2],
310 "func": addDecoration,
312 g_TileClasses.forest, 2,
313 g_TileClasses.mountain, 2,
314 g_TileClasses.player, 12
316 "stay": [g_TileClasses.highlands, 2],
323 addElements(shuffleArray([
325 "func": addSmallMetal,
327 g_TileClasses.berries, 5,
328 g_TileClasses.forest, 3,
329 g_TileClasses.mountain, 3,
330 g_TileClasses.player, 30,
331 g_TileClasses.rock, 10,
332 g_TileClasses.metal, 20
334 "stay": [g_TileClasses.highlands, 2],
342 g_TileClasses.berries, 5,
343 g_TileClasses.forest, 3,
344 g_TileClasses.mountain, 3,
345 g_TileClasses.player, 30,
346 g_TileClasses.rock, 20,
347 g_TileClasses.metal, 10
349 "stay": [g_TileClasses.highlands, 2],
357 g_TileClasses.berries, 5,
358 g_TileClasses.forest, 8,
359 g_TileClasses.metal, 3,
360 g_TileClasses.mountain, 3,
361 g_TileClasses.player, 20,
362 g_TileClasses.rock, 3
364 "stay": [g_TileClasses.highlands, 2],
366 "mixes": ["similar"],
371 addElements(shuffleArray([
375 g_TileClasses.animals, 20,
376 g_TileClasses.forest, 2,
377 g_TileClasses.metal, 2,
378 g_TileClasses.mountain, 3,
379 g_TileClasses.player, 20,
380 g_TileClasses.rock, 2
382 "stay": [g_TileClasses.highlands, 2],
388 "func": addStragglerTrees,
390 g_TileClasses.berries, 5,
391 g_TileClasses.forest, 2,
392 g_TileClasses.metal, 2,
393 g_TileClasses.mountain, 3,
394 g_TileClasses.player, 12,
395 g_TileClasses.rock, 2
397 "stay": [g_TileClasses.highlands, 2],
405 g_Map.log("Render eden");
409 "func": addLayeredPatches,
411 g_TileClasses.dirt, 5,
412 g_TileClasses.forest, 2,
413 g_TileClasses.mountain, 2,
414 g_TileClasses.player, 12
416 "stay": [g_TileClasses.eden, 2],
422 "func": addDecoration,
424 g_TileClasses.forest, 2,
425 g_TileClasses.mountain, 2,
426 g_TileClasses.player, 12
428 "stay": [g_TileClasses.eden, 2],
435 addElements(shuffleArray([
439 g_TileClasses.berries, 5,
440 g_TileClasses.forest, 3,
441 g_TileClasses.mountain, 2,
442 g_TileClasses.player, 20,
443 g_TileClasses.rock, 3,
444 g_TileClasses.metal, 3
446 "stay": [g_TileClasses.eden, 2],
454 g_TileClasses.berries, 5,
455 g_TileClasses.forest, 3,
456 g_TileClasses.mountain, 2,
457 g_TileClasses.player, 20,
458 g_TileClasses.rock, 3,
459 g_TileClasses.metal, 3
461 "stay": [g_TileClasses.eden, 2],
467 "func": addSmallMetal,
469 g_TileClasses.berries, 5,
470 g_TileClasses.forest, 3,
471 g_TileClasses.mountain, 2,
472 g_TileClasses.player, 20,
473 g_TileClasses.rock, 3,
474 g_TileClasses.metal, 3
476 "stay": [g_TileClasses.eden, 2],
484 g_TileClasses.berries, 5,
485 g_TileClasses.forest, 3,
486 g_TileClasses.mountain, 2,
487 g_TileClasses.player, 30,
488 g_TileClasses.rock, 3,
489 g_TileClasses.metal, 3
491 "stay": [g_TileClasses.eden, 2],
499 g_TileClasses.berries, 5,
500 g_TileClasses.forest, 8,
501 g_TileClasses.metal, 3,
502 g_TileClasses.mountain, 8,
503 g_TileClasses.player, 20,
504 g_TileClasses.rock, 3
506 "stay": [g_TileClasses.eden, 2],
508 "mixes": ["similar"],
509 "amounts": ["scarce"]
513 addElements(shuffleArray([
517 g_TileClasses.animals, 2,
518 g_TileClasses.forest, 2,
519 g_TileClasses.metal, 2,
520 g_TileClasses.mountain, 3,
521 g_TileClasses.player, 20,
522 g_TileClasses.rock, 2
524 "stay": [g_TileClasses.eden, 2],
530 "func": addStragglerTrees,
532 g_TileClasses.berries, 5,
533 g_TileClasses.forest, 2,
534 g_TileClasses.metal, 2,
535 g_TileClasses.mountain, 8,
536 g_TileClasses.player, 12,
537 g_TileClasses.rock, 2
539 "stay": [g_TileClasses.eden, 2],
542 "amounts": ["scarce"]
548 g_Map.createTileClass(),
550 stayClasses(g_TileClasses.land, 5),
552 g_TileClasses.forest, 2,
553 g_TileClasses.rock, 4,
554 g_TileClasses.metal, 4,
555 g_TileClasses.berries, 2,
556 g_TileClasses.animals, 2,
557 g_TileClasses.mountain, 2)
560 setAmbientColor(0.521, 0.475, 0.322);
562 setSunColor(0.733, 0.746, 0.574);
563 setSunRotation(Math.PI);
564 setSunElevation(1/2);
568 setFogColor(0.69, 0.616, 0.541);
572 setPPSaturation(0.42);