Skip to main content

Python library for connecting to and interacting with Puck servers

Project description

Puck Bridge Python

A Python library for connecting to and interacting with Puck servers. This package provides real-time game state tracking, event handling, and server management capabilities. The PuckBridgeMod is required to be on the server.

Features

  • Real-time game state monitoring
  • Player statistics and performance tracking
  • Event-driven architecture with custom handlers
  • Goal scoring and player action notifications
  • Team balance and player management
  • Server administration commands
  • Performance metrics and FPS monitoring
  • Easy-to-use utility functions
  • Supports multiple servers at once via instance-based API

Installation

pip install puck-bridge-py

Or install from source:

git clone https://github.com/sn0w12/puckbridgepy.git
cd puckbridge
pip install -e .

Quick Start (Instance-based API)

from puck_bridge_py import PuckBridge, Commands, Utilities

bridge = PuckBridge(host="127.0.0.1", port=9000)
bridge.start_server(blocking=True)

commands = Commands(bridge)
utilities = Utilities(bridge)

def on_goal_scored(data):
    team = data.get("team", "unknown")
    player = data.get("players", {}).get("goal", {})
    player_name = player.get("username", "unknown")
    print(f"GOAL! {player_name} scored for {team}!")
    print(f"Current score: {utilities.get_current_score()}")

utilities.register_goal_handler(on_goal_scored)

Multi-Server Example

You can run multiple servers at once, each with their own state and handlers:

from puck_bridge_py import PuckBridge, Commands, Utilities

bridge1 = PuckBridge(host="127.0.0.1", port=9000)
bridge2 = PuckBridge(host="127.0.0.1", port=9001)

bridge1.start_server(blocking=False)
bridge2.start_server(blocking=False)

commands1 = Commands(bridge1)
utilities1 = Utilities(bridge1)

commands2 = Commands(bridge2)
utilities2 = Utilities(bridge2)

def on_goal1(data):
    print("Bridge1 goal:", data)
utilities1.register_goal_handler(on_goal1)

def on_goal2(data):
    print("Bridge2 goal:", data)
utilities2.register_goal_handler(on_goal2)

commands1.send_system_message("Hello from server 1!")
commands2.send_system_message("Hello from server 2!")

Core Concepts

Game State Management

The library automatically tracks:

  • Players: Names, teams, statistics, connection status
  • Game State: Score, time, period, game phase
  • Performance: FPS, server performance metrics

Event System

Register handlers for specific game events:

  • goal_scored - When a goal is scored
  • player_spawned - When a player joins
  • player_despawned - When a player leaves
  • game_state - When game state changes

Game Phases:

  • None - No active game
  • Warmup - Pre-game warmup period
  • FaceOff - Face-off is about to begin
  • Playing - Active gameplay
  • BlueScore - Blue team scored (celebration phase)
  • RedScore - Red team scored (celebration phase)
  • Replay - Goal replay is being shown
  • PeriodOver - Current period has ended
  • GameOver - Game has completely finished

API Reference

Instance-based API

Server Management

bridge = PuckBridge(host="127.0.0.1", port=9000)
bridge.start_server(blocking=True)  # or blocking=False for non-blocking
bridge.is_connected()  # Check if connected to game

Game State

game_state_mgr = bridge.get_game_state()
utilities = Utilities(bridge)
utilities.get_current_score()
utilities.get_game_phase()
utilities.get_game_time()
utilities.is_game_in_progress()
utilities.is_game_paused()
utilities.is_game_active()
utilities.is_period_over()
utilities.is_game_over()
utilities.is_warmup()
utilities.is_scoring_phase()

Player Management

utilities.get_all_players()
utilities.get_player_by_username(username)
utilities.get_blue_players()
utilities.get_red_players()
utilities.get_top_scorers(limit=5)

Team Information

utilities.get_team_balance()
utilities.get_player_count()

Utilities

utilities.format_game_time(seconds)
utilities.format_score_string()
utilities.get_performance_stats()

Event Registration

utilities.register_goal_handler(handler)
utilities.register_player_join_handler(handler)
utilities.register_player_leave_handler(handler)
utilities.register_game_state_handler(handler)

Commands

commands = Commands(bridge)
commands.send_system_message(message)
commands.restart_game(reason)
commands.kick_player(steam_id, reason)
commands.kick_player_by_name(username, reason)

Data Classes

Player

@dataclass
class Player:
    client_id: int
    username: str
    state: str = "unknown"
    team: str = "none"  # "blue", "red", or "none"
    role: str = "none"
    number: int = 0
    goals: int = 0
    assists: int = 0
    ping: int = 0
    handedness: str = "right"
    country: str = ""
    steam_id: str = ""
    patreon_level: int = 0
    admin_level: int = 0
    last_updated: datetime = field(default_factory=datetime.now)

GameState

@dataclass
class GameState:
    phase: str = "unknown"  # "None", "Warmup", "FaceOff", "Playing", "BlueScore", "RedScore", "Replay", "PeriodOver", "GameOver"
    time: float = 0.0
    period: int = 0
    blue_score: int = 0
    red_score: int = 0
    last_updated: datetime = field(default_factory=datetime.now)

Performance

@dataclass
class Performance:
    current_fps: float = 0.0
    min_fps: float = 0.0
    average_fps: float = 0.0
    max_fps: float = 0.0
    last_updated: datetime = field(default_factory=datetime.now)

Configuration

Server Configuration

The server can be configured with custom host and port settings:

from puck_bridge_py import PuckBridge

# Default configuration (127.0.0.1:9000)
bridge = PuckBridge()
bridge.start_server()

# Custom port
bridge = PuckBridge(port=9001)
bridge.start_server()

# Custom host and port
bridge = PuckBridge(host="0.0.0.0", port=8080)
bridge.start_server()

# Listen on all interfaces
bridge = PuckBridge(host="0.0.0.0")
bridge.start_server()

Default Settings:

  • Host: 127.0.0.1 (localhost only)
  • Port: 9000

Security Note: Using 0.0.0.0 as the host will make the server accessible from other machines on the network. Only use this if you understand the security implications.

Game Setup

  1. Start your Puck Bridge Python server (with desired host/port)
  2. Configure your Puck game to connect to the correct address
  3. Join a game - the library will automatically start receiving data

Default Connection: 127.0.0.1:9000

Usage Examples

Basic Game Monitoring

import time
import threading
from puck_bridge_py import PuckBridge, Utilities

bridge = PuckBridge()
utilities = Utilities(bridge)

def monitor_game():
    while True:
        if utilities.get_player_count() > 0:
            phase = utilities.get_game_phase()
            score = utilities.get_current_score()
            time_str = utilities.format_game_time(utilities.get_game_time())

            print(f"Phase: {phase} | Time: {time_str} | Score: Blue {score['blue']} - Red {score['red']}")

        time.sleep(10)

threading.Thread(target=monitor_game, daemon=True).start()
bridge.start_server()

Advanced Event Handling

from puck_bridge_py import PuckBridge, Utilities

bridge = PuckBridge()
utilities = Utilities(bridge)

def on_goal_scored(data):
    team = data.get("team")
    players = data.get("players", {})
    scorer = players.get("goal", {}).get("username", "Unknown")

    assists = []
    for assist_key in ["assist1", "assist2"]:
        if assist_key in players:
            assists.append(players[assist_key].get("username", "Unknown"))

    print(f"GOAL by {scorer} ({team})")
    if assists:
        print(f"   Assists: {', '.join(assists)}")

    top_scorers = utilities.get_top_scorers(3)
    print("   Top Scorers:")
    for i, player in enumerate(top_scorers):
        if player.goals > 0:
            print(f"     {i+1}. {player.username}: {player.goals}G {player.assists}A")

def on_player_joined(data):
    player = data.get("player", {})
    username = player.get("username", "Unknown")
    team = player.get("team", "none")

    print(f"{username} joined (Team: {team})")

    balance = utilities.get_team_balance()
    print(f"   Teams: Blue {balance['blue']} - Red {balance['red']}")

utilities.register_goal_handler(on_goal_scored)
utilities.register_player_join_handler(on_player_joined)

bridge.start_server()

Server Administration

from puck_bridge_py import PuckBridge, Commands, Utilities

bridge = PuckBridge()
commands = Commands(bridge)
utilities = Utilities(bridge)

def admin_commands():
    while True:
        command = input("Admin> ").strip().lower()

        if command.startswith("kick "):
            username = command[5:]
            if commands.kick_player_by_name(username, "Kicked by admin"):
                print(f"Kicked {username}")
            else:
                print(f"Failed to kick {username}")

        elif command == "restart":
            if commands.restart_game("Game restarted by admin"):
                print("Game restarted")
            else:
                print("Failed to restart game")

        elif command.startswith("msg "):
            message = command[4:]
            if commands.send_system_message(f"[ADMIN] {message}"):
                print("Message sent")
            else:
                print("Failed to send message")

        elif command == "players":
            players = utilities.get_all_players()
            for player in players.values():
                print(f"  {player.username} (Team: {player.team}, Goals: {player.goals})")

        elif command == "quit":
            break

import threading
threading.Thread(target=admin_commands, daemon=True).start()
bridge.start_server()

Performance Monitoring

from puck_bridge_py import PuckBridge, Utilities
import time

bridge = PuckBridge()
utilities = Utilities(bridge)

def performance_monitor():
    while True:
        if utilities.is_connected():
            stats = utilities.get_performance_stats()
            player_count = utilities.get_player_count()

            print(f"Performance: {stats['current_fps']:.1f} FPS "
                  f"(avg: {stats['average_fps']:.1f}) | "
                  f"Players: {player_count}")

        time.sleep(5)

import threading
threading.Thread(target=performance_monitor, daemon=True).start()
bridge.start_server()

Event Data Structures

Goal Scored Event

{
    "team": "blue",  # or "red"
    "scores": {"blue": 1, "red": 0},
    "players": {
        "goal": {"username": "PlayerName", "clientId": 123},
        "assist1": {"username": "AssistPlayer", "clientId": 124},  # optional
        "assist2": {"username": "AssistPlayer2", "clientId": 125}  # optional
    }
}

Player Spawned Event

{
    "player": {
        "clientId": 123,
        "username": "PlayerName",
        "team": "blue",
        "state": "playing",
        "goals": 0,
        "assists": 0,
        # ... other player fields
    }
}

License

This project is licensed under the MIT License - see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

puck_bridge_py-0.2.3.tar.gz (16.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

puck_bridge_py-0.2.3-py3-none-any.whl (16.2 kB view details)

Uploaded Python 3

File details

Details for the file puck_bridge_py-0.2.3.tar.gz.

File metadata

  • Download URL: puck_bridge_py-0.2.3.tar.gz
  • Upload date:
  • Size: 16.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for puck_bridge_py-0.2.3.tar.gz
Algorithm Hash digest
SHA256 5ae4ed10f08fd7871b79791bcd12534e520e40f5a81432d8f5db87be7a1ef950
MD5 927c2c7e9d03e9ce025ecc34fd164f64
BLAKE2b-256 6277f004e0b769aa9882ab168ac564ed5e9d55f0244a96a49f6339a386acb218

See more details on using hashes here.

File details

Details for the file puck_bridge_py-0.2.3-py3-none-any.whl.

File metadata

  • Download URL: puck_bridge_py-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 16.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for puck_bridge_py-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 eba442d9ea5cfa6930732ecdeacba7e2cb4a41b68d2fe09c33fb01619a8ae9ce
MD5 93a01418e7145e2a056dd784b3d09a8c
BLAKE2b-256 e8eb0c191fde9800539be1541878e6124a774f052882bbbfe604ef9a8f6b2e12

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page