Streets, Highways, Rails & Monorails¶
TL;DR
Streets, highways, rails and monorails each expect a set of default part names to exist. Any of those names can point at a custom part instead. Streets, highways and railways also accept a list of parts, sampled at random per placement. Monorails accept one name only.
This is a contract, not a suggestion. If a part named street_full does not exist and nothing overrides that name, that piece of infrastructure does not generate. game test
One shape can have several parts¶
The single most common assumption is that each street shape is locked to exactly one part. It is not. Streets, highways, and railways accept either a single name or a list of names, and the mod picks one at random each time it places that piece: game test
{
"streetblocks": {
"parts": {
"full": ["street_full", "mypack:street_full_cracked", "mypack:street_full_grassy"],
"straight": "mypack:street_straight_wide"
}
}
}
| Category | Multiple variants? | How one is chosen code review |
|---|---|---|
| Streets | Yes, list or single string | Uniform random, every entry equally likely |
| Highways | Yes, list or single string | Uniform random |
| Railways | Yes, list or single string | Uniform random |
| Monorails | No, single string only | n/a |
Passing a list to a monorail key is a datapack load error, not a silent fallback. code review
There is no weighting
Unlike building selectors or Conditions, these lists have no factor key. Every entry in the list is equally likely. If you want one variant to be rare, you cannot express that here, list it once among many common ones, or use a Variant inside the palette instead (see below).
Adjacent chunks roll independently, with no attempt to match neighbours. Two touching straight-street chunks can and often will pick different variants, so variants need to line up seamlessly at chunk edges or the seams will be obvious. Do not count on predicting which variant a given chunk gets before you visit it; once a chunk is generated it is saved, so it will not change afterward. game test
Where each override goes¶
The two families live in different files, which is easy to get wrong: code review
{
"streetblocks": {
"parts": {
"full": ["street_full"],
"straight": ["street_straight"],
"end": ["street_end"],
"bend": ["street_bend"],
"t": ["street_t"],
"none": ["street_none"],
"all": ["street_all"]
}
}
}
Because streets are a City Style property, and a World Style can pick city styles per biome, streets can vary by biome: give citystyle_desert its own streetblocks.parts and desert cities get different roads. code review
{
"outsidestyle": "outside",
"citystyles": [ ... ],
"parts": {
"highways": {
"tunnel": ["highway_tunnel", "mypack:highway_tunnel_lit"],
"open": "highway_open"
},
"railways": {
"railshorizontal": ["rails_horizontal", "mypack:rails_horizontal_broken"]
},
"monorails": {
"both": "mypack:monorails_both_neon"
}
}
}
These are one set per world style, resolved with no biome input, so highways, rails, and monorails cannot vary by biome. The only way to differentiate them is a separate world style entirely. code review
A name given here replaces the mod's part for that shape rather than joining a pool alongside it. Pointing every highway shape at one part makes every highway in the world that part, and the same holds for railways. game test
Monorail parts have not been placed in a test
Highway and railway parts named this way were run in a world and counted. Monorail parts were not: no arrangement tried placed one, including two spheres present, monorailChance at 1.0, and the spheres shrunk so the chunks between them lie outside both. Treat a custom monorail part as untested rather than as working. unverified
The part name keys¶
Any key you leave out keeps its default part name. The keys are not always spelled like the part names they default to. code review
A World Style's parts block takes three keys, one per family, and each holds the shape keys listed below it: code review
| Key | Holds code review |
|---|---|
highways |
The highway shape keys |
railways |
The railway shape keys |
monorails |
The three monorail keys |
Streets are not in that block. They live on a City Style under streetblocks.parts, which is what lets them vary by biome while these three cannot. code review
Streets¶
| Key | Default part | Used when code review |
|---|---|---|
full |
street_full |
Never. See below. |
straight |
street_straight |
2 connections, opposite sides |
bend |
street_bend |
2 connections, adjacent sides |
t |
street_t |
3 connections |
all |
street_all |
4 connections (crossroads) |
end |
street_end |
1 connection |
none |
street_none |
0 connections |
connector |
street_large_connector |
Where a wide road meets a narrower one. 7.5.1 and later |
stair |
street_stair |
Where a road changes city level. 7.5.1 and later |
The key is literally "t", not "tsplit". code review
The last two arrived with the planned road network. The same block of keys appears three times on a 7.5 city style, under parts for ordinary streets, largeparts for the wide planned roads and tertiaryparts for access roads, each taking the full set independently. See What changed in 7.5. code review
full never generates. Setting it does nothing.
A street chunk is assigned one of 3 street types. PARK is chosen by
parkchance. Otherwise the mod picks at random from the remaining types:
streetType = StreetType.values()[ random.nextInt(0, StreetType.values().length - 2) ]
StreetType has 3 constants, NORMAL, FULL and PARK, so this is
nextInt(0, 1). The upper bound is exclusive, so the only value it can return
is 0, which is NORMAL. FULL is never assigned anywhere in the mod. game test
The 6 other keys above are reached through the connection count and work
normally. Only full is unreachable. code review
Verified unreachable in 7.4.12, 7.5.1, 8.4.1, 9.5.1 and 10.0.1. The subtraction looks like it should be 1 rather than 2, so this reads as an off-by-one in the mod, not a design decision. code review
Confirmed in game: a city style whose full key pointed at 2 clearly marked
parts produced neither marker anywhere across a world of streets. game test
Highways¶
Six keys in 7.4.12 and twelve from 7.5.1 onward. code review
| Key | Default part | Needs code review |
|---|---|---|
tunnel |
highway_tunnel |
7.4.12 |
open |
highway_open |
7.4.12 |
bridge |
highway_bridge |
7.4.12 |
tunnel_bi |
highway_tunnel_bi |
7.4.12 |
open_bi |
highway_open_bi |
7.4.12 |
bridge_bi |
highway_bridge_bi |
7.4.12 |
open_bend |
highway_open_bend |
7.5.1 |
open_t |
highway_open_t |
7.5.1 |
bridge_bend |
highway_bridge_bend |
7.5.1 |
bridge_t |
highway_bridge_t |
7.5.1 |
tunnel_bend |
highway_tunnel_bend |
7.5.1 |
tunnel_t |
highway_tunnel_t |
7.5.1 |
_bi ("bidirectional") is used where an X highway and a Z highway meet at the same level. code review
The six _bend and _t shapes arrived with the planned road network in 7.5.1. Before it a highway only ran straight or crossed another at the same level, so there was nothing to turn a corner with. On 7.4.12 these six keys are unknown and ignored, which means a pack written for 7.5 loads on 7.4.12 rather than failing. The reverse is the trap: a 7.4.12 pack that overrides every highway shape keeps its straight sections on 7.5 and gets the mod's own parts at every corner. code review
Railways¶
Sixteen keys. Note they are all lowercase with no separators, while the default part names they map to are snake_case, an easy source of silent typos. code review
| Key | Default part code review |
|---|---|
stationunderground |
station_underground |
stationopen |
station_open |
stationopenroof |
station_openroof |
stationundergroundstairs |
station_underground_stairs |
stationstaircase |
station_staircase |
stationstaircasesurface |
station_staircase_surface |
railshorizontal |
rails_horizontal |
railshorizontalend |
rails_horizontal_end |
railshorizontalwater |
rails_horizontal_water |
railsvertical |
rails_vertical |
railsverticalwater |
rails_vertical_water |
rails3split |
rails_3split |
railsbend |
rails_bend |
railsflat |
rails_flat |
railsdown1 |
rails_down1 |
railsdown2 |
rails_down2 |
A surface station gets one extra step. The mod flips a fair coin between the stationopen and stationopenroof lists, then draws a variant at random from whichever list won. code review
Monorails¶
| Key | Default part | List allowed code review |
|---|---|---|
both |
monorails_both |
No |
vertical |
monorails_vertical |
No |
station |
monorails_station |
No |
Rules your custom parts must follow¶
A typo in a part name fails in two very different ways
| Category | If the named part does not exist |
|---|---|
| Streets | The mod logs a warning, and that chunk simply gets no street layer. There is no crash and no fallback, just a gap in the road. In a list of 3 where one name is wrong, roughly 1 in 3 of those street chunks silently comes out broken. |
| Highways, railways, monorails | The mod throws and world generation stops. Loud, but at least obvious. |
There is never a fallback to the default part name. Check your spelling, and remember that a bare name means lostcities:<name>, so your own parts need your namespace. See Namespaces. game test
The silent warn-and-skip is wider than streets
Streets are the most visible case. The mod uses the same warn-and-skip lookup for every one of these:
fountains, parks, stairs, rail dungeons, building fronts, and a city sphere's centerpart. game test
A wrong name in any of them produces Cannot find '<name>' in minecraft:root! as a log warning and then nothing at that spot. If a park or a fountain never appears and no error is raised, check the log before you check your selectors. game test
An infrastructure part must be exactly 16×16. A street, highway, railway or monorail part fills its whole chunk, so anything else leaves gaps or corrupts. Larger than 16 is the dangerous case: a write past column 15 wraps back into the same chunk instead of spilling into the next one. All 32 default infrastructure parts are 16×16. code review
This is a rule about these four families, not about parts in general. A building front is deliberately a narrow strip, and the mod ships three of them at 2×16 and 3×16. code review
Author variants in the same orientation as the part they replace. The mod picks the rotation from the road layout, not from your part, so a street_bend variant gets rotated by the same rule the built-in one does. If your bend is drawn facing a different way than the original, it will be rotated wrongly at three quarters of the corners in your world. full, none, and all are never rotated, so those can safely be asymmetric. code review
Reuse the palette characters the category expects. A highway part expects its support character, and a rail part expects the rail palette. A part that references a character its palette does not define throws during generation. code review
For streets, the character that matters is the city style's street. Its streetbase and streetvariant neighbours look like they belong in the same list, but neither is read during generation. See City Style. What a street is actually built from is the characters inside the street part, resolved against the merged palette like any other part. code review
Varying the material instead of the part¶
If the goal is "my streets look too repetitive," authoring several near-identical parts is usually the harder path. The Style and Variant systems already randomize blocks underneath a single part:
{
"blocks": [
{ "random": 32, "block": "minecraft:polished_blackstone_bricks" },
{ "random": 32, "block": "minecraft:cracked_polished_blackstone_bricks" },
{ "random": 1000, "block": "minecraft:polished_blackstone" }
]
}
That gives per-block variation with weighting, which flat part lists cannot do, and it costs one file instead of several parts. Use part lists when the shape differs (a roundabout, a collapsed section, a checkpoint), and variants when only the material differs. game test
The mod ships zero examples of the list form
None of the built-in world styles or city styles override these part names at all, they all run on exactly one variant per slot. The feature is real and present in the code, it just has no demonstration in the default content, which is why it is widely assumed not to exist.
An inheritance trap for street parts¶
City style inherit handles streetblocks.parts as one unit: writing any parts block at all, even a partial one, stops the parent's parts from being inherited. Keys you did not list fall back to the hardcoded defaults, not to the parent's overrides. game test
If a parent city style overrides full and bend, and your child overrides only full, the child's bend reverts to the built-in street_bend, it does not keep the parent's. Restate every key you want to keep. See City Style: Inheritance. game test