Bounty Hunter
codex_bounty_hunter adds interactive bounty boards + hunt missions + an optional Bounty Hunter License (ID) flow for RedM.
This documentation is written for server owners and developers.
Because the main logic is protected by CFX escrow, you only edit what is intentionally exposed (the Configs/*.lua files and the optional Configs/FunctionsConfig.lua hooks).
What players can do
Walk up to a bounty board (Valentine / Blackwater / Saint Denis / Rhodes / Strawberry by default)
Open the Bounty Board UI
Accept a bounty (a configurable deposit is taken)
Follow a clue phase, then a hunt phase
Deliver the target alive or dead (some bounties can require alive)
Get paid on success
Officers can issue a Bounty Hunter License (ID), which can be required to open the board
What you (server owner) can configure
Board locations / objects
Spawn pools and clue locations per board
Mission templates (NPC models, guard count, weapons, rewards multipliers)
Framework type (VORP / RSG / TPZ)
Deposit percentage and money type
Time limit per mission
Law job list & grade needed to issue IDs
Enable/disable license requirement to open the board
Optional integration hooks (money handling, open/close UI hooks, etc.)
Use the sidebar pages to configure, install and customize.
How it works
This section explains the runtime flow in a way that matches what the resource actually does.
1) Board objects exist in the world
The script spawns (or reuses if already present) bounty board objects at the coordinates defined in Configs/ObjectsConfig.lua.
Each object entry binds a board name (example: Valentine) to a set of world coordinates.
2) Players open the board UI
When a player is close enough to a configured board object, they get a Codex Prompt (hold key) to open the board.
When opened:
The client sets NUI focus and shows the UI
The client notifies the server the UI is open for that board
The client requests the list of bounties for that board via a server callback
The UI renders the list and allows Accept / Track / Clear
License gate (optional)
If CodexConfig.EnableCheckBountyIDs = true, the client calls a server callback first to verify the player has a valid issued Bounty Hunter ID (issued by an allowed law job). If the player has no valid license, the board will not open.
3) Accepting a bounty → creates a live bounty row
When a player presses Accept in the UI:
The server reads the selected bounty template row (from
codex_bounty_templates)A deposit is charged:
deposit = floor(reward * CodexConfig.PercentageMoney)A new active bounty row is inserted into
codex_bountiesA mission payload is built from your spawn pool configs (
Configs/BountySpawns.lua) and mission templates (Configs/MissionsConfig.lua)The server starts the mission for that player by sending the payload to the client
Important: Only one active mission per player is allowed at a time.
4) Mission phases
Phase A — Clues
The mission starts in a clue collection phase:
The client places blips for each clue location
A clue object is spawned (prop model is configurable)
The player must collect
requiredCluesclues (from your spawn entry)
Phase B — Hunt
Once enough clues are collected:
The target NPC and guards are spawned at the configured spawn point
The target gets a blip
Guards and target attack the player
Some mission templates can allow the target to attempt escape (and in the “Drug Baron” template the target can spawn a horse and flee).
Phase C — Deliver
When the target is detected as either:
Dead (killed), or
Captured alive (hogtied / cuffed — best-effort detection)
…the player must go to the drop-off location for that board.
When they enter the drop-off radius, the client reports completion to the server and cleanup runs.
5) Time limit and failure
A mission time limit is enforced server-side using CodexConfig.MissionTimeLimitSeconds:
If the timer expires, the server fails the mission (
time_expired)If the player dies during an active mission, the client reports failure (
player_died)
When a mission fails, the bounty row is marked inactive so it disappears from boards.
6) Payout
On completion:
If
requiresAlive = trueand the target is delivered dead → the mission fails (target_killed) and pays nothing.Otherwise, payout is:
finalReward = floor(rewardBase * multiplier)
Where multiplier comes from the mission template:
rewardAliveMultwhen delivered aliverewardDeadMultwhen delivered dead
Money is paid using the default Codex Core account functions, unless you enable hooks and override the money functions.
Installation
Dependencies
The resource declares these dependencies:
codex_coreoxmysqlox_lib(initialized via@ox_lib/init.lua)
Make sure all three are started before codex_bounty_hunter.
Basic install steps
Put the resource folder in your server resources (example:
resources/[codex]/codex_bounty_hunter)Ensure dependencies start first:
ensure oxmysqlensure ox_libensure codex_core
Start this resource:
ensure codex_bounty_hunter
Import the SQL (see the Database page)
Configure board positions and mission settings in
Configs/*.lua
Common “first run” checklist
Verify
oxmysqlconnection string is correctVerify
codex_coreis working and exports are availableConfirm your framework setting matches your server:
CodexConfig.Framework = 'vorp' | 'rsg' | 'tpz'
Confirm you have at least one bounty template row in
codex_bounty_templatesfor each board you want active
Configuration
All user-editable settings for escrow-protected servers are in Configs/*.lua.
Configs/config-main.lua (CodexConfig)
Configs/config-main.lua (CodexConfig)Core
DeveloperModeDebug printing. Do not enable on live servers.Framework'vorp','rsg', or'tpz'EnableCodexPromptsEnables the “hold key” prompts for opening boards and collecting clues.UseHooksWhentrue, the resource will call functions you place inConfigs/FunctionsConfig.lua.
Bounties & missions
EnableCheckBountyIDsWhentrue, players must have a valid issued Bounty Hunter license (ID) to open bounty boards.MaxBountiesPerPlayerMaximum bounties a player can have (the resource also enforces one active mission at a time).PercentageMoneyDeposit ratio required to accept a bounty. Example:0.5means a bounty with reward$1000requires$500deposit.MoneyTypeAccount type used by CodexCore money functions:0money1gold2roll
MissionTimeLimitSecondsServer-enforced time limit. Example default is1800(30 minutes).
Law / issuing IDs
JobGradeAccessMinimum job grade required to issue IDs with/issueid.LawJobsAllowedA list of jobs that count as law enforcement (also used to validate ID issuers).LicenseItemItem name given when a player completes license info (default:bounty_license).
Keys
CodexConfig.Keys contains key hashes. The script uses CodexConfig.Keys["G"] for prompts by default.
If you change a key value, use only valid key hashes for RedM.
Configs/ObjectsConfig.lua (CodexDataObjects)
Configs/ObjectsConfig.lua (CodexDataObjects)Defines bounty board object placements:
ModelNameobject model (defaultmp005_p_mp_bountyboard02x)ModelCoordsworld positionModelHeadingheadingDistanceToReacthow close the player must beBoundBoardNameboard label shown/used when opening the UI
The board name is later normalized to a lowercase internal name:
Valentine →
valentineBlackwater →
blackwaterSaint Denis →
saintdenisRhodes →
rhodesStrawberry →
strawberry
Configs/BountySpawns.lua (CodexBountySpawns)
Configs/BountySpawns.lua (CodexBountySpawns)Defines the spawn pool for each board (must match the internal board name used in DB and normalization).
Each entry contains:
idunique spawn IDtypemission template key (must exist inMissionsConfig.luatemplates)spawncoordinates + headingsearchRadiusused for clue area (payload)requiredCluesnumber of clues needed to progressclueslist of clue positions; each clue can include atype(campfire / footprints / witness, etc.) for your own organization.
Configs/MissionsConfig.lua (CodexBountyMissions)
Configs/MissionsConfig.lua (CodexBountyMissions)Drop-offs
DropOffs defines the delivery location per board.
Clue prop
CluePropModel defines the prop model used as clue objects.
Templates
Templates define how targets and guards spawn and behave.
Included templates:
basic_outlawgang_leaderdrug_baron
Each template includes:
labeltargetModelguardsandguardModelsweaponsspawnRadiusescape(target can flee)baronEscapeOnHorse(Drug Baron only)escapeHealthPercent(when to flee)reward multipliers:
rewardAliveMultrewardDeadMult
Bounty boards & locations
Boards are defined in Configs/ObjectsConfig.lua as world objects.
Default locations included:
Valentine
Blackwater
Saint Denis
Strawberry
Rhodes
To add or move a board:
Add a new entry to
CodexDataObjectsChoose the world coordinates and heading
Set a
BoundBoardName(example"Valentine")Ensure your database has bounty templates for the corresponding internal board name
Board name matching (important)
The system normalizes board names by:
lowercasing
removing spaces
Then matches known boards like:
"Saint Denis"→saintdenis
Your codex_bounty_templates.board values must use the internal names (e.g. saintdenis, not Saint Denis).
Your Configs/BountySpawns.lua keys also must use the internal names.
Missions
Mission selection
When a bounty is accepted, the mission payload is built from:
The newly created bounty row (
codex_bounties)A random spawn entry from
Configs/BountySpawns.luafor that boardThe mission template referenced by the spawn entry (
type) inConfigs/MissionsConfig.lua
Clues phase
Each spawn entry provides a list of clue positions.
The player collects clues until
requiredCluesis reached.Clues show as map blips and spawn clue objects (prop model from
CodexBountyMissions.CluePropModel).
Hunt phase
After enough clues:
Target ped spawns using the template
targetModelGuards spawn using template
guardModelsandguardscountWeapons are randomly selected from template
weapons
Escape behavior
If a template has escape = true, the target can flee when:
target health percentage drops below
escapeHealthPercent, ORmost guards are dead (>= 60% dead)
For drug_baron, if baronEscapeOnHorse = true, a horse is spawned and the target mounts and flees.
Delivery
Each board has a drop-off coordinate in CodexBountyMissions.DropOffs.
Delivery is detected when the player comes close enough to the drop-off after the target is:
dead, or
captured alive (hogtied/cuffed best-effort)
Success payout
Payout uses the reward multipliers from the template:
Alive payout:
floor(rewardBase * rewardAliveMult)Dead payout:
floor(rewardBase * rewardDeadMult)
If the bounty requires alive delivery (requiresAlive = true) and the target is dead, the mission fails with no payout.
Bounty Hunter License (ID)
This resource includes a Bounty Hunter License system.
What it is
Law enforcement can issue an ID card to a player.
The ID is stored in the database table
codex_bounty_ids.The player can fill out extra license information in the UI and receive the configured license item (
CodexConfig.LicenseItem).
Require license to open boards
If CodexConfig.EnableCheckBountyIDs = true, players must have a valid ID row:
The server checks
codex_bounty_idsfor the player’s name.The issuer job must match one of the jobs in
CodexConfig.LawJobsAllowed.
If the player does not have a valid ID, the board UI will not open and they will be notified.
Issuing IDs (law officers)
Client command:
Rules:
Your job must be in
CodexConfig.LawJobsAllowedYour job grade must be >=
CodexConfig.JobGradeAccess
When issued:
The target player is shown an ID overlay (NUI)
The server stores (or updates) the ID row in
codex_bounty_ids
Completing license info
When the ID overlay is shown for an issued ID (not view-only), the player can fill in:
First name, last name
Birth year (must be 1700–1899)
Town of birth
Father’s first and last names
On successful save:
the DB row is updated and marked complete
the player receives
CodexConfig.LicenseItem(defaultbounty_license)
Showing your license item to another player
The configured license item is registered as usable. When used:
The script finds the nearest player
It shows the license UI to that nearby player in view-only mode
Hooks & integration
Because escrow hides most core logic, this resource exposes an optional hook file:
Configs/FunctionsConfig.lua
Enable hooks by setting:
Available hook functions
Client hooks
CodexFunctions.Client.OnOpenBoard(boardName)Called when a player tries to open the board UI. Returnfalseto block opening; returntrueornilto allow.CodexFunctions.Client.OnCloseBoard()Called when the board UI is closed.
Server hooks
CodexFunctions.Server.OnAcceptBounty(source, bountyId)Called when a bounty is accepted.CodexFunctions.Server.OnTrackBounty(source, bountyId)Called when a bounty is tracked.CodexFunctions.Server.OnClearBounty(source)Called when a player clears their active bounty.CodexFunctions.Server.OnIssueID(issuerSource, targetPlayerId, targetName)Called when an officer issues an ID.
Money integration hooks
If you do not want to use CodexCore’s money functions, implement:
CodexFunctions.Server.TryTakeMoney(source, amount) -> boolean
Optionally you can also implement:
CodexFunctions.Server.GiveMoney(source, amount) -> boolean
If a money hook is enabled and returns true, it is considered successful. If it errors or returns false, the resource falls back to its default behavior.
Example: integrating with another money system
Keep hook functions small and safe: the core calls them using protected
pcall.
Database
This resource uses oxmysql and expects specific tables.
Tables used
codex_bounty_templates
codex_bounty_templatesTemplates shown on the board UI. The Accept button reads from this table.
Required columns used by the resource:
id(primary key)board(internal board name:valentine,blackwater,saintdenis,rhodes,strawberry, etc.)namerewarddescriptionlocationactive(1/0)
Optional column (read safely):
capture_alive(1/0) If present and set to 1, that bounty requires alive delivery.
codex_bounties
codex_bountiesLive bounties created when a player accepts a bounty. The UI “Accepted” state is based on this table.
Columns used:
idnamerewarddescriptionlocationboardactiveaccepted_byaccepted_attracked_by
When a mission finishes or fails, the row is set inactive (active = 0).
codex_bounty_ids
codex_bounty_idsStores issued bounty hunter IDs.
Columns used:
id(format:BH-00000)name(player name)issuer_jobissued_by_officer(1/0)issued_at(timestamp)bh_info_completed(1/0)License info fields saved on completion:
bh_first_name,bh_last_namebh_birth_year,bh_town_birthbh_father_first,bh_father_last
Importing SQL
Use the SQL files provided with the resource package to create these tables.
If your package contains:
create_codex_bounties.sqlcreate_codex_bounty_ids.sql
…import them with your preferred MySQL tool (phpMyAdmin, HeidiSQL, etc.) into the same database used by oxmysql.
Commands, events & callbacks
This page lists what a developer/server owner can rely on.
Commands
/issueid <serverId>
/issueid <serverId>Client command for law officers to issue a Bounty Hunter ID to a player.
Requires job in
CodexConfig.LawJobsAllowedRequires grade >=
CodexConfig.JobGradeAccess
/codex_bounty_refresh [board]
/codex_bounty_refresh [board]Server command to force-refresh open bounty board UIs (admin only).
With a board name: refreshes only that board’s open UIs
Without args: refreshes all open UIs
Server callbacks (CodexCore)
codex_bounty:server:GetBounties(boardName)Returns board bounties fromcodex_bounty_templates.codex_bounty:server:CheckPlayerBountyIDs()Checks if the player has a valid issued license incodex_bounty_ids.codex_bounty_hunter:CheckCooldown()Queriescodex_bounty_idsfor the player’s name and returns(true, id)if found, otherwisefalse.
Server events
codex_bounty:server:UIOpened(boardName)codex_bounty:server:UIClosed()codex_bounty:server:AcceptBounty(templateId)codex_bounty:server:TrackBounty(bountyId)codex_bounty:server:ClearBounty()codex_bounty:server:CompleteMission({ bountyId, alive })codex_bounty:server:FailMission({ reason })codex_bounty:server:FailMissionDirect(targetSrc, reason)codex_bounty:server:IssueID(targetPlayerId, targetName)codex_bounty:server:SaveBHInfo(data)codex_bounty:server:RegisterBH(data)(generates an ID payload and shows it)
Client events
codex_bounty:client:OpenBountyBoardUI(boardName)codex_bounty:client:PushBounties(bounties, playerServerId)codex_bounty:client:StartMission(payload)codex_bounty:client:MissionFinished({ paid })codex_bounty:client:MissionFailed({ reason })codex_bounty:client:ShowIssuedID(payload)codex_bounty:client:ShowBountyID(payload)codex_bounty:client:UseLicenseNearestcodex_bounty:client:Notify(msg, time)
Troubleshooting
The board prompt never appears
Checklist:
CodexConfig.EnableCodexPrompts = trueYour board object coords in
Configs/ObjectsConfig.luaare correctThe model name is valid (
mp005_p_mp_bountyboard02xby default)You are within
DistanceToReact
The board UI opens but is empty
Confirm you have rows in
codex_bounty_templateswhere:boardmatches the internal name (valentine,blackwater, etc.)active = 1
Confirm oxmysql is connected and working
Use
/codex_bounty_refreshto refresh open UIs (admin)
Players cannot open boards (license error)
Set
CodexConfig.EnableCheckBountyIDs = falseto disable license requirements, OREnsure players have rows in
codex_bounty_idsissued by a job inCodexConfig.LawJobsAllowed
Accept button does nothing
Ensure
oxmysqlis runningEnsure the bounty template ID exists and is active
Check server console for “[Codex Bounty]” logs
Mission fails instantly
Common causes:
Another active mission exists for that player (only one active mission per player)
The mission payload failed to build because there are no spawn entries for that board in
Configs/BountySpawns.lua
Payout doesn’t work
If you enabled hooks, ensure your money hooks return
trueon successOtherwise, ensure
codex_coreaccount functions are working andCodexConfig.MoneyTypematches your economy setup
Developer debugging tips
Enable
CodexConfig.DeveloperMode = truetemporarily to print helpful logs.Disable it again for production servers.
Last updated
Was this helpful?


