Zones
A zone is a named area on the map. The server tells your scripts when a player walks in or out, and a zone can block damage or hurt players on its own. The functions are in modkit.zones.
Getting coordinates
Stand where the zone should be and read your position.
modkit.commands.add("pos", function(player)
local x, y, z = player:pos()
if x then player:message(string.format("x = %.0f, y = %.0f, z = %.0f", x, y, z)) end
end)
Positions are Unreal units. 100 units are one metre, so a radius of 15000 is 150 m. For a polygon walk the corners in order and note each position.
A complete resource
resources/zones/manifest.lua
name "zones"
server "server.lua"
resources/zones/server.lua
modkit.zones.add({
name = "sanctuary",
shape = "circle",
x = -215000, y = 48000, radius = 15000,
blockDamage = true,
data = { enter = "Sanctuary. Fighting does nothing here.", leave = "You left the sanctuary." },
})
modkit.zones.add({
name = "tar pit",
shape = "polygon",
points = {
{ x = 102000, y = -33000 }, { x = 109000, y = -33000 },
{ x = 111000, y = -27000 }, { x = 104000, y = -25000 },
},
damagePerSecond = 25,
data = { enter = "The tar burns. Get out." },
})
modkit.zones.add({
name = "nesting grounds",
shape = "circle",
x = 5000, y = 61000, radius = 30000,
data = { herbivoresOnly = true },
})
local CARNIVORES = { Tyrannosaurus = true, Carnotaurus = true, Ceratosaurus = true, Deinosuchus = true }
local warned = {}
modkit.events.add("zoneEnter", function(player, zone)
if zone.data and zone.data.enter then player:notify(zone.data.enter) end
if zone.data and zone.data.herbivoresOnly and CARNIVORES[player.species] then
warned[player.steamId] = os.time()
player:announce("Carnivores have 30 seconds to leave the nesting grounds.", "Warning", 8)
end
end)
modkit.events.add("zoneLeave", function(player, zone)
if zone.data and zone.data.leave then player:notify(zone.data.leave) end
if zone.name == "nesting grounds" then warned[player.steamId] = nil end
end)
modkit.events.add("everySecond", function()
for steamId, since in pairs(warned) do
if os.time() - since >= 30 then
local player = modkit.players.get(steamId)
if player and player.alive then player:damage(player.maxHealth * 0.05) else warned[steamId] = nil end
end
end
end)
The coordinates are placeholders. Put in positions from your map.
How it works
The server compares every living player with all zones twice per second. A player who runs through a very small zone between two checks is not noticed. Make zones big enough that a running dinosaur spends more than half a second inside.
blockDamage cancels an attack when the attacker or the victim stands in the zone. It covers player dinosaurs and AI spawned with modkit.ai.
damagePerSecond is applied once per second to every living player inside. Zones add up when they overlap. A player whose health reaches zero dies.
data is yours. The zone table in the events carries it, so one handler can serve many zones.
Zones are not saved. Create them when the resource starts, as above. For zones that admins draw in the game, keep the definitions in modkit.storage and add them again on start.
A player who dies, disconnects or goes back to the character select leaves all zones, and zoneLeave fires for each.