Explosive Devices
Explosive Devices adds a deployable bomb case and an operator-and-tablet defuse minigame to FiveM. Players place the case, attach one of four payloads, and arm it.
Defusing it means working the physical device against a private rulebook tablet. One player can do both jobs, or an operator can work with one or more nearby tablet viewers. The puzzle is generated fresh for every bomb.
If the timer runs out, the payload detonates and leaves a hazard zone behind: fire, a biohazard cloud, a radiation zone, or an EMP blackout.
This page covers installation and configuration. For gameplay, see the Player Guide for planting a bomb, the Defuse Guide for the response and minigame, and Biohazard & Infection for the effects left by a biohazard payload.
Features
Section titled “Features”- Placeable bomb case: Place it precisely with a live preview, rotation, height, and ground snap.
- Four payload types: Explosive, biohazard, nuclear, and EMP, each with its own defuse difficulty and aftermath.
- Solo or co-op defuse minigame: One operator can work the device and rulebook alone, or another authorised tablet holder can relay the rulebook in co-op mode.
- Generated per bomb: Wires, protocol, serial, symbol sequence, module meter, and code are generated fresh for every case.
- Transmitter and remote detonation: Optional transmitter link with a signal grace period, plus remote and countdown detonation.
- Responder scanner and scene markers: A group-restricted scanner that sweeps for bomb signals and hazard zones, with synced scene blips.
- Hazard zones that outlast the bomb: Radiation, biohazard, fire, explosive, and EMP presets with damage, status effects, NPC panic, visuals, audio, and blackouts.
- Progressive biohazard infection: The pathogen agent can apply one of the configured staged infections with symptoms, transmission, linked outbreaks, temporary stabilisation, and framework-aware persistence.
- Protective clothing support: Clothing profiles or your own hooks decide who can enter a radiation or biohazard zone safely.
- Optional acquisition loop: Buy bomb intel from a ped, follow a randomised stash lead, and claim the case before it expires.
- Framework and inventory adapters: Ox, QBCore, QBox, and ESX, plus six inventory adapters.
Requirements
Section titled “Requirements”ox_libv3.30.0or newer.ox_targetv1.17.0or newer. This is the only supported target resource.kf-defuse-assets, the streamed asset resource with the case, payload, transmitter, and scanner models.- One supported inventory adapter set in
Config.inventory:ox_inventory(2.43.0or newer)codem-inventoryqb-inventoryqs-inventoryorigen_inventorytgiann-inventory
- Optionally one supported framework for group checks, cash, and status effects:
es_extended(1.0.0or newer)qb-core(1.0.0or newer)qbx_core(1.0.0or newer)ox_core(0.21.3or newer)
Installation
Section titled “Installation”-
Download Explosive Devices
Section titled “Download Explosive Devices”Download the latest granted asset from the Cfx.re Portal.
-
Install dependencies
Section titled “Install dependencies”Install and start
ox_lib,ox_target, and your inventory resource. -
Add Explosive Devices to your resources
Section titled “Add Explosive Devices to your resources”Place both folders in your server resources directory:
kf-defusekf-defuse-assets
-
Start resources in
Section titled “Start resources in server.cfg”server.cfgStart dependencies before Explosive Devices, and start the asset resource before the script. The custom weapons, case models, and payload models have to be registered first, otherwise you’ll get an invisible case and a blank device screen.
server.cfg ensure ox_libensure ox_target# Start your inventory.ensure ox_inventoryensure kf-defuse-assetsensure kf-defuse -
Configure adapters
Section titled “Configure adapters”Open
config.luaand set the inventory, target, and notification adapters for your server.config.lua Config.inventory = 'ox_inventory'Config.target = 'ox_target'Config.notifications = trueConfig.notify = 'ox_lib'You can use
Config.inventory = 'auto'when exactly one supported inventory resource is started. If you run more than one, set it explicitly. -
Add the weapons to your inventory
Section titled “Add the weapons to your inventory”Add the bomb case, the transmitter, and the responder scanner to your weapons config. Do not mark the bomb case as throwable; players deploy it through Place Case.
Default location:
resources/[ox]/ox_inventory/data/weapons.luaweapons.lua ['WEAPON_KFDEFUSE'] = {label = 'Bomb Case',weight = 15000,},['WEAPON_KFDEFUSETRANSMITTER'] = {label = 'Transmitter',weight = 1000,throwable = true,},['WEAPON_KFDEFUSESCANNER'] = {label = 'Bomb Scanner',weight = 2000,}, -
Add the payload, tablet, and antidote items
Section titled “Add the payload, tablet, and antidote items”Add the four payloads, defuse tablet, and infection antidote to your items config.
Default location:
resources/[ox]/ox_inventory/data/items.luaitems.lua ['kf_defuse_payload_explosive'] = {label = 'Explosive Payload',weight = 8000,stack = false,close = true,},['kf_defuse_payload_biohazard'] = {label = 'Biohazard Payload',weight = 8000,stack = false,close = true,},['kf_defuse_payload_nuclear'] = {label = 'Nuclear Payload',weight = 8000,stack = false,close = true,},['kf_defuse_payload_emp'] = {label = 'EMP Payload',weight = 8000,stack = false,close = true,},['kf_defuse_tablet'] = {label = 'Defuse Tablet',weight = 1000,stack = false,close = true,client = {export = 'kf-defuse.useDefuseTablet',},},['kf_defuse_antidote'] = {label = 'Infection Antidote',weight = 250,stack = true,close = true,consume = 0,client = {export = 'kf-defuse.useAntidote',},}, -
Add the images to the inventory images folder
Section titled “Add the images to the inventory images folder”Add all the image files from
kf-defuse/inventory-imagesinto the ox_inventory images folder.Default location:
resources/[ox]/ox_inventory/web/imagesThe files are named after the items they belong to, so you only need to rename them if you changed an item name in
config.luaorconfig_payloads.lua. -
Add items to your item dispenser
Section titled “Add items to your item dispenser”Add the case, payloads, transmitter, scanner, and tablet to your armoury, shop, loot table, DutyKit, or other item dispenser. Scanners usually belong in a police armoury rather than a general shop.
You can skip the bomb case here if you want players to get it only through the acquisition loop.
Item Reference
Section titled “Item Reference”| Purpose | Item name | Notes |
|---|---|---|
| Bomb case | WEAPON_KFDEFUSE | Held weapon used to place a case. |
| Transmitter | WEAPON_KFDEFUSETRANSMITTER | Custom held weapon used to link a case and hold its signal. |
| Responder scanner | WEAPON_KFDEFUSESCANNER | Held to sweep for bomb signals and hazard zones. |
| Defuse tablet | kf_defuse_tablet | Private rulebook for the operator and tablet viewers. |
| Infection antidote | kf_defuse_antidote | Usable item that cures one persistent infection. |
| Explosive payload | kf_defuse_payload_explosive | |
| Biohazard payload | kf_defuse_payload_biohazard | |
| Nuclear payload | kf_defuse_payload_nuclear | |
| EMP payload | kf_defuse_payload_emp |
Item names live in config.lua (case, transmitter, scanner, tablet), config_payloads.lua (payloads), and config_infections.lua (antidote). Rename the values, not the payload keys.
Acquisition Loop
Section titled “Acquisition Loop”Explosive Devices ships with an optional in-world way to obtain a bomb case, so you don’t have to sell one in a shop. Item dispensers work just as well.
A ped sells bomb intel. When a player buys it, the server picks an unused stash from that source’s pool, creates a personal lead, sets a waypoint and route blip, and spawns a bag at the stash. Only the buyer can claim it, and only before the lead expires.
The values in this example are illustrative; use the source values configured for your server.
sandy_intel = { label = 'Bomb Intel', price = 25000, antidotePrice = 25000, payloadType = 'explosive', offerLifetimeMs = 900000, coords = vector3(1737.02, 3709.64, 34.14), stashPool = { { id = 'grapeseed_barn', coords = vector3(2445.84, 4967.55, 46.81) }, { id = 'harmony_rear_lot', coords = vector3(573.85, 2788.57, 42.19) }, { id = 'redwood_container', coords = vector3(1335.73, 4348.57, 44.34) }, },},The ped exposes separate bomb-intel and antidote-intel options. A player can hold only one lead, so choosing an antidote stash prevents them from taking a bomb-equipment lead until the first lead is claimed or cleared. Bomb stashes grant the case and source payload plus the configured transmitter and tablet. Antidote stashes grant one antidote only.
Players can only hold one lead at a time, and the same stash can’t be handed to two active leads from one source. Leads clear on claim, expiry, disconnect, and resource stop.
To turn the loop off, empty Config.acquisition.sources.
Configuration
Section titled “Configuration”Configuration is split across five focused files. Use the file that owns the system you want to change.
| File | Contents |
|---|---|
config.lua | Framework adapters, notifications, responder access and tools, protective clothing, acquisition sources, and the bomb case’s placement, arming, transmitter, detonation, and world-behaviour settings. |
config_infections.lua | Infection persistence and progression, exposure and transmission, outbreak rules, medical stabilisation, non-persistent gas agents, and strain symptoms. |
config_payloads.lua | Payload identity and inventory presentation, streamed models, per-payload defuse requirements, detonation behaviour, and the effects assigned to each payload. |
config_effects.lua | Reusable radiation, biohazard, fire, explosive, and EMP hazard presets, including their area behaviour, damage and status effects, NPC response, visuals, audio, scanner markers, and blackouts. |
config_defuse.lua | Defuse camera and interaction behaviour, solo/co-op rules, countdown and failure handling, the optional Summary tab, optional puzzle rules, and the generated lookup data. |
Defuse difficulty
Section titled “Defuse difficulty”Difficulty comes from how big the lookup pools are and how often extra rules get rolled. It all lives in config_defuse.lua.
wireColors,protocols,moduleIds, andsymbolSequencesare the pools the puzzle is built from. Rename entries freely. If you add or remove any, updateprotocolRulesandmoduleRulesto match, since each rule refers to a pool entry by name.- Per-payload wire counts live in
config_payloads.lua.wireCountMaxcan’t be higher than the number of configuredwireColors. protocolDecoyCount,serialRowCount, andsymbolFolderEntryCountset how much decoy data the tablet user has to search through.extraRulessets the chances for the optional twists: a required countdown digit, a timed window after the code, and a wrong code detonating on the spot. For digit rules, the padded zero at the front of the displayed timer does not count.
Protective clothing
Section titled “Protective clothing”Configure this to make hazmat gear count. Players wearing a configured outfit take no damage or status effects from radiation and biohazard zones.
Config.protectiveClothing = { enabled = true, effects = { radiation = true, biohazard = true }, profiles = { { model = `mp_m_freemode_01`, components = { { id = 11, collection = 'collection_name', drawable = 0 }, }, props = {}, }, }, isClientProtected = function(ped, effectType) return false end, isServerProtected = function(source, effectType) return false end,}Add your hazmat outfits to profiles, or use the hooks if another resource already tracks protective gear. isServerProtected is the right place for authoritative inventory or state checks.
The client clothing profiles and reports can prevent normal zone damage and status effects. Persistent biohazard infection is stricter: isServerProtected must return true on the server. A client-only outfit check does not prevent infection.
Biohazard agents and infection
Section titled “Biohazard agents and infection”The biohazard payload selects one agent in config_payloads.lua:
Config.bomb.payloads.biohazard.agent = 'pathogen' -- 'pathogen' | 'cs' | 'kog'pathogenis the default. After an unprotected player remains in the area for the configured dwell time, the server can assign one of the configured progressive strains. Infectious strains can then spread between nearby players.cscauses eye irritation, coughing, and impaired vision while the player is inside the cloud, followed by a short visual recovery. It does not create an infection state.kogknocks out an unprotected player after its dwell time and applies post-wake impairment. It does not create an infection state.
Only one agent runs for the biohazard payload. See Biohazard & Infection for the player effects and configured timings.
Infection configuration
Section titled “Infection configuration”Infection settings now live in config_infections.lua:
Config.infection = { enabled = true, progressionClock = 'wall', -- 'wall' | 'online' progressionTimeScale = 1.0, antidoteItemName = 'kf_defuse_antidote', stabilizationMinutes = 15, stabilizeOn = { hospital_respawn = false, revive = false, }, hospitalInteractionDistance = 2.0, hospitalPatientDistance = 5.0, treatmentDurationMs = 15000, treatmentCooldownMs = 15000, hospitalLocations = { vec3(308.36, -595.25, 43.28), }, safety = { allowLethalSymptoms = true, }, -- Exposure, transmission, outbreak, agent, and strain settings follow.}wall progression continues while a persisted character is offline. online counts connected play time and periodically checkpoints it. progressionTimeScale is useful for reaching later stages more quickly while testing.
Stabilisation suppresses symptoms and contagiousness for stabilizationMinutes; when that time expires, the same infection resumes at its current progression stage. An antidote permanently clears the infection and is consumed only after the server accepts the cure. Set allowLethalSymptoms = false to make configured infection damage stop before it kills the player.
Framework persistence
Section titled “Framework persistence”| Framework | Infection state |
|---|---|
| QBCore, QBox, ESX | Stored in character metadata and restored when that character returns. |
| ox_core | Kept in server memory for the current session. It is lost when the player disconnects or the resource/server restarts. |
Symptoms, transmission, outbreaks, stabilisation, and debug controls still work with ox_core. Only persistence is unavailable.
Protective equipment
Section titled “Protective equipment”Pathogen infection and KOG knockout require server-verified biohazard protection through Config.protectiveClothing.isServerProtected(source, 'biohazard'). A client clothing profile on its own can prevent local area effects, including CS irritation and coughing, but it cannot authoritatively prevent infection or KOG knockout.
Medical integration
Section titled “Medical integration”At a configured hospital point, target a nearby player to expose Stabilize infection and Cure infection. Both actions take 15 seconds and can be cancelled. Cure consumes the patient’s antidote first, then the caregiver’s. Using an antidote directly from inventory runs the same treatment flow on the item holder.
stabilizeOn controls automatic treatment from hospital respawn and revive events. Both are disabled by default because the hospital target interaction is the default treatment path.
hospitalEvents = { disabled = {}, additionalTrustedServer = { -- { name = 'medical:server:playerRespawned', outcome = 'hospital_respawn' }, }, additionalClientReports = { -- { name = 'medical:client:playerRespawned', outcome = 'hospital_respawn' }, },}- Prefer
additionalTrustedServerwhen your medical resource emits a server event. The invoking resource is checked, and the target player’s server ID must be the first argument. - Use
additionalClientReportsonly when the medical resource has no suitable server event. Client reports are validated against a recent recorded death, the player’s alive state, a report cooldown, and the configured hospital radius for hospital respawns. - Leaving
hospitalLocationsempty disables only the hospital proximity check. Add your hospital coordinates when you want that validation. - Add an event name to
disabledto turn off a built-in or additional listener.
Explosive Devices includes hooks for the common QB hospital, QBox medical, and ESX spawn/revive flows. Custom medical resources should use the trusted server path whenever possible.
Translations
Section titled “Translations”Target options, notifications, placement controls, and the on-screen defuse prompts all come from a locale file. English ships in locales/en.json.
To translate or reword them, copy en.json to your language code and set the locale in server.cfg:
setr ox_locale "de"kf-defuse/locales/de.jsonKeep the keys exactly as they are and translate the values. Some strings have %s placeholders that get filled in at runtime, like a payload name or a countdown value, so leave those where they are.
If you just want to reword a few lines rather than add a language, edit en.json directly.
Exports
Section titled “Exports”-- Client: open the private tablet view for the calling player.exports['kf-defuse']:useDefuseTablet()
-- Server: trigger the tablet flow for a player.exports['kf-defuse']:useDefuseTablet(source)
-- Client: use an antidote from the calling player's inventory.exports['kf-defuse']:useAntidote()
-- Server: trigger the 15-second antidote flow for a player.exports['kf-defuse']:useAntidote(source)
-- Client: tell Explosive Devices that a player entered or left an EMP effect area.-- Only needed when an external system manages that presence.exports['kf-defuse']:setEmpEffectAreaPresence(areaId, inside)
-- Server: read a connected player's current infection diagnosis.local diagnosis = exports['kf-defuse']:get_infection_diagnosis(source)get_infection_diagnosis returns nil when the source is not connected. Otherwise it returns the strain ID, infection and stabilisation timestamps, elapsed progression, current stage, and whether the player is stabilised, contagious, symptomatic, or in a lethal stage. An uninfected player receives the same diagnosis shape with no strain or stage.
Advanced Adapter Overrides
Section titled “Advanced Adapter Overrides”These files are escrow-ignored, so you can adapt Explosive Devices to a custom server stack without editing locked code:
config.luaconfig_infections.luaconfig_payloads.luaconfig_effects.luaconfig_defuse.luaclient/framework/*.luaclient/interface/*.luaclient/inventory/*.luaclient/target/*.luaserver/framework/*.luaserver/inventory/*.lua
Inventory adapters must provide:
ServerFramework.addInventoryItem(player, itemName, amount, metadata)ServerFramework.removeInventoryItem(player, itemName, amount, metadata, slot)ServerFramework.getInventoryItem(player, itemName, preferredVariation)Notification adapters are expected to provide:
ClientFramework.notify(data)Common Questions
Section titled “Common Questions”No notifications are showing up. Check that Config.notifications = true and that Config.notify names a resource you actually run.
The case is invisible, or the device screen is blank. kf-defuse-assets is either missing or starting after kf-defuse. The asset resource has to come first in server.cfg.
The Place Case option is missing. Equip WEAPON_KFDEFUSE, then check that ox_target is running and Config.target is set to ox_target. Players can have up to the configured number of cases deployed at a time.
There are no target options on the case. Open, payload, arm, recover, and detonation options are available to any nearby player within the configured interaction range; placer ownership is not required. Defuse Device shows up for players allowed by Config.responderTools.groups once the case is armed.
The scanner and marker options are missing. The player isn’t in one of the Config.responderTools.groups, or isn’t holding WEAPON_KFDEFUSESCANNER. Placing a marker also needs them within the configured marker interaction range of the case.
Attaching a payload fails. The payload item has to exist in the inventory under the exact name from config_payloads.lua. Detaching only returns the item if there’s space for it.
Asset Reference
Section titled “Asset Reference”Explosive Devices creates and uses the following model names. The custom case, payload, component, and weapon assets are provided by kf-defuse-assets; the tablet, acquisition, and scanner entries use runtime or base-game models.
Bomb case and weapon models
Section titled “Bomb case and weapon models”| Use | Model name |
|---|---|
| Active world and placement case | kf_gas_defuse_case_open_anime |
| Held bomb-case weapon | kf_explosive_hand_held_case |
| Transmitter weapon | w_kf_throwphone_handset |
| Responder scanner weapon | w_am_digiscanner_reh |
Payload objects
Section titled “Payload objects”These payload models are attached to the case while a payload is installed:
| Payload | Model name |
|---|---|
| Explosive | kf_bomb_payload_c4_explosive_canister |
| Biohazard | kf_bomb_payload_gas_canister |
| Nuclear | kf_bomb_payload_dirty_canister |
| EMP | kf_bomb_payload_emp_canister |
| Gas canister fallback | kf_bomb_payload_gas_canister_2 |
Defuse interaction objects
Section titled “Defuse interaction objects”These component models are attached to the case during the defuse sequence:
| Component | Model name |
|---|---|
| Red light | kf_red_light |
| Green light | kf_green_light |
| Gauge indicator | kf_gas_defuse_case_gauge_indicator |
| Rotation switch | kf_gas_defuse_case_rotation_switch |
| Green wire | kf_wire_green |
| Red wire | kf_wire_red |
| Blue wire | kf_wire_blue |
| Yellow wire | kf_yellow_wire |
| White wire | kf_wire_white |
| Crimson wire | kf_wire_crimson |
Utility and acquisition entities (configurable)
Section titled “Utility and acquisition entities (configurable)”| Use | Model name |
|---|---|
| Defuse tablet prop | xs_prop_arena_tablet_drone_01 |
| Acquisition stash | prop_cs_heist_bag_02 |
| Acquisition source ped | g_m_m_armgoon_01 |