PEAK
Install

Details

Last Updated
First Uploaded
Downloads
48
Likes
0
Size
4.8MB
Dependency string
Flonou-FFSPeak-0.9.1
Dependants

FFSPeak

Version: 0.9.0
Compatible with: PEAK 1.65.a

FFSPeak is a multiplayer observer and synchronization system for PEAK. It consists of a BepInEx plugin (Unity mod) and a Python WebSocket server that enables real-time spectating, lobby management, and item spawn synchronization.

Features

  • Observer System: Watch multiple players in real-time with configurable lobbies
  • Lobby Management: Create password-protected lobbies with player and time limits
  • State Synchronization: Real-time player position, animation, and status updates
  • Item Spawn Sync: Synchronized item spawning across all players
  • API Integration: REST and SSE endpoints for score tracking and event monitoring
  • Recording/Playback: Session recording and replay (⚠️ experimental, not yet complete)

Quick Start

Running Multiple PEAK Instances

To test or run multiple PEAK clients simultaneously:

  1. Navigate to your PEAK installation directory (e.g., SteamLibrary\steamapps\common\PEAK\)
  2. Create a file named steam_appid.txt next to the PEAK executable
  3. Add the following content:
    3527290
    
  4. Launch PEAK.exe directly (not through Steam) — you can now run multiple instances

Server Setup

The Python server requires Redis as a message broker and data store.

Prerequisites

Installation

Note: The Python server files are included in the Thunderstore package under the server/ directory. After installing the mod, you can find them in your BepInEx plugins folder at BepInEx/plugins/FFSPeak/server/.

  1. Navigate to the server directory:

    # If installed via Thunderstore
    cd BepInEx/plugins/FFSPeak/server
    
    # Or if cloning from repository
    cd FFSPeakServer
    
  2. Install Python dependencies:

    pip install -r requirements.txt
    
  3. Start Redis (if not already running):

    docker run -d --name redis -p 6379:6379 redis:7
    
  4. Launch the WebSocket server:

    python server_ws.py --api-key-file api_key.txt --port 4000 --http-port 4001
    

Command Line Options

The server accepts the following arguments:

Option Default Description
--port 4000 WebSocket server port
--http-port 4001 HTTP REST API and SSE port
--api-key-file Path to file containing API key (recommended)
--api-key API key as plain string (⚠️ insecure, visible in process list)

Environment variables can also be used:

  • WS_PORT, HTTP_PORT: Override default ports
  • SSE_API_KEY_FILE: Path to API key file

Configuration File

Server behavior is configured via environment variables. See FFSPeakServer/docs/configuration.md for details on:

  • Redis connection settings (REDIS_HOST, REDIS_PORT)
  • Pub/Sub channels (REDIS_STATE_CHANNEL, REDIS_EVENTS_CHANNEL)
  • Performance tuning (observer tick rates, LOD settings)

Client Configuration

Command Line Options

The FFSPeak client plugin supports several command line options for easier testing and configuration:

Option Aliases Description
-observer Force observer mode (disables player mode)
-player Force player mode (disables observer mode)
-serverurl <url> --server-url, --serverurl, -url, --url Override WebSocket server URL
-port <port> --port, -wsport, --ws-port, --wsport Override WebSocket server port

Example usage:

# Launch as observer connecting to a custom server
PEAK.exe -observer -serverurl ws://example.com:4000

# Launch as player with custom port
PEAK.exe -player -port 8080

Using FFSPeak (Observer Workflow)

Creating a Game (as Observer)

  1. Start an offline game
  2. Create a lobby:
    • Set an optional password
    • Select a level from the dropdown
    • Set player limit (max players allowed)
    • Set time limit (match duration)
    • Freeze on Join: Toggle whether players should be frozen when they connect
      • Observers can unfreeze players later using the "Start/Resume" button
  3. Click "Start/Set" to configure the lobby
  4. Click "Join" to enter the game as an observer

Joining a Game (as Player)

  1. Start an offline game
  2. Select a lobby from the list
  3. Enter password (if required)
  4. Click "Join"

Observer UI Utilities

When connected as an observer, the following hotkeys open administration panels:

Key Panel Description
F3 Remote Player Administration Manage connected players: kick, teleport, spawn items, apply afflictions, modify stats
F4 Message System Send messages to players or broadcast announcements
F8 FPS Display Toggle FPS counter (available to all users)
F9 Lobby Manager Main lobby creation and configuration panel
F10 Admin Commands Execute administrative commands and server operations
F11 Toolbox Additional observer utilities and tools

Note: F8 (FPS display) is available to both observers and players.

Item Spawn Synchronization

FFSPeak integrates with ItemSpawnSync to synchronize item spawns across all players.

Creating/Uploading Spawn Data

  1. Join as an observer using the "Join Without Spawn" button (found in the Advanced foldout)
  2. Use ItemSpawnSync shortcuts (default keybinds):
    • Ctrl+F8: Load loot data from level
    • Ctrl+F4: Spawn items at current position
    • Ctrl+F5: Save spawned items to file
  3. Restart the game (optional, to clear local state)
  4. Select the spawn data file in the FFSPeak Advanced foldout
  5. Click "Send" to upload spawn data to the server
  6. Restart again (if needed) — spawn data should now sync to all players

Note: The spawn synchronization workflow is still being refined. Users may need to restart the game to get the last spawn data.


Observer Authentication

Observer Key Setup

Observer keys control who can connect to the server as an observer. If no observer keys are defined, anyone can join as an observer (open registration mode).

Creating Observer Keys

Observer keys are stored in the FFSPeakServer/observer_keys/ directory as .txt or .json files.

Option 1: Manual creation

  1. Create a file in FFSPeakServer/observer_keys/:

    # Text file (one key per line)
    echo "my-secure-observer-key-123" > observer_keys/team_keys.txt
    
    # JSON file (array format)
    echo '["key1", "key2", "key3"]' > observer_keys/team_keys.json
    
  2. Reload keys into Redis:

    • While the server is running, press k in the server console to reload keys
    • Or restart the server (keys are loaded automatically on startup)

Option 2: Interactive server commands

While the server is running, use the following console commands:

Command Description
k Reload observer keys from observer_keys/ directory
ka Add a new observer key interactively
kg Generate and save a random observer key to a JSON file

Option 3: Programmatic generation

from observer_keys import generate_and_save_random_key
key = generate_and_save_random_key('my_team.json')
print(f"Generated key: {key}")

Using Observer Keys

When connecting as an observer:

  1. The client will prompt for an observer key (if keys are configured on the server)
  2. Enter your assigned key
  3. If authentication succeeds, you'll be granted observer access

Security Note: If you want to restrict observer access, always configure at least one observer key. Without any keys defined, the server operates in open mode and accepts all observer connections.


HTTP API

The server exposes an HTTP/SSE API for external integrations (e.g., overlays, bots, dashboards).

API Key Setup

API keys (different from observer keys) are required to access protected HTTP/SSE endpoints. To generate a key:

  1. Create a file (e.g., api_key.txt) containing a secure random string:

    # Generate a random key (Linux/Mac)
    openssl rand -base64 32 > api_key.txt
    
    # Generate a random key (Windows PowerShell)
    -join ((48..57) + (65..90) + (97..122) | Get-Random -Count 32 | % {[char]$_}) > api_key.txt
    
  2. Pass it to the server via --api-key-file api_key.txt

  3. Use this key in HTTP headers: X-API-Key: <your-key>

Available Endpoints

  • GET /api/score — Retrieve current game score/state
  • SSE /api/events — Subscribe to real-time events:
    • Timer start/stop/finish
    • Player finish events
    • Level changes

See FFSPeakServer/WEBSOCKET_README.md for full protocol documentation.


Recording and Playback (⚠️ Experimental)

FFSPeak includes a recording system to capture game sessions and replay them later.

Status: This feature is incomplete and not fully functional in the current version. Use at your own risk.

To use (when functional):

  1. Start server_playback.py alongside the WebSocket server
  2. Sessions are automatically recorded to records/
  3. Replay using playback commands (see FFSPeakServer/docs/server_playback.md)

Building the Plugin

Prerequisites

  • .NET SDK: 6.0 or later
  • BepInEx 5: Installed in your PEAK game directory
  • Game assemblies: Located in <PEAK_Install>/PEAK_Data/Managed/

Setup

  1. Copy Config.Build.user.props.template to Config.Build.user.props
  2. Edit Config.Build.user.props:
    <GamePath>C:\Path\To\Your\PEAK</GamePath>
    <PluginOutputPath>C:\Path\To\BepInEx\plugins\</PluginOutputPath>
    

Build Commands

Debug build (includes testing shortcuts):

dotnet build -c Debug

Release build:

dotnet build -c Release

Thunderstore package:

dotnet build -c Publish -target:PackTS -v d

Package output: artifacts/thunderstore/

Debug Mode Features

When built in Debug configuration, the plugin includes testing shortcuts:

  • F9: Open checkpoint teleport UI
  • Ctrl + Numpad 0–9: Teleport to checkpoints (0 = spawn, ascending to peak)
  • Invincibility toggle: Available via checkpoint UI

⚠️ Debug shortcuts are disabled in Release and Publish builds. They should not appear in distributed versions.


Documentation

For detailed server architecture and API documentation:


Dependencies

Required Mods

Recommended Mods


License

See LICENSE for details.


Contributing (The project not opened to contributions yet)

Contributions are welcome! Please ensure:


Support

For issues, questions, or feature requests, please contact us on the peak modding discord thread dedicated to this mod

Thunderstore development is made possible with ads. Please consider making an exception to your adblock.