WP Trick or Treat
Current version: 2.0.28
wp_trickortreat is a protected Halloween event system for FiveM built around wp_bridge. It supports target or marker interaction, persistent house progress, area completion tracking, two reward modes, a Halloween NUI, Candy Value, a configurable shop, cash-out rewards, consumable virtual candy, leaderboards, milestones, and administrative reset tools.
Features
Trick-or-treat gameplay
- 838 configured house locations
- 39 grouped neighbourhood areas
- Per-player or global house completion
- Server-side distance validation
- Configurable nighttime-only operation
- Configurable basket requirement
- Optional answer ped and door sequence
- Optional map blips
ox_targetthroughwp_bridgeby default- Marker interaction as an alternative
- Automatic marker fallback when target registration fails
Halloween NUI
The built-in panel includes:
- Overview
- Area progress
- Leaderboard
- Candy Shop
- Candy Cash Out
- Admin controls
- Image-based reward notifications
- Draggable house tracker
- Hidden scrollbars on scrollable pages
- Configurable logo, title, subtitle, and accent colour
- Configurable command and keyboard shortcut
The default panel controls are:
J Open or close the panel
/trickortreat Open or close the panel
F7 Move the tracker while the basket is equipped
Players can rebind the panel shortcut through:
House tracker
The tracker appears only while the basket is equipped.
It displays:
- Houses completed
- Total houses
- Houses remaining
- Candy Value when using the built-in payout system
- Current route progress
The tracker position is saved locally for each player.
Persistent progression
The resource stores:
- Player profiles
- Houses completed
- Area progress
- Virtual candy quantities
- Lifetime Candy Value
- Current Candy Value
- Milestone claims
- Shop purchase logs
- Cash-out logs
Administrative tools
Authorized administrators can:
- Reset one online player’s house progress
- Reset all players’ house progress
- Optionally reset milestone claims
- Use the Admin page in the NUI
- Use server or in-game commands
Commands:
Dependencies
Required:
ox_liboxmysqlwp_bridge
Provider resources depend on the configuration of wp_bridge.
The default development setup uses:
- Qbox
ox_inventoryox_target
ox_target is required when:
and wp_bridge is configured to use ox_target.
Resource order
Start the selected framework, inventory, and target providers before wp_bridge.
Example:
ensure ox_lib
ensure qbx_core
ensure ox_inventory
ensure ox_target
ensure oxmysql
ensure wp_bridge
ensure wp_trickortreat
Installation
1. Install the resource
Place the resource folder in your server resources directory:
Add it to the server configuration:
2. Install the basket item
The default basket item is:
For ox_inventory, add this item to:
['jackolantern'] = {
label = "Jack-o'-Lantern Basket",
weight = 100,
stack = false,
close = true,
consume = 0,
description = 'A Halloween basket used for trick or treating.',
client = {
image = 'jackolantern.png',
export = 'wp_trickortreat.useBasket'
}
},
Keep consume set to zero
consume = 0 prevents the basket from being removed when used.
The basket export is an equip toggle. It does not intentionally consume the item.
3. Install the basket image
Place:
in:
4. Install the database
The resource automatically creates its required tables when it starts.
A manual SQL file is also included:
Tables:
wp_trickortreat_profiles
wp_trickortreat_visits
wp_trickortreat_global_visits
wp_trickortreat_candy
wp_trickortreat_milestones
wp_trickortreat_shop_logs
wp_trickortreat_cashout_logs
5. Configure rewards
Before enabling the event, review:
Every real inventory item used by the shop, legacy mode, or milestone rewards must exist in the active inventory.
6. Enable the resource
Restart:
Asset Escrow
Only the main configuration file is editable:
House and area locations are stored in:
That file is intentionally escrow protected.
Current manifest configuration:
Core Configuration
Enable or disable the event
Set this to false to stop trick-or-treat gameplay without removing the resource.
Debug logging
Enable it temporarily while diagnosing:
- Basket checks
- Target registration
- Inventory capacity
- Shop delivery
- Cash-out payout
- Admin authorization
Do not normally leave debug mode enabled on a production server.
Basket configuration
Config.Basket = {
required = true,
item = 'jackolantern',
useMode = 'ox_inventory',
prop = {
enabled = false,
model = '',
attach = {
bone = 57005,
offset = vec3(0.40, -0.02, 0.09),
rotation = vec3(28.79, -79.40, -95.07)
}
}
}
Require the basket
When enabled, players must:
- Own the configured basket item
- Use it to equip the basket
- Keep it equipped while visiting houses
Basket use mode
Default:
This uses:
The alternative value is:
Only use bridge mode when the installed wp_bridge version exposes a compatible usable-item registration API.
Optional held prop
No prop is required by default:
To use a streamed model:
prop = {
enabled = true,
model = 'your_model_name',
attach = {
bone = 57005,
offset = vec3(0.40, -0.02, 0.09),
rotation = vec3(28.79, -79.40, -95.07)
}
}
The model must be streamed by this resource or another started resource.
Time restrictions
Enable nighttime-only operation:
The default allowed period is from 18:00 through 06:00.
Target or marker interaction
Target mode
This registers house zones through wp_bridge.
Default settings:
Config.Interaction = {
mode = 'target',
fallbackToMarkers = true,
distance = 2.25,
targetRadius = 2.25,
targetIcon = 'fa-solid fa-ghost',
targetLabel = 'Trick or Treat'
}
Marker mode
Marker settings:
marker = {
type = 2,
drawDistance = 18.0,
scale = vec3(0.25, 0.25, 0.25),
colour = {
r = 255,
g = 115,
b = 20,
a = 185
},
key = 38,
helpText = 'Press ~INPUT_CONTEXT~ to Trick or Treat'
}
Automatic fallback
When enabled, the resource switches to markers if target registration fails.
Visit mode
Available values:
Player mode
Every player may visit every house once.
Global mode
Once any player completes a house, that house becomes unavailable to everyone.
Additional security settings:
Config.HouseRules = {
visitMode = 'player',
maxServerDistance = 5.5,
requestCooldownMs = 1000,
tokenLifetimeMs = 15000
}
Do not increase the distance or token lifetime without a gameplay reason.
Blips
Config.Blips = {
enabled = true,
sprite = 40,
colour = 47,
scale = 0.55,
shortRange = true,
label = 'Trick or Treat'
}
Disable all house blips:
Payout Modes
The resource provides two separate house reward systems:
Available values:
Built-in payout mode
This is the primary system.
Players receive virtual branded candy rather than real inventory items.
Virtual candy is:
- Selected server-side
- Stored in SQL
- Displayed in the NUI
- Assigned a Candy Value
- Spendable in the Candy Shop
- Optionally edible from the NUI
No inventory item definition is required for each built-in candy.
Built-in drop count
This controls how many weighted candy selections are made at each completed house.
Candy definition
{
id = 'wp_gold_fang_gummies',
brand = 'WaCKPaCK',
label = 'Gold Fang Gummies',
type = 'candy',
description = 'Golden fruit gummies shaped like tiny monster fangs.',
rarity = 'common',
weight = 18,
min = 1,
max = 3,
value = 5,
image = 'images/candy/wp_gold_fang_gummies.png',
edible = true,
hunger = 8,
thirst = 0
}
Field reference:
| Field | Purpose |
|---|---|
id |
Unique internal candy identifier |
brand |
Brand displayed in the NUI |
label |
Product name displayed to players |
type |
candy, snack, or drink |
description |
Product description |
rarity |
Display and organization value |
weight |
Relative chance of selection |
min |
Minimum quantity awarded |
max |
Maximum quantity awarded |
value |
Candy Value earned per unit |
image |
NUI image path |
edible |
Whether it can be consumed |
hunger |
Hunger amount applied |
thirst |
Thirst amount applied |
Weighted selection
Higher weight values are selected more often.
Example:
{ rarity = 'common', weight = 18 }
{ rarity = 'uncommon', weight = 9 }
{ rarity = 'rare', weight = 4 }
The weights are relative. They do not need to total 100.
Candy Value
Candy Value is awarded when the candy is collected:
If the house awards three units:
Eating the candy later removes one virtual candy from the collection, but it does not remove Candy Value already earned.
Built-in candy images
Place images in:
Use the exact file path configured in each entry:
Recommended built-in configuration
Config.PayoutMode = 'builtin'
Config.BuiltIn = {
minimumDrops = 1,
maximumDrops = 3,
candies = {
{
id = 'example_candy',
brand = 'Example Brand',
label = 'Example Candy',
type = 'candy',
description = 'A fictional Halloween candy.',
rarity = 'common',
weight = 20,
min = 1,
max = 3,
value = 5,
image = 'images/candy/example_candy.png',
edible = true,
hunger = 8,
thirst = 0
}
}
}
Legacy payout mode
Legacy mode awards actual inventory items directly.
Every configured item must exist in the active inventory.
Legacy roll count
This controls the number of reward-group selections per house.
Legacy reward groups
Config.Legacy = {
rollsPerHouse = 1,
groups = {
{
id = 'common',
weight = 70,
items = {
{
item = 'example_common_item',
min = 1,
max = 3
}
}
},
{
id = 'good',
weight = 22,
items = {
{
item = 'example_good_item',
min = 1,
max = 2
}
}
},
{
id = 'rare',
weight = 7,
items = {
{
item = 'example_rare_item',
min = 1,
max = 1
}
}
},
{
id = 'jackpot',
weight = 1,
items = {
{
item = 'example_jackpot_item',
min = 1,
max = 1
}
}
}
}
}
Legacy group selection
The group weights are relative:
After a group is selected, one item from that group is selected.
Empty groups
Do not leave a weighted group empty.
Bad:
Use either:
or configure at least one valid item.
Inventory requirements
For every legacy item:
confirm the exact item name exists in the active inventory.
Item names are case-sensitive and must match punctuation, underscores, and hyphens.
Candy Shop
The Candy Shop exchanges Candy Value for real inventory items.
Maximum quantity per transaction:
Shop categories
Define category keys and labels:
Assign a matching lowercase category key to each item:
{
id = 'shop_lighter',
item = 'lighter',
label = 'Lighter',
amount = 1,
price = 100,
category = 'useful'
}
Add another category:
Config.Shop.categories = {
useful = 'Useful',
premium = 'Premium',
medical = 'Medical',
crafting = 'Crafting'
}
Then use:
Category keys are normalized to lowercase for NUI filtering.
Shop item fields
{
id = 'shop_lighter',
item = 'lighter',
label = 'Lighter',
amount = 1,
price = 100,
category = 'useful'
}
| Field | Purpose |
|---|---|
id |
Unique shop entry ID |
item |
Exact inventory item name |
label |
Player-facing name |
amount |
Inventory amount granted per purchase |
price |
Candy Value cost |
category |
Category key |
Every id must be unique.
Every item must exist in the active inventory.
Candy Cash Out
Cash Out can be disabled independently:
Default conversion:
Config.Shop.cashOut = {
enabled = true,
pointsPerUnit = 100,
cashPerUnit = 50,
minimumUnits = 1,
maximumUnits = 100,
title = 'Candy Cash Out',
description = 'Exchange Candy Value for a configured payout.'
}
With these values:
The NUI shows:
- Current Candy Value balance
- Total possible cash value
- Selected cash payout
- Candy Value required
- Minus and plus amount controls
Cash payout
Available account values depend on the active framework and bridge configuration.
Typical values:
Bank example:
Dirty money as item count
Use one item per payout dollar:
A $300 payout attempts to add:
This setup requires enough inventory capacity for the full item amount.
Dirty money as one metadata item
Use a single item carrying the value in metadata:
default = {
type = 'metadata_item',
item = 'smallbills',
itemAmount = 1,
metadataValueKey = 'worth',
metadata = {
description = 'Halloween candy cash-out proceeds'
}
}
A $300 payout creates one item with metadata similar to:
The metadata key must match the dirty-money system used by the server.
Common examples may use keys such as:
Use the key expected by the installed inventory or money resource.
Job-specific payout overrides
Example: everyone receives dirty money, while police and EMS receive clean cash.
Config.Shop.cashOut.payout = {
default = {
type = 'metadata_item',
item = 'smallbills',
itemAmount = 1,
metadataValueKey = 'worth',
metadata = {
description = 'Halloween candy cash-out proceeds'
}
},
jobOverrides = {
police = {
type = 'account',
account = 'cash'
},
ambulance = {
type = 'account',
account = 'cash'
}
}
}
The keys must match exact framework job names:
Job resolution is performed server-side.
Milestones
Enable milestones:
Example:
Behavior depends on payout mode:
Built-in mode
adds Candy Value.
Legacy mode
awards a real inventory item.
Replace every replace_me_* milestone item before using legacy mode.
Consumable Candy
Progress duration:
Automatic status mode
Automatic mode supports the configured QB/Qbox-style events and ESX status setup.
QB or Qbox events
statusMode = 'qb'
qb = {
hungerEvent = 'consumables:server:addHunger',
thirstEvent = 'consumables:server:addThirst'
}
ESX Status
Custom status event
The client event receives:
Disable status changes
Candy can still be collected, but configured hunger and thirst changes will not be applied.
Leaderboard
Available name sources:
Enable anonymous display:
User Interface
Config.UI = {
commandEnabled = true,
command = 'trickortreat',
keybind = {
enabled = true,
key = 'J',
description = 'Open the Trick or Treat panel'
},
logo = 'images/logo.png',
title = 'Halloween Trick or Treat',
subtitle = 'WaCKPaCK Development Studios',
accent = '#ff7a18'
}
Change the default key
Example:
Disable the command
Disable the keybind
Change branding
logo = 'images/logo.png'
title = 'Halloween Trick or Treat'
subtitle = 'Your Server Name'
accent = '#ff7a18'
Replace the logo file in:
or change the configured NUI path.
Notifications
Tracker
Available default side values:
Inventory item images
Default ox_inventory path:
Manual fallback path:
Manual item images belong in:
Use the exact inventory item name as the PNG filename.
Admin Configuration
Config.Admin = {
enabled = true,
acePermission = 'wp.trickortreat.admin',
groups = {
-- 'admin',
-- 'god'
},
identifiers = {
},
allowServerConsole = true,
resetMilestones = true
}
ACE setup
Recommended:
add_ace group.admin wp.trickortreat.admin allow
add_principal identifier.discord:YOUR_DISCORD_ID group.admin
Other principal examples:
add_principal identifier.license:YOUR_LICENSE group.admin
add_principal identifier.license2:YOUR_LICENSE2 group.admin
add_principal identifier.fivem:YOUR_FIVEM_ID group.admin
The resource currently checks both compatibility permission names:
Verify the group permission
Server console:
Expected:
Verify the player principal
Example:
Expected:
Verify inside the resource
Run in-game:
Successful output resembles:
Close and reopen the NUI after changing permissions.
Identifier fallback
For development or non-ACE setups:
Use the raw identifier in this config table, without the identifier. ACE prefix.
Security
Authoritative operations remain server-side.
Security checks include:
- Framework identity resolution through
wp_bridge - Basket ownership validation
- Server-authorized equipped state
- Server-side distance checks
- Valid house-ID checks
- Action cooldowns
- Short-lived completion tokens
- One-time token consumption
- Per-player action locks
- Persistent visit constraints
- Global visit locking when enabled
- Server-side weighted reward selection
- Server-side Candy Value changes
- Inventory existence and capacity checks
- Refunds when shop delivery fails
- Refunds when cash-out delivery fails
- Server-side job payout selection
- Admin permission checks
- SQL-backed milestone claims
- No trusted payout amount from the NUI
Troubleshooting
The basket item disappears after restart
Confirm the item contains:
and:
Do not configure the basket as a normally consumed item.
Perform a full server restart after changing ox_inventory/data/items.lua.
The basket says it is missing even though it is in the inventory
Check the exact configured name:
It must exactly match the inventory item name.
Enable:
Run:
Confirm the reported inventory count is at least 1.
The tracker appears immediately after joining
The tracker should only appear while the basket is equipped.
Confirm the current resource version is installed and no older copy is being started from another folder.
Search the server resources for duplicate folders named:
Restart the resource after replacing it.
The tracker does not appear
Confirm:
Use the basket item to equip it.
The tracker does not open merely because the item exists in the inventory.
No target interaction appears
Confirm:
Check the resource order:
Confirm wp_bridge is configured to use ox_target.
Enable debug mode and check F8 for the house-zone registration count.
Use markers temporarily:
House blips appear, but target does not work
Blips and target zones are separate systems.
Blips working only confirms the house list loaded.
Verify:
ox_targetis startedwp_bridgeis startedwp_bridgetarget provider is set correctlyConfig.Interaction.mode = 'target'- The current resource version is being loaded
Markers do not appear
Markers appear only when:
or automatic target fallback activates.
Check:
and ensure the player is near a configured door.
“You cannot carry that reward”
This message indicates the inventory capacity check rejected the configured reward.
Check:
- The item exists
- The item name is exact
- The item weight is valid
- The requested quantity is reasonable
- The inventory has enough slots and weight
Enable debug mode and inspect:
logs.
“The purchase could not be completed”
The capacity check may pass while actual item delivery fails.
Enable:
Inspect the server console for the exact AddItem failure reason.
Confirm the shop entry uses a real item:
and that lighter exists in the active inventory.
Candy Value is refunded when delivery fails.
Cash out fails with money_provider_unavailable
Confirm:
- The correct
wp_bridgeversion is installed - The framework is detected
- The player is fully loaded
- The account is valid
Test:
or:
Enable debug mode and inspect the AddMoney provider log.
Cash out fails with invalid_source
This indicates the framework or bridge could not resolve the active player source.
Confirm:
wp_bridgestarts after the frameworkwp_trickortreatstarts afterwp_bridge- The player is fully loaded
- There is not an outdated duplicate
wp_bridgefolder
Restart in order:
Dirty-money cash out does not create the expected value
Check the configured metadata key:
The expected key depends on the installed dirty-money system.
Inspect an existing valid dirty-money item and match its metadata structure.
Example alternatives:
or:
Admin button does not appear
Run in-game:
The output must include:
Verify the group:
Verify the connected identifier:
The group permission being true does not prove the connected player inherits that group.
Close and reopen the panel after permission changes.
Admin console check is allowed, but the panel is still hidden
The NUI receives admin status when dashboard data is loaded.
Close the panel completely and reopen it using:
or:
If needed:
Then reopen the panel.
A weighted legacy reward gives nothing
Check for an empty group with a non-zero weight:
Add an item or set:
Candy images do not display
Confirm the configured path:
and the file exists at:
PNG names are case-sensitive on Linux hosts.
Shop item images do not display
The default lookup is:
Confirm the inventory image exists.
For manual images, place:
and keep:
The world becomes black behind the NUI
This is usually caused by replacing the supplied NUI CSS with a full-screen opaque background or backdrop filter.
Keep the root NUI background transparent.
Only the panel and intended overlay layers should use dark backgrounds.
A strange circle or decoration appears outside the panel
Check custom NUI changes for:
- Full-screen pseudo-elements
- Decorative radial gradients
- Absolutely positioned glow circles
::beforeor::afterelements outside the panel
Keep decorative elements inside the dashboard container.
SQL tables are missing
The resource attempts to create them automatically.
Confirm:
oxmysqlis started- Database credentials are valid
wp_trickortreatstarts afteroxmysql
Manual import:
Progress will not reset
Confirm admin authorization first:
Commands:
When:
milestone claims are also removed.
Diagnostic Checklist
When reporting an issue, include:
wp_trickortreat version
wp_bridge version
framework
inventory provider
target provider
Config.PayoutMode
Config.Interaction.mode
relevant Config.Debug output
server console error
client F8 error
Recommended temporary setting:
Return it to:
after testing.
Support Notes
Before requesting support:
- Confirm the latest resource version is installed.
- Remove or rename older duplicate resource folders.
- Verify the server starts the intended copy.
- Enable debug logging.
- Reproduce the problem once.
- Save the complete server and client error output.
- Include the relevant configuration section without exposing private identifiers or credentials.