How a Chunk Becomes a City¶
You do not need this page to build a custom city
Everything required to author content lives in Reference and Concepts. This section covers why the generator behaves as it does: background for the keys documented elsewhere, and a starting point when a world does not look the way the settings say it should.
TL;DR
Every chunk's city and building decision is made once, the first time that chunk generates, from the world seed and the chunk coordinates. Changing a profile or city style has no effect on chunks that already exist, only on chunks generated afterwards. code review
Decisions are permanent per chunk¶
Minecraft asks a chunk generator to generate a given chunk once. Everything on this page, is it a city, which building, how many floors, which city style, happens exactly once for that chunk and is written into the placed blocks. Editing profile or city style JSON afterwards changes nothing about chunks that already exist. code review
That is why a changed setting appears to do nothing. The setting works, and the chunks being looked at were written to disk before it changed. Testing a change means generating into new terrain, or force-regenerating those chunks. See Seeing your changes. code review
Two ways a chunk becomes part of a city¶
Decided by the sign of a profile's cityChance, documented on the Profile Reference. code review
Each chunk independently rolls a chance to become a city centre, then takes a random radius between cityMinRadius and cityMaxRadius. Whether a chunk counts as in a city comes from its distance to every nearby centre: each centre contributes a factor that fades towards its edge, and overlapping centres' factors add together. cityThreshold is the cutoff those summed factors have to clear. code review
That is why raising cityMaxRadius does more than make individual cities bigger. Past a point, neighbouring fade zones overlap and sum past the threshold, and cities meant to be separate merge into one sprawl. code review
No discrete centres and no radius. A four-octave Perlin noise key, shaped by cityPerlinScale, cityPerlinOffset and cityPerlinInnerScale, covers the whole map, and cityThreshold gates it the same way. The result reads as uneven, organic coverage rather than clean circles, which suits a wasteland or a sprawl: a region that is mostly city with pockets that are not, rather than distinct separated cities. code review
In either mode, being near spawn can scale the effective city factor down through citySpawnDistance1 and 2 with citySpawnMultiplier1 and 2, which is how the immediate spawn area is kept less dense. code review
Blending city styles at the edges¶
cityStyleThreshold and cityStyleAlternative let a city's outer, weaker-factor edge use a different, usually sparser city style than its dense core. One city, two looks, and a transition from downtown to outskirts instead of a hard edge. Leaving cityStyleThreshold at its default of -1 disables this and uses one style throughout. code review
City level: terrain height decides building scale¶
Every city chunk is assigned a city level from 0 to 7, by comparing the real terrain height under it against the eight cityLevel0Height to cityLevel7Height thresholds. Taller natural terrain gives a higher city level. code review
City level then feeds the floor-count formula through its cityFactor term, so buildings on naturally elevated terrain tend to roll taller than buildings on low ground. That is by design. For uniform height regardless of terrain, overrideFloors on a Building forces it per building rather than fighting the terrain. code review game test
City spheres¶
Relevant to the space, spheres and cavernspheres landscape types. Candidate sphere centres sit on a fixed grid, each independently gated by citySphereChance. code review
The grid test is a bitmask on the chunk coordinate. By default a chunk is a candidate when both chunkX & 15 and chunkZ & 15 equal 8, which is one candidate every 16 chunks, offset to the middle of each block of 16. grid32 changes the mask to 31, giving one every 32 chunks. The offset of 8 is why candidates sit mid-grid rather than on the corners. Overlapping spheres resolve by disabling the smaller one, and a Predefined Sphere always beats a randomly generated one at the same spot. code review
Monorails need agreement from both sides
Each sphere independently rolls, per direction, whether it wants a monorail connection that way, and a line generates between two spheres only where both rolled true facing each other. monorailChance: 1.0 means every sphere always wants one, which is not the same as every pair agreeing. At 1.0 both sides do roll true, so every geometrically possible connection appears, but the check stays per pair rather than global. code review
All of that is read from the code. No monorail has been placed in a test. Sphere generation itself has been, and monorails have not, in any arrangement tried. unverified
Highways¶
Two independent Perlin noise keys, one per axis, decide where highway lines run, shaped by highwayMainPerlinScale, highwaySecondaryPerlinScale and highwayPerlinFactor. code review
highwayDistanceMask is a bitmask, so it takes 0, 1, 3, 7, 15 and so on, a power of two minus one. It spaces candidate lines at regular intervals rather than letting the noise key put them anywhere, which is why it jumps in fixed increments instead of scaling smoothly. 0 is not the tightest spacing, it is off: the level lookup returns -1 before it reads anything else, and no highway generates anywhere. game test A candidate line generates only where it is at least 5 chunks long and touches two cities, unless highwayRequiresTwoCities is false, and its height comes from whichever endpoint rule highwayLevelFromCities selects. code review
Multi-chunk buildings¶
Multi-Building placement is greedy and area-grid based. Each grid cell, sized by multisettings.areasize on a World Style, rolls a random count of multi-buildings to place, largest first, weighted towards whichever city style dominates that area. code review
Largest is measured as dimx + dimz rather than area, so a 1 by 5 multi-building sorts level with a 3 by 3. correctstylefactor, default 0.8, can reject a placement into a chunk whose city style does not match closely enough even where the area had room. A multi-building not showing up where you expect is more often a style mismatch in that spot than a placement-chance problem. code review
See also¶
- Profile Reference for every key named above
- The Generation Pipeline for what happens once a chunk's decisions are made
- Damage, Ruins & Explosions