Exports
HZ-Bets is standalone-first: the core logic and UI live entirely in the resource and expose one small, stable contract. Every entry point (command, keybind, NPC, phone) calls the same door.
Client exports
exports['HZ-Bets']:OpenBets(tab) -- open the app. tab is optional: 'events' | 'mybets' | 'admin'
exports['HZ-Bets']:CloseBets() -- close it
exports['HZ-Bets']:Toggle() -- open if closed, close if open
exports['HZ-Bets']:IsOpen() -- boolean
-- or fire the event from anywhere:
TriggerEvent('HZ-Bets:open') -- optionally pass a tab
The admin tab only renders if the server confirms the player is an admin.
Reading the live board
The board is published to GlobalState and is readable by any resource — no callback needed:
local board = GlobalState.hzbets_board -- { serverNow, active = {…}, settled = {…} }
local scorers = GlobalState.hzbets_scorers -- top scorers (when OpenLigaDB is on)
This is exactly how the phone companion reads the data with zero coupling to HZ-Bets' internals.
Phone / external integration
A phone adapter doesn't need any change to HZ-Bets. It:
- reads
GlobalState.hzbets_boardfor the live board, and - forwards bet placement / "my bets" through the same HZ-Bridge callbacks the desktop UI uses (the server stays the single authority).
exports['HZ-Bets']:OpenBets()
The UI never depends on a phone being present. Whether opened from a command, an NPC, or a phone home-screen, it talks to the same server-authoritative engine.
