Skip to content

Zombies

Zombies are bs_zombies. It’s the biggest resource by far. The short version of how it works: the server keeps a list of every walker (the registry), their health, and who is hosting them. Players only ever see peds for walkers near them. Everything is in resources/[beyond]/bs_zombies/config/.

Three types in Zombies.Types (config_zombies.lua): walker, brute, crawler. Crawlers need the nutria_crawl_anims resource started before bs_zombies or they stand up.

-- bs_zombies/config/config_net.lua
Zombies.Mode = 'networked' -- or 'legacy'
  • networked (default) - one real OneSync ped per walker, created by the server. Everyone sees the same zombie at the same spot. OneSync migrates ownership to a nearby client, and only the owner runs its AI.
  • legacy - the old way. Each client builds its own local peds and reports positions back. Use it if networked mode gives you trouble, it’s a restart of bs_zombies, nothing else.

You can switch it from the F1 console too (Zombies category), needs a restart of bs_zombies.

How many walkers get a real ped at once:

cap = min(hardCap, baseCap + perPlayerCap * (players - 1))
KeyDefaultMeaning
promoteRadius300a walker within this of any player gets a ped
demoteHysteresis60ped removed when nobody is within radius + this
baseCap24with one player online
perPlayerCap18added for each extra player
hardCap160never more than this
perPlayerNear34max around one player
perfBudgetMs70if the server’s average frame goes above this, the cap scales down
perfMinFactor0.35…but never below this fraction
entitySoft / entityHard1400 / 1900total peds+objects+vehicles. Between them the cap shrinks, at hard the farthest walkers get removed
fpsGood / fpsLow / lowFpsFactor45 / 25 / 0.5a player with low FPS gets fewer walkers around them
corpseSeconds120networked corpse lifetime
simDensityScale0.35sim population is scaled by this in networked mode (restart)

If you raise hardCap also raise Streaming.PoolGuard.maxNetworked (default 96), it limits how many walker records exist at all.

From config_streaming.lua:

KeyDefault
Streaming.spawnMin / spawnMax200 / 300walkers spawn in this ring around a player
Streaming.PoolGuard.minSpawnDistance100nothing spawns closer than this to any player
Zombies.Settings.spawnDistanceMin100same floor, sector side
Streaming.PoolGuard.maxPerPlayer28walkers counted around each player
Streaming.PoolGuard.clientPedLimit180client stops creating peds at this ped pool size
Streaming.PoolGuard.clientMaxLocal40max walker peds one client holds (legacy)
Streaming.cleanupDistance480

The spawn floor is the biggest of spawnDistanceMin, minSpawnDistance and 100. So zombies don’t pop in your face, ever, except the staff force spawn.

Nothing spawns inside safe zones (config_zones.lua). Zombies also don’t climb, at all. That’s Zombies.Mobility, please don’t turn it on, they climb onto roofs and get stuck.

The map is split into sectors that wake up and sleep. You edit them in the sector map panel, a web page the nodes resource serves. On first boot it prints the URL with a key to the console. If you want your own key:

set bs_sectormap_key "your-own-long-random-token"

Use set, not setr. setr sends the convar to every client and then every player has your key.

Staff also have /atlas (bs_atlas), a live map of the simulation in game.

Gunshots, cars, the decoy gadget, events: they all make noise and noise pulls walkers (config_noise.lua, Zombies.NoiseSources). Suppressors cut weapon noise a lot (Weapons.Effects.suppressor.noiseScale = 0.28). Hordes are in Zombies.Horde, world event horde waves are in World events.

CommandSideWhat
/znetserver, staffnetworked count, cap and why, frame avg, entity census, your near count
/zsyncserver, staffper player, server walkers nearby vs peds the client really has
/zdiagservergeneral state, includes the /znet lines
/zstatus, /zsim, /znodes, /sectorserverdirector, simulation, nodes, your sector
/zclearserverclear walkers
/znetc, /zgaitclientadopted networked walkers, owner, gait
/poolsclientped pool usage
/safezonesclientdraw safe zone circles

The full list is on the bs_zombies API page.

  1. Set Zombies.Mode = 'legacy' (F1 or the file), ensure bs_zombies. Done.
  2. Report what you saw with the /znet and /zsync output, that’s the first thing I’ll ask.