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.2.tar.gz (16.3 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.2-py3-none-any.whl (15.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: puck_bridge_py-0.2.2.tar.gz
  • Upload date:
  • Size: 16.3 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.2.tar.gz
Algorithm Hash digest
SHA256 b9f1a41203ae7c5d03cd0b828e1f4ebad748fc93f8f78633cc20bbabd9d202f5
MD5 08557949976453ac5245b7ae475de0a4
BLAKE2b-256 19dc0f7b5810b165e231f94ea1b54777d480632cda8e351c23da0620801303b9

See more details on using hashes here.

File details

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

File metadata

  • Download URL: puck_bridge_py-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 15.9 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 92456e5a187c06070320fc25c861c3be32279b289be6921f86b9aed2ea107f46
MD5 f668f53160df4a4422484ca70ad46a5e
BLAKE2b-256 8b331f46c0769d30f4e3c78ad15520be7f50bda920a2868c92b76ff6e9b82ae3

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