A multiplayer tank game server implementation using ProudNet networking library, providing both C# and C++ versions with cross-platform support.
Before building this project, you must have the ProudNet folder installed at the same level as the tank_server
project folder.
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
doc/
- Documentation filesinclude/
- Header files for C++ developmentlib/
- Library files for both .NET and C++Sample/
- Example projectsutil/
- Utility tools and license authenticationContains shared resources used by both server and client implementations.
Contents:
Key Files:
Tank.PIDL
- Tank game protocol definitionsCompilePIDL_cs.bat
- PIDL compilation script (C#)CompilePIDL_cpp.bat
- PIDL compilation script (C++)Vars.cs
- C# configurationVars.h
- C++ configurationC# implementation of the tank game server.
Features:
Key Files:
TankServer.cs
- Main server implementationTankServer.csproj
- .NET project filebuild.bat
- Build script with DLL copyingC# console-based client for the tank game.
Features:
Key Files:
TankClient.cs
- Main client implementationTankClient.csproj
- .NET project filebuild.bat
- Build script with DLL copyingC++ implementation of the tank game server with Linux support.
Features:
Key Files:
src/TankServer.cpp
- Main C++ server implementationCMakeLists.txt
- CMake configurationDockerfile
- Docker container configurationdocker-compose.yml
- Docker Compose setuprun.bat
- Windows execution scriptBuild Options:
ProudNet/
directory at the same level as tank_server/
ProudNet/util/PIDL.exe
exists for protocol compilationThe 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:
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:
ProudNet/util/PIDL.exe -cs Tank.PIDL -outdir ../Server
ProudNet/util/PIDL.exe -cs Tank.PIDL -outdir ../Client
Tank_stub.cs
- Handles incoming RMI callsTank_proxy.cs
- Sends outgoing RMI callsTank_common.cs
- Common definitions and constantsNavigate 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:
dotnet build --configuration Debug
ProudDotNetServer.dll
, ProudDotNetClient.dll
ProudNetServer.dll
, ProudNetServerPlugin.dll
libcrypto-3-x64.dll
, libssl-3-x64.dll
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:
status
, health
, damage
, heal
, respawn
, q
(quit)The client uses the same Tank.PIDL file as the server, ensuring perfect protocol compatibility:
CompilePIDL_cs.bat
script generates identical networking code for both projectsThis approach guarantees that:
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:
dotnet build --configuration Debug
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:
Client 3 connected
- A new client has successfully connected and been assigned ID 3New tank created for client 3 with tank type -1 and health 100/100
- Server creates a tank object for the new client:
-1
means no tank type selected yetNot enough clients to create P2P group (need at least 2)
- P2P group creation requires at least 2 clients for peer-to-peer communication๐ก 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:
Client-side P2P events:
P2P: Member X joined group Y
- P2P group membership notificationsOnPlayerJoined: Tank 3 joined at (x,y)
- Receives info about existing playersOnTankHealthUpdated: Tank 3 health: 100/100
- Receives health status of other tanksP2P: Received group info, Group ID: 5
- Confirms P2P group setup๐ฎ Now you can test multiplayer features:
msg hello
in one client to send P2P messages to othersmove x y dir
to see position updates across clientsfire dir
to test projectile synchronizationThe 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.
Since both C# and C++ servers use the same Tank.PIDL file, they are fully compatible:
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:
Tank_stub.cpp/.h
- Handles incoming RMI callsTank_proxy.cpp/.h
- Sends outgoing RMI callsTank_common.cpp/.h
- Common definitions and constantsBefore 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 )
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:
TankServer.cpp
and Vars.cpp
with C++17 standardThe build script will:
ProudNetServer.lib
, ProudNetClient.lib
ws2_32
(Windows Sockets), winmm
(Multimedia), iphlpapi
(IP Helper)atls
(Active Template Library)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:
run.bat
automatically locates the built executable๐ 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:
โ Complete Functional Parity:
status
, health
, damage
, heal
, respawn
) work identically๐ฏ This demonstrates that the C++ server is a complete drop-in replacement for the C# server with 100% protocol compatibility.
The C++ server can be deployed as a Docker container on Ubuntu 24.04 for production environments.
If running on Windows, ensure Docker is configured for Linux containers:
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:
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:
๐ Docker Container Details:
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
๐ 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
๐ Performance:
๐ง Cross-Platform:
๐ฆ Containerization:
๐ Protocol Compatibility:
๐ 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.
This section demonstrates a real-world scenario where two clients connect simultaneously and test tank movement functionality.
move 1 1 0
command to move to position (1,1) with direction 0 degreesmove 2 2 90
command to move to position (2,2) with direction 90 degreesConnected 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:
move 1 1 0
command, own tank status is updatedOnPlayerJoined
event when Client 4 connects to serverConnected 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:
move 2 2 90
command to move tank to position (2,2) with 90-degree directionNew 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:
SendMove
RMI call๐ Real-time Synchronization:
๐ P2P Networking:
๐ State Management:
๐ฎ Game Logic:
In addition to movement, clients can test projectile firing and P2P messaging functionality.
fire 180 10
- Fire projectile in direction 180 degrees with force 10msg hi
- Send P2P message "hi" to other connected clientsfire 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:
fire 180 10
sends projectile with 180-degree direction and force value 10msg hi
sends P2P message to all connected clientsOnSpawnBullet: 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:
OnSpawnBullet
RMI call with firing tank's position and projectile parameters๐ซ Projectile System:
๐ฌ P2P Messaging:
๐ Event Broadcasting:
ProudNet/util/PIDL.exe
exists and is accessible