An in-game stash creation tool for QBCore servers.
Admins can place new stashes anywhere in the world through an interactive UI, without ever touching a config file or restarting the server.
- In-game admin panel powered by
ox_lib— no file editing needed to create stashes - Three stash types
- Standard – a single shared inventory for everyone
- Personal – one private inventory per player (same physical spot, isolated per
citizenid) - Locker – players pick a number (1-100); each number is a distinct inventory automatically created on first use
- Coordinate picker via
pulsar-advencedcoords— click anywhere in the world to place the stash - Job restriction — optionally lock a stash to a specific job (enforced server-side)
- qb-target interaction zone spawned automatically at the chosen position
- Persistent storage — stashes are saved to
stashes.jsonand restored on every server restart (no database required) - Server-side permission checks — admin group verified on the server, clients cannot bypass it
- Optimised: target zones are only registered once and the stash list is lazily loaded per client on connect
| Resource | Purpose |
|---|---|
| qb-core | Framework — player data & groups |
| qs-inventory | Inventory system — stash registration & opening |
| ox_lib | UI dialogs & notifications |
| qb-target | World interaction zones |
| pulsar-advencedcoords | In-world coordinate picker |
All dependencies must be started before pulsar-stashcreator in your server.cfg.
- Drop the
pulsar-stashcreatorfolder into yourresourcesdirectory. - Add the following line to your
server.cfgafter all dependencies:ensure pulsar-stashcreator - Make sure all dependencies listed above are also ensured.
- Restart the server (or
refresh+ensure pulsar-stashcreator).
All options are in config.lua.
-- Command used to open the creation panel (without the /)
Config.Command = 'createstash'
-- QBCore player groups allowed to use the command (also checked server-side)
Config.AdminGroups = { 'admin', 'god' }
-- Interaction radius around each stash prop for qb-target
Config.TargetDistance = 2.0
-- FontAwesome icon class shown in the qb-target menu
Config.TargetIcon = 'fas fa-box-open'
-- Default slot count pre-filled in the creation form
Config.DefaultSlots = 50
-- Default max weight (grams) pre-filled in the creation form
Config.DefaultWeight = 100000Open config.lua and add your group name to the table:
Config.AdminGroups = { 'admin', 'god', 'moderator' }The check is also performed on the server side, so a player cannot bypass it from the client.
- In-game, type
/createstash(or whatever you set asConfig.Command). - A form appears — fill in:
Field Description Stash Name Display name shown in the qb-target prompt (3–50 characters) Stash Type Standard,Personal, orLocker(see below)Number of Slots How many inventory slots the stash has Max Weight Maximum total weight in grams Job Restriction Job name to restrict access (leave empty for no restriction) - After confirming, a notification tells you to click a location in the world using the
pulsar-advencedcoordspicker. - The stash is created instantly — no restart needed. All online players immediately see the new interaction zone.
Walk up to a stash marker and use qb-target (default E / right-click aim).
The label shown in the menu is the stash name set by the admin.
A single, shared inventory located at the defined position.
Everyone who has access opens the same storage.
[Position A] → inventory: stash_armory_1710000000
One inventory per player, all anchored to the same world position.
Useful for personal lockers in apartments, hospital wardrobes, etc.
[Position A] → player CHAR123 → inventory: stash_locker_1710000000_CHAR123
→ player CHAR456 → inventory: stash_locker_1710000000_CHAR456
The player is prompted to choose a number between 1 and 100.
Each number maps to a distinct inventory created automatically on first access.
[Position A] → player picks 1 → inventory: stash_changing_1710000000_1
→ player picks 42 → inventory: stash_changing_1710000000_42
Stashes are saved in stashes.json inside the resource folder.
This file is created automatically on the first stash creation and reloaded every time the resource starts.
⚠️ Do not deletestashes.jsonwhile the server is running — it will be overwritten with the current in-memory state on the next save.
To delete a stash, remove its entry from stashes.json while the resource is stopped, then restart the resource.
These are internal events. You should not call them directly from other resources.
| Event | Side | Description |
|---|---|---|
pulsar-stashcreator:server:GetStashes |
Server | Client requests the full stash list on connect |
pulsar-stashcreator:server:CreateStash |
Server | Admin submits a new stash definition |
pulsar-stashcreator:server:OpenStash |
Server | Player requests to open a stash (permission + type resolution) |
pulsar-stashcreator:client:LoadStashes |
Client | Server sends the full stash list to a specific client |
pulsar-stashcreator:client:AddStash |
Client | Server broadcasts a newly created stash to all clients |
pulsar-stashcreator:client:OpenStashInventory |
Client | Server tells the client to open the qs-inventory UI |
Stash registration uses the official qs-inventory exports:
-- Server-side registration before opening
exports['qs-inventory']:RegisterStash(source, stashId, slots, weight)
-- Client-side opening (triggered after server validation)
TriggerServerEvent('inventory:server:OpenInventory', 'stash', stashId)
TriggerEvent('inventory:client:SetCurrentStash', stashId)
⚠️ qs-inventoryinternally prefixes stash IDs withStash_in its database.
The IDs used in this script do not include that prefix — the inventory system adds it automatically.
| Symptom | Likely cause | Fix |
|---|---|---|
/createstash does nothing |
Player group not in Config.AdminGroups |
Add the group or change the player's group in QBCore |
| Stash zone not appearing | pulsar-advencedcoords returned nil |
Make sure the resource is started and working correctly |
| Stash disappears after restart | stashes.json was missing or corrupted |
Check the server console for load errors |
| "This stash no longer exists" | stashes.json was modified manually |
Ensure the JSON is valid and the id field is intact |
| Inventory doesn't open | qs-inventory not started |
Ensure load order in server.cfg |
| Job restriction not working | Player job not set in QBCore | Verify Player.PlayerData.job.name matches the restriction value |
This resource is provided as-is for private server use.
Do not redistribute or resell without permission from the author.
Made by Flitcher