RoadsideScenery
Woods, farms and towns beside a HighwayRoad, planted the same way on every drive.
What it does
For each 30 m chunk of road, RoadsideScenery.core makes a list of things standing beside it. Pines, oaks and birches clump into woods. Bushes, rocks and farm fences fill the gaps, reeds grow on river banks, and telephone poles and reflector posts line the shoulders. In towns there are houses, the odd barn and street lamps.
The road plan says where nothing may stand: the tarmac, the ditch and the river.
Use it in a scene
A scene is just data — a list of entities, each with its components. At startup the SceneLoader turns this JSON into a live world; edit the file and reload to rebuild it.
Build it from scratch with the bjs CLI:
- 1Scaffold a project
World, renderer, and dev server — ready to run.
- 2Install dependencies
- 3Add RoadsideScenery
Copies its source into src/ so the scene resolves.
First time? Run bjs login once.
- 4Paste the scene into src/scenes/arcade-room.ts and run
SceneLoader builds the world from the JSON; reload to rebuild.
It finds the HighwayRoad on its own. If the world has no road, it plants beside a default one. Call registerRoadsideSceneryExtension(adapter) at bootstrap to see it.
Seeded chunks
Each chunk gets its own random numbers, made from the two seeds and the chunk number:
So chunk 4012 is the same wood every time you pass it, and chunks can be built in any order. A new road seed gives new woods too. A few things come at a fixed rhythm instead of by chance:
Draw calls
Each kind of thing is one low-poly mesh with its colour baked into the vertices. The plugin draws it once and repeats it for every placement (thin instances), with a small tint per copy so no two trees match. A forest of two thousand trees costs about as many draw calls as there are kinds of tree. The trees and houses cast shadows on the road when castShadows is on.
Without the plugin nothing is drawn, but the plan still exists, so cars still hit the trees.
At night
The lamp heads and house windows glow, and each street lamp lays a soft pool of light on the road. The pools are painted on, not real lights. A whole town costs nothing against the light limit the headlights need.
Solid things
Trunks, poles, lamps, signs, rocks and houses are also circles. CarCollision asks for the ones near a car, from its own code:
That is how a car that leaves the road hits a tree. Bushes, reeds, fences and reflector posts give way.
Settings
| Field | Default | What it does |
|---|---|---|
seed | 7 | Mixed with the road's seed to pick what grows where. |
chunkLength | 30 | Length of one chunk, metres. Keep it equal to the road's chunkLength so the two rebuild together. |
reach | 78 | How far from the paved edge things grow, metres. |
clearance | 3.2 | Nothing closer than this to the paved edge (clears the ditch). |
treeDensity | 0.7 | Tree density, 0 to 1. Above 1 fills every woodland cell. |
undergrowth | 1 | Bushes and rocks, as a multiple of the usual amount. |
houseDensity | 0.82 | Share of town plots that have a house, 0 to 1. |
houseSpacing | 19 | Metres between house plots along the road. Never less than 12. |
lampSpacing | 26 | Metres between street lamps in towns. 0 = no lamps (towns get poles instead). |
poleSpacing | 42 | Metres between telephone poles out of town. 0 = none. |
follow | "Player" | Entity whose position decides which stretch is planted. |
chunksBehind | 2 | Chunks kept behind the followed car. |
chunksAhead | 8 | Chunks kept ahead of it. |
castShadows | true | Trees and houses cast shadows on the road. |
Change any of them while the game runs (LiveTuner does) and the roadside replants around the car.
Events
| Event | Payload | Direction |
|---|---|---|
roadsideScenery.ready | { entityId } | emits once, when the first chunks are planted |
dayNight.changed | { entityId, hour, darkness, phase } | listens, reads darkness to light the lamps and windows |
Needs
- HighwayRoad: the shape of the road to plant beside.
- MeshPrimitive: where the followed car is right now.





























































