Development/fr: Difference between revisions

From DDraceNetwork
(Updating to match new version of source page)
No edit summary
 
(15 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<languages/>
<languages />
<div lang="en" dir="ltr" class="mw-content-ltr">
This article aims to introduce you into DDNet '''''development''''', since it's an open-source game, it relies on random people kind enough to contribute to it on their free time.
</div>


Cet article a pour but de vous introduire au '''''développement''''' de DDNet. En tant que jeu open-source, il repose sur la générosité et le temps libre des contributeurs.


<div lang="en" dir="ltr" class="mw-content-ltr">
== Your development environment ==
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Your_development_environment"></span>
It is extremely recommended to set up a Linux environment to begin programming in DDNet for the following reasons (as of now):
== Environnement de développement ==
* Most DDNet contributors actually use Linux to contribute.
* Easier package management, you can easily install all the needed libraries and begin contributing.
* This article doesn't have yet a Windows version and is focused on Linux.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Il est fortement recommandé de mettre en place un environnement Linux pour commencer à programmer dans DDNet pour les raisons suivantes (à ce jour) :
First an foremost, DDNet is coded using the C++ programming language, you will need to be fairly familiar with it, but you can also know the basics and learn more with it.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
* La plupart des contributeurs utilisent Linux;
Some useful resources to learn C++:
* La gestion des paquets est plus facile, vous pouvez facilement installer toutes les librairies requises;
* [https://www.learncpp.com/ learncpp.com]
* Cet article n'a pas encore de version Windows et se concentre sur Linux.
* [https://en.cppreference.com/w/ cppreference.com]
* Your search engine of preference
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Tout d'abord, DDNet est codé en utilisant le langage de programmation C++. Vous devrez être assez familier avec ce langage, mais vous pouvez aussi en connaître les bases et en apprendre davantage en développant sur DDNet.
The source code of DDNet is managed using [https://git-scm.com/ Git], a version control system, an essential tool to collaborate with multiple developers.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Quelques ressources utiles pour apprendre le C++ :
If you don't have git yet in your Linux distribution, make sure to install it, for example in most debian/ubuntu based distributions: <code>sudo apt install git</code>.
* [https://openclassrooms.com/fr/courses/1894236-apprenez-a-programmer-en-c openclassrooms.com] (bases, contient de la publicité, peut être limité en termes de pages par jour)
</div>
* [https://openclassrooms.com/fr/courses/7137751-programmez-en-oriente-objet-avec-c openclassrooms.com] (programmation orientée objet, contient de la publicité, peut être limité en termes de pages par jour)
* [https://cpp.developpez.com/cours/ developpez.com] (liste de tutoriels)
*[https://fr.cppreference.com/w/ cppreference.com] (pour les utilisateurs avancés)


Le code source de DDNet est géré à l'aide de [https://git-scm.com/ Git], un système de contrôle de version et un outil essentiel pour collaborer avec plusieurs développeurs.


<div lang="en" dir="ltr" class="mw-content-ltr">
Si vous ne disposez pas encore de git dans votre distribution Linux, veillez à l'installer, par exemple dans la plupart des distributions basées sur Debian/Ubuntu : <code>sudo apt install git</code>.
== Getting the source code ==
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
The source code is located on [https://github.com/ddnet/ddnet Github], you can get the source code by cloning without the need of an account, but if you want to ever put your changes to the official source code you will need one.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Getting_the_source_code"></span>
If you are not familiar with git/github you can learn the basics here: [https://docs.github.com/en/get-started/quickstart/hello-world Hello World - Github]
== Obtenir le code source ==
</div>


Le code source se trouve sur [https://github.com/ddnet/ddnet Github], vous pouvez le récupérer en clonant le répertoire sans compte: <code>git clone --recursive https://github.com/ddnet/ddnet.git</code>.
Cependant, vous devez avoir un compte pour proposer vos modifications à la communauté.


<div lang="en" dir="ltr" class="mw-content-ltr">
== Installing the dependencies ==
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Si vous n'êtes pas familier avec git/github, vous pouvez apprendre les bases ici : [https://docs.github.com/fr/get-started/quickstart/hello-world Hello World - Github]
If you are on Linux, you can install all the needed dependencies by reading the README on the DDNet github page: https://github.com/ddnet/ddnet#dependencies-on-linux--macos
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
For Arch Linux:
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Installing_the_dependencies"></span>
<code>sudo pacman -S --needed base-devel cmake curl freetype2 git glew gmock libnotify opusfile python sdl2 sqlite wavpack</code>
== Installer les dépendances ==
</div>


Sous Linux, vous pouvez installer les dépendances nécessaires en lisant le fichier README du répertoire github de DDNet: https://github.com/ddnet/ddnet#dependencies-on-linux--macos.


<div lang="en" dir="ltr" class="mw-content-ltr">
Pour Arch Linux :
== Compiling DDNet ==
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="bash">
We use CMake to control the compilation process, if you have all the dependencies installed, it's as easy as following these commands (make sure you are on the DDNet folder):
sudo pacman -S --needed base-devel cmake curl ffmpeg freetype2 git glew glslang gmock libnotify libpng opusfile python rust sdl2 spirv-tools sqlite vulkan-headers vulkan-icd-loader wavpack x264
</div>
</syntaxhighlight>
 
Pour Debian :


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
mkdir build
sudo apt install build-essential cargo cmake git glslang-tools google-mock libavcodec-extra libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libcurl4-openssl-dev libfreetype6-dev libglew-dev libnotify-dev libogg-dev libopus-dev libopusfile-dev libpng-dev libsdl2-dev libsqlite3-dev libssl-dev libvulkan-dev libwavpack-dev libx264-dev python3 rustc spirv-tools
cd build
</syntaxhighlight>
 
<span id="Compiling_DDNet"></span>
== Compiler DDNet ==
 
Nous utilisons [https://cmake.org/ CMake] pour gérer la compilation. Une fois que toutes les dépendances sont installés (incluant CMake), vous pouvez exécuter les commandes suivantes depuis le répertoire DDNet :
 
<syntaxhighlight lang="bash">
mkdir build && cd build
cmake ..
cmake ..
make -j$(nproc)
make -j$(nproc)
</syntaxhighlight>
</syntaxhighlight>
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="General_information"></span>
== General information ==
== Informations générales ==
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Voici quelques informations générales :
Here are some general bits of information:
*Actuellement, le code source est compilé avec le standard C++17, mais vous constaterez que de nombreuses parties du code sont plus proches du C puisque seul le nouveau code utilise des parties du standard C++17.
* Currently, the source code is compiled with the C++17 standard, but you will see that many parts of the code are more C-like since only mostly new code uses C++17 stuff.
*<code>std::string</code> est rarement utilisé, les tableaux de caractères et l'utilisation des méthodes <code>system.h</code> pour les manipuler sont la norme.
* <code>std::string</code> is rarely used, char arrays plus using <code>system.h</code> methods for handling them are the norm.
*Tout ce qui est E/S, formatage et affichage est réalisés en utilisant les méthodes de <code>system.h</code>.
* Most I/O code, formatting and printing is done using <code>system.h</code> provided methods.
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="The_source_code_layout"></span>
== The source code layout ==
== Disposition du code source ==
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Maintenant que vous pouvez build DDNet, vous pouvez commencer à faire des modifications.
Now that you can build DDNet you can begin editing it.
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="The_src/base_directory"></span>
=== The src/base directory ===
=== Répertoire src/base ===
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Comme DDNet est un jeu multi-plateforme, une couche d'abstraction est nécessaire pour un développement plus aisé. Ce répertoire contient les fonctions utiles pour tout ce qui touche au système d'exploitation.
Since DDNet is a cross-platform game, an abstraction layer over that is needed to make development easier, this directory contains many useful functions to handle that.
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="The_src/engine_directory"></span>
=== The src/engine directory ===
=== Répertoire src/engine ===
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Ici se trouve le moteur de jeu qui gère tout ce qui n'est pas lié à la jouabilité, à savoir les graphismes, le son, le réseau, etc.
Here lies the game engine, it handles most stuff that is not gameplay related, such as graphics, sound, network, etc.
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="The_src/game_directory"></span>
=== The src/game directory ===
=== Répertoire src/game ===
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Tout le code lié au gameplay est ici, séparé entre le client et le serveur.
All gameplay related code is here, separated into client and server.
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Server_side"></span>
==== Server side ====
==== Serveur ====
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Le jeu repose sur un ensemble de '''composants''' qui dérivent tous de la classe mère <code>CEntity</code> définie dans <code>src/game/server/entity.h</code>.
This game uses its own [https://en.wikipedia.org/wiki/Entity_component_system Entity Component System], the main class to which all other entities derive from is <code>CEntity</code> located in <code>src/game/server/entity.h</code>.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Ces entités sont gérées par la classe <code>CGameWorld</code> définie dans <code>src/game/server/gameworld.h</code>.
These entities are managed by the game world located here <code>src/game/server/gameworld.h</code>
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Quelques entités importantes:
Some important entities are:
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
* [https://github.com/ddnet/ddnet/blob/master/src/game/server/entities/character.h CCharacter] qui représente un [[Special:MyLanguage/Common Terminology/fr#Tee|Tee]] vivant. Elle est instanciée quand un tee apparaît et supprimée quand il meurt.
* [https://github.com/ddnet/ddnet/blob/master/src/game/server/entities/character.h CCharacter]: Represents a [[Special:MyLanguage/Common_Terminology#Tee|tee]] that is alive, it is instantiated when a tee spawns and deleted when it dies. For information about the player kept between deaths, see [https://github.com/ddnet/ddnet/blob/master/src/game/server/player.h CPlayer].
* [https://github.com/ddnet/ddnet/blob/master/src/game/server/player.h CPlayer] contient les informations non liées au [[Special:MyLanguage/Common Terminology/fr#Tee|Tee]] (pseudo, drapeau, etc.).
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Client_side"></span>
==== Client side ====
==== Client ====
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Le client est lui aussi constitué de composants qui sont tous des classes dérivées de [https://github.com/ddnet/ddnet/blob/master/src/game/client/component.h CComponent] définie dans <code>src/game/client/component.h</code>. Ces composants peuvent implémenter les méthodes virtuelles <code>OnInit</code>, <code>OnMessage</code>, etc. pour fournir leurs fonctionnalités.
The client side is made up of components, these are classes that inherit <code>CComponent</code>: These components can implement the virtual methods such as <code>OnInit</code>, <code>OnMessage</code>, etc. to provide their functionality.
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Networking"></span>
==== Networking ====
==== Réseau ====
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Le protocole réseau est généré par des scripts Python qui produisent du code C++. Par exemple, le fichier <code>datasrc/network.py</code> définit tous les paquets réseaux.
The network protocol is mostly generated by python scripts that output C++ code, for example, <code>datasrc/network.py</code> defines all network packets.
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Code_conventions"></span>
== Code conventions ==
== Convention de code ==
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
La discussion sur les conventions d'écriture se trouve ici: [https://github.com/ddnet/ddnet/issues/2945 ddnet#2945]
The ongoing discussion on code conventions is located here: [https://github.com/ddnet/ddnet/issues/2945 ddnet#2945]
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Actuellement, ce qui suit s'applique :
Currently, the following applies:
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Indentation_style"></span>
=== Indentation style ===
=== Indentation ===
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Le [https://fr.wikipedia.org/wiki/Style_d%27indentation#Style_Allman style d'Allman] est utilisé.
[https://en.wikipedia.org/wiki/Indentation_style#Allman_style Allman style] is used.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<blockquote>
<blockquote>
This style puts the brace associated with a control statement on the next line, indented to the same level as the control statement. Statements within the braces are indented to the next level.
Nommé d'après Eric Allman, ce style respecte un alignement strict des accolades ouvrantes et fermantes, comme dans l'exemple ci-dessous :
</blockquote>
</blockquote>
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
while(x == y)
while(x == y)
Line 205: Line 146:
     SomethingElse();
     SomethingElse();
}
}
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
FinalThing();
Finalthing();
</syntaxhighlight>
</syntaxhighlight>
</div>


<span id="Classes_and_Structs"></span>
=== Classes et structures ===


<div lang="en" dir="ltr" class="mw-content-ltr">
Toutes les classes et structures doivent être précédées par un <code>C</code> ou un <code>I</code> pour les interfaces. Pour des raisons historiques, certaines structures ne l'ont pas comme dans la partie graphique.
=== Classes and Structs ===
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Exemple:
Must be prefixed by <code>C</code> (for legacy reasons this is ignored for structs in some places, such as in graphics code) or <code>I</code> for interfaces.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Example:
</div>
<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
class CCharacter : public CEntity
class CCharacter : public CEntity
Line 232: Line 163:
}
}
</syntaxhighlight>
</syntaxhighlight>
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Enums_and_constants"></span>
=== Enums and constants ===
=== Énumérations et constantes ===
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Elles doivent être écrites en notation ''screaming snake case [https://fr.wikipedia.org/wiki/Snake_case]'' (''i.e.'' tout en majuscules avec un ''underscore'' <code>_</code> entre les mots). Par example: <code>MAX_PLAYERS</code>
Should be screaming snake case, for example: <code>MAX_PLAYERS</code>
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="c++">
<syntaxhighlight lang="cpp">
enum
enum
{
{
Line 256: Line 182:
};
};
</syntaxhighlight>
</syntaxhighlight>
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Variable_naming"></span>
=== Variable naming ===
=== Convention de nommage ===
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
* Le nom des variables doit contenir 3 parties : le qualificatif, le préfixe et le nom.
* The names of variables contain 3 parts: qualifier, prefix and name.
* Les noms doivent commencer par une majuscule à moins qu'elle ne soit de longueur unitaire sans aucun qualificatif ou préfixe, par exemple les variables de boucle <code>i</code> et <code>j</code>.
* Variable names should start with uppercase unless they are 1 char long without any prefix or qualifier, for example: <code>i</code>, <code>x</code>, <code>y</code>.
* Les noms des variables doivent être écrits en '''anglais''' et suivent la convention ''camel case [https://fr.wikipedia.org/wiki/Camel_case]'' (''i.e.'' majuscule à chaque mot).  
* Variables can have more than 1 qualifier (or zero) and more than 1 prefix (or zero).
* Les variables peuvent avoir plus d'un qualificatif ou plus d'un préfixe.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Ils sont disposés de la manière suivante: <code>[qualificatifs]_[préfixes][Nom]</code>.
These are laid out like this: <code>[qualifiers]_[prefixes][Name]</code>
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Qualifiers"></span>
==== Qualifiers ====
==== Qualificatifs ====
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
* <code>m</code> pour les variables membres: <code>m_MyVariable</code>
* <code>m</code> for member variables: <code>m_MyVariable</code>.
* <code>s</code> pour les variables statiques: <code>s_MyStaticVariable</code>
* <code>s</code> for static variables: <code>s_MyStaticVariable</code>.
* <code>g</code> pour les variables globales : <code>gs_MyGlobalStaticVar</code>
* <code>g</code> for global variables with external linkage: <code>gs_MyGlobalStaticVar</code>.
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Prefixes"></span>
==== Prefixes ====
==== Préfixes ====
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
* <code>p</code> pour les pointeurs : <code>pMyPointer</code>, <code>m_pCharacter</code>, <code>ppMyPointerToPointer</code>
* <code>p</code> for pointers: <code>pMyPointer</code>, <code>m_pCharacter</code>, <code>ppMyPointerToPointer</code>.
* <code>a</code> pour les tableaux : <code>aMyArray[MAX_PLAYERS]</code>, <code>aBuf</code>
* <code>a</code> for arrays: <code>aMyArray</code>, <code>aBuf</code>.
*<code>v</code> pour les <code>std::vector</code> : <code>vMyVector</code>, <code>vpvMyVectorOfPointersToVectors</code>.
* <code>fn</code> for functions: <code>pfnMyCallback</code>, <code>m_papfnMyPointerToArrayOfCallbacks</code>.
* <code>fn</code> pour les fonctions : <code>pfnMyCallback</code>, <code>m_papfnMyPointerToArrayOfCallbacks</code>
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Common_snippets"></span>
== Common snippets ==
== Exemples courants ==
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
Voici une liste d'extraits de code que vous pouvez voir fréquemment dans la base de code :
Here is a list of code that you may frequently see across the codebase:
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Formatting_text"></span>
=== Formatting text ===
=== Formatage de texte ===
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="c++">
<syntaxhighlight lang="cpp">
char aBuf[128];
char aBuf[128];
str_format(aBuf, sizeof(aBuf), "number: %d", 2);
str_format(aBuf, sizeof(aBuf), "number: %d", 2);
</syntaxhighlight>
</syntaxhighlight>
</div>


Voir [https://cplusplus.com/reference/cstdio/printf/ printf documentation] pour une liste de tous les spécificateurs de format.
=== Itérer sur tous les joueurs ===


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="c++">
=== Iterating over all players ===
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="cpp">
for(int i = 0; i < MAX_CLIENTS; i++)
for(int i = 0; i < MAX_CLIENTS; i++)
{
{
Line 329: Line 236:
}
}
</syntaxhighlight>
</syntaxhighlight>
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Printing_to_the_game_console"></span>
=== Printing to the game console ===
=== Afficher dans la console de jeu ===
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="c++">
<syntaxhighlight lang="cpp">
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "wikiprint", "Hello from the ddnet wiki!");
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "wikiprint", "Hello from the ddnet wiki!");
</syntaxhighlight>
</syntaxhighlight>
</div>




<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="Debug_printing"></span>
=== Debug printing ===
=== Affichage de débogage ===
</div>
 
<syntaxhighlight lang="c++">
int i = 2;
dbg_msg("wikiprint", "Hello from the ddnet wiki: %d", i)
</syntaxhighlight>


<div lang="en" dir="ltr" class="mw-content-ltr">
===Traduction du texte dans le client===
<code>Localize</code> peut être utilisé dans le client du jeu pour obtenir la traduction d'un texte spécifique à partir du fichier de langue sélectionné par l'utilisateur.
<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
int i = 2;
DoButton(..., Localize("Connect"), ...);
dbg_msg("wikiprint", "Hello from the ddnet wiki: %d", i);
</syntaxhighlight>
Le texte peut également contenir des spécificateurs de format. La chaîne traduite doit alors contenir les mêmes spécificateurs de format.
<syntaxhighlight lang="cpp">
char aBuf[128];
str_format(aBuf, sizeof(aBuf), Localize("%d of %d servers"), NumServers, TotalServers);
</syntaxhighlight>
</syntaxhighlight>
</div>
Un script est utilisé pour chercher dans le code les appels à <code>Localize</code> et collecter les chaînes de caractères pour mettre à jour les fichiers de traduction.
Pour cette raison, l'appel à <code>Localize</code> ne doit pas contenir d'autre code, sinon le script ne peut pas déterminer le texte correctement.
<syntaxhighlight lang="cpp">
// Ne faites PAS ça :
const char *pStr = Localize(Team == TEAM_RED ? "Red team" : "Blue team");


// Faites plutôt ceci :
const char *pStr = Team == TEAM_RED ? Localize("Red team") : Localize("Blue team");
</syntaxhighlight>


<div lang="en" dir="ltr" class="mw-content-ltr">
<span id="External_resources"></span>
== External resources ==
== Ressource externes ==
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
* [https://edgarluque.com/blog/ui-code-ddnet/ UI Code in DDraceNetwork] par [[Special:MyLanguage/User:Ryozuki|Ryozuki]]
* [https://edgarluque.com/blog/intro-to-ddnet/ An intro to the DDraceNetwork game source code]  by [[Special:MyLanguage/User:Ryozuki|Ryozuki]]
* [https://edgarluque.com/blog/intro-to-ddnet/ An intro to the DDraceNetwork game source code]  par [[Special:MyLanguage/User:Ryozuki|Ryozuki]]
* [https://edgarluque.com/blog/code-conventions-in-ddnet/ Code conventions in DDraceNetwork]  by [[Special:MyLanguage/User:Ryozuki|Ryozuki]]
* [https://edgarluque.com/blog/code-conventions-in-ddnet/ Code conventions in DDraceNetwork]  par [[Special:MyLanguage/User:Ryozuki|Ryozuki]]
* [https://edgarluque.com/blog/chat-command-ddracenetwork/ Implementing a chat command in DDraceNetwork]  by [[Special:MyLanguage/User:Ryozuki|Ryozuki]]
* [https://edgarluque.com/blog/chat-command-ddracenetwork/ Implementing a chat command in DDraceNetwork]  par [[Special:MyLanguage/User:Ryozuki|Ryozuki]]
* [https://codedoc.ddnet.org/ Auto generated docs]
* [https://codedoc.ddnet.org/ Auto generated docs]
* [https://ddnet.org/libtw2-doc/ Technical documentation of Teeworlds file formats and network protocol]
* [https://ddnet.org/libtw2-doc/ Technical documentation of Teeworlds file formats and network protocol]
* [https://heinrich5991.github.io/blog/blog/one-tick-unfreeze The Anatomy of a One Tick Unfreeze]
* [https://heinrich5991.github.io/blog/blog/one-tick-unfreeze The Anatomy of a One Tick Unfreeze]
* [https://www.youtube.com/playlist?list=PLhJkqAQmOh5LyYOfnMy4PJB6CSZltQyTc Teeworlds programming YouTube tutorial] by ChillerDragon
* [https://www.youtube.com/playlist?list=PLhJkqAQmOh5LyYOfnMy4PJB6CSZltQyTc Teeworlds programming YouTube tutorial] par ChillerDragon
</div>
*[https://chillerdragon.github.io/teeworlds-protocol/ Teeworlds 0.6/0.7 network protocol documentation] par [[User:ChillerDragon|ChillerDragon]]
 
<span id="About_Tee_Skin_Rendering"></span>
== À propos du rendu des Skin ==
 
Cette section explique comment effectuer l'affichage du skin d'un Tee.
 
Valeurs rassemblées par Patiga
Remerciements à Jupstar
Segment Scaling:
    body: 100%
    feet: 150%
    eyes: 120%
    eye blink: 45%
    hand: 93.75%
Positioning:
    64/64 = 1 = width or height of the body segment
    body: 4/64 up
    feet:
        10/64 down
        7/64 left/right
    eyes:
        0.125 up
        0.05 left/right
    eye movement:
        dir = angle of eyes (view angle), right = 0
        eyes:
            x: cos(dir) * 0.125
            y: sin(dir) * 0.1
        each eye (away from the other):
            x: abs(cos(dir)) * 0.01

Latest revision as of 14:36, 5 May 2024

Cet article a pour but de vous introduire au développement de DDNet. En tant que jeu open-source, il repose sur la générosité et le temps libre des contributeurs.


Environnement de développement

Il est fortement recommandé de mettre en place un environnement Linux pour commencer à programmer dans DDNet pour les raisons suivantes (à ce jour) :

  • La plupart des contributeurs utilisent Linux;
  • La gestion des paquets est plus facile, vous pouvez facilement installer toutes les librairies requises;
  • Cet article n'a pas encore de version Windows et se concentre sur Linux.

Tout d'abord, DDNet est codé en utilisant le langage de programmation C++. Vous devrez être assez familier avec ce langage, mais vous pouvez aussi en connaître les bases et en apprendre davantage en développant sur DDNet.

Quelques ressources utiles pour apprendre le C++ :

Le code source de DDNet est géré à l'aide de Git, un système de contrôle de version et un outil essentiel pour collaborer avec plusieurs développeurs.

Si vous ne disposez pas encore de git dans votre distribution Linux, veillez à l'installer, par exemple dans la plupart des distributions basées sur Debian/Ubuntu : sudo apt install git.


Obtenir le code source

Le code source se trouve sur Github, vous pouvez le récupérer en clonant le répertoire sans compte: git clone --recursive https://github.com/ddnet/ddnet.git. Cependant, vous devez avoir un compte pour proposer vos modifications à la communauté.


Si vous n'êtes pas familier avec git/github, vous pouvez apprendre les bases ici : Hello World - Github


Installer les dépendances

Sous Linux, vous pouvez installer les dépendances nécessaires en lisant le fichier README du répertoire github de DDNet: https://github.com/ddnet/ddnet#dependencies-on-linux--macos.

Pour Arch Linux :

sudo pacman -S --needed base-devel cmake curl ffmpeg freetype2 git glew glslang gmock libnotify libpng opusfile python rust sdl2 spirv-tools sqlite vulkan-headers vulkan-icd-loader wavpack x264

Pour Debian :

sudo apt install build-essential cargo cmake git glslang-tools google-mock libavcodec-extra libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libcurl4-openssl-dev libfreetype6-dev libglew-dev libnotify-dev libogg-dev libopus-dev libopusfile-dev libpng-dev libsdl2-dev libsqlite3-dev libssl-dev libvulkan-dev libwavpack-dev libx264-dev python3 rustc spirv-tools

Compiler DDNet

Nous utilisons CMake pour gérer la compilation. Une fois que toutes les dépendances sont installés (incluant CMake), vous pouvez exécuter les commandes suivantes depuis le répertoire DDNet :

mkdir build && cd build
cmake ..
make -j$(nproc)


Informations générales

Voici quelques informations générales :

  • Actuellement, le code source est compilé avec le standard C++17, mais vous constaterez que de nombreuses parties du code sont plus proches du C puisque seul le nouveau code utilise des parties du standard C++17.
  • std::string est rarement utilisé, les tableaux de caractères et l'utilisation des méthodes system.h pour les manipuler sont la norme.
  • Tout ce qui est E/S, formatage et affichage est réalisés en utilisant les méthodes de system.h.


Disposition du code source

Maintenant que vous pouvez build DDNet, vous pouvez commencer à faire des modifications.


Répertoire src/base

Comme DDNet est un jeu multi-plateforme, une couche d'abstraction est nécessaire pour un développement plus aisé. Ce répertoire contient les fonctions utiles pour tout ce qui touche au système d'exploitation.


Répertoire src/engine

Ici se trouve le moteur de jeu qui gère tout ce qui n'est pas lié à la jouabilité, à savoir les graphismes, le son, le réseau, etc.


Répertoire src/game

Tout le code lié au gameplay est ici, séparé entre le client et le serveur.


Serveur

Le jeu repose sur un ensemble de composants qui dérivent tous de la classe mère CEntity définie dans src/game/server/entity.h.

Ces entités sont gérées par la classe CGameWorld définie dans src/game/server/gameworld.h.

Quelques entités importantes:

  • CCharacter qui représente un Tee vivant. Elle est instanciée quand un tee apparaît et supprimée quand il meurt.
  • CPlayer contient les informations non liées au Tee (pseudo, drapeau, etc.).


Client

Le client est lui aussi constitué de composants qui sont tous des classes dérivées de CComponent définie dans src/game/client/component.h. Ces composants peuvent implémenter les méthodes virtuelles OnInit, OnMessage, etc. pour fournir leurs fonctionnalités.


Réseau

Le protocole réseau est généré par des scripts Python qui produisent du code C++. Par exemple, le fichier datasrc/network.py définit tous les paquets réseaux.


Convention de code

La discussion sur les conventions d'écriture se trouve ici: ddnet#2945

Actuellement, ce qui suit s'applique :


Indentation

Le style d'Allman est utilisé.

Nommé d'après Eric Allman, ce style respecte un alignement strict des accolades ouvrantes et fermantes, comme dans l'exemple ci-dessous :

while(x == y)
{
    Something();
    SomethingElse();
}

FinalThing();

Classes et structures

Toutes les classes et structures doivent être précédées par un C ou un I pour les interfaces. Pour des raisons historiques, certaines structures ne l'ont pas comme dans la partie graphique.

Exemple:

class CCharacter : public CEntity
{
    // ...
}


Énumérations et constantes

Elles doivent être écrites en notation screaming snake case [1] (i.e. tout en majuscules avec un underscore _ entre les mots). Par example: MAX_PLAYERS

enum
{
	FAKETUNE_FREEZE = 1,
	FAKETUNE_SOLO = 2,
	FAKETUNE_NOJUMP = 4,
	FAKETUNE_NOCOLL = 8,
	FAKETUNE_NOHOOK = 16,
	FAKETUNE_JETPACK = 32,
	FAKETUNE_NOHAMMER = 64,
};


Convention de nommage

  • Le nom des variables doit contenir 3 parties : le qualificatif, le préfixe et le nom.
  • Les noms doivent commencer par une majuscule à moins qu'elle ne soit de longueur unitaire sans aucun qualificatif ou préfixe, par exemple les variables de boucle i et j.
  • Les noms des variables doivent être écrits en anglais et suivent la convention camel case [2] (i.e. majuscule à chaque mot).
  • Les variables peuvent avoir plus d'un qualificatif ou plus d'un préfixe.

Ils sont disposés de la manière suivante: [qualificatifs]_[préfixes][Nom].


Qualificatifs

  • m pour les variables membres: m_MyVariable
  • s pour les variables statiques: s_MyStaticVariable
  • g pour les variables globales : gs_MyGlobalStaticVar


Préfixes

  • p pour les pointeurs : pMyPointer, m_pCharacter, ppMyPointerToPointer
  • a pour les tableaux : aMyArray[MAX_PLAYERS], aBuf
  • v pour les std::vector : vMyVector, vpvMyVectorOfPointersToVectors.
  • fn pour les fonctions : pfnMyCallback, m_papfnMyPointerToArrayOfCallbacks


Exemples courants

Voici une liste d'extraits de code que vous pouvez voir fréquemment dans la base de code :


Formatage de texte

char aBuf[128];
str_format(aBuf, sizeof(aBuf), "number: %d", 2);

Voir printf documentation pour une liste de tous les spécificateurs de format.

Itérer sur tous les joueurs

for(int i = 0; i < MAX_CLIENTS; i++)
{
    // Server-side
    CPlayer *pPlayer = GameServer()->m_apPlayers[i];
}


Afficher dans la console de jeu

Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "wikiprint", "Hello from the ddnet wiki!");


Affichage de débogage

int i = 2;
dbg_msg("wikiprint", "Hello from the ddnet wiki: %d", i)

Traduction du texte dans le client

Localize peut être utilisé dans le client du jeu pour obtenir la traduction d'un texte spécifique à partir du fichier de langue sélectionné par l'utilisateur.

DoButton(..., Localize("Connect"), ...);

Le texte peut également contenir des spécificateurs de format. La chaîne traduite doit alors contenir les mêmes spécificateurs de format.

char aBuf[128];
str_format(aBuf, sizeof(aBuf), Localize("%d of %d servers"), NumServers, TotalServers);

Un script est utilisé pour chercher dans le code les appels à Localize et collecter les chaînes de caractères pour mettre à jour les fichiers de traduction. Pour cette raison, l'appel à Localize ne doit pas contenir d'autre code, sinon le script ne peut pas déterminer le texte correctement.

// Ne faites PAS ça :
const char *pStr = Localize(Team == TEAM_RED ? "Red team" : "Blue team");

// Faites plutôt ceci :
const char *pStr = Team == TEAM_RED ? Localize("Red team") : Localize("Blue team");

Ressource externes

À propos du rendu des Skin

Cette section explique comment effectuer l'affichage du skin d'un Tee.

Valeurs rassemblées par Patiga
Remerciements à Jupstar

Segment Scaling:
   body: 100%
   feet: 150%
   eyes: 120%
   eye blink: 45%
   hand: 93.75%

Positioning:
   64/64 = 1 = width or height of the body segment
   body: 4/64 up
   feet:
       10/64 down
       7/64 left/right
   eyes:
       0.125 up
       0.05 left/right

   eye movement:
       dir = angle of eyes (view angle), right = 0
       eyes:
           x: cos(dir) * 0.125
           y: sin(dir) * 0.1
       each eye (away from the other):
           x: abs(cos(dir)) * 0.01