Commands#
Air Hockey registers one everyday command and nine debug tools. All of them are typed in chat with a leading /.
Command | Who | Description |
|---|---|---|
| Creator permission | Opens the Air Hockey Table Creator: place, name, price, move, delete and teleport to tables. |
| Debug on | Sets a table down with the aiming mode and prints its |
| Debug on | A test table 2.5 m in front of you, facing the way you face. Until the next restart. |
| Debug on | Prints your position and heading as a |
| Debug on | Lists in F8 which table, paddle and puck models exist in your game. |
| Debug on | Draws the playing area of the nearest table: rails, goal mouths, centre line and corners. Run it again, or press |
| Debug on | Changes one geometry value for this session — |
| Debug on | Raise or lower the puck's surface ( |
| Debug on | Two stand-in players holding paddles at the nearest table, to check how players are posed. |
The debug tools refuse to run unless Config.Debug = true, and their chat suggestions only appear then. They do not check the creator permission, so keep debug off on a live server. Their own on-screen messages are not part of the locale files.
Controls#
At a table#
Key | Does |
|---|---|
| Within 2.5 m of a table's centre: opens the menu with Player vs Player and Player vs Bot. Change it with |
During a match#
Key | Does |
|---|---|
| Move the paddle, within your half of the table. Speed: |
| Leave the match. The Leave Match dialog asks you to Confirm or Cancel first. |
Challenges#
Where | Does |
|---|---|
Select an opponent | Click a player to send them the challenge, or close the window to cancel. |
Challenge received | Accept starts the match, Decline tells the challenger. With no answer it closes on its own after 30 seconds. |
Placing a table#
Key | Does |
|---|---|
| Aim — the see-through table follows where the camera looks, up to 50 m away. |
| Set it down. |
| Rotate, for as long as the key is held. |
| Raise or lower, 5 cm per notch. |
| Cancel. |
/ahplace uses the same keys, except that only E sets the table down.
In the creator window#
Control | Does |
|---|---|
+ | A new table. |
Search | Filters the list by name or ID. |
A table in the list | Opens it for editing; selecting it again closes it. |
Teleport button | Takes you to that table, after a confirmation. |
| Closes the window. |
Debug tools#
/ahbounds — the playing area
Drawn just above the nearest table: the side and end rails in white, the goal mouths in orange, the centre line in blue and the four corners in yellow. The values it uses are printed in F8. Hide it with Backspace or by running the command again.
/ahtune — the geometry
/ahtune hx|hy|gw|oz|pz [delta] — half width, half length, goal half-width, puck height and paddle height. The new values show in a notification and as a ready-to-paste line in F8. Width, length and goal width never go below a few centimetres.
/ahtune gw 0.01 # goals 1 cm wider on each side
/ahtune hy -0.02 # playing surface 2 cm shorter at each end
/ahtune pz # paddles 2 cm higher/ahwatch — the pose
Spawns two stand-in players at the nearest table, one at each end, frozen in the playing pose with a hand on their paddle. Use it to judge the table height and the paddle height from the outside, the way spectators will see it.
Debug on during a match
Orange posts mark the edges of both goal mouths, and if no puck model exists in your game a dark disc stands in for the puck, so you can still test the physics.
For Developers#
Air Hockey has no exports. What another resource needs comes from a replicated state bag and the bridge functions in the open files.
Is this player playing air hockey?#
While a player is in a match, their ped carries qah_playing = true. It is replicated, so both sides can read it — to block an emote menu, a phone or a job action while somebody is at the table:
-- server
local ped = GetPlayerPed(source)
if Entity(ped).state.qah_playing then
return -- busy at the air hockey table
end
-- client
if Entity(PlayerPedId()).state.qah_playing then
return
endAir Hockey reads it too: a player whose ped carries it cannot be challenged — the challenger sees That player is busy right now.
The bridge functions#
Function | Side | Decides |
|---|---|---|
| Server | Entry fees. Overridden by |
| Server | Access to the creator, and every create, move and delete. |
| Server | The name in the opponent list and the challenge window. |
| Client | Every message a player sees, and the prompt over each table. |
Examples for each are in Integrations.



