Before You Begin#
Before installing Air Hockey, make sure your server meets the minimum requirements. Three things are mandatory; everything else is optional and detected on its own.
Requirement | Status | Notes |
|---|---|---|
OneSync | Required | Declared as a dependency — the resource does not start without it. |
| Required | Stores the tables placed with the creator. The database table creates itself. |
| Required | Callbacks, the game menu and notifications. |
Framework | Optional |
|
| Optional | Notifications in its style. |
| Optional | Draws the [E] - Play Air Hockey prompt instead of the built-in 3D text. |
Air Hockey uses GTA V's own air hockey table (prop_airhockey_01), paddles and puck, so there is nothing to stream and no asset pack to install.
Downloading Air Hockey#
After purchasing Air Hockey, the resource is automatically linked to your CFX Portal account.
Sign in to the CFX Portal using the same account used during checkout, open Granted Assets, and download Air Hockey.
After extracting the download, you should have the following folder:
qs-airhockey/
├── config/ -- config.lua: everything you may edit
├── client/custom/ -- notifications and the 3D prompt (editable)
├── server/custom/ -- money, permission and names per framework (editable)
├── database/ -- sql.sql, only if you prefer importing by hand
├── locales/ -- 41 languages
└── web/build/ -- the interface, ready to useOnly
config/,client/custom/,server/custom/andlocales/are open for editing. Everything else is protected by the CFX asset escrow and is replaced as a whole by each update.
Installing the Resource#
Move the qs-airhockey folder into your server's resources directory. It can live anywhere inside it, including a category folder:
resources/
└── [qs]/
└── qs-airhockey/Once copied, open your server.cfg and make sure every dependency — and everything it should detect — starts before Air Hockey:
ensure oxmysql
ensure ox_lib
# Framework
ensure es_extended
# ensure qb-core
# ensure qbx_core
# Optional
ensure qs-interface
ensure qs-textui
ensure qs-airhockeyThe loading order matters. The framework and qs-textui are detected once, when Air Hockey starts, so one that starts later is not found: a late framework leaves Air Hockey in standalone mode — nobody is charged — and a late qs-textui leaves the built-in prompt in place.
The Database#
There is no SQL file you have to import. On every start Air Hockey checks for its table, qs_airhockey_tables, and creates it if it is missing. It holds the tables placed with the creator, one row per table:
Column | Holds |
|---|---|
| The table's identifier, worked out from where it stands. Moving a table gives it a new one. |
| Position and heading as JSON: |
| The name given in the creator. |
| The entry fee. |
|
|
If your database user is not allowed to create tables, import database/sql.sql by hand once — it is the same table.
Only tables placed or edited with the creator are stored. Tables listed in
Config.Tablesand tables found on maps are registered again on every start, so they never need a row — until you give one a name and a fee in the creator.
Granting Creator Access#
The table creator is behind an ACE permission, command.ahcreator by default. Give it to your admin group in server.cfg and put yourself in that group:
add_ace group.admin command.ahcreator allow
add_principal identifier.license:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx group.adminIf your staff are already in group.admin, the first line is all you need — and a group that already has command allow, as in FiveM's default server.cfg, has it already. Aces are read when server.cfg is executed, so restart the server after adding them.
To use an ace of your own instead, add Config.Creator to config/config.lua and grant that one:
Config.Creator = {
permission = 'qs-airhockey.admin',
}Prefer your framework's admin groups? The check is one small function you can extend — see Integrations.
Configuring the Resource#
Everything lives in one commented file, config/config.lua. It is read when the resource starts, so restart qs-airhockey after editing it.
Section | Contents |
|---|---|
| The language — one of 41 codes. |
| How close a player must be to play, to see tables and games, to be challenged and to watch a match. |
| Goals needed to win, and the match clock in seconds ( |
| How the puck and paddles behave, and how fast the mouse moves the paddle. |
| The bot: its speed, where it defends and how accurate it is. |
| Network tuning for duels and for spectators. |
| The props, and the stand-in characters shown for an opponent who has not loaded yet. |
| Picking up air hockey tables already on maps, and tables written by hand. |
| Geometry: the playing surface measured on the prop, the goal mouths, and the player's view. Set with the calibration tools. |
| The key that opens the game menu, and the debug and calibration tools. |
The values worth reviewing first:
Config.Locale = 'en' -- ar, bg, bn ... uk, ur, vi, zh
Config.InteractDistance = 2.5 -- metres from the table's centre to see the prompt
Config.NearbyPlayerRadius = 15.0 -- metres around the table to list challengeable players
Config.WinScore = 10 -- goals to win
Config.RoundTime = 180 -- seconds (0 = no timer)
Config.Mouse = {
sensitivity = 0.09, -- paddle speed per mouse movement
}
Config.NPC = {
speed = 1.1, -- how fast the bot's paddle can move
aggression = 0.40, -- 0-1: the line it defends in its half
errorRange = 0.15, -- aim error (lower = harder)
}Entry fees belong to each table and are set in the creator —
Config.PlayPricein the file is not used. The geometry sections ship calibrated forprop_airhockey_01; leave them alone unless you use another table model — Usage explains the calibration tools.
Verifying the Installation#
Restart your server and read the console. On a working install you will see:
[qs-airhockey] Loaded 0 table(s) from SQL.The number is how many tables the creator has saved. If the line never appears, oxmysql is not connected, or it starts after Air Hockey.
Then join your server and work through the first loop:
Place a table
Type
/ahcreator, press +, name the table and press Place. Aim at the floor, left click to set it down, then Save table.Play the bot
Walk up to the table and press
E→ Player vs Bot. Move the mouse to drive your paddle into the puck and score on the far goal.Challenge somebody
With a second player within 15 m, choose Player vs Player and pick them from the list. They accept on their own screen and the match starts for both.
Nothing in the creator needs a restart: tables, names and entry fees reach every player at once. Usage covers everything a game can do.



