This documentation contains all installation steps as well as explanations for table control, UI logic, training features and OBS integration.
sudo apt update sudo apt install nginx php8.3-fpm php8.3-sqlite3 -y
sudo mkdir -p /var/www/billard/assets/css sudo mkdir -p /var/www/billard/assets/js sudo mkdir -p /var/www/billard/logos
sudo chown -R www-data:www-data /var/www/billard sudo chmod -R 775 /var/www/billard
sudo chown -R www-data:www-data /var/www/html sudo chmod -R 775 /var/www/html
Configuration path: /etc/nginx/sites-available/default
server {
listen 80;
root /var/www/billard;
index index.php index.html;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
}
}
sudo nginx -t sudo systemctl restart nginx
| View | URL | Description |
|---|---|---|
| Scoreboard | http://[IP]/ | Main application for players |
| Monitor (DE) | http://[IP]/monitor_de.php | Live display of all tables (German) |
| Monitor (EN) | http://[IP]/monitor_en.php | Live display of all tables (English) |
| OBS Small | http://[IP]/obs_small.php?Tisch=1 | OBS overlay small - Style 1 |
| OBS Small 2 | http://[IP]/obs_small_2.php?Tisch=1 | OBS overlay small - Style 2 (black scores, red stripe) |
| OBS Small 3 | http://[IP]/obs_small_3.php?Tisch=1 | OBS overlay small - Style 3 (blue scores) |
| OBS Small 4 | http://[IP]/obs_small_4.php?Tisch=1 | OBS overlay small - Style 4 (Maroon/Bordeaux) |
| OBS Big | http://[IP]/obs_big.php?Tisch=1 | OBS overlay large - Style 1 |
| OBS Big 2 | http://[IP]/obs_big_2.php?Tisch=1 | OBS overlay large - Style 2 (split stripes, logos) |
| OBS Big 3 | http://[IP]/obs_big_3.php?Tisch=1 | OBS overlay large - Style 3 (logos, blue scores) |
| OBS Big 4 | http://[IP]/obs_big_4.php?Tisch=1 | OBS overlay large - Style 4 (Maroon/Bordeaux, logos) |
| Hilfe (DE) | http://[IP]/help_de.html | Documentation (German) |
| Help (EN) | http://[IP]/help_en.html | This documentation (English) |
| Parameter | Behavior |
|---|---|
| index.php | Free selection: Tables 1-8 selectable in setup |
| index.php?Tisch=0 | Admin mode: Table selection hidden |
| index.php?Tisch=1 | Fixed mode: Table fixed (1-8) |
The color scheme can be set directly via a URL parameter. Both German and English names are accepted:
| Parameter (EN) | Parameter (DE) | Color Scheme |
|---|---|---|
| ?theme=yellow | ?theme=gelb | Default (Yellow/Gold) |
| ?theme=blue | ?theme=blau | Blue/Cyan |
| ?theme=green | ?theme=gruen | Green |
| ?theme=white | ?theme=weiss | Light Mode |
The language can be set directly via a URL parameter:
| Parameter | Language |
|---|---|
| ?lang=de | German |
| ?lang=en | English |
http://[IP]/?Tisch=1&theme=blue&lang=en
http://[SERVER-IP]/obs_big.php?Tisch=1| Version | Width | Height | Usage |
|---|---|---|---|
| obs_small.php | 700 px | 100 px | Compact display, stream corner |
| obs_small_2.php | 700 px | 120 px | Separate fields, black scores, red stripe |
| obs_small_3.php | 700 px | 120 px | Separate fields, blue scores |
| obs_small_4.php | 500 px | 120 px | Maroon/Bordeaux design, compact |
| obs_big.php | 1400 px | 150 px | Full width, bottom of screen |
| obs_big_2.php | 1400 px | 180 px | Split stripes (name/club), logos, red accents |
| obs_big_3.php | 1400 px | 150 px | Logos, blue score boxes |
| obs_big_4.php | 1200 px | 150 px | Maroon/Bordeaux design, logos, yellow accents |
Logos are automatically displayed when a PNG file with the exact club name exists:
# Create logo folder sudo mkdir -p /var/www/billard/logos # Upload logos (examples) /var/www/billard/logos/BC Berlin.png /var/www/billard/logos/BC Bremen.png /var/www/billard/logos/Imperium.png
During a running game, the discipline and running game time are displayed in the header.
HH:MM:SS formatIn addition to the browser overlays, individual TXT files are automatically generated in the /obs/ folder. These can be used as browser sources in OBS.
| File | Content | Example |
|---|---|---|
table1_discipline.txt | Discipline | 14/1 |
table1_raceto.txt | Race to | 100 |
table1_player1.txt | Player 1 name | Max Mustermann |
table1_player2.txt | Player 2 name | John Doe |
table1_club1.txt | Club player 1 | BC Berlin |
table1_club2.txt | Club player 2 | BC Bremen |
table1_score1.txt | Score player 1 | 42 |
table1_score2.txt | Score player 2 | 38 |
table1_innings1.txt | Innings player 1 | 12 |
table1_innings2.txt | Innings player 2 | 11 |
table1_highseries1.txt | High run player 1 | 15 |
table1_highseries2.txt | High run player 2 | 9 |
table1_series1.txt | Current run player 1 | 3 |
table1_series2.txt | Current run player 2 | 0 |
table1_gd1.txt | GD player 1 | 3.50 |
table1_gd2.txt | GD player 2 | 3.45 |
table1_starttime.txt | Start time | 14:30:00 |
table1_matchtime.txt | Match time (HH:MM) | 01:23 |
table1_balls1.txt | Balls pocketed player 1 (One Pocket / Bank Pool) | 5 |
table1_balls2.txt | Balls pocketed player 2 (One Pocket / Bank Pool) | 3 |
table1_runout1.txt | Runouts player 1 | 2 |
table1_runout2.txt | Runouts player 2 | 1 |
The recommended method is using a Browser source with the xObsBrowserAutoRefresh plugin:
http://[SERVER-IP]/obs/table1_score1.txtbody {
background-color: rgba(0, 0, 0, 0);
color: #ffffff;
font-family: "Arial";
font-size: 40px;
font-weight: bold;
text-shadow: 2px 2px 4px #000000;
overflow: hidden;
}
To display text vertically centered with horizontal alignment, use the following CSS variants:
Text left-aligned:
body {
background-color: rgba(0, 0, 0, 0);
color: #ffffff;
font-family: "Arial";
font-size: 40px;
font-weight: bold;
text-shadow: 2px 2px 4px #000000;
overflow: hidden;
margin: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: flex-start;
}
Text centered:
body {
background-color: rgba(0, 0, 0, 0);
color: #ffffff;
font-family: "Arial";
font-size: 40px;
font-weight: bold;
text-shadow: 2px 2px 4px #000000;
overflow: hidden;
margin: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
Text right-aligned:
body {
background-color: rgba(0, 0, 0, 0);
color: #ffffff;
font-family: "Arial";
font-size: 40px;
font-weight: bold;
text-shadow: 2px 2px 4px #000000;
overflow: hidden;
margin: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: flex-end;
}
OBS_INTERVAL in config.php). The /obs/ folder is created automatically.
For 8-Ball, 9-Ball and 10-Ball, the break mode can be selected in setup:
| Mode | Behavior |
|---|---|
| Alternate Break | The break alternates after each rack (+ or -) to the other player |
| Winner Break | The winner of a rack keeps the break (only switches on +) |
All disciplines (14/1, 8-Ball, 9-Ball, 10-Ball) have a Help Button (question mark) in the control bar.
| Discipline | Pages | Features |
|---|---|---|
| 14/1 Continuous | 5 rule pages + 7 examples | Rerack examples with before/after SVGs |
| 8-Ball | 4 rule pages | Rack image (SVG) directly on the "Rack & Break" page |
| 9-Ball | 4 rule pages | Rack image (SVG) directly on the "Rack & Break" page |
| 10-Ball | 4 rule pages | Rack image (SVG) directly on the "Rack & Break" page |
/regeln/ folder. The popup is scrollable and has Prev/Next buttons for navigation.
The GD (Game Average = Points / Innings) is displayed for 14/1 games in multiple places:
| Location | Display | Description |
|---|---|---|
| Running Game | GD: X.XX | Live GD in the stats row below the score (Inn | Series | HS | GD) |
| Player Stats | Best GD: X.XX | Highest GD ever achieved on the player card |
| Champions | Best GD | New champion card for the player with the highest GD |
| History | Innings: X / HS: X / GD: X.XX | GD per player in each 14/1 history entry |
Each player now has a history chart for their 14/1 games. The chart shows the development of high run and GD over the last 20 matches.
| Element | Color | Y-Axis | Description |
|---|---|---|---|
| High Run | Green | Left (0-100) | Best run per game |
| GD | Blue | Right (0-20) | Game average per match |
| X-Axis | - | - | Last 20 games (-20 to 0) |
Below the chart the following values are displayed:
The scoreboard now supports full multi-language capability. The language can be switched at any time in the sidebar.
| Language | Code | File |
|---|---|---|
| German | de | /assets/lang/de.json |
| English | en | /assets/lang/en.json |
During a 14/1 game, an overview of all innings played so far can be displayed at any time.
| Column | Description |
|---|---|
| Inn. | Inning number |
| Points (left) | Points of player 1 in this inning |
| Score | Current score after the inning |
| Points (right) | Points of player 2 in this inning |
61 points game with the 3-foul rule. If a player commits 3 fouls in a row, they lose the game.
Sink balls into your designated pocket. Default target: 8 balls.
Only bank shots allowed. Target: 5 balls.
Only bank shots with all 15 balls. Target: 8 balls.
8-Ball, 9-Ball and 10-Ball can be played as doubles (2 vs 2). Team names are automatically combined.
| Level | Errors | GD | Target | Maximum |
|---|---|---|---|---|
| Level 1 | 2 | 4 | 120 | 150 |
| Level 2 | 1 | 6 | 120 | 150 |
| Level 3 | 0 | 12 | 120 | 150 |
| Level 4 | 0 | 17 | 170 | 200 |
| Level | Errors | Start Balls | Target | Maximum |
|---|---|---|---|---|
| Level 1 | 2 | 4 | 40 | 90 |
| Level 2 | 1 | 6 | 60 | 90 |
| Level 3 | 0 | 9 | 90 | 90 |
Bowling scoring on the pool table. Single player training with classic bowling point calculation.
| Property | Value |
|---|---|
| Frames | 10 |
| Balls per Frame | 10 |
| Max. Attempts per Frame | 2 (Frame 10: up to 3) |
| Maximum Score | 300 (12 Strikes) |
| Result | Symbol | Points |
|---|---|---|
| Strike | X (red) | 10 + next 2 throws |
| Spare | / (blue) | 10 + next 1 throw |
| Open | Number | Sum of pocketed balls |
| PIN Type | Default | Usage |
|---|---|---|
| Master PIN | 12345 |
Manage players, delete stats, delete history entries |
| Player PIN | 000000 |
Start training |
assets/js/app.js (line 7): masterPin: "12345"
| Endpoint | Description |
|---|---|
api.php?action=load |
Load all player data |
api.php?action=save |
Save data (POST) |
api.php?action=get_tables |
Live table data for Monitor/OBS |
api.php?action=update_table |
Send table update (POST) |
| Problem | Solution |
|---|---|
| HTTP 500 | Check write permissions (Step 4) |
| OBS shows nothing | Increase browser source width, leave CSS empty |
| Logo not visible | Filename must exactly match the club name |
| Training buttons not responding | Check browser console (F12), training.js complete? |
sudo tail -f /var/log/nginx/error.log - Error log
# Create backup cd /var/www sudo tar -czf billard-backup-$(date +%Y%m%d).tar.gz billard/ # Restore backup sudo tar -xzf billard-backup-20250127.tar.gz
All data can be exported as a JSON file and re-imported directly in the app.
billard-backup-YYYY-MM-DD.jsonThe rankings show all players in a sortable table.
| Sort By | Description |
|---|---|
| Win% | Win percentage (default) - Players with less than 5 games are dimmed |
| Wins | Number of games won |
| High Run | Best run (HS) |
| Best GD | Best game average |
Detailed statistics per player, accessible via the player action popup.
| Section | Content |
|---|---|
| Overview | Win%, total games, wins, losses |
| Win Streaks | Current streak (wins/losses), best win streak |
| Per Discipline | Wins, losses, high run, GD - broken down by 14/1, 8-Ball, 9-Ball etc. |
| Head-to-Head | Record against each opponent (W / L) |
The win percentage is displayed directly on each player card (with at least 1 game). Players with 3+ consecutive wins receive a green streak badge (e.g. "5W").
In the champions section, the player with the best win percentage is displayed (minimum 5 games required).
Two players can be compared directly.
| Category | Description |
|---|---|
| Win% | Win percentage |
| Wins / Losses | Total count |
| High Run | Best run |
| Best GD | Game average |
| Head-to-Head | Direct record against each other |
History entries can be filtered:
The game history can be exported as a CSV file (semicolon-separated, UTF-8 with BOM for Excel).
Included columns: Date, Discipline, Race, Player 1, Player 2, Score 1, Score 2, Winner
Shows the development of training results as a line chart.
A new button in the popup menu (tool icons) allows you to cancel the current game.
The appearance of buttons can be configured in config.php.
| Constant | Values | Description |
|---|---|---|
ICON_STYLE |
'round' / 'square' |
Round icons (default) or square icons with rounded corners |
ICON_3D |
true / false |
Enable or disable 3D shadows (neumorphism effect) (default: flat) |
define('ICON_STYLE', 'square'); // 'round' or 'square'
define('ICON_3D', true); // true = 3D shadows, false = flat
The sidebar provides access to Legal Notice (Impressum) and Privacy Policy pages. The pages contain sample texts that should be customized.
In config.php:
define('SHOW_LEGAL', true); // true = visible, false = hidden
legal_de.php, English texts in legal_en.php. Texts switch automatically when changing the language.
The start page (index.php) can optionally be protected with a login. There are two login methods: admin login and player login.
In config.php:
define('REQUIRE_LOGIN', true); // true = login required, false = no login
define('LOGIN_USER', 'admin'); // Admin username
define('LOGIN_PASS', 'billard'); // Admin password
The administrator can log in using the credentials defined in config.php (LOGIN_USER / LOGIN_PASS).
Players can log in with their name and PIN, provided the "Login Startpage" checkbox is enabled in the player editor.
A Logout button appears in the sidebar (only visible when login is active). Clicking it ends the session.
REQUIRE_LOGIN = false (default), no login is required and the logout button is hidden.
Pro Billiard Scoreboard System v4.5 | Developed for billiard players