EndCore Framework

Radiation zones

Create irradiated areas with en-zombies hot zones or your own script using SetRadiationExposure, and tune protection, treatment and the HUD.

Radiation zones are places players can enter, but shouldn't stay. Inside, radiation builds up tick by tick. Past a threshold it starts hurting them and draining their immunity, which lets infection take hold. It is a clean way to guard your best loot without adding more zombies.

There are two ways to make a zone:

  1. An en-zombies hot zone with radiation set. No code, works with the Build tab, and gets a zone banner on the HUD. Use this for almost everything.
  2. Your own script calling SetRadiationExposure. For shapes or rules en-zombies zones don't cover, such as an interior, a leaking barrel, or radiation that turns on during an event.

How radiation works

Radiation is part of the survival tick in en-core, which runs every 60 seconds by default.

  • Each player has an exposure rate. While it is above 0, each tick adds that many rads, up to a maximum of 1000.
  • While the rate is 0, radiation decays by 0.5 per tick instead.
  • At 400 rads or more, each tick deals 4 damage and removes 1 immunity.
  • Below 400, immunity recovers by 0.5 per tick.
  • Lower immunity lets infection grow faster.
Key in en-core/config/server.luaDefault
survival.radiation.max1000
survival.radiation.decay0.5
survival.radiation.sicknessAt400
survival.radiation.damage4
survival.radiation.immunityDrain1.0

Players also feel it on the client: a screen effect from 250 rads, a stronger one and random stumbles from 400. Those client thresholds are fixed and don't follow the server config.

Protection

Exposure is reduced by protection before it is absorbed:

text
absorbed = rate * (1 - protection)

Protection is the player's radProtection state bag from worn clothing (en-clothing), plus any radResist skill bonus, capped at 0.95. The shipped gas mask gives 0.35. To add better gear, give a clothing item a radProtection value; see en-clothing.

As a rule of thumb, at a rate of 12 an unprotected player reaches sickness in about 34 ticks (34 minutes). With a gas mask they absorb 7.8 per tick and last about 52 minutes.

Option 1: an en-zombies hot zone

en-zombies already ships an irradiated zone: Humane Labs, with a radiation rate of 12. Any zone in Config.zones in en-zombies/config/shared.lua can carry radiation. Radiation usually makes sense on a hot zone:

lua
{
    name = 'alamo_wreck', label = 'Alamo Sea Wreck', type = 'hot',
    coords = vec3(1300.0, 4200.0, 32.0), radius = 250.0,
    density = 1.4, types = { walker = 60, runner = 30, brute = 10 },
    radiation = 20,
    falloff = 0.75,
},
FieldRangeWhat it does
radiation0 to 1000Rads per tick at the centre
falloff0 to 1, default 0.75How much weaker it is at the edge. 0 is the same everywhere. 0.75 means the edge gets a quarter of the centre.
radius5 to 5000Zones are cylinders: only horizontal distance counts, so height doesn't matter

The rate a player receives depends on how deep inside they are:

text
rate = radiation * ((1 - falloff) + falloff * depth)

depth is 1 at the centre and 0 at the edge. The result is rounded to the nearest 0.5. With radiation = 20 and the default falloff, players take 20 per tick at the centre and 5 at the edge. That gives them a warning at the boundary and a real reason not to linger in the middle.

When a player enters the zone, en-zombies calls SetRadiationExposure for them, updates it as they move deeper, and clears it when they leave or when en-zombies stops. The HUD shows the zone banner and its Geiger counter reacts immediately.

Placing it in game

  1. Press F10, open the Build tab and choose Zombie zones.
  2. Choose New, set the type to hot, and fill in the label, radius, density and type mix.
  3. Set Radiation and Radiation falloff.
  4. Stand at the centre and press Use my position. Save.

The zone is live for everyone immediately. A placed zone with the same name as a config zone overrides it. See en-zombies.

Option 2: your own exposure script

SetRadiationExposure(source, ratePerTick) sets a player's exposure rate. 0 clears it and natural decay resumes. The player is told immediately, so the HUD Geiger counter reacts without waiting for the next tick. Exposure is also cleared automatically when a character unloads.

Here is a small server script for an irradiated area of your own. Only send updates when the rate changes:

lua
-- server/reactor.lua
local CENTRE = vec3(2750.0, 1520.0, 24.5)   -- example position; copy yours with /coords
local RADIUS = 60.0
local RATE = 25                             -- rads per survival tick

local exposed = {}                          -- [source] = rate we last set

CreateThread(function()
    while true do
        for _, id in ipairs(GetPlayers()) do
            local src = tonumber(id)
            if exports['en-core']:IsPlayerLoaded(src) then
                local inside = #(GetEntityCoords(GetPlayerPed(src)) - CENTRE) <= RADIUS
                local rate = inside and RATE or 0
                if (exposed[src] or 0) ~= rate then
                    exposed[src] = rate
                    exports['en-core']:SetRadiationExposure(src, rate)
                end
            end
        end
        Wait(2000)
    end
end)

-- en-core clears exposure on unload, so forget our copy too.
AddEventHandler('encore:server:onPlayerUnload', function(src) exposed[src] = nil end)
AddEventHandler('playerDropped', function() exposed[source] = nil end)

-- Don't leave players irradiated if this resource stops.
AddEventHandler('onResourceStop', function(resource)
    if resource ~= GetCurrentResourceName() then return end
    for src, rate in pairs(exposed) do
        if rate > 0 then exports['en-core']:SetRadiationExposure(src, 0) end
    end
end)
Warning

A player has one exposure rate. en-zombies only sends a new rate when a player's zone rate changes, so if your area overlaps an en-zombies radiation zone, whichever script wrote last wins. Keep custom areas away from en-zombies radiation zones.

For a one-off dose rather than an area, such as a leaking barrel or a failed quest, add radiation directly:

lua
exports['en-core']:AddRadiation(source, 150, 'Leaking barrel')

Treatment

Players need a way back. By default:

  • Rad pills (en-consumables) remove 20 rads at once, then 15 more every 30 seconds, four times.
  • Waking up at an en-respawn spawn resets radiation to 0.
  • Staying out of zones lets it decay by 0.5 per tick, which is slow on purpose.

To add your own treatment, either give an item a negative radiation effect in en-consumables/config/shared.lua, or register a usable handler:

lua
encore.inventory.registerUsable('radaway', function(source, item, slot)
    local player = exports['en-core']:GetPlayer(source)
    if not player or player.Functions.GetRadiation() <= 0 then return false end
    player.Functions.RemoveRadiation(150, 'RadAway')
    return true -- consume one
end)

Testing

CommandEffect
/radzone me 50Set your exposure to 50 per tick. 0 clears it.
/survival me radiation 0Set your radiation directly
/charinfo meShow your current survival stats

Temporarily lowering survival.tickInterval in en-core/config/server.lua makes testing faster. Put it back before you open the server.

HUD

en-hud shows radiation when it is above 0, warns at 150 and turns critical at 400. Its Geiger counter listens to encore:client:radiationExposure, so it clicks the moment exposure starts. These values in Config.thresholds in en-hud/config.lua are for display only; real damage comes from en-core.