diff --git a/Client/CMakeLists.txt b/Client/CMakeLists.txt index 227f238b..f5e2f618 100644 --- a/Client/CMakeLists.txt +++ b/Client/CMakeLists.txt @@ -74,6 +74,13 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # --- Compiler settings --- target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23) +if(WIN32) + target_compile_definitions(${PROJECT_NAME} PUBLIC + _WIN32_WINNT=0x0A00 # Windows 10 + WIN32_LEAN_AND_MEAN + ) +endif() + if (MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W4 /permissive-) else () diff --git a/README.md b/README.md index 4169d8e7..c91e48fd 100644 --- a/README.md +++ b/README.md @@ -1,168 +1,173 @@ -
R-Type banner
+
+ R-Type Logo # CPP-500 ‒ `R-Type` -###### An [Epitech](https://www.epitech.eu/) project +**A multithreaded networked ECS-based Game Engine & R-Type recreation.** -## Project Purpose +[![C++ Standard](https://img.shields.io/badge/C%2B%2B-23-blue.svg?style=flat-square&logo=c%2B%2B)](https://en.cppreference.com/w/cpp/23) +[![License](https://img.shields.io/badge/license-Zlib-green.svg?style=flat-square)](LICENSE.md) +[![Build Status](https://img.shields.io/github/actions/workflow/status/lypitech/rtype/ci-cd.yml?branch=main&style=flat-square)](https://github.com/lypitech/rtype/actions) -This project is developed as part of the EPITECH Advanced C++ curriculum. -Its primary objective is to design and implement an ECS-based game engine built on a client–server architecture. -The engine is intended to provide a solid foundation for real-time gameplay, efficient communication between components, -and scalable system design. +

+ About • + Compatibility • + Getting Started • + Documentation • + Team +

+
-To showcase and validate the engine’s features, the project includes a full recreation of the classic 1987 game -[_R-Type_](https://en.wikipedia.org/wiki/R-Type). -This recreation serves both as a technical demonstration and as a practical benchmark, ensuring that the engine supports -entity management, networking, rendering, event handling, and other core gameplay mechanics. +--- -## Dependencies / Requirements / Supported platforms +## About -Make sure to clone the repository and its submodules: +This project is developed as part of the [Epitech](https://www.epitech.eu/) +curriculum, Advanced C++ unit (Year 3). -```sh -git clone --recurse-submodules https://github.com/lypitech/rtype.git -``` - -This project uses [`Conan`](https://conan.io/) as its package manager. -You can read how to setup `Conan` in [docs/setup_conan.md](/docs/setup_conan.md). +The primary goal of it is to design and implement a robust game engine +featuring: +- **An ECS ([`rtecs`](lib/rtecs))**: A high-performance Entity Component System + for modular game logic. +- **High level network library ([`rtnt`](lib/rtnt))**: A cross-platform, + asynchronous network library built on [Asio](https://think-async.com/Asio/) + providing reliable UDP communication. +- **Multithreading**: Decoupled game logic, rendering, and network I/O. +- **Cross-platform support**: Can run on macOS, Linux and Windows on `arm64` and + `x86_64` CPU architectures. -## Build +To demonstrate the engine, we have recreated the mechanics of the classic 1987 +arcade game [R-Type](https://en.wikipedia.org/wiki/R-Type), serving as a +benchmark for real-time multiplayer performance. -This project uses **CMake** as its build system. +## Compatibility -### Build & Run +This project is developed using **C++23**. +It has been strictly tested and validated on the following environments: -```sh -# Configure and generate build files -conan install . --output-folder=build/ --build=missing -s compiler.cppstd=23 -cmake -B build/ - -# Compile the project -cmake --build build/ -``` +| Platform | Compiler / Toolchain | CMake | Status | +|:-----------------------------------------------|:-----------------------------|:---------------|:------:| +| macOS (`arm64`) 26.2 Tahoe | AppleClang `17.0.0.17000603` | `4.1.2` | ✅ | +| Linux (`x86_64`) Xubuntu 25.10 | GNU `15.2.0` | `3.31.6` | ✅ | +| Windows (`x86_64`) 10 IoT Enterprise LTSC 2024 | MSVC `19.50.35718.0` | `4.11.1-msvc1` | ✅ | -If you want the build to be faster (to use all of your CPU cores), simply add `--parallel` to the options! +> [!WARNING] +> While other configurations might work, they are not officially supported. +> Ensure your environment matches the C++23 requirements. -### Other Targets +## Getting started -You can use the following custom build targets: +### Prerequisites -| Target | Description | -| ------- | -------------------------------------------------------------- | -| `re` | Rebuilds the project from scratch. | -| `debug` | Builds the project with debugging symbols and logging enabled. | +- [Git](https://git-scm.com) +- C++ compiler supporting C++23 ([GCC](https://gcc.gnu.org) 10+, + [Clang](https://clang.llvm.org) 10+, + [MSVC](https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B) 19.28+) +- [CMake](https://cmake.org) 3.20+ +- [Conan](https://conan.io/) 2.0+ -Usage example: +### Installation & Build -```sh -cmake --build build --target clean -cmake --build build --target debug -``` - -### nix - -You can also run the project via [nix](https://nixos.org/download/#download-nix): -``` -nix run "github:lypitech/rtype#r-type_client" --impure -- -h 127.0.0.1 -p 4242 -nix run "github:lypitech/rtype#r-type_server" -- -p 4242 --config waveConfig.json -``` > [!NOTE] -> Please note the `--impure` flag as it is necessary in order to run in a non-NixOS graphical environement. - -### Testing - -You can run tests by running: - -```sh -cmake --build build/ --target test -cd build/ -ctest --output-on-failure +> Make sure to properly [setup Conan](docs/setup_conan.md) on your machine +> before. + +1. Clone the repository along with its submodules: + ```sh + git clone --recurse-submodules https://github.com/lypitech/rtype.git + cd rtype + ``` + +2. Install dependencies: + ```sh + conan install . --output-folder=build/ --build=missing -s compiler.cppstd=23 -s build_type=Release + ``` + +3. Compile the project using CMake: + ```shell + # Generate build files + cmake -B build/ -DCMAKE_BUILD_TYPE=Release + + # Build (use --parallel for faster compilation) + cmake --build build/ --config Release --parallel + ``` + +Server and client binaries will respectively be stored in +`./build/Server/r-type_server` and `./build/Client/r-type_client`. + +### Using Nix + +If you are a Nix user, you can run the project directly: +```shell +nix run "github:lypitech/rtype#r-type_server" -- ... +nix run "github:lypitech/rtype#r-type_client" --impure -- ... ``` -## Usage instructions - -To play the game, you must launch the **Server** first, followed by one or more **Clients**. - -> [!IMPORTANT] -> The command-line flags defined below are **mandatory**. Failing to provide them will cause the application to crash. - -### 1. Starting the Server - -The server requires a listening port to be specified using the `-p` flag. - -```sh -# Syntax -./build/Server/r-type_server -p - -# Example: Start server on port 4242 -./build/Server/r-type_server -p 4242 -``` - -### 2. Starting the Client +> [!NOTE] +> Please note the `--impure` flag as it is necessary in order to run in a +> non-NixOS graphical environement. -The client requires both the target host IP (-h) and the target port (-p) to be specified. +### Usage -```sh -# Syntax -./build/Client/r-type_client -h -p +This project follows a Client-Server architecture. +You MUST start the Server before any Clients. -# Example: Connect to localhost on port 4242 -./build/Client/r-type_client -h 127.0.0.1 -p 4242 +1. Start the server + ```shell + # Usage: ./r-type_server -p --config + ./build/Server/r-type_server -p 4242 --config waveConfig.json + ``` -# Example: Connect to a remote server -./build/Client/r-type_client -h 192.168.1.50 -p 4242 -``` +2. Start a client + ```shell + # Usage: ./r-type_client -h -p + ./build/Client/r-type_client -h 127.0.0.1 -p 4242 + ``` ### Controls -Once in the game, use the following keys to pilote your ship: -| Action | Key (Keyboard) | -| :--- | :--- | -| Move | Arrow Keys | -| Exit | Escape | - -## Quick-start information - -Want to play immediately? Follow these steps to build and run a local game. +| Action | Input | +|--------|-----------------------------------------------------| +| Move | | +| Shoot | Space | +| Exit | Esc | -**1. Build the project:** -Open a terminal in the project root and run: +## Testing +You can run the unit tests suite by running: ```sh -git clone --recurse-submodules https://github.com/lypitech/rtype.git -cd rtype -conan install . --output-folder=build/ --build=missing -s compiler.cppstd=23 -cmake -B build/ -DCMAKE_BUILD_TYPE=Release -cmake --build build/ --parallel -``` - -**2. Run the Server** -Open a **new terminal** inside the project root and run this: +cmake --build build/ --target test +cd build/ -```sh -./build/Server/r-type_server -p 4242 +ctest --output-on-failure ``` -**3. Run the Client** -Open another **new terminal** inside the project root and run this: +## Documentation -```sh -./build/Client/r-type_client -h 127.0.0.1 -p 4242 -``` +For deeper technical details regarding the engine's modules and research, please +refer to our internal documentation or the Wiki. -> Note: You can open multiple terminal to run multiple clients at the same time ! - -## Useful links +- [Research papers](docs/researches) +- Network library (`rtnt`): + - [Library README](lib/rtnt/README.md) + - [Protocol RFC (`rtntp`)](docs/rtntp.txt) +- Entity Component System (`rtecs`): + - [Library README](lib/rtecs/README.md) +- General: + - [Subject PDF](docs/B-CPP-500_rtype.pdf) + - [Appendix PDF](docs/B-CPP-500_rtype_apendix.pdf) ## License -See [LICENSE](/LICENSE.md). +This project is licensed under the zlib/libpng License. +See the [LICENSE](/LICENSE.md) file for details. + +## Team -## Authors / contacts +| | | | | | +|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------:| +| [**Pierre MARGUERIE**](https://github.com/PierreMarguerie)
[*pierre.marguerie@epitech.eu*](mailto:pierre.marguerie@epitech.eu) | [**Lysandre BOURSETTE**](https://github.com/Shuvlyy)
[*lysandre.boursette@epitech.eu*](mailto:lysandre.boursette@epitech.eu) | [**Nathan JEANNOT**](https://github.com/nl1x)
[*nathan.jeannot@epitech.eu*](mailto:nathan.jeannot@epitech.eu) | [**Louis PERSIN**](https://github.com/electroniciv)
[*louis.persin@epitech.eu*](mailto:louis.persin@epitech.eu) | [**Esteban BOUYAULT-YVANEZ**](https://github.com/Babouye)
[*esteban.bouyault-yvanez@epitech.eu*](mailto:esteban.bouyault-yvanez@epitech.eu) | -louis.persin@epitech.eu -lysandre.boursette@epitech.eu -nathan.jeannot@epitech.eu -pierre.marguerie@epitech.eu -esteban.bouyault-yvanez@epitech.eu +
+An Epitech project +
diff --git a/Server/CMakeLists.txt b/Server/CMakeLists.txt index 57855d3b..4fa2895d 100644 --- a/Server/CMakeLists.txt +++ b/Server/CMakeLists.txt @@ -80,14 +80,17 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # --- Compiler settings --- target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23) -if (MSVC) - target_compile_definitions(${PROJECT_NAME} - PUBLIC - WIN32_LEAN_AND_MEAN - NOMINMAX - NOGDI - NOUSER +if(WIN32) + target_compile_definitions(${PROJECT_NAME} PUBLIC + _WIN32_WINNT=0x0A00 # Windows 10 + WIN32_LEAN_AND_MEAN + NOMINMAX + NOGDI + NOUSER ) +endif() + +if (MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W4) else() target_compile_options(${PROJECT_NAME} PRIVATE diff --git a/lib/cli_parser/CMakeLists.txt b/lib/cli_parser/CMakeLists.txt index c9293101..99b7d955 100644 --- a/lib/cli_parser/CMakeLists.txt +++ b/lib/cli_parser/CMakeLists.txt @@ -33,6 +33,13 @@ set_target_properties(${PROJECT_NAME} PROPERTIES # --- Compiler settings --- target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23) +if(WIN32) + target_compile_definitions(${PROJECT_NAME} PUBLIC + _WIN32_WINNT=0x0A00 # Windows 10 + WIN32_LEAN_AND_MEAN + ) +endif() + if (MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W4 /permissive-) else() diff --git a/lib/rtecs/CMakeLists.txt b/lib/rtecs/CMakeLists.txt index 397074ac..ffb74a8f 100644 --- a/lib/rtecs/CMakeLists.txt +++ b/lib/rtecs/CMakeLists.txt @@ -54,6 +54,13 @@ set_target_properties(${PROJECT_NAME} PROPERTIES # --- Compiler settings --- target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23) +if(WIN32) + target_compile_definitions(${PROJECT_NAME} PUBLIC + _WIN32_WINNT=0x0A00 # Windows 10 + WIN32_LEAN_AND_MEAN + ) +endif() + if (MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W4 /permissive-) else() diff --git a/lib/rtecs/README.md b/lib/rtecs/README.md index 6cfea1e5..8e559b94 100644 --- a/lib/rtecs/README.md +++ b/lib/rtecs/README.md @@ -1,12 +1,34 @@ # `rtecs` -`rtecs` is a library that implement an optimised Entity Component System for C++. +`rtecs` is a library that implement an optimized Entity Component System for +C++. + +It provides a flexible architecture to decouple data (Components) from logic +(Systems), allowing for high-performance game development. ## Features -- Register entities and its components using a bitmask. -- Register components and systems. -- Apply all systems -- Apply specific system from its ID. +- **Sparse set storage:** High-performance component storage ensuring data locality + and O(1) lookups. +- **Dynamic bitsets:** Efficient bitmasking to handle entity-component associations + dynamically. +- **Flexible systems:** Register and run logic systems globally or individually by + ID. +- **Group views:** Create SparseGroups to iterate efficiently over entities + possessing specific subsets of components. +- **Safe architecture:** Automatic validation of entity existence and component + integrity. + +## Compatibility + +| | macOS (AppleClang) | Linux (G++) | Windows (MSVC) | +|-------:|:--------------------------------------------------------:|:-----------------------------------------:|:-------------------------------------------------------:| +| arm64 | ✅
- `AppleClang 17.0.0.17000603`
- `CMake 4.1.2` | ☑️ | ☑️ | +| x86_64 | ☑️ | ✅
- `GNU 15.2.0`
- `CMake 3.31.6` | ✅
- `MSVC 19.50.35718.0`
- `CMake 4.11.1-msvc1` | + +✅: Tested on real hardware +☑️: Compiled but not physically tested + +The indicated versions are 100% functional. Any older version MIGHT NOT work. ## Installation @@ -14,7 +36,7 @@ - C++ Compiler that supports C++23 (Clang 10+, GCC 10+, MSVC 19.28+) - [CMake](https://cmake.org) version 3.20 or higher -- [Conan](https://conan.io) package manager +- [Conan](https://conan.io) package manager version 2.22.2 ### Using the library in your project @@ -29,6 +51,35 @@ target_link_libraries(${PROJECT_NAME} ) ``` +### Building tests + +`rtecs` comes with a suite of unit tests (that uses +[GTest](https://github.com/google/googletest)). +You can build them by following these steps: + +1. Fetch dependencies with Conan +```sh +conan install . --output-folder=build/ --build=missing -s build_type=Debug +``` + +2. Configure the project +```sh +cmake -S . -B build/ \ + -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake \ + -DCMAKE_BUILD_TYPE=Debug \ + -DRECS_BUILD_TESTS=ON +``` + +3. Build the library +```sh +cmake --build build/ # --parallel for faster compilation +``` + +4. Run the unit tests suite +```sh +ctest --test-dir build/ --output-on-failure +``` + ## How to use ### Summary diff --git a/lib/rteng/CMakeLists.txt b/lib/rteng/CMakeLists.txt index e1756b75..4337e5b7 100644 --- a/lib/rteng/CMakeLists.txt +++ b/lib/rteng/CMakeLists.txt @@ -55,14 +55,17 @@ set_target_properties(${PROJECT_NAME} PROPERTIES # --- Compiler settings --- target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23) -if (MSVC) - target_compile_definitions(${PROJECT_NAME} - PUBLIC +if(WIN32) + target_compile_definitions(${PROJECT_NAME} PUBLIC + _WIN32_WINNT=0x0A00 # Windows 10 WIN32_LEAN_AND_MEAN NOMINMAX NOGDI NOUSER ) +endif() + +if (MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W4) else() target_compile_options(${PROJECT_NAME} PRIVATE diff --git a/lib/rtnt/CMakeLists.txt b/lib/rtnt/CMakeLists.txt index d5628afd..83afa7a5 100644 --- a/lib/rtnt/CMakeLists.txt +++ b/lib/rtnt/CMakeLists.txt @@ -70,6 +70,13 @@ set_target_properties(${PROJECT_NAME} PROPERTIES # --- Compiler settings --- target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23) +if(WIN32) + target_compile_definitions(${PROJECT_NAME} PUBLIC + _WIN32_WINNT=0x0A00 # Windows 10 + WIN32_LEAN_AND_MEAN + ) +endif() + if (MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W4) else() diff --git a/lib/rtnt/README.md b/lib/rtnt/README.md index 61e27cd2..41af950f 100644 --- a/lib/rtnt/README.md +++ b/lib/rtnt/README.md @@ -116,7 +116,6 @@ ctest --test-dir build/ --output-on-failure | Channel independency | ✅ | Blocks Channel 1 while leaving Channel 2 open. Verifies that Channel 2 continues processing packets even while Channel 1 is stalling. | | Stats | ✅ | Same as *Packet Loss*, but attaches a `Recorder` to export CSV metrics on bandwidth usage, RTT and retransmission rates. | - ## How to use ### 1. Packets diff --git a/lib/rtnt/include/rtnt/core/session.hpp b/lib/rtnt/include/rtnt/core/session.hpp index 958070a5..6496163b 100644 --- a/lib/rtnt/include/rtnt/core/session.hpp +++ b/lib/rtnt/include/rtnt/core/session.hpp @@ -126,7 +126,7 @@ class Session bool _hasReceivedRemotePacket = false; packet::SequenceId _localSequenceId = 0; - packet::SequenceId _remoteSequenceId = 0; + // packet::SequenceId _remoteSequenceId = 0; packet::AcknowledgeId _remoteAcknowledgeId = 0; packet::AcknowledgeBitfield _remoteAcknowledgeBitfield = 0; diff --git a/lib/rtnt/src/core/session.cpp b/lib/rtnt/src/core/session.cpp index 9ab2b694..05b6743b 100644 --- a/lib/rtnt/src/core/session.cpp +++ b/lib/rtnt/src/core/session.cpp @@ -354,7 +354,7 @@ void Session::updateAcknowledgeInfo(uint32_t sequenceId) uint32_t shift = sequenceId - _remoteAcknowledgeId; if (shift > 32) { - for (size_t i = 0; i < 32; ++i) { + for (uint32_t i = 0; i < 32; ++i) { if (_remoteAcknowledgeBitfield & (1U << i)) { _oldPacketHistory.push_back(_remoteAcknowledgeId - (i + 1)); } @@ -362,7 +362,7 @@ void Session::updateAcknowledgeInfo(uint32_t sequenceId) _oldPacketHistory.push_back(_remoteAcknowledgeId); _remoteAcknowledgeBitfield = 0; } else { - for (size_t i = 32 - shift; i < 32; ++i) { + for (uint32_t i = 32 - shift; i < 32; ++i) { if (_remoteAcknowledgeBitfield & (1U << i)) { _oldPacketHistory.push_back(_remoteAcknowledgeId - (i + 1)); } diff --git a/lib/rtnt/tests/CMakeLists.txt b/lib/rtnt/tests/CMakeLists.txt index 8dea380e..e0cf624f 100644 --- a/lib/rtnt/tests/CMakeLists.txt +++ b/lib/rtnt/tests/CMakeLists.txt @@ -29,9 +29,11 @@ target_compile_definitions(rtnt_tests PRIVATE ) # Shuvlog: For relative paths in sources. -target_compile_options(rtnt_tests PRIVATE - -fmacro-prefix-map=${CMAKE_SOURCE_DIR}=. -) +if (NOT MSVC) + target_compile_options(rtnt_tests PRIVATE + -fmacro-prefix-map=${CMAKE_SOURCE_DIR}=. + ) +endif () # --- Headers --- target_include_directories(rtnt_tests PRIVATE