Skip to content
GAMPEON
Play

Dev blog · · 5 min read

Close up and far away

Block worlds now reach the horizon, villages load only when players come near, and animals and people from scripts walk around. The far side of the world costs almost nothing on the network.

  • engine
  • networking
  • worlds
  • scripting
Block terrain seen from above, fine around a player and coarser with distance.

The last post was about building the same world on every screen. This one is about distance. A big world only works if the server and each player's game spend their effort where the players are. Three things landed since then: block terrain out to the horizon, villages that load only near players, and animals and people from scripts. All three follow the same idea: what is far away costs almost nothing, on the network and on the server.

The horizon costs no bandwidth

Until now a block world ended where the detailed chunks ended. Now every game draws coarse block terrain out to 2 km, with distant trees up to 512 m.

None of it travels over the network. Each game already has the seed and the biome rules, so it runs the same generator for the far terrain too. It builds the terrain in tiles around the camera, like a quadtree: each step outwards merges twice as many block columns into one cell. A cell takes the height of its highest column, so the coarse ground never sits below the real one, and walls and skirts at the tile edges keep it free of cracks.

Schematic side view: full block chunks near the player, distant trees up to 512 m, coarse block terrain up to 2 km. Each step outwards doubles the cell size, and the coarse cells never sit below the real ground.
Detail where you are, coarse blocks to the horizon.

Tiles are built on worker threads, and at most four finished tiles per frame go to the game thread. When the camera moves, an old tile stays until every new tile over it is ready, so there is never a hole. Far terrain has no collision and no shadows. Only games that draw a picture build it, so a dedicated server skips it completely. Player edits don't show in the far tiles, because the tiles are too coarse for that. Up close, where the real chunks are, every edit is there.

Plants on solid ground

At the edge of the drawn world, plants used to float in the air. Now they end with the chunks, and every plant, rock and tuft of grass stands fully on the ground. Each one needs a standing area where all block columns have the same height. For a tree only the trunk counts, so its crown can still reach over a step. A plant that doesn't fit moves to the middle of its block, and if it doesn't fit there either, that column stays empty.

Four side views: a bush on flat ground stands where it was placed, a bush that touches a higher column moves to the middle of its block, a large rock that fits nowhere leaves the column empty, and a tree only needs flat ground under its trunk.
The red line has to be flat.

The server and every game work this out from the same mesh sizes, so collision stays the same everywhere. Players can now also break trees, rocks and bushes, and scripts decide what they get in the new foliageBreak event.

Villages that load when you come close

Block worlds can now place whole maps from a game package as villages, chosen by the seed, and connect them with roads: asphalt, center lines, sidewalks and street lights. In one test world the server placed 84 villages at startup.

Loading 84 maps into every player's game would not work, so map instances now have a stream distance. A player's game loads a map only while its camera is that close. The server keeps a map loaded while any player is that close, so the collision is there where people walk. A loaded map unloads only beyond 1.25 times that distance. A player who stands right at the edge doesn't make it load and unload over and over. A server can hold up to 512 map instances.

Schematic top view: a village inside two circles. It loads when the player crosses the inner circle and unloads only when the player leaves the outer circle at 1.25 times the distance.
Load inside the inner circle, unload only past the outer one.

In that test, a village with 4,565 actors loaded when the player came close and was hidden again when they left. The server held about 120 ticks per second with one player.

One test worldValue
Villages placed at startup84
Actors in the village that streamed in4,565
Server ticks per second, one playerabout 120

Animals and people from scripts

Scripts can now create peds: animals and people with a model from the game package. A server script registers the model, creates the ped and gives it tasks: wander in an area, walk to a place, stand still. Peds jump up one block, stay away from edges and water, and play idle, walk and run animations from the game package. They need no animation logic of their own, because game packages carry no code. Modular characters can have up to 40 parts, and parts can hang on sockets.

The network side is where distance matters again:

  • When a ped appears for a player, the game gets its model name once. Each game loads meshes, materials and animations from its own copy of the game package. The server loads none of them.
  • Each player gets updates only for peds within 150 m, ten times per second.
  • With no player within 150 m, a ped goes to sleep. It stands still, its movement stops, and after one second it sends nothing. It wakes up when a player comes within 140 m.
  • In block worlds the server only has collision near players. Farther away, a ped follows the block surface from the block data instead, and walks normally again when collision is back.
Schematic top view: a player in the middle of a 150 m circle. Peds inside walk around and get ten updates per second. Peds outside sleep and cost nothing. They wake at 140 m.
Near peds move. Far peds sleep.

In our test world, a script places people in a town and animals in a meadow around each player, and removes them all when the last player leaves.

Also new

Games with their own web interface can now open their own pause menu with Esc, read and change the player's settings (mouse, field of view, graphics, window and volume) and quit the game from it. The settings belong to the player and apply in every game.

What these numbers do not say

  • One test, one player. The 84 villages and about 120 ticks per second come from one run on a test server with a single player, not from a crowd.
  • Far terrain is not measured yet. It runs in the current release, but we have no frame time measurements for it yet.
  • Peds are new. They have spawned and replicated on a test server. A play test with several players comes next, and what we find goes into the next round of fixes.
  • The next performance round is still waiting for its report. Its numbers get their own post.

What's next

  • Peds: fixes from the first play test with several players.
  • Map instances: more control from scripts over what a loaded map shows.
  • Server performance: the full report of the next round.

The short version of every change is in the changelog.

GAMPEON Team · Written by our AI assistant from the work we merged, and published after automatic checks.