Server-Authoritative.
Cheat-Proof by Design.
rde_hookers is a statebag-synced NPC companion service system for ox_core, built to the same production standards as every other RDE resource — server-owned state, ox_core player validation on every event, and a configurable auto-opening service menu that avoids key-conflict issues entirely.
Overview
An ox_target-driven NPC interaction system with a statebag-first architecture — the server owns all state, so nothing about pricing, duration, or active status can be manipulated client-side.
withPlayer statebag prevents the same NPC from being engaged by two players simultaneously — a common exploit vector in similar scripts.
Why this over typical implementations
| Typical Scripts | rde_hookers |
|---|---|
| No sync — only works for the spawning client | Statebag-synced, server-authoritative |
| Hardcoded keybinds — conflicts with vehicle controls | Auto-menu opens after parking, no key conflicts |
| Crashes on player disconnect | All edge cases handled, zero crashes |
| Discord-only logging | Optional Nostr logging, decentralized |
Quick Start
ensure oxmysql
ensure ox_lib
ensure ox_core
ensure ox_target
ensure ox_inventory
ensure rde_nostr_log -- optional
ensure rde_hookers
No database tables needed — zero SQL setup. Start the resource and check console for the startup banner.
Player Flow
- Approach an NPC on foot or drive up — ox_target shows an interaction option (must be driver, seat must be free)
- NPC walks to the vehicle and gets in
- Park and stop the engine, or put the vehicle in neutral
- After a configurable delay, the service menu opens automatically
- Select a service — server charges the configured currency via ox_inventory
- Animation and duration run server-authoritatively
Configuration
Config.Locale = 'en'
Config.Currency = 'money' -- ox_inventory item name
Config.MaxServiceSpeed = 3.0 -- km/h — stationary threshold
Config.Advanced = {
InteractionDistance = 3.0, -- ox_target radius (metres)
AutoMenuDelay = 2500, -- ms parked before menu auto-opens
EntryTimeout = 10, -- seconds before NPC entry times out
}
Nostr Logging
If rde_nostr_log is installed and started, invites, purchases, aborted services, and admin commands log automatically. The script checks GetResourceState('rde_nostr_log') before every log call — completely silent fallback if it's not running.
Exports
| Export | Notes |
|---|---|
| HasEnoughMoney(source, amount) | Check currency balance |
| PlayerHasHooker(source) | Returns true/false — active NPC check |
| GetActiveHookerCount() | Server-wide active count |
| GetStatistics() | Lifetime totals — invites, services, revenue |
| Admin Command | Description |
|---|---|
| /hookerstats | Active count, in-service count, revenue & stats |
| /hookercleanup | Force-dismiss all active NPCs server-wide |
Common Pitfalls
Service menu never opens
The vehicle must be fully stopped — speed below Config.MaxServiceSpeed (default 3 km/h) — and the player must be the driver.
Fix: put the vehicle in neutral or turn the engine off, then wait for AutoMenuDelay (default 2.5s).
Server crashes on player disconnect
A known bug in older versions caused by GetPlayerName infinite recursion.
Fix: resolved in the current release — update if you're on an older build.
FAQ
Can two players interact with the same NPC?
No — the withPlayer statebag marks an NPC as engaged the moment a player invites them, blocking concurrent access.
Is Nostr logging required?
No — fully optional, silent no-op if rde_nostr_log isn't installed.
Roadmap
Privacy check (refuse service near NPCs), multiple service locations, optional risk/reward mechanic.
Player-owned management system, dynamic pricing, reputation-based discounts, custom ped outfits.