Browse docs
Server: CreateOilSpill(payload, creator, options)
Call these exports from a server script in your own resource, with sky_firejob started. They create or remove an incident when called. Automatic oil leaks after collisions or from wear need Sky Mechanic or another resource that detects the condition and calls Firejob.
The return formats and IDs differ between fire and oil exports:
| Operation | Return value on success | ID to keep |
|---|---|---|
CreateFire | One table: { success = true, fireId = ..., type = ..., label = ... } | result.fireId, a numeric fire ID |
CreateVehicleFire | One table: { success = true, fireId = ... } | Keep the vehicle network ID you supplied for RemoveVehicleFire; result.fireId identifies the fire |
CreateOilSpill | Two values: true, spill | spill.id, a string such as "17", for RemoveOilSpill |
GetOilSpills | An array of spill tables | Each entry's spill.id; the array index is not the spill ID |
creator, where accepted, is a player's current server ID (source). Use 0 or omit it for server-created incidents. It is separate from the vehicle network ID, fire ID, and oil spill ID.
Server Exports
CreateOilSpill(payload, creator, options)
Creates an active oil spill and synchronizes it to clients. Firejob assigns the spill ID; you do not generate or supply it.
This export returns two values. On success, the second value is a table containing the new ID at spill.id. On failure, the second value is an error string.
| Argument / payload field | Type | Required / default | Meaning |
|---|---|---|---|
payload | table | Required | Spill creation data |
payload.coords | { x, y, z } or vector3 | Required | World position with numeric coordinates |
payload.radius | number | Configured slip radius, normally 1.25 | Spill radius; clamped to 0.25–5.0 |
payload.intensity | number | Configured default, normally 1.0 | Intensity from 0.0 to 1.0; 1.0 is full intensity |
payload.source | string | "vehicle" in the spill record | Origin tag, such as "my_incident_resource"; useful when finding your spills later |
payload.sourcePart | string | "engine_oil" | Originating fluid/component, for example "engine_oil" or "transmission_fluid" |
payload.sourceVehicleNetId | number | 0 | Optional originating vehicle network ID; separate from the new spill ID |
payload.sourcePlate | string | "" | Optional plate metadata |
payload.canSpread | boolean | true | Whether vehicles may spread this spill |
payload.state | string | "fresh" | Use "bound" to create a spill that is already treated with absorbent |
creator | number | Optional | Player server ID associated with the request; use 0 for a scripted incident |
options | table | Optional | Source grouping and explicit limit overrides, described below |
Create, keep the ID, and remove the spill later
This complete server-side example creates a spill, saves its ID, and removes that same spill after one minute. Replace the coordinates with your incident location. In a real incident system, keep the ID in your own incident state and remove it when that incident ends.
-- server.lua
local ok, spill_or_error = exports["sky_firejob"]:CreateOilSpill({
coords = { x = 215.0, y = -810.0, z = 30.0 },
source = "my_incident_resource",
radius = 1.5,
intensity = 0.9
}, 0)
if not ok then
print(("Could not create oil spill: %s"):format(spill_or_error))
return
end
local spill_id = spill_or_error.id -- e.g. "17"; this is the ID to save.
print(("Created oil spill %s"):format(spill_id))
SetTimeout(60000, function()
local removed = exports["sky_firejob"]:RemoveOilSpill(spill_id, "incident_finished")
if removed then
print(("Removed oil spill %s"):format(spill_id))
else
print(("Oil spill %s could not be removed; it may already be gone."):format(spill_id))
end
end)
For example, a successful call returns true followed by a table with these fields:
| Field | Type | Meaning |
|---|---|---|
id | string | Assigned spill ID, for example "17"; pass this to RemoveOilSpill |
coords | { x, y, z } | Spill position |
radius, intensity | number | Effective values after defaults and clamping |
state | string | "fresh" or "bound" |
source, sourcePart, sourcePlate | string | Origin metadata |
sourceVehicleNetId | number | Originating vehicle network ID, or 0 |
canSpread | boolean | Whether the spill may spread |
boundBy | number or absent | Player server ID associated with binding, if recorded |
createdAtMs | number | Creation time relative to the current server runtime; not a Unix timestamp |
A failed call returns false, error:
| Error | Meaning |
|---|---|
disabled | The oil spill system is disabled |
invalid_payload | payload is not a table |
invalid_coords | Coordinates are missing or invalid |
cooldown | The same source group created a spill too recently |
too_close | The position is too close to the last spill created by that source group |
vehicle_limit | The originating vehicle has reached its active-spill limit |
resetting_ids | An oil-spill ID reset is currently in progress |
Only read .id after checking ok. local spill = CreateOilSpill(...) would capture the first return value, a boolean, instead of the spill table.
Source grouping and limits
By default, calls from the same calling resource and the same payload.source share a cooldown and minimum-distance record. When payload.source is omitted, the export uses "external" for this grouping. Changing creator or sourceVehicleNetId alone does not create a separate source group.
For independent vehicle trails, set options.sourceKey to a stable key unique to your resource and that vehicle, such as "my_incident_resource:vehicle:123" for vehicle network ID 123. sourceKey groups creation limits; it is not a spill ID and is not included in GetOilSpills() results.
The shipped defaults are a 5-second cooldown, 6-metre spacing, 12 active spills per vehicle, and 80 active spills overall. Exceeding the overall limit removes the oldest spill to make room. The effective configuration can change these limits. Removing a spill does not clear its source group's last creation time or position, so immediately repeating the example may return cooldown or too_close.
options field | Type / default | Effect |
|---|---|---|
sourceKey | string, automatic grouping | Explicit shared key for cooldown and spacing |
ignoreSourceCooldown | boolean, false | Skip the source cooldown check for this creation |
ignoreSourceMinDistance | boolean, false | Skip minimum spacing for this creation |
ignoreVehicleLimit | boolean, false | Skip the per-vehicle limit for this creation |
ignoreEnabled | boolean, false | Allow this creation even when the oil spill system is disabled |
Use overrides deliberately for scripted scenes that need them. These server exports do not run cleanup job, duty, or item checks for the calling resource.
Lifetime and saved IDs
Spills can disappear through cleanup, expiry, spreading, capacity limits, or explicit removal. The shipped lifetime is 90 minutes. Firejob attempts to save spills to its database; a successful creation return confirms an active synchronized spill, not a database-write acknowledgement. Database failures are logged separately.
Delete on restart is enabled by default. Disable it to restore unexpired saved spills after a resource restart. An explicit ID reset renumbers active spills, and cleared IDs may be reused later. Treat saved IDs as references to the current incident, not permanent identifiers. Use GetOilSpills() and your origin metadata when rebuilding an integration's state.