diff --git a/README.md b/README.md index 216709f93..1db93bd19 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,81 @@ # Ryan R-Type +**Ryan R-Type** is a modern networked multiplayer space shooter game inspired by the classic R-Type arcade game. Built with a client-server architecture in C++20, it features real-time multiplayer gameplay, a custom Entity-Component-System (ECS), and advanced networking protocols. + +## ๐Ÿš€ Features + +- ๐ŸŽฎ **Multiplayer Support**: Up to 4 players in cooperative gameplay +- ๐ŸŒ **Real-time Networking**: UDP-based communication with client-server architecture +- ๐ŸŽจ **Modern Graphics**: SFML-powered rendering with dynamic effects +- ๐Ÿ”ง **Configurable Server**: Customizable port, IP, and tick rate +- ๐Ÿ•น๏ธ **Custom ECS**: High-performance entity management system +- ๐ŸŽฏ **Lobby System**: Create and join game lobbies with unique codes +- ๐Ÿ“Š **HTTP API**: RESTful API for game statistics and management +- ๐Ÿ”’ **Cross-platform**: Supports Windows, Linux, and macOS + +## ๐Ÿ“‹ System Requirements + +### Minimum Requirements +- **OS**: Windows 10+, Linux (Ubuntu 20.04+), macOS 11+ +- **Compiler**: GCC 11+, Clang 12+, or MSVC 2019+ +- **CMake**: Version 3.23 or higher +- **RAM**: 512 MB +- **Network**: Internet connection for multiplayer + +### Development Requirements +- **C++ Compiler** with C++20 support +- **CMake**: 3.23+ +- **vcpkg**: Package manager for dependencies +- **Git**: Version control + +## โšก Quick Start + +### Running Pre-built Binaries + +```bash +# Start the server (default: 127.0.0.1:4242) +./r-type_server + +# In another terminal, start the client +./r-type_client -n Player1 +``` + +### Multiplayer Setup + +```bash +# Server on a specific IP and port +./r-type_server -p 8080 -i 0.0.0.0 + +# Clients connect to the server +./r-type_client -p 8080 -i -n Alice +./r-type_client -p 8080 -i -n Bob +``` + ## Installing Ryan R-Type -### Via Releases +### Via Releases (Recommended) + +Download the latest pre-built binaries from our [releases page](https://github.com/AlbanRSS/doc-rtype/releases). + +**Installation steps:** -To install our project, you just need to go to our release page and follow the release's instructions to download it. +1. Download the appropriate archive for your platform: + - **Windows**: `r-type-windows-x64.zip` + - **Linux**: `r-type-linux-x64.tar.gz` + - **macOS**: `r-type-macos-x64.tar.gz` + +2. Extract the archive: + ```bash + # Linux/macOS + tar -xzf r-type-*.tar.gz + cd r-type + + # Windows: Use Windows Explorer or + unzip r-type-windows-x64.zip + cd r-type + ``` + +3. Run the executables (see [Quick Start](#-quick-start) section) ### Via cloning @@ -28,19 +99,21 @@ After compiling the project, you can run the server and client executables. #### Running the Server ```bash -./r-type_server -p -i -n +./r-type_server -p -i ``` Arguments: -- `-p `: Specify the port number (required) -- `-i `: Specify the IP address to bind to (required) -- `-n `: Specify the maximum number of clients (1-4, default: 1) (required) +- `-p `: Specify the port number (default: 4242) (optional) +- `-i `: Specify the IP address to bind to (default: 127.0.0.1) (optional) +- `-tps `: Specify the TPS (ticks per second) (default: 20) (optional) - `-d`: Enable debug mode (optional) - `-h`: Display help message (optional) +Note: Port 5173 is reserved for HTTP server. + Example: ```bash -./r-type_server -p 4242 -i 127.0.0.1 -n 4 +./r-type_server -p 4242 -i 127.0.0.1 -tps 20 ``` #### Running the Client @@ -60,7 +133,88 @@ Example: ./r-type_client -p 4242 -i 127.0.0.1 -n Player1 ``` -## Contributing +## ๐Ÿ”ง Troubleshooting + +### Common Issues + +#### Server: Port Already in Use +```bash +# Error: Address already in use +# Solution: Use a different port +./r-type_server -p 8080 -i 127.0.0.1 +``` + +#### Client: Connection Refused +```bash +# Possible causes: +# 1. Server is not running +# 2. Wrong IP or port +# 3. Firewall blocking connection + +# Verify server is running on the correct port +./r-type_server -p 4242 -i 0.0.0.0 + +# Connect with matching port +./r-type_client -p 4242 -i +``` + +#### Compilation Errors +```bash +# If vcpkg dependencies fail to install +./scripts/install_dependencies.sh + +# Clean build directory and rebuild +./scripts/clean_project.sh +./scripts/compile_project.sh +``` + +#### HTTP Server Port Conflict +Port 5173 is reserved for the HTTP API server. If you need to run the game server on a different port: +```bash +./r-type_server -p 4243 # Use any port except 5173 +``` + +#### Permission Denied on Scripts +```bash +# Unix systems: Make scripts executable +chmod +x ./scripts/*.sh +``` + +### Performance Issues + +**High Latency:** +- Ensure stable network connection +- Try reducing TPS: `./r-type_server -tps 15` +- Check firewall/router settings + +**Low FPS:** +- Update graphics drivers +- Close resource-intensive applications +- Check system meets minimum requirements + +### Debug Mode + +Enable debug mode for detailed logging: +```bash +# Server +./r-type_server -d + +# Client +./r-type_client -d +``` + +### Getting Help + +If you encounter issues not covered here: +1. Check the [documentation](https://albanrss.github.io/doc-rtype/) +2. Search [existing issues](https://github.com/AlbanRSS/doc-rtype/issues) +3. Create a new issue with: + - Your OS and version + - Steps to reproduce + - Error messages/logs + - Expected vs actual behavior + +## ๐Ÿค Contributing For contribution guidelines, including prerequisites and commit conventions, please refer to [HOWTOCONTRIBUTE.md](HOWTOCONTRIBUTE.md). @@ -68,11 +222,13 @@ For contribution guidelines, including prerequisites and commit conventions, ple ### Docusaurus -The **Docusaurus** documentation regroups the entirety of the project documentation, protocole server gui and clinet information, but also how to contribute to the project and how to use the project itlsef. +The **Docusaurus** documentation contains the entirety of the project documentation, including protocol specifications, server/client information, contribution guidelines, and usage instructions. + +๐Ÿ“– **Access the online documentation**: https://albanrss.github.io/doc-rtype/ -Access the documentation at https://albanrss.github.io/doc-rtype/ +#### Running Documentation Locally -To run the documentation travel to the `/documentation` folder than run the following : +To run the documentation locally, navigate to the `/documentation` folder and run the following: ``` bash cd documentation/docusaurus/ @@ -82,33 +238,42 @@ npm start Then you can find the documentation at http://localhost:3000/ -#### Prerequisite : +#### Prerequisites -To run the Docusaurus documentation you will need to have the docusaurus librairy installed on your device. +To run the Docusaurus documentation locally: +- **Node.js**: Version 18.0 or higher +- **npm**: Version 8.0 or higher -- [Docusaurus](https://docusaurus.io/docs/installation) +The Docusaurus library will be automatically installed when running `npm install`. + +For more information, see the [Docusaurus installation guide](https://docusaurus.io/docs/installation). ### Doxygen -The **Doxygen** module allows you to generate pdf documentation and schemas of the project architecure and logic. +The **Doxygen** module generates PDF documentation and diagrams of the project architecture and logic. -To update the documentation run the following : +To generate the documentation, run: -``` bash -./scripts/generateDoc.sh +```bash +./scripts/generate_doc.sh ``` -#### Prerequisite : +The generated documentation will be available in `documentation/doc/`. -To run the doxygen generations script you will need to have the Doxygen and pdf-Latex Library, you can find there install guide here +#### Prerequisites -- [Doxygen](https://www.doxygen.nl/manual/install.html) -- [PDF Latex](https://www.latex-project.org/get/) +To run the Doxygen generation script, you need: +- **Doxygen**: Version 1.9.0 or higher +- **LaTeX**: For PDF generation (pdflatex) +- **Graphviz**: For generating diagrams (optional but recommended) -You also need to make sure that the script is executable. +Installation guides: +- [Doxygen Installation](https://www.doxygen.nl/manual/install.html) +- [LaTeX Installation](https://www.latex-project.org/get/) +- [Graphviz Installation](https://graphviz.org/download/) -``` bash -cd ./script -chmod +x generateDoc.sh +**Make the script executable:** +```bash +chmod +x ./scripts/generate_doc.sh ``` diff --git a/client/gsm/states/scenes/InGame/InGameState.cpp b/client/gsm/states/scenes/InGame/InGameState.cpp index 4ac29d57b..c5ece0ed8 100644 --- a/client/gsm/states/scenes/InGame/InGameState.cpp +++ b/client/gsm/states/scenes/InGame/InGameState.cpp @@ -508,7 +508,8 @@ void InGameState::drawInGameMetrics(std::shared_ptr window, float std::count(metricsText.begin(), metricsText.end(), '\n')) + 1; size_t totalHeight = textHeight + (numLines - 1) * 5; size_t baseX = static_cast(constants::MAX_WIDTH - 5.0f); - size_t baseY = static_cast(constants::MAX_HEIGHT - totalHeight - 15.0f); + size_t baseY = static_cast(constants::MAX_HEIGHT - + static_cast(totalHeight) - 15.0f); std::istringstream iss(metricsText); std::string line; diff --git a/documentation/docusaurus/docs/CLIENT/client-architecture.md b/documentation/docusaurus/docs/CLIENT/client-architecture.md new file mode 100644 index 000000000..db81c2552 --- /dev/null +++ b/documentation/docusaurus/docs/CLIENT/client-architecture.md @@ -0,0 +1,832 @@ +--- +sidebar_position: 3 +--- + +# Client Architecture + +Detailed technical documentation of the R-Type client architecture. + +## Overview + +The client is responsible for: +- **Rendering**: Visual display of game state +- **Input handling**: Keyboard, mouse, and gamepad +- **Audio playback**: Music and sound effects +- **Network communication**: Sync with server +- **Local prediction**: Smooth gameplay despite network latency +- **UI management**: Menus and HUD + +## Architecture Diagram + +```mermaid +graph TB + subgraph "Client Core" + MAIN[main.cpp] + CORE[Core] + UTILS[Utils CLI Parser] + end + + subgraph "Network Layer" + CN[ClientNetwork] + PS[PacketSender] + PR[PacketReceiver] + end + + subgraph "Game State Machine" + GSM[GameStateMachine] + MENU[MenuState] + GAME[InGameState] + PAUSE[PauseState] + LOBBY[LobbyState] + end + + subgraph "Systems" + RS[RenderSystem] + AS[AudioSystem] + IS[InputSystem] + ANS[AnimationSystem] + PS_SYSTEM[ParallaxSystem] + end + + subgraph "Resource Management" + RM[ResourceManager] + TM[TextureManager] + SM[SoundManager] + FM[FontManager] + end + + subgraph "UI" + UI_MGR[UIManager] + WIDGETS[UI Widgets] + HUD[HUD Elements] + end + + MAIN --> CORE + CORE --> CN + CORE --> GSM + CORE --> RM + + GSM --> MENU + GSM --> GAME + GSM --> PAUSE + GSM --> LOBBY + + GAME --> RS + GAME --> AS + GAME --> IS + GAME --> ANS + GAME --> PS_SYSTEM + + RM --> TM + RM --> SM + RM --> FM + + GAME --> UI_MGR + UI_MGR --> WIDGETS + UI_MGR --> HUD + + CN --> PS + CN --> PR +``` + +## Core Components + +### Core Class + +**File:** `client/Core.cpp`, `client/Core.hpp` + +Central coordinator for the client application. + +**Responsibilities:** +- Initialize all subsystems +- Manage main game loop +- Coordinate between systems +- Handle window events + +**Key Methods:** +```cpp +class Core { +public: + Core(); + ~Core(); + + void startNetwork(); // Initialize network connection + void initFirstScene(); // Set up initial game state + void run(); // Main game loop + + std::shared_ptr getNetwork(); + +private: + void processEvents(); // Handle window events + void update(float deltaTime); // Update game logic + void render(); // Draw frame +}; +``` + +**Game Loop:** +```cpp +void Core::run() { + sf::Clock clock; + + while (window->isOpen()) { + float deltaTime = clock.restart().asSeconds(); + + processEvents(); // Input handling + network->receive(); // Network updates + update(deltaTime); // Game logic + render(); // Draw + + // Frame rate limiting + sf::sleep(sf::milliseconds(16)); // ~60 FPS + } +} +``` + +### ClientNetwork + +**File:** `client/ClientNetwork.cpp`, `client/ClientNetwork.hpp` + +Manages all network communication with the server. + +**Features:** +- UDP socket management +- Packet sending/receiving +- Connection state tracking +- Heartbeat mechanism + +**Key Methods:** +```cpp +class ClientNetwork { +public: + void connect(const std::string& ip, uint16_t port); + void disconnect(); + + void send(const Packet& packet); + void receive(); // Process incoming packets + + bool isConnected() const; + uint8_t getClientId() const; + + void setPort(uint16_t port); + void setIp(const std::string& ip); + void setName(const std::string& name); + void setDebugMode(bool debug); + +private: + void handlePacket(const Packet& packet); + void sendHeartbeat(); +}; +``` + +**Connection Flow:** +```cpp +// 1. Initialize network +network->setIp("127.0.0.1"); +network->setPort(4242); +network->setName("Player1"); + +// 2. Connect to server +network->connect(); + +// 3. Game loop +while (running) { + network->receive(); // Process packets + // ... game logic + network->send(inputPacket); // Send player input +} + +// 4. Disconnect +network->disconnect(); +``` + +## Game State Machine + +**File:** `client/gsm/GameStateMachine.cpp` + +Manages different game screens and transitions. + +### State Interface + +```cpp +class IState { +public: + virtual ~IState() = default; + + virtual void enter() = 0; // Called when entering state + virtual void exit() = 0; // Called when leaving state + virtual void update(float dt) = 0; + virtual void render() = 0; + virtual void handleEvent(const sf::Event& event) = 0; +}; +``` + +### Available States + +#### MenuState +- Main menu display +- Button navigation +- Option selection + +#### LobbyState +- Lobby creation/joining +- Player list display +- Ready status management +- Chat system + +#### InGameState +- Active gameplay +- HUD rendering +- Player controls +- Game logic + +#### PauseState +- Game paused overlay +- Settings access +- Resume/quit options + +### State Transitions + +```cpp +class GameStateMachine { +public: + void changeState(std::unique_ptr newState); + void pushState(std::unique_ptr state); // Stack states + void popState(); // Return to previous + + void update(float deltaTime); + void render(); + void handleEvent(const sf::Event& event); + +private: + std::vector> stateStack; +}; +``` + +**Example Usage:** +```cpp +// From menu to lobby +gsm->changeState(std::make_unique()); + +// Pause game (stack states) +gsm->pushState(std::make_unique()); + +// Resume (pop pause state) +gsm->popState(); +``` + +## Systems + +### RenderSystem + +**File:** `client/systems/rendering/RenderSystem.cpp` + +Handles all visual rendering. + +**Features:** +- Sprite rendering +- Layer management +- Camera/viewport +- Parallax backgrounds +- Particle effects + +```cpp +class RenderSystem : public ASystem { +public: + void update(float deltaTime) override; + +private: + void renderEntities(); + void renderUI(); + void renderParallax(); + void sortByLayer(); + + std::shared_ptr window; + sf::View camera; +}; +``` + +**Rendering Pipeline:** +``` +1. Clear window +2. Set camera view +3. Render background layers (parallax) +4. Sort entities by layer +5. Render entities (sprites) +6. Render particle effects +7. Render UI (HUD) +8. Display frame +``` + +### InputSystem + +**File:** `client/systems/input/InputSystem.cpp` + +Processes user input from multiple sources. + +**Supported Devices:** +- Keyboard +- Mouse +- Gamepad (Xbox, PlayStation, Generic) + +```cpp +class InputSystem : public ASystem { +public: + void update(float deltaTime) override; + void handleEvent(const sf::Event& event); + + bool isActionPressed(InputAction action) const; + Vector2D getMovementVector() const; + +private: + void updateKeyboard(); + void updateGamepad(); + + InputMappingManager mappings; + std::map actionStates; +}; +``` + +**Input Actions:** +```cpp +enum class InputAction { + MoveUp, + MoveDown, + MoveLeft, + MoveRight, + Shoot, + Special, + Pause, + Chat +}; +``` + +### AudioSystem + +**File:** `client/systems/audio/` + +Manages music and sound effect playback. + +**Components:** +- **MusicSystem**: Background music management +- **SoundSystem**: Sound effects playback + +```cpp +class MusicSystem : public ASystem { +public: + void playMusic(const std::string& musicId); + void stopMusic(); + void setVolume(float volume); // 0.0 - 100.0 + void setMusicVolume(float volume); + +private: + sf::Music currentMusic; + std::map musicPaths; +}; + +class SoundSystem : public ASystem { +public: + void playSound(const std::string& soundId); + void playSoundAt(const std::string& soundId, Vector2D position); + void setSFXVolume(float volume); + +private: + std::vector activeSounds; + std::map soundBuffers; +}; +``` + +**Positional Audio:** +```cpp +// Play sound at entity position +auto transform = registry->getComponent(entity); +soundSystem->playSoundAt("explosion", {transform->x, transform->y}); +``` + +### AnimationSystem + +**File:** `client/systems/animation/AnimationSystem.cpp` + +Manages sprite animations. + +```cpp +class AnimationSystem : public ASystem { +public: + void update(float deltaTime) override; + +private: + void updateAnimations(float deltaTime); + void changeAnimation(Entity entity, const std::string& animName); +}; +``` + +**AnimationComponent:** +```cpp +struct AnimationComponent : public IComponent { + std::string currentAnim; + int currentFrame; + float frameTime; + float elapsed; + bool loop; + + std::map animations; +}; + +struct Animation { + std::vector frames; + float frameDuration; +}; +``` + +## UI System + +### UIManager + +**File:** `client/ui/UIManager.cpp` + +Manages all UI elements and widgets. + +**Features:** +- Widget hierarchy +- Event handling +- Layout management +- Theme support + +```cpp +class UIManager { +public: + void addWidget(std::shared_ptr widget); + void removeWidget(const std::string& id); + + void update(float deltaTime); + void render(sf::RenderWindow& window); + void handleEvent(const sf::Event& event); + +private: + std::vector> widgets; + std::shared_ptr focusedWidget; +}; +``` + +### Widget Types + +#### Button +```cpp +class Button : public Widget { +public: + void setOnClick(std::function callback); + void setText(const std::string& text); + void setTexture(const sf::Texture& texture); +}; +``` + +#### TextBox +```cpp +class TextBox : public Widget { +public: + void setText(const std::string& text); + std::string getText() const; + void setEditable(bool editable); +}; +``` + +#### Slider +```cpp +class Slider : public Widget { +public: + void setValue(float value); // 0.0 - 1.0 + float getValue() const; + void setOnValueChanged(std::function callback); +}; +``` + +#### Label +```cpp +class Label : public Widget { +public: + void setText(const std::string& text); + void setFont(const sf::Font& font); + void setColor(const sf::Color& color); +}; +``` + +## Resource Management + +### ResourceManager + +**File:** `client/initResourcesManager/` + +Central resource loading and caching system. + +**Managed Resources:** +- Textures (PNG, JPG) +- Sounds (WAV, OGG) +- Fonts (TTF) +- Shaders (GLSL) +- Configurations (JSON) + +```cpp +class ResourceManager { +public: + static ResourceManager& getInstance(); + + // Texture management + sf::Texture& getTexture(const std::string& id); + void loadTexture(const std::string& id, const std::string& path); + + // Sound management + sf::SoundBuffer& getSoundBuffer(const std::string& id); + void loadSound(const std::string& id, const std::string& path); + + // Font management + sf::Font& getFont(const std::string& id); + void loadFont(const std::string& id, const std::string& path); + + // Shader management + sf::Shader& getShader(const std::string& id); + void loadShader(const std::string& id, const std::string& vertex, + const std::string& fragment); + + void unloadAll(); + +private: + std::map textures; + std::map sounds; + std::map fonts; + std::map shaders; +}; +``` + +**Usage:** +```cpp +// Load resources +auto& rm = ResourceManager::getInstance(); +rm.loadTexture("player", "assets/sprites/player.png"); +rm.loadSound("shoot", "assets/sounds/shoot.wav"); + +// Use resources +sf::Sprite sprite(rm.getTexture("player")); +sf::Sound sound(rm.getSoundBuffer("shoot")); +``` + +## Client Prediction + +### Local Prediction + +To compensate for network latency, the client predicts player movement locally. + +**Strategy:** +1. Client sends input to server +2. Client immediately applies input locally (prediction) +3. Server processes input and sends authoritative state +4. Client reconciles with server state + +```cpp +void ClientNetwork::handleMovementPrediction() { + // Apply input immediately (prediction) + auto transform = registry->getComponent(localPlayer); + transform->x += input.dx * deltaTime; + transform->y += input.dy * deltaTime; + + // Store predicted state + predictionHistory.push_back({frameNumber, transform->x, transform->y}); + + // Send input to server + sendInputPacket(input); +} + +void ClientNetwork::reconcileWithServer(const ServerState& serverState) { + auto transform = registry->getComponent(localPlayer); + + // Check if prediction was correct + float errorX = abs(transform->x - serverState.x); + float errorY = abs(transform->y - serverState.y); + + if (errorX > RECONCILIATION_THRESHOLD || errorY > RECONCILIATION_THRESHOLD) { + // Correct to server state + transform->x = serverState.x; + transform->y = serverState.y; + + // Replay inputs after server frame + replayInputs(serverState.frameNumber); + } +} +``` + +### Entity Interpolation + +Other entities are interpolated between received server states for smooth movement. + +```cpp +void ClientNetwork::interpolateEntities(float deltaTime) { + auto view = registry->view(); + + for (Entity entity : view) { + if (entity == localPlayer) continue; // Don't interpolate local player + + auto transform = registry->getComponent(entity); + auto network = registry->getComponent(entity); + + // Interpolate between previous and current server state + float alpha = network->interpolationTime / network->interpolationDelay; + transform->x = lerp(network->prevX, network->targetX, alpha); + transform->y = lerp(network->prevY, network->targetY, alpha); + + network->interpolationTime += deltaTime; + } +} +``` + +## Configuration + +### Settings Management + +**File:** `client/SettingsManager.cpp` + +Manages persistent client settings. + +```cpp +class SettingsManager { +public: + static SettingsManager& getInstance(); + + void load(); // Load from saves/settings.json + void save(); // Save to saves/settings.json + + // Graphics + void setResolution(int width, int height); + void setFullscreen(bool fullscreen); + void setVSync(bool vsync); + void setFPSLimit(int limit); + + // Audio + void setMasterVolume(float volume); + void setMusicVolume(float volume); + void setSFXVolume(float volume); + + // Gameplay + void setPlayerName(const std::string& name); + void setAutoReconnect(bool enabled); + + // Getters + int getWidth() const; + int getHeight() const; + bool isFullscreen() const; + // ... etc + +private: + SettingsConfig config; +}; +``` + +**Settings File Format:** +```json +{ + "graphics": { + "resolution": {"width": 1920, "height": 1080}, + "fullscreen": false, + "vsync": true, + "fpsLimit": 60 + }, + "audio": { + "masterVolume": 80, + "musicVolume": 70, + "sfxVolume": 85 + }, + "network": { + "defaultServer": "127.0.0.1", + "defaultPort": 4242, + "autoReconnect": true + }, + "gameplay": { + "playerName": "Player1", + "showFPS": false + } +} +``` + +## Performance Optimization + +### Frame Rate Management + +```cpp +// Target frame time (60 FPS = 16.67ms) +const float TARGET_FRAME_TIME = 1.0f / 60.0f; + +void Core::run() { + sf::Clock clock; + float accumulator = 0.0f; + + while (window->isOpen()) { + float deltaTime = clock.restart().asSeconds(); + accumulator += deltaTime; + + // Fixed timestep for game logic + while (accumulator >= TARGET_FRAME_TIME) { + update(TARGET_FRAME_TIME); + accumulator -= TARGET_FRAME_TIME; + } + + // Render with interpolation + render(accumulator / TARGET_FRAME_TIME); + } +} +``` + +### Asset Streaming + +Large assets loaded asynchronously: + +```cpp +void ResourceManager::loadAssetsAsync() { + std::thread([this]() { + loadTexture("background1", "assets/bg1.png"); + loadTexture("background2", "assets/bg2.png"); + // ... more assets + }).detach(); +} +``` + +### Entity Culling + +Only render entities in view: + +```cpp +bool isInView(const TransformComponent& transform, const sf::View& view) { + sf::FloatRect viewBounds( + view.getCenter() - view.getSize() / 2.f, + view.getSize() + ); + + return viewBounds.contains(transform.x, transform.y); +} + +void RenderSystem::update(float deltaTime) { + auto view = registry->view(); + + for (Entity entity : view) { + auto transform = registry->getComponent(entity); + + if (isInView(*transform, camera)) { + // Render only visible entities + renderEntity(entity); + } + } +} +``` + +## Directory Structure + +``` +client/ +โ”œโ”€โ”€ main.cpp # Entry point +โ”œโ”€โ”€ Core.cpp/hpp # Main game loop +โ”œโ”€โ”€ ClientNetwork.cpp/hpp # Network communication +โ”œโ”€โ”€ Utils.cpp/hpp # CLI parsing +โ”œโ”€โ”€ constants.hpp # Client constants +โ”‚ +โ”œโ”€โ”€ components/ # Client-specific components +โ”‚ โ”œโ”€โ”€ SpriteComponent.hpp +โ”‚ โ”œโ”€โ”€ AnimationComponent.hpp +โ”‚ โ””โ”€โ”€ CameraComponent.hpp +โ”‚ +โ”œโ”€โ”€ gsm/ # Game State Machine +โ”‚ โ”œโ”€โ”€ GameStateMachine.cpp +โ”‚ โ””โ”€โ”€ states/ +โ”‚ โ”œโ”€โ”€ MenuState.cpp +โ”‚ โ”œโ”€โ”€ LobbyState.cpp +โ”‚ โ”œโ”€โ”€ InGameState.cpp +โ”‚ โ””โ”€โ”€ PauseState.cpp +โ”‚ +โ”œโ”€โ”€ systems/ # Client systems +โ”‚ โ”œโ”€โ”€ rendering/ +โ”‚ โ”‚ โ”œโ”€โ”€ RenderSystem.cpp +โ”‚ โ”‚ โ”œโ”€โ”€ ParallaxSystem.cpp +โ”‚ โ”‚ โ””โ”€โ”€ AnimationSystem.cpp +โ”‚ โ”œโ”€โ”€ audio/ +โ”‚ โ”‚ โ”œโ”€โ”€ MusicSystem.cpp +โ”‚ โ”‚ โ””โ”€โ”€ SoundSystem.cpp +โ”‚ โ””โ”€โ”€ input/ +โ”‚ โ””โ”€โ”€ InputSystem.cpp +โ”‚ +โ”œโ”€โ”€ ui/ # User interface +โ”‚ โ”œโ”€โ”€ UIManager.cpp +โ”‚ โ”œโ”€โ”€ Widget.cpp +โ”‚ โ””โ”€โ”€ widgets/ +โ”‚ โ”œโ”€โ”€ Button.cpp +โ”‚ โ”œโ”€โ”€ TextBox.cpp +โ”‚ โ””โ”€โ”€ Slider.cpp +โ”‚ +โ”œโ”€โ”€ initResourcesManager/ # Resource management +โ”‚ โ””โ”€โ”€ ResourceManager.cpp +โ”‚ +โ””โ”€โ”€ packet/ # Packet handling + โ”œโ”€โ”€ ClientSentPacket.cpp + โ””โ”€โ”€ ClientReceivedPacket.cpp +``` + +## See Also + +- [Client User Guide](./user-guide.md) +- [Server Architecture](../SERVER/server-intro.md) +- [Network Protocol](../NETWORK/network-intro.md) +- [ECS Documentation](../ECS/ecs-intro.md) diff --git a/documentation/docusaurus/docs/CLIENT/client-intro.md b/documentation/docusaurus/docs/CLIENT/client-intro.md index 4856cbb80..42c37a3c8 100644 --- a/documentation/docusaurus/docs/CLIENT/client-intro.md +++ b/documentation/docusaurus/docs/CLIENT/client-intro.md @@ -4,29 +4,529 @@ sidebar_position: 1 # R-Type โ€” Client Overview -This page gives a short, practical introduction to the Rโ€‘Type client component: what it contains, how to build and run it for development, and where to look for common features (input, rendering, audio, UI). +This page provides a comprehensive introduction to the Rโ€‘Type client component: what it contains, how to build and run it for development, and where to look for common features (input, rendering, audio, UI). ## Purpose -The client implements the graphical and audio front-end for the game: rendering, input handling, local state interpolation, UI, and audio playback. It connects to the server for multiplayer state and uses the project's common libraries for ECS, resource management and packets. +The client implements the graphical and audio front-end for the game: +- **Rendering**: Visual display using SFML +- **Input handling**: Keyboard, mouse, and gamepad support +- **Local state interpolation**: Smooth gameplay despite network latency +- **UI management**: Menus, HUD, and widgets +- **Audio playback**: Music and sound effects -## Important client folders and files +It connects to the server for multiplayer state synchronization and uses the project's common libraries for ECS, resource management, and network packets. -- `client/` โ€” main client source tree - - `main.cpp`, `Core.cpp/.hpp` โ€” application entry and lifecycle - - `initResourcesManager/GraphicalInputProvider.cpp` โ€” keyboard/mouse/gamepad initialization - - `systems/` โ€” client-side ECS systems (rendering, audio, input handling) - - `components/` โ€” rendering components (sprites, animations, text, health bars) - - `ui/` โ€” UI elements, navigation and managers +## Quick Links -- `assets/` โ€” shared assets used by the client (shaders, sprites, sounds, fonts) - - `assets/shaders/` โ€” color-blind and high-contrast shaders (e.g. `deuteranopia.frag`) +- **[User Guide](./user-guide.md)**: How to play the game +- **[Client Architecture](./client-architecture.md)**: Technical implementation details +- **[Installation](../INTRO/installation.md)**: Setup instructions -- `saves/` โ€” persisted settings and user data (including `accessibility.json`, `keybinds.json`) +## Key Features -## Key features and where to find them +### Graphics +- **SFML-based rendering**: Hardware-accelerated 2D graphics +- **Sprite animations**: Frame-based animation system +- **Parallax backgrounds**: Multi-layer scrolling backgrounds +- **Particle effects**: Explosions and visual effects +- **Layer management**: Z-ordering for proper rendering -- Input remapping and mapping structures: `common/InputMapping/` (`InputMapping.hpp`, `InputMappingManager.hpp`, `InputAction.hpp`). -- Rendering systems: `client/systems/rendering/` (game zone, parallax, hitboxes, animations). -- Audio: `client/systems/audio/MusicSystem.cpp`, `SoundSystem.cpp`. -- Network/packets: `client/packet/` and `common/packet/` for serialization and default handlers. +### Input +- **Multiple input devices**: Keyboard, mouse, gamepad +- **Remappable controls**: Full key/button remapping +- **Input mapping system**: Action-based input abstraction +- **Gamepad support**: Xbox, PlayStation, and generic controllers + +### Audio +- **Background music**: OGG Vorbis streaming +- **Sound effects**: WAV format with pooling +- **Positional audio**: 3D sound positioning +- **Volume controls**: Separate music/SFX volume + +### Networking +- **UDP communication**: Low-latency multiplayer +- **Client prediction**: Local movement prediction +- **Entity interpolation**: Smooth remote entity movement +- **Packet handling**: Custom binary protocol + +### Accessibility +- **Color-blind modes**: Deuteranopia, Protanopia, Tritanopia shaders +- **High contrast mode**: Enhanced visibility +- **UI scaling**: Adjustable interface size +- **Alternative indicators**: Numeric health, audio cues + +## Important Client Folders and Files + +### Core Files + +``` +client/ +โ”œโ”€โ”€ main.cpp # Application entry point +โ”œโ”€โ”€ Core.cpp / Core.hpp # Main game loop and lifecycle +โ”œโ”€โ”€ ClientNetwork.cpp/hpp # Network communication +โ”œโ”€โ”€ Utils.cpp/hpp # CLI argument parsing +โ”œโ”€โ”€ constants.hpp # Client-side constants +โ””โ”€โ”€ SettingsManager.cpp/hpp # Persistent settings +``` + +### Game State Management + +``` +client/gsm/ +โ”œโ”€โ”€ GameStateMachine.cpp # State management +โ””โ”€โ”€ states/ + โ”œโ”€โ”€ MenuState.cpp # Main menu + โ”œโ”€โ”€ LobbyState.cpp # Lobby creation/joining + โ”œโ”€โ”€ InGameState.cpp # Active gameplay + โ””โ”€โ”€ PauseState.cpp # Pause overlay +``` + +### Systems + +``` +client/systems/ +โ”œโ”€โ”€ rendering/ +โ”‚ โ”œโ”€โ”€ RenderSystem.cpp # Main rendering +โ”‚ โ”œโ”€โ”€ ParallaxSystem.cpp # Background scrolling +โ”‚ โ””โ”€โ”€ AnimationSystem.cpp # Sprite animations +โ”œโ”€โ”€ audio/ +โ”‚ โ”œโ”€โ”€ MusicSystem.cpp # Background music +โ”‚ โ””โ”€โ”€ SoundSystem.cpp # Sound effects +โ””โ”€โ”€ input/ + โ””โ”€โ”€ InputSystem.cpp # Input processing +``` + +### Components + +``` +client/components/ +โ”œโ”€โ”€ SpriteComponent.hpp # Visual representation +โ”œโ”€โ”€ AnimationComponent.hpp # Animation data +โ”œโ”€โ”€ CameraComponent.hpp # Viewport control +โ””โ”€โ”€ UIComponent.hpp # UI elements +``` + +### UI System + +``` +client/ui/ +โ”œโ”€โ”€ UIManager.cpp # UI management +โ”œโ”€โ”€ Widget.cpp # Base widget class +โ””โ”€โ”€ widgets/ + โ”œโ”€โ”€ Button.cpp # Clickable buttons + โ”œโ”€โ”€ TextBox.cpp # Text input/display + โ”œโ”€โ”€ Slider.cpp # Value sliders + โ””โ”€โ”€ Label.cpp # Text labels +``` + +### Resource Management + +``` +client/initResourcesManager/ +โ””โ”€โ”€ GraphicalInputProvider.cpp # Resource initialization +``` + +### Network + +``` +client/packet/ +โ”œโ”€โ”€ ClientSentPacket.cpp # Outgoing packets +โ””โ”€โ”€ ClientReceivedPacket.cpp # Incoming packet handling +``` + +## Shared Resources + +### Assets + +``` +assets/ +โ”œโ”€โ”€ fonts/ # TrueType fonts for UI +โ”œโ”€โ”€ musics/ # Background music (OGG) +โ”œโ”€โ”€ shaders/ # GLSL shaders +โ”‚ โ”œโ”€โ”€ deuteranopia.frag # Color-blind shader +โ”‚ โ”œโ”€โ”€ protanopia.frag +โ”‚ โ””โ”€โ”€ tritanopia.frag +โ”œโ”€โ”€ sounds/ # Sound effects (WAV) +โ”œโ”€โ”€ sprites/ # Game sprites (PNG) +โ””โ”€โ”€ ui/ # UI textures +``` + +### Configuration + +``` +saves/ +โ”œโ”€โ”€ settings.json # Graphics, audio, network settings +โ”œโ”€โ”€ keybinds.json # Custom key mappings +โ”œโ”€โ”€ accessibility.json # Accessibility options +โ”œโ”€โ”€ scores.json # High scores +โ””โ”€โ”€ users.json # Player profiles +``` + +### Common Libraries + +``` +common/ +โ”œโ”€โ”€ ECS/ # Entity-Component-System +โ”œโ”€โ”€ components/ # Shared game components +โ”œโ”€โ”€ systems/ # Shared game systems +โ”œโ”€โ”€ packet/ # Network packet definitions +โ””โ”€โ”€ InputMapping/ # Input abstraction + โ”œโ”€โ”€ InputMapping.hpp + โ”œโ”€โ”€ InputMappingManager.hpp + โ””โ”€โ”€ InputAction.hpp +``` + +## Building the Client + +### Prerequisites + +- **C++ Compiler**: GCC 11+, Clang 12+, or MSVC 2019+ +- **CMake**: 3.23+ +- **vcpkg**: For dependency management +- **SFML**: 2.6+ (auto-installed via vcpkg) + +### Compilation + +**Unix (Linux/macOS):** +```bash +./scripts/install_dependencies.sh +./scripts/compile_project.sh + +# Client binary +./r-type_client +``` + +**Windows:** +```cmd +.\scripts\install_dependencies.bat +.\scripts\compile_project.bat + +REM Client binary +.\r-type_client.exe +``` + +### CMake Configuration + +```bash +# Configure +cmake --preset unix-release + +# Build +cmake --build build/unix-release --target r-type_client + +# Run +./build/unix-release/r-type_client +``` + +## Running the Client + +### Basic Usage + +```bash +# Connect to localhost with default name +./r-type_client + +# Specify server and player name +./r-type_client -i 192.168.1.100 -p 4242 -n Alice + +# Enable debug logging +./r-type_client -d +``` + +### Command-Line Arguments + +| Argument | Description | Default | +|----------|-------------|---------| +| `-i ` | Server IP address | 127.0.0.1 | +| `-p ` | Server port | 4242 | +| `-n ` | Player name | Auto-generated | +| `-d` | Enable debug mode | Disabled | +| `-h` | Display help | - | + +## Key Features and Where to Find Them + +### Input Remapping + +**Location:** `common/InputMapping/` + +**Files:** +- `InputMapping.hpp`: Individual key-action binding +- `InputMappingManager.hpp`: Manages all bindings +- `InputAction.hpp`: Action definitions + +**Usage:** +```cpp +// Define actions +enum class InputAction { + MoveUp, MoveDown, MoveLeft, MoveRight, + Shoot, Special, Pause +}; + +// Load mappings +InputMappingManager mappings; +mappings.load("saves/keybinds.json"); + +// Check input +if (mappings.isActionPressed(InputAction::Shoot)) { + // Fire weapon +} +``` + +### Rendering Systems + +**Location:** `client/systems/rendering/` + +**Files:** +- `RenderSystem.cpp`: Main sprite rendering +- `ParallaxSystem.cpp`: Multi-layer backgrounds +- `AnimationSystem.cpp`: Frame-based animations +- `HitboxRenderSystem.cpp`: Debug collision visualization + +**Rendering Order:** +1. Parallax background (far โ†’ near) +2. Game entities (sorted by layer) +3. Particle effects +4. UI / HUD +5. Debug overlays (if enabled) + +### Audio Systems + +**Location:** `client/systems/audio/` + +**Files:** +- `MusicSystem.cpp`: Background music management +- `SoundSystem.cpp`: Sound effect playback + +**Features:** +- Music streaming (OGG Vorbis) +- Sound pooling for effects +- Positional 3D audio +- Volume mixing (master, music, SFX) + +### Network Packet Handling + +**Location:** `client/packet/` and `common/packet/` + +**Client Sent Packets:** +- `CONNECTION_CLIENT`: Initial connection request +- `EVENT`: Player input events +- `CLIENT_READY`: Ready status +- `REQUEST_LOBBY`: Create lobby +- `CONNECT_TO_LOBBY`: Join lobby +- `DISCONNECTION`: Clean disconnect + +**Client Received Packets:** +- `ACCEPTATION`: Connection accepted with client ID +- `SPAWN_ENTITY`: New entity in game +- `DEATH_ENTITY`: Entity destruction +- `CAN_START`: Game start signal +- `END_GAME`: Game over with results +- `SERVER_STATUS`: Lobby information +- `LOBBY_CODE`: Lobby code assignment + +### UI Components + +**Location:** `client/ui/` + +**Widget Hierarchy:** +``` +Widget (base class) +โ”œโ”€โ”€ Button +โ”œโ”€โ”€ TextBox +โ”œโ”€โ”€ Slider +โ”œโ”€โ”€ Label +โ”œโ”€โ”€ Image +โ””โ”€โ”€ Container + โ”œโ”€โ”€ Panel + โ””โ”€โ”€ ScrollPanel +``` + +**Example Usage:** +```cpp +// Create a button +auto button = std::make_shared