My primary language is not english, so this text may contain lots of mistakes, please forgive them...
MBilliards, it's a billiard game in gmod, unique and complete!
The code lacks at comments, but it's not that difficulty to understand how it works, and the addon
was tested in SinglePlayer and Multiplayer in LAN.
All models (billiard tables, cue and balls) are Real Scaled:
Balls: 57mm of diamenter;
Cue: 154cm length, cue tip with 12mm of diameter;
(*) Full Singleplayer and Multiplayer support;
(*) High quality models/materials;
(*) Custom wood style GUI (built for 1024x768, but you'll not have any problem with other resolutions [I hope]);
(*) 3 table sizes (9ft, 10ft, 12ft) and 3 table colors (Green, Light blue, Red);
Commands: (These commands doesn't have to be called directly from the console):
(*) "billiard_quit" - used to get you out of a billiard game, NOTE: If you quit, you'll lose the game.
(*) "billiard_acceptorefuse" Bool - only the "owner" of a billiard table can use this command,
this is used to accept or refuse a "join game" request from other players.
(*) "billiard_admins_only" def: false - Sets whether if only admins can create new billiard tables or not
(*) "billiard_max_tables" def: 4 - How many billiard tables are allowed to be created, this value is global.
(*) "billiard_req_time" def: 20 - Request time limit, in seconds, if one player requested to join a billiard table,
the "owner" of that table will have 20 seconds to refuse or accept, it's automatically refused if it reaches zero.
(*) "billiard_no_training" def: true - Should Training mode be disabled? In MY point of view, the training mode should
always be disabled unless in single player or LAN with low players, because in the Training mode only one
player is allowed per billiard table.
(*) When a ball collides with other ball or with the table at low velocity (usually less than ~0.15) the ball's velocity
will be increased (Not much), I'm sure it's related to the engine, so most of these kind of problems can't be fixed.
Keep in mind that Source Engine physics isn't perfect nor optmized for billiard playing.
(*) If you quit the game while no-clipping inside the world or any other prop it'll cause errors, I really don't understand why this
The Options when creating a billiard table:
(*) Enable Anti BFH (BFH means Ball Flying over Hole) - If the ball's velocity is high enough and has been stroke
into a pocket the possibilities that the ball hits the pocket and returns back are huge, so to avoid such things I have created
a way to force this ball to be pocketed (althought that effect still happens), actually there's two methods of doing so:
Method 1 - Uses the ball's think function to detect if it's over a hole, by using a trace.
Method 2 - Uses the Billiard table think function to detect if any ball is over a pocket, by using ents.FindInSphere()
for each pocket.
Disabling this option may increase performance.
(*) MingeBag Protection - I've included a way to protect billiard tables (also cues and balls) from being messed up
by mingebags, if enabled, the table will be un-moveable, tools won't work, etc. Also, a special model is placed over
the billiard table to avoid mingebags from moving the balls by walking over them or using other models to mess up
with the game.
(*) Training Mode - If enabled, no other player will be able to request to play with you, also, you can move any ball
at any time (Game rules still apply!).
(*) SmartCue - If enabled, the Cue won't pass trought into any ball (but still passes trough the table), it uses a trace to
check if there's a ball in it's "route", this feature is just visual, it doesn't affect gameplay.
Disabling this option may increase performance.
(*) Cue FirstPerson - If enabled, you will have a FirstPerson camera in the cue during your Turn, like I said before, it uses the
server Move hook to do it's movement. Disabling this option may increase performance.
(*) GameType - Here you can choose what game type you want to play, currently there is 8-Ball, 9-Ball, Snooker and Rotation.
Each gametype has it's own rules.
(*) Round Time - Amount of time that the player will have to position cue ball / aim / shoot, if it reaches zero, it's a foul
and the incoming player will have the CueBall in hand. You can choose 15sec, 30sec, 45sec or 60sec.
(*) TableSize - You can choose between 3 table sizes: 9ft, 10ft and 12ft
You cannot play Snooker in 9ft table!
Mouse Client Configuration:
As of revision 6, a new feature has been added, it's the client mouse configuration, which allows each client to
configure mouse sensitivity and inverted X/Y axis.
This mouse configuration only affects mouse while playing in a billiard game!
You can access this menu by pressing F7
"Mouse Sensitivity" def: "2" - Mouse sensitivity, value range from 0.5 to 10.
"Cue Invert Mouse Horizontally" def: 0 - Mouse inverted horizontally? Only works while in Cue Camera
"Cue Invert Mouse Vertically" def: 0 - Mouse inverted vertically? Only works while in Cue Camera
"Invert Mouse Horizontally" def: 0 - Mouse inverted horizontally?
"Invert Mouse Vertically" def: 0 - Mouse inverted vertically?
Note: These mouse setting are saved locally, which means you don't have to configure each time you enter a server or re-open gmod.
Entering a Billiard table:
Just walk close to one table and press "Use" button (usually it's the E button), but if the table already has a player
he is considered the "owner" of such table and will be his decision if you will be able to play with him or not.
Exiting a billiard table:
Just press the "Use" button again (usually it's the E button) and you be prompted if you really want to quit the game.
Note: by quiting a game you'll automatically lose the game.
If the option CueFirstPerson is enabled:
Cue controlling is done by moving your mouse(forward/backward/left/right);
to strike, keep pressing your "Attack2" button (usually it's the right mouse button) and move the mouse forward/backward;
You can also zoom in and zoom out by binding your mouse wheel (just type this in the console):
bind mwheelup "invprev; decbzoom"
bind mwheeldown "invnext; incbzoom"
After striking with the mouse, don't release the right mouse button until your mouse is fully stopped.
else if the option CueFirstPerson is disabled:
Aiming the cue is done by player movement, to shoot you'll have to set the shot force manually by using the same
zoom binding, and the shot is done by pressing the "Attack" button (usually it's the left mouse button)
This is a light weight method, but is harder to aim.
Ball positioning (only while in hand) is done by keeping pressed the "Sprint" button (usually it's the Left Shift button)
and moving your mouse forward/backward/left/right.
To set a biliard table's configuration after it's creation, exit the game (if you are playing) and keep the "Reload" button pressed
(usually it's the R button) and press "Use" button (usually it's the E button), a window will appear with the current
In Training Mode, to change the ball press the Forward button (usually it's the W button) or Back button (usually it's the S button)
and you'll be able to move it.
If a player jumps in a table with the mingebag protection on, he automatically loses the game.
Pocketing the CueBall is a foul and in all games (except in Snooker) the incoming player have the CueBall in hand.
For LUA developers:
If you want to implement a gambling system, I've also made some cool hooks for it:
hook.Add("CanPlayerEnterBilliard", "myCanPlayerEnter", function(ptable, ply) end)
hook.Add("OnBilliardGameStart", "myBilliardStartFunc", function(ptable, ply1, ply2) end)
hook.Add("OnBilliardGameEnd", "myBilliardEndFunc", function(ptable, winner, loser) end)
NOTE: You should always verify if ply2/loser exist, because these hooks are called even with only one player!
The hook "OnBilliardGameStart" is called before anything and "OnBilliardGameEnd" is called after everything else.
Slot1 should Always have a player if is intend to play!
When creating a billiard table, make sure you set its size before call Spawn(), and never forget to call SetConfig()
[release]Gameplay video: (Recorded in SinglePlayer):Code:local ent = ents.Create("billiard_table") ent:SetSize(9) -- Can be 9, 10 or 12 ent:SetPos(pos) ent:Spawn() ent:SetConfig() -- As of revision 9, you can leave blank to use the default config
[/release][release]SVN Download: http://mbilliards.googlecode.com/svn/trunk/
If you don't know how to use SVN, follow this tutorial[/release][release]ChangeLog:
Version 1.0.4 - Revision 12
(*) "Move" hook no longer returns CMoveData, which was causing issues with other "Move" hooks.
(*) Added new gametype: Carambol
(*) Fixed Camera problem in training mode
(*) Added Client Mouse adjustments, can be accessed by pressing F7
(*) Added one more LOD to cue and to each billiard table
(*) Fixed problem related to requests menu
(*) Using now the "base_anim" base for the entites
(*) Ball entities are now stored directly in the billiard table, less use of ents.GetByIndex()
(*) After player respawns their weapons are stripped
(*) Addded Play area, leaving this area may result in a loss of game
(*) Fixed "unknown" foul reason in Snooker
(*) Fixed the problem where sometimes the next player is wrong
(*) Changed ball's speed loss when collides with other ball
(*) Improved some functions
(*) New Icon.tga image
(*) Addon released[/release]
Please let me know if you find any other bug.
MBilliards by Athos