Tank Game Server Project

A multiplayer tank game server implementation using ProudNet networking library, providing both C# and C++ versions with cross-platform support.

๐Ÿ“‹ Table of Contents

Prerequisites

Before building this project, you must have the ProudNet folder installed at the same level as the tank_server project folder.

Required Directory Structure

project_root/
โ”œโ”€โ”€ tank_server/          # This project
โ”‚   โ”œโ”€โ”€ Common/
โ”‚   โ”œโ”€โ”€ Server/
โ”‚   โ”œโ”€โ”€ Client/
โ”‚   โ””โ”€โ”€ Server_CPP/
โ””โ”€โ”€ ProudNet/            # Required: Files from ProudNet installation
    โ”œโ”€โ”€ doc/             # ProudNet documentation
    โ”œโ”€โ”€ include/         # ProudNet header files
    โ”œโ”€โ”€ lib/             # ProudNet library files
    โ”œโ”€โ”€ Sample/          # ProudNet sample projects
    โ””โ”€โ”€ util/            # ProudNet utilities

ProudNet Installation

  1. Download and install ProudNet from the official website
  2. Ensure the ProudNet folder contains the following subdirectories:
    • doc/ - Documentation files
    • include/ - Header files for C++ development
    • lib/ - Library files for both .NET and C++
    • Sample/ - Example projects
    • util/ - Utility tools and license authentication

Project Structure

๐Ÿ“ Common

Contains shared resources used by both server and client implementations.

Contents:

Key Files:

๐Ÿ–ฅ๏ธ Server

C# implementation of the tank game server.

Features:

Key Files:

๐ŸŽฎ Client

C# console-based client for the tank game.

Features:

Key Files:

๐Ÿง Server_CPP

C++ implementation of the tank game server with Linux support.

Features:

Key Files:

Build Options:

Development Notes

Getting Started

Prerequisites

  1. Copy ProudNet files from your ProudNet installation location to create a ProudNet/ directory at the same level as tank_server/
  2. Verify that ProudNet/util/PIDL.exe exists for protocol compilation

1. C# Server Implementation

Step 1: Understanding the Protocol Definition (Tank.PIDL)

The Tank.PIDL file defines the communication protocol between server and client:

// Tank.PIDL - Protocol Interface Definition Language
global Tank 2000 // Client-Server and Server-Client RMI, first message ID = 2000
{
    // Client to Server functions
    SendMove([in] float posX, [in] float posY, [in] float direction);
    SendFire([in] int shooterId, [in] float direction, [in] float launchForce, ...);
    SendTankType([in] int tankType);
    
    // Server to Client functions  
    OnPlayerJoined([in] int clientId, [in] float posX, [in] float posY, [in] int tankType);
    OnTankPositionUpdated([in] int clientId, [in] float posX, [in] float posY, [in] float direction);
    OnSpawnBullet([in] int clientId, [in] int shooterId, ...);
    // ... more RMI functions
}

This PIDL file defines:

Step 2: Generate C# Stub and Proxy Classes

Run the PIDL compiler to generate C# networking code:

cd tank_server/Common
CompilePIDL_cs.bat

Expected Output:

C:\Users\wayne\Documents\proud_tank\tank_server\Common [master +5 ~14 -15 !]> .\CompilePIDL_cs.bat 
PIDL compile complete!
Press any key to continue . . .

This script will:

Step 3: Build the Server

Navigate to the Server directory and build:

cd tank_server/Server
build.bat

Expected Output:

C:\Users\wayne\Documents\proud_tank\tank_server\Server [master +15 ~13 -15 !]> ./build.bat
========================================
Tank Server Build Script
========================================
Build configuration: Debug
Building Tank Server...
Restore complete (0.2s)
  TankServer succeeded (1.8s) โ†’ bin\Debug\net9.0\TankServer.dll

Build succeeded in 2.3s
Build completed successfully!
Using build output path: bin\Debug\net9.0
Build output directory exists: bin\Debug\net9.0
ProudNet DotNet directory exists: ..\..\ProudNet\lib\DotNet
ProudNet x64 directory exists: ..\..\ProudNet\lib\DotNet\x64
========================================
Copying ProudNet DLLs...
========================================
Copying libcrypto-3-x64.dll...
        1 file(s) copied.
Copying libssl-3-x64.dll...
        1 file(s) copied.
Copying ProudDotNetClient.dll...
        1 file(s) copied.
Copying ProudDotNetClient.pdb...
        1 file(s) copied.
Copying ProudDotNetServer.dll...
        1 file(s) copied.
Copying ProudDotNetServer.pdb...
        1 file(s) copied.
Copying ProudNetClient.dll...
        1 file(s) copied.
Copying ProudNetClientPlugin.dll...
        1 file(s) copied.
Copying ProudNetServer.dll...
        1 file(s) copied.
Copying ProudNetServerPlugin.dll...
        1 file(s) copied.
Copying ProudNetServerPlugin.pdb...
        1 file(s) copied.
========================================
Build and DLL copy completed!
========================================

Output directory: bin\Debug\net9.0
You can now run the Tank Server executable.

Press any key to continue . . .

The build script will:

Step 4: Run the Server

cd tank_server/Server/bin/Debug/net9.0
TankServer.exe

Expected Output:

C:\Users\wayne\Documents\proud_tank\tank_server\Server [master +5 ~14 -15 !]> .\bin\Debug\net9.0\TankServer.exe      
Tank Server started on port 33334
Server is running. Commands:
status: Show connected clients
health [id]: Show tank health (all or specific ID)
damage id amount: Apply damage to a tank
heal id amount: Heal a tank
respawn id x y: Respawn a tank at position (x,y)
q: Quit server
Client 3 connected
New tank created for client 3 with tank type -1 and health 100/100
Not enough clients to create P2P group (need at least 2)

The server will:

2. C# Client Implementation

Step 1: Shared Protocol Understanding

The client uses the same Tank.PIDL file as the server, ensuring perfect protocol compatibility:

This approach guarantees that:

Step 2: Build the Client

Navigate to the Client directory and build:

cd tank_server/Client  
build.bat

Expected Output:

C:\Users\wayne\Documents\proud_tank\tank_server\Client [master +5 ~14 -15 !]> .\build.bat
========================================
Tank Client Build Script
========================================
Build configuration: Debug
Building Tank Client...
Restore complete (0.3s)
  TankClient succeeded (0.2s) โ†’ bin\Debug\net9.0\TankClient.dll

Build succeeded in 0.8s
Build completed successfully!
Using build output path: bin\Debug\net9.0
Build output directory exists: bin\Debug\net9.0
ProudNet DotNet directory exists: ..\..\ProudNet\lib\DotNet
ProudNet x64 directory exists: ..\..\ProudNet\lib\DotNet\x64
========================================
Copying ProudNet DLLs...
========================================
Copying libcrypto-3-x64.dll...
        1 file(s) copied.
Copying libssl-3-x64.dll...
        1 file(s) copied.
Copying ProudDotNetClient.dll...
        1 file(s) copied.
Copying ProudDotNetClient.pdb...
        1 file(s) copied.
Copying ProudDotNetServer.dll...
        1 file(s) copied.
Copying ProudNetClient.dll...
        1 file(s) copied.
Copying ProudNetClientPlugin.dll...
        1 file(s) copied.
Copying ProudNetServer.dll...
        1 file(s) copied.
========================================
Build and DLL copy completed!
========================================

Output directory: bin\Debug\net9.0
You can now run the Tank Client executable.

Press any key to continue . . .

The client build script performs the same operations as the server:

Step 3: Run the Client

cd tank_server/Client/bin/Debug/net9.0
TankClient.exe

Expected Output:

C:\Users\wayne\Documents\proud_tank\tank_server\Client [master +6 ~14 -15 !]> .\bin\Debug\net9.0\TankClient.exe
Connecting to server...
Commands:
move x y dir : Move tank to position (x,y) with direction dir
fire dir [force] : Fire in direction dir with optional force (default 25.0)
tank n       : Select tank type (0-3)
health h [max]: Update tank health to h with optional max health
destroy [id] : Send tank destroyed event (id of destroyer, default 0 = environment)
spawn x y dir type health: Spawn/respawn tank
msg text     : Send P2P message to other clients
history      : Show message history
status       : Show P2P connection status
auto         : Toggle auto movement
q            : Quit
Connected to server. My ID: 3

๐Ÿ” Check Server Connection:

When the client successfully connects, you should also see a connection message on the server console:

Server Console Output:

C:\Users\wayne\Documents\proud_tank\tank_server\Server [master +5 ~14 -15 !]> .\bin\Debug\net9.0\TankServer.exe
Tank Server started on port 33334
Server is running. Commands:
status: Show connected clients
health [id]: Show tank health (all or specific ID)
damage id amount: Apply damage to a tank
heal id amount: Heal a tank
respawn id x y: Respawn a tank at position (x,y)
q: Quit server
Client 3 connected
New tank created for client 3 with tank type -1 and health 100/100
Not enough clients to create P2P group (need at least 2)

๐Ÿ“ Server Log Explanation:

๐Ÿ’ก To test P2P functionality:

Run a second client in another terminal to see:

Second Client Output:

C:\Users\wayne\Documents\proud_tank\tank_server\Client [master +5 ~14 -15 !]> .\bin\Debug\net9.0\TankClient.exe          
Connecting to server...                                                                                                                                                                                                                             
Commands:                                                                                                                                                                                                                                           
move x y dir : Move tank to position (x,y) with direction dir                                                                                                                                                                                       
fire dir [force] : Fire in direction dir with optional force (default 25.0)
tank n       : Select tank type (0-3)
health h [max]: Update tank health to h with optional max health
destroy [id] : Send tank destroyed event (id of destroyer, default 0 = environment)
spawn x y dir type health: Spawn/respawn tank
msg text     : Send P2P message to other clients
history      : Show message history
status       : Show P2P connection status
auto         : Toggle auto movement
q            : Quit
Connected to server. My ID: 4
P2P: Member 4 joined group 5
P2P: Member 3 joined group 5
P2P: Added member 3 to group member list
OnPlayerJoined: Tank 3 joined at (12.939716,28.795837) with tank type -1
OnTankHealthUpdated: Tank 3 health: 100/100
P2P: Received group info, Group ID: 5

Updated Server Console Output:

C:\Users\wayne\Documents\proud_tank\tank_server\Server [master +5 ~14 -15 !]> .\bin\Debug\net9.0\TankServer.exe
Tank Server started on port 33334
Server is running. Commands:
status: Show connected clients
health [id]: Show tank health (all or specific ID)
damage id amount: Apply damage to a tank
heal id amount: Heal a tank
respawn id x y: Respawn a tank at position (x,y)
q: Quit server
Client 3 connected
New tank created for client 3 with tank type -1 and health 100/100
Not enough clients to create P2P group (need at least 2)
Client 4 connected
New tank created for client 4 with tank type -1 and health 100/100
Sending existing player info to new client: ID=3, Type=-1, Health=100/100
Notifying existing client 3 about new player: ID=4, Type=-1, Health=100/100
P2P group created with 2 members, Group ID: 5
Sent P2P group info to client 3: P2P_GROUP_INFO:5
Sent P2P group info to client 4: P2P_GROUP_INFO:5

๐Ÿ“ Multi-Client Connection Analysis:

When the second client connects:

  1. Client 4 connects - Server assigns new ID and creates tank object
  2. Player synchronization - Server exchanges player information:
    • Sends existing player info (Client 3) to the new client (Client 4)
    • Notifies existing client (Client 3) about the new player (Client 4)
  3. P2P group creation - Now that there are 2+ clients:
    • Server creates P2P group with ID 5
    • Both clients receive P2P group information
    • Clients can now communicate directly via P2P messaging

Client-side P2P events:

๐ŸŽฎ Now you can test multiplayer features:

3. C++ Server Implementation (Optional)

The C++ server implementation provides the exact same functionality as the C# server, offering cross-platform support and containerized deployment options. This is an optional advanced implementation that demonstrates ProudNet's multi-language capabilities.

Protocol Compatibility

Since both C# and C++ servers use the same Tank.PIDL file, they are fully compatible:

Key Advantages of C++ Implementation

Step 1: Generate C++ Stub and Proxy Classes

First, generate the C++ networking code from the PIDL file:

cd tank_server/Common
CompilePIDL_cpp.bat

Expected Output:

C:\Users\wayne\Documents\proud_tank\tank_server\Common [master +5 ~14 -15 !]> .\CompilePIDL_cpp.bat
[INFO] Generating C++ files from Tank.PIDL...
[INFO] PIDL C++ compilation complete!
[INFO] Generated files in ..\Server_CPP\include directory.
Press any key to continue . . .

This will generate C++ stub/proxy classes in the Server_CPP/include/ directory:

Step 2: Build the C++ Server (Windows)

Prerequisites for Windows Build

Before building the C++ server, ensure you have the following components installed:

Required Software:

Required Visual Studio Components:

When installing Visual Studio, make sure to include these workloads and components:

Important Note about ATL:

The Active Template Library (ATL) is essential for ProudNet linking on Windows. In CMakeLists.txt, you can see it's explicitly linked:

target_link_libraries(TankGameServer
    # ... other libraries ...
    atls       # ATL library addition
)

Build Process

Navigate to the Server_CPP directory and build using the provided script:

cd tank_server/Server_CPP
build.bat

Expected Build Output:

C:\Users\wayne\Documents\proud_tank\tank_server\Server_CPP [master +5 ~14 -15 !]> .\build.bat
[INFO] =========================================
[INFO] Starting TankGameServer C++ Build...
[INFO] =========================================
[INFO] Detecting Visual Studio installation...
[INFO] Visual Studio 2022 Community found
[INFO] Setting up VS2022 environment...
**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.14.0
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
[INFO] Using Visual Studio 2022 with generator: NMake Makefiles
[INFO] ProudNet Path: C:\Users\wayne\Documents\proud_tank\ProudNet
[INFO] Build Type: Release
[INFO] Using: Visual Studio 2022 with NMake Makefiles
[INFO] Checking and generating PIDL files...
[INFO] Compiling PIDL files...
[INFO] Generating C++ files from Tank.PIDL...
[INFO] PIDL C++ compilation complete
[INFO] Generated files in ..\Server_CPP\include directory.
Press any key to continue . . .
[INFO] Creating build directory...
[INFO] Removing existing build directory...
[INFO] Configuring CMake...
[INFO] Using NMake Makefiles generator
-- The C compiler identification is MSVC 19.44.35207.1
-- The CXX compiler identification is MSVC 19.44.35207.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Building on Windows - Using OpenSSL and CURL from ProudNet
-- System check: Windows
-- Current working directory: C:/Users/wayne/Documents/proud_tank/tank_server/Server_CPP
-- Build type: Release
-- ProudNet Path: C:\Users\wayne\Documents\proud_tank\ProudNet
-- Operating System: Windows
-- Using Visual Studio version from command line: 2022
-- Found Visual Studio installation: C:/Program Files/Microsoft Visual Studio/2022/Community
-- Visual Studio Path: C:/Program Files/Microsoft Visual Studio/2022/Community
-- Using Release Library Path: C:\Users\wayne\Documents\proud_tank\ProudNet/lib/x64/v140/Release
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/wayne/Documents/proud_tank/tank_server/Server_CPP/build
[INFO] Building project...
[ 33%] Building CXX object CMakeFiles/TankGameServer.dir/src/TankServer.cpp.obj
TankServer.cpp
[ 66%] Building CXX object CMakeFiles/TankGameServer.dir/C_/Users/wayne/Documents/proud_tank/tank_server/Common/Vars.cpp.obj
Vars.cpp
[100%] Linking CXX executable TankServer.exe
[100%] Built target TankGameServer
[INFO] Build successful
[INFO] Executable: C:\Users\wayne\Documents\proud_tank\tank_server\Server_CPP\build\Release\TankGameServer.exe
[INFO] Copying required DLL files...
[INFO] =========================================
[INFO] Build completed
[INFO] Executable: C:\Users\wayne\Documents\proud_tank\tank_server\Server_CPP\build\TankServer.exe
[INFO] =========================================
Press any key to continue . . .

Build Process Analysis:

  1. Visual Studio Detection: Automatically detects VS 2022 Community installation
  2. Environment Setup: Initializes VS 2022 Developer Command Prompt with x64 tools
  3. PIDL Compilation: Automatically generates C++ stub/proxy classes
  4. CMake Configuration: Uses NMake Makefiles generator for MSVC compiler
  5. Compilation: Builds TankServer.cpp and Vars.cpp with C++17 standard
  6. Linking: Links with ProudNet libraries, Windows system libraries, and ATL
  7. DLL Copying: Copies required ProudNet DLLs to executable directory

The build script will:

Step 3: Run the C++ Server (Windows)

cd tank_server/Server_CPP
run.bat

Expected Server Output:

C:\Users\wayne\Documents\proud_tank\tank_server\Server_CPP [master +5 ~14 -15 !]> .\run.bat
[INFO] Starting TankGameServer C++ Server...
[INFO] Found executable at build\TankServer.exe (NMake build
[INFO] Server is starting. Press 'q' to quit.
[INFO] Running: C:\Users\wayne\Documents\proud_tank\tank_server\Server_CPP\build\TankServer.exe
========== Tank Server Started ==========
TCP Server listening on 0.0.0.0:33334
WebSocket Server listening on 0.0.0.0:33335/ws
Ready to accept connections from all network interfaces
==========================================
Server is running. Commands:
status: Show connected clients
health [id]: Show tank health (all or specific ID)
damage id amount: Apply damage to a tank
heal id amount: Heal a tank
respawn id x y: Respawn a tank at position (x,y)
q: Quit server

Server Startup Analysis:

  1. Executable Detection: run.bat automatically locates the built executable
  2. Network Binding: Server binds to all network interfaces (0.0.0.0)
    • TCP Server: Port 33334 for game connections
    • WebSocket Server: Port 33335/ws for web client support
  3. Command Interface: Same server commands as C# version
  4. Ready State: Server is ready to accept client connections

Step 4: C# Client Compatibility Test

๐Ÿ”„ Protocol Compatibility Verification:

The C++ server is fully compatible with the existing C# clients. You can connect the same C# clients from Step 2 to this C++ server without any modifications.

Connect C# Client to C++ Server:

# In another terminal, run the C# client
cd tank_server/Client/bin/Debug/net9.0
TankClient.exe

C++ Server Console Log (Client Connection):

Client 3 connected from 127.0.0.1:52341
New tank created for client 3 with tank type -1 and health 100/100
Not enough clients to create P2P group (need at least 2)

Server Log Analysis:

  1. Identical Client Processing: C++ server handles client connections exactly like C# server
  2. Same Tank Creation: Creates tank objects with identical initial state (health 100/100, type -1)
  3. Player Synchronization: Exchanges player information between clients identically
  4. P2P Group Management: Creates P2P groups with same logic and group ID assignment
  5. Protocol Compatibility: All RMI functions and message formats work seamlessly

โœ… Complete Functional Parity:

๐ŸŽฏ This demonstrates that the C++ server is a complete drop-in replacement for the C# server with 100% protocol compatibility.

Step 5: Docker Deployment (Linux/Ubuntu)

The C++ server can be deployed as a Docker container on Ubuntu 24.04 for production environments.

Prerequisites for Docker Deployment

Windows Docker Setup

If running on Windows, ensure Docker is configured for Linux containers:

  1. Install Docker Desktop from the official website
  2. Switch to Linux containers:
    • Right-click Docker Desktop system tray icon
    • Select "Switch to Linux containers..."
    • Wait for Docker to restart in Linux container mode

ProudNet License Configuration (Optional)

By default, the server runs in 50 CCU limitation mode without a license key. For production deployment with unlimited concurrent users, you can configure a ProudNet license:

Step 1: License Key Setup

Edit the tank_server/licensekey.txt file:

# Default content (50 CCU limitation): Replace with your actual ProudNet license key:
PUT_YOUR_PROUDNET_LICENSE_KEY_HERE

Step 2: License Verification

The Docker build process automatically detects and applies the license:

Expected Docker Output with License:

tank-server-1  | License key found: /app/licensekey.txt
tank-server-1  | ProudNet license validation successful
tank-server-1  | Starting server with full license (unlimited CCU)

Expected Docker Output without License (Default):

tank-server-1  | License key file not found: /app/licensekey.txt
tank-server-1  | Building without ProudNet license.
tank-server-1  | Starting server without license (50 CCU limitation mode).

๐Ÿ”‘ License Benefits:

Docker Deployment Commands

cd tank_server/Server_CPP
docker-compose up

Expected Docker Output:

C:\Users\wayne\Documents\proud_tank\tank_server\Server_CPP [master +5 ~14 -15 !]> docker-compose up
Compose can now delegate builds to bake for better performance.
 To do so, set COMPOSE_BAKE=true.
[+] Building 2.3s (22/22)                                                                                                                                 docker:desktop-linux 
[+] Building 2.3s (22/23)                                                                                                                                 docker:desktop-linux 
[+] Building 2.3s (23/23) FINISHED                                                                                                                        docker:desktop-linux 
 => [tank-server internal] load build definition from Dockerfile                                                                                                          0.0s 
 => => transferring dockerfile: 6.39kB                                                                                                                                    0.0s 
 => [tank-server internal] load metadata for docker.io/library/ubuntu:24.04                                                                                               1.9s 
 => [tank-server auth] library/ubuntu:pull token for registry-1.docker.io                                                                                                 0.0s 
 => [tank-server internal] load .dockerignore                                                                                                                             0.0s 
 => => transferring context: 2B                                                                                                                                           0.0s 
 => [tank-server  1/16] FROM docker.io/library/ubuntu:24.04@sha256:6015f66923d7afbc53558d7ccffd325d43b4e249f41a6e93eef074c9505d2233                                       0.0s 
 => [tank-server internal] load build context                                                                                                                             0.1s
 => => transferring context: 106.41kB                                                                                                                                     0.0s
 => CACHED [tank-server  2/16] RUN apt-get update && apt-get install -y     build-essential     cmake     git     libssl-dev     libssl3     libcurl4-openssl-dev     tz  0.0s
 => CACHED [tank-server  3/16] WORKDIR /app                                                                                                                               0.0s
 => CACHED [tank-server  4/16] COPY tank_server/Server_CPP/src /app/src/                                                                                                  0.0s
 => CACHED [tank-server  5/16] COPY tank_server/Server_CPP/include /app/include/                                                                                          0.0s
 => CACHED [tank-server  6/16] COPY tank_server/Server_CPP/CMakeLists.txt /app/CMakeLists.txt                                                                             0.0s
 => CACHED [tank-server  7/16] COPY tank_server/Common/Vars.cpp /app/Common/Vars.cpp                                                                                      0.0s
 => CACHED [tank-server  8/16] COPY tank_server/Common/Vars.h /app/Common/Vars.h                                                                                          0.0s
 => CACHED [tank-server  9/16] COPY ProudNet/include /app/ProudNet/include/                                                                                               0.0s
 => CACHED [tank-server 10/16] COPY ProudNet/lib/x86_x64-linux /app/ProudNet/lib/x86_x64-linux/                                                                           0.0s
 => CACHED [tank-server 11/16] COPY ProudNet/util/PNLicenseAuth /app/ProudNet/util/                                                                                       0.0s 
 => CACHED [tank-server 12/16] RUN if [ -f "tank_server/licensekey.txt" ] &&     [ "$(cat tank_server/licensekey.txt)" != "PUT_YOUR_PROUDNET_LICENSE_KEY_HERE" ]; then    0.0s 
 => CACHED [tank-server 13/16] RUN chmod +x /app/ProudNet/util/PNLicenseAuth &&     echo "System information:" &&     uname -a &&     echo "Current directory:" &&     p  0.0s 
 => CACHED [tank-server 14/16] RUN echo "Copied file structure:" &&     ls -la /app &&     echo "Common directory:" &&     ls -la /app/Common/ || echo "Failed to copy C  0.0s 
 => CACHED [tank-server 15/16] RUN echo '#!/bin/bash \necho "Server build starting..." \n\ncheck_file() { \n  if [ ! -f "$1" ]; then \n    echo "File not found: $1" \n   0.0s
 => CACHED [tank-server 16/16] RUN chmod +x /app/start.sh                                                                                                                 0.0s
 => [tank-server] exporting to image                                                                                                                                      0.0s 
 => => exporting layers                                                                                                                                                   0.0s 
 => => writing image sha256:cf987b1363c26bf89aa7ced6c0eca898573679bc92001c3aedee2ff1fe7c649e                                                                              0.0s 
 => => naming to docker.io/library/server_cpp-tank-server                                                                                                                 0.0s 
 => [tank-server] resolving provenance for metadata file                                                                                                                  0.0s 
[+] Running 2/2
 โœ” tank-server                         Built                                                                                                                              0.0s 
 โœ” Container server_cpp-tank-server-1  Created                                                                                                                            0.0s 
Attaching to tank-server-1
tank-server-1  | Server build starting...
tank-server-1  | File found: /app/Common/Vars.cpp
tank-server-1  | File found: /app/Common/Vars.h                                                                                                                                
tank-server-1  | Directory found: /app/ProudNet/lib/x86_64-linux                                                                                                              
tank-server-1  | ProudNet license check in progress...                                                                                                                         
tank-server-1  | License file information:                                                                                                                                     
tank-server-1  | total 18560                                                                                                                                                   
tank-server-1  | drwxr-xr-x 1 root root     4096 Jun  2 15:03 .
tank-server-1  | drwxr-xr-x 1 root root     4096 Jun  2 15:03 ..                                                                                                               
tank-server-1  | -rwxr-xr-x 1 root root 18987960 May 20 23:14 PNLicenseAuth                                                                                                    
tank-server-1  | License key file not found: /app/licensekey.txt                                                                                                               
tank-server-1  | Building without ProudNet license.                                                                                                                            
tank-server-1  | ODBC driver information:                                                                                                                                      
tank-server-1  | /app/start.sh: line 72: odbcinst: command not found                                                                                                           
tank-server-1  | Could not get ODBC information.
tank-server-1  | -- OpenSSL found: /usr/include
tank-server-1  | -- OpenSSL libraries: /usr/lib/x86_64-linux-gnu/libssl.so;/usr/lib/x86_64-linux-gnu/libcrypto.so
tank-server-1  | -- OpenSSL version: 3.0.13                                                                                                                                    
tank-server-1  | -- CURL found: /usr/include/x86_64-linux-gnu                                                                                                                  
tank-server-1  | -- CURL libraries: /usr/lib/x86_64-linux-gnu/libcurl.so
tank-server-1  | -- CURL version: 8.5.0                                                                                                                                        
tank-server-1  | -- System check: Linux                                                                                                                                        
tank-server-1  | -- Current working directory: /app                                                                                                                            
tank-server-1  | -- Build type:                                                                                                                                                
tank-server-1  | -- ProudNet Path: /app/ProudNet                                                                                                                               
tank-server-1  | -- Operating System: Linux
tank-server-1  | -- Library path check: /app/ProudNet/lib/x86_64-linux                                                                                                        
tank-server-1  | -- Found Linux ProudNet library: /app/ProudNet/lib/x86_64-linux                                                                                              
tank-server-1  | -- Library file list: /app/ProudNet/lib/x86_64-linux/Debug;/app/ProudNet/lib/x86_64-linux/Release                                                           
tank-server-1  | -- Found ODBC library: /usr/lib/x86_64-linux-gnu/libodbc.so                                                                                                   
tank-server-1  | -- Found ODBCINST library: /usr/lib/x86_64-linux-gnu/libodbcinst.so
tank-server-1  | -- Linking OpenSSL libraries: /usr/lib/x86_64-linux-gnu/libssl.so;/usr/lib/x86_64-linux-gnu/libcrypto.so                                                      
tank-server-1  | -- Linking CURL library: /usr/lib/x86_64-linux-gnu/libcurl.so                                                                                                 
tank-server-1  | -- Configuring done (0.1s)                                                                                                                                    
tank-server-1  | -- Generating done (0.0s)                                                                                                                                     
tank-server-1  | -- Build files have been written to: /app/build                                                                                                               
tank-server-1  | [100%] Built target TankGameServer
tank-server-1  | Build completed, attempting to start server...
tank-server-1  | Starting server without license (50 CCU limitation mode).                                                                                                     
tank-server-1  | No NIC binding though multiple NIC detected##Process=/app/build                                                                                               
tank-server-1  | ========== Tank Server Started ==========
tank-server-1  | TCP Server listening on 0.0.0.0:33334                                                                                                                         
tank-server-1  | WebSocket Server listening on 0.0.0.0:33335/ws                                                                                                                
tank-server-1  | Ready to accept connections from all network interfaces                                                                                                       
tank-server-1  | ==========================================                                                                                                                    
tank-server-1  | Server is running. Commands:                                                                                                                                  
tank-server-1  | status: Show connected clients                                                                                                                                
tank-server-1  | health [id]: Show tank health (all or specific ID)
tank-server-1  | damage id amount: Apply damage to a tank                                                                                                                      
tank-server-1  | heal id amount: Heal a tank                                                                                                                                   
tank-server-1  | respawn id x y: Respawn a tank at position (x,y)                                                                                                              
tank-server-1  | q: Quit server

Docker Build Process Analysis:

  1. Multi-stage Build: Uses Ubuntu 24.04 base image with cached build layers
  2. Dependencies Installation: Installs build-essential, cmake, OpenSSL, CURL development libraries
  3. File Structure Copy: Copies source files, ProudNet libraries, and build configuration
  4. License Detection: Checks for ProudNet license key (falls back to 50 CCU limitation mode)
  5. Library Detection: Automatically finds and links system libraries:
    • OpenSSL 3.0.13: SSL/TLS support
    • CURL 8.5.0: HTTP client support
    • ODBC: Database connectivity support
  6. CMake Configuration: Configures build with Linux-specific ProudNet libraries
  7. Compilation: Successfully builds TankGameServer executable
  8. Server Startup: Starts in 50 CCU limitation mode (no license key provided)

๐Ÿ“‹ Docker Container Details:

Docker Container Management

View running containers:

docker ps

Expected Output:

CONTAINER ID   IMAGE                    COMMAND                   CREATED       STATUS         PORTS                                  NAMES
dd96172cd51d   server_cpp-tank-server   "/bin/bash /app/starโ€ฆ"   2 hours ago   Up 7 seconds   0.0.0.0:33334-33335->33334-33335/tcp   server_cpp-tank-server-1

View server logs:

docker logs server_cpp-tank-server-1

Stop the server:

docker-compose down

Step 6: Cross-Platform Client Testing

๐ŸŒ Test C# Client โ†’ C++ Docker Server:

The C# client can connect to the dockerized C++ server running on Ubuntu:

# In another terminal, run the C# client
cd tank_server/Client/bin/Debug/net9.0
TankClient.exe

Expected Client Connection:

Connected to server. My ID: 3

Expected Docker Server Log:

tank-server-cpp  | Client 3 connected from 172.17.0.1:52341
tank-server-cpp  | New tank created for client 3 with tank type -1 and health 100/100

Key Benefits of C++ Implementation:

๐Ÿš€ Performance:

๐Ÿง Cross-Platform:

๐Ÿ“ฆ Containerization:

๐Ÿ”„ Protocol Compatibility:

WebSocket Integration

๐ŸŒ Additional WebSocket Server (Port 33335):

The C++ server implementation includes an additional WebSocket server that runs alongside the main TCP server:

๐ŸŽฎ Unity WebGL Client Support:

This WebSocket functionality is specifically designed for Unity tank clients that will be built as WebGL applications:

Connection Example:

ws://localhost:33335/ws  // Local development
ws://your-server.com:33335/ws  // Production deployment

This dual-protocol architecture enables seamless integration between traditional desktop applications and modern web-based gaming platforms.

4. Multiplayer Movement Testing

This section demonstrates a real-world scenario where two clients connect simultaneously and test tank movement functionality.

Test Scenario

Client 1 (ID=3) Console Log:

Connected to server. My ID: 3
move 1 1 0
Status: Tank ID=3, Position=(1,1), Type=0, Health=100/100
OnPlayerJoined: Tank 4 joined at (64.18131,34.385406) with tank type -1
P2P: Member 3 joined group 5
P2P: Member 4 joined group 5
P2P: Added member 4 to group member list
OnTankHealthUpdated: Tank 4 health: 100/100
P2P: Received group info, Group ID: 5
>>> OTHER TANK 4 MOVED TO (2,2) dir=90

Client 1 Log Analysis:

  1. Self Movement Processing: After executing move 1 1 0 command, own tank status is updated
  2. New Player Detection: Receives OnPlayerJoined event when Client 4 connects to server
  3. P2P Group Formation: P2P group (ID: 5) is created when 2+ clients are connected
  4. Other Tank Movement Notification: Receives Client 4's movement in real-time and displays it

Client 2 (ID=4) Console Log:

Connected to server. My ID: 4
P2P: Member 4 joined group 5
P2P: Member 3 joined group 5
P2P: Added member 3 to group member list
OnPlayerJoined: Tank 3 joined at (1,1) with tank type -1
OnTankHealthUpdated: Tank 3 health: 100/100
P2P: Received group info, Group ID: 5
move 2 2 90
Status: Tank ID=4, Position=(2,2), Type=0, Health=100/100

Client 2 Log Analysis:

  1. Server Connection: Successfully connected to server and assigned ID 4
  2. P2P Group Participation: Joins P2P group 5 together with existing Client 3
  3. Existing Player Info Reception: Receives tank information (position, health) of already connected Client 3
  4. Self Movement Execution: Uses move 2 2 90 command to move tank to position (2,2) with 90-degree direction

Server Console Log:

New tank created for client 4 with tank type -1 and health 100/100
Sending existing player info to new client: ID=3, Type=-1, Health=100/100
Notifying existing client 3 about new player: ID=4, Type=-1, Health=100/100
P2P group created with 2 members, Group ID: 5
Sent P2P group info to client 3: P2P_GROUP_INFO:5
Sent P2P group info to client 4: P2P_GROUP_INFO:5
SendMove from client 4: pos=(2,2), direction=90

Server Log Analysis:

  1. New Client Processing: Creates new tank object for Client 4 (initial health 100/100)
  2. Player Information Synchronization:
    • Sends existing player (ID=3) information to new client (ID=4)
    • Notifies existing client (ID=3) about new player (ID=4)
  3. P2P Group Management: Creates P2P group (ID: 5) when 2+ clients are present and distributes group information
  4. Movement Command Processing: Receives and processes Client 4's SendMove RMI call

Core Multiplayer Features Verification:

๐Ÿ”„ Real-time Synchronization:

๐ŸŒ P2P Networking:

๐Ÿ“Š State Management:

๐ŸŽฎ Game Logic:

5. Fire and Messaging Testing

In addition to movement, clients can test projectile firing and P2P messaging functionality.

Extended Test Commands

Client 1 (ID=3) Fire and Message Commands:

fire 180 10
Fire request sent: direction=180, force=10, position=(1, 1, 1)
Status: Tank ID=3, Position=(1,1), Type=0, Health=100/100
msg hi
P2P message sent via server: hi
Status: Tank ID=3, Position=(1,1), Type=0, Health=100/100

Client 1 Command Analysis:

  1. Fire Command Execution: fire 180 10 sends projectile with 180-degree direction and force value 10
  2. Fire Confirmation: Client receives confirmation with firing position and parameters
  3. Message Command Execution: msg hi sends P2P message to all connected clients
  4. Message Confirmation: Client receives confirmation that message was sent via server relay

Client 2 (ID=4) Receiving Fire and Message Events:

OnSpawnBullet: Tank 3 fired from (1,1) dir=180, force=10
Fire position: (1, 1, 1), shooter ID=3
P2P Message from Client ID 3 (relayed): hi

Client 2 Reception Analysis:

  1. Bullet Spawn Event: Receives OnSpawnBullet RMI call with firing tank's position and projectile parameters
  2. Fire Details: Gets complete information about shooter ID, position, direction, and force
  3. P2P Message Reception: Receives the P2P message from Client 3 relayed through the server

Key Multiplayer Communication Features:

๐Ÿ”ซ Projectile System:

๐Ÿ’ฌ P2P Messaging:

๐Ÿ”„ Event Broadcasting:

Troubleshooting