Development/fr: Difference between revisions

From DDraceNetwork
(Fixed enums case)
(Updating to match new version of source page)
Line 1: Line 1:
{{DISPLAYTITLE:Développement}}
<languages/>
{{LangNavBox}}
<div lang="en" dir="ltr" class="mw-content-ltr">
Cet article vous introduit au développement de DDNet. En tant que jeu à sources ouvertes, il repose sur la générosité et le temps libre des contributeurs.
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>


== Environnement de développement ==
Il est recommandé de développer dans un environnement Linux pour les raisons suivantes:


* la plupart des contributeurs utilisent Linux;
<div lang="en" dir="ltr" class="mw-content-ltr">
* gestion des paquets plus aisée, vous pouvez facilement installer les librairies requises;
== Your development environment ==
* cet article n'a pas encore de version Windows et se concentre sur Linux.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
It is extremely recommended to set up a Linux environment to begin programming in DDNet for the following reasons (as of now):
* 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>


DDNet est écrit en langage C++ et vous devez en avoir une bonne connaissance mais vous pouvez aussi en connaître les bases et apprendre en développant pour DDNet.
<div lang="en" dir="ltr" class="mw-content-ltr">
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>


Quelques ressources de développement utiles:
<div lang="en" dir="ltr" class="mw-content-ltr">
Some useful resources to learn C++:
* [https://www.learncpp.com/ learncpp.com]
* [https://en.cppreference.com/w/ cppreference.com]
* Your search engine of preference
</div>


* [https://en.cppreference.com/w/ cppreference.com] (référence C++ en anglais pour utilisateurs avancés)
<div lang="en" dir="ltr" class="mw-content-ltr">
* [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)
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.
* [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)
</div>
* [https://cpp.developpez.com/cours/ developpez.com] (liste de tutoriels)


Le code source de DDNet est géré par [https://git-scm.com/ Git], un outil de versionnage. Vous pouvez l'installer dans la majorité des distributions basées sur Ubuntu/Debian : <code>sudo apt install git</code>.
<div lang="en" dir="ltr" class="mw-content-ltr">
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>.
</div>


== Obtenir le code source ==
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 devrez avoir un compte pour proposer vos modifications à la communauté.


Quelques ressources pour apprendre Git:
<div lang="en" dir="ltr" class="mw-content-ltr">
== Getting the source code ==
</div>


* [https://docs.github.com/en/get-started/quickstart/hello-world Hello World - Github] (en anglais)
<div lang="en" dir="ltr" class="mw-content-ltr">
* [https://openclassrooms.com/fr/courses/7162856-gerez-du-code-avec-git-et-github openclassrooms.com]
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>


== Installer les dépendances ==
<div lang="en" dir="ltr" class="mw-content-ltr">
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.
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]
</div>


== 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">
<div lang="en" dir="ltr" class="mw-content-ltr">
mkdir build && cd build
== Installing the dependencies ==
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
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">
<code>sudo pacman -S --needed base-devel cmake curl freetype2 git glew gmock libnotify opusfile python sdl2 sqlite wavpack</code>
</div>
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
== Compiling DDNet ==
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
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):
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
<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">
== General information ==
</div>


== Informations générales ==
<div lang="en" dir="ltr" class="mw-content-ltr">
Actuellement, le code est compilé avec le standard C++17 mais vous constaterez que la majeure partie du code est plus proche du C et seul le nouveau code utilise des parties du standard C++17.
Here are some general bits of information:
* 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> is rarely used, char arrays plus using <code>system.h</code> methods for handling them are the norm.
* Most I/O code, formatting and printing is done using <code>system.h</code> provided methods.
</div>


<code>std::string</code> est rarement utilisée. Les tableaux de caractères et l'utilisation des méthodes de  <code>system.h</code> sont la norme.


Tout ce qui est E/S, formatage et affichage est réalisés en utilisant les méthodes de <code>system.h</code>.
<div lang="en" dir="ltr" class="mw-content-ltr">
== The source code layout ==
</div>


== Disposition du code source ==
<div lang="en" dir="ltr" class="mw-content-ltr">
Now that you can build DDNet you can begin editing it.
</div>


=== 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 ===
<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.
=== The src/base directory ===
</div>


=== Répertoire src/game ===
<div lang="en" dir="ltr" class="mw-content-ltr">
Tout ce qui concerne la jouabilité, séparé entre client et serveur, incluant la physique du jeu et l'interface graphique du client.
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>


==== Serveur ====
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>. Ces entités sont gérées par la classe <code>CGameWorld</code> définie dans <code>src/game/server/gameworld.h</code>.


Quelques entités importantes:
<div lang="en" dir="ltr" class="mw-content-ltr">
=== The src/engine directory ===
</div>


* [https://github.com/ddnet/ddnet/blob/master/src/game/server/entities/character.h CCharacter] qui représente un [[Common Terminology/fr#Tee|Tee]] vivant. Elle est instanciée quand un tee apparaît et supprimée quand il meurt.
<div lang="en" dir="ltr" class="mw-content-ltr">
* [https://github.com/ddnet/ddnet/blob/master/src/game/server/player.h CPlayer] contient les informations non liées au [[Common Terminology/fr#Tee|Tee]] (pseudo, drapeau, etc.).
Here lies the game engine, it handles most stuff that is not gameplay related, such as graphics, sound, network, etc.
</div>


==== Client ====
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.


==== Réseau ====
<div lang="en" dir="ltr" class="mw-content-ltr">
Le protocole réseau est généré par des scripts Python qui génèrent le code C++. Par exemple, le fichier <code>datasrc/network.py</code> définit tous les paquets réseaux.
=== The src/game directory ===
</div>


== Convention de code ==
<div lang="en" dir="ltr" class="mw-content-ltr">
La discussion pour les conventions d'écriture se trouve ici: [https://github.com/ddnet/ddnet/issues/2945 ddnet#2945]
All gameplay related code is here, separated into client and server.
</div>


Actuellement, ce qui suit s'applique.


=== Indentation ===
<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é.<syntaxhighlight lang="c">
==== Server side ====
while (x == y)
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
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">
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">
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]: 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].
</div>
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
==== Client side ====
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
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">
==== Networking ====
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
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">
== Code conventions ==
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
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">
Currently, the following applies:
</div>
 
 
<div lang="en" dir="ltr" class="mw-content-ltr">
=== Indentation style ===
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
[https://en.wikipedia.org/wiki/Indentation_style#Allman_style Allman style] is used.
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
<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.
</blockquote>
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="cpp">
while(x == y)
{
{
     Something();
     Something();
     SomethingElse();
     SomethingElse();
}
}
</div>


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


=== 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>


Exemple:<syntaxhighlight lang="c++">
<div lang="en" dir="ltr" class="mw-content-ltr">
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">
class CCharacter : public CEntity
class CCharacter : public CEntity
{
{
Line 97: Line 232:
}
}
</syntaxhighlight>
</syntaxhighlight>
</div>


=== Énumérations et constantes ===
 
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><syntaxhighlight lang="c++">
<div lang="en" dir="ltr" class="mw-content-ltr">
=== Enums and constants ===
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
Should be screaming snake case, for example: <code>MAX_PLAYERS</code>
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="cpp">
enum
enum
{
{
Line 111: Line 256:
};
};
</syntaxhighlight>
</syntaxhighlight>
</div>
<div lang="en" dir="ltr" class="mw-content-ltr">
=== Variable naming ===
</div>
<div lang="en" dir="ltr" class="mw-content-ltr">
* The names of variables contain 3 parts: qualifier, prefix and name.
* 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>.
* Variables can have more than 1 qualifier (or zero) and more than 1 prefix (or zero).
</div>
<div lang="en" dir="ltr" class="mw-content-ltr">
These are laid out like this: <code>[qualifiers]_[prefixes][Name]</code>
</div>
<div lang="en" dir="ltr" class="mw-content-ltr">
==== Qualifiers ====
</div>
<div lang="en" dir="ltr" class="mw-content-ltr">
* <code>m</code> for member variables: <code>m_MyVariable</code>.
* <code>s</code> for static variables: <code>s_MyStaticVariable</code>.
* <code>g</code> for global variables with external linkage: <code>gs_MyGlobalStaticVar</code>.
</div>


=== Convention de nommage ===
<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. 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>. 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). Les variables peuvent avoir plus d'un qualificatif ou plus d'un préfixe.
==== Prefixes ====
</div>


Ils sont disposés de la manière suivante: <code>[qualificatifs]_[préfixes][Nom]</code>.
<div lang="en" dir="ltr" class="mw-content-ltr">
* <code>p</code> for pointers: <code>pMyPointer</code>, <code>m_pCharacter</code>, <code>ppMyPointerToPointer</code>.
* <code>a</code> for arrays: <code>aMyArray</code>, <code>aBuf</code>.
* <code>fn</code> for functions: <code>pfnMyCallback</code>, <code>m_papfnMyPointerToArrayOfCallbacks</code>.
</div>


==== Qualificatifs ====


* <code>m</code> pour les variables membres: <code>m_MyVariable</code>
<div lang="en" dir="ltr" class="mw-content-ltr">
* <code>s</code> pour les variables statiques: <code>s_MyStaticVariable</code>
== Common snippets ==
* <code>g</code> pour les variables globales : <code>gs_MyGlobalStaticVar</code>
</div>


==== Préfixes ====
<div lang="en" dir="ltr" class="mw-content-ltr">
Here is a list of code that you may frequently see across the codebase:
</div>


* <code>p</code> pour les pointeurs: <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>fn</code> pour les fonctions: <code>pfnMyCallback</code>, <code>m_papfnMyPointerToArrayOfCallbacks</code>


== Exemples courants ==
<div lang="en" dir="ltr" class="mw-content-ltr">
=== Formatting text ===
</div>


=== Formatage de texte ===
<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>


=== Itérer tous les joueurs ===
 
<syntaxhighlight lang="c++">
<div lang="en" dir="ltr" class="mw-content-ltr">
=== 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++)
{
{
     // Server-side
     // Server-side
     CPlayer *pPlayer = GameServer()->m_apPlayers[i];
     CPlayer *pPlayer = GameServer()->m_apPlayers[i];
    if(pPlayer == nullptr)
        continue;
    // do something with pPlayer
}
}
</syntaxhighlight>
</syntaxhighlight>
</div>


=== Afficher dans la console de jeu ===
 
<syntaxhighlight lang="c++">
<div lang="en" dir="ltr" class="mw-content-ltr">
=== Printing to the game console ===
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
<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>
</div>


</syntaxhighlight>


=== Affichage de débogage ===
<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="c++">
=== Debug printing ===
</div>
 
<div lang="en" dir="ltr" class="mw-content-ltr">
<syntaxhighlight lang="cpp">
int i = 2;
int i = 2;
dbg_msg("wikiprint", "Hello from the ddnet wiki: %d", i)
dbg_msg("wikiprint", "Hello from the ddnet wiki: %d", i);
</syntaxhighlight>
</syntaxhighlight>
</div>
<div lang="en" dir="ltr" class="mw-content-ltr">
== External resources ==
</div>
<div lang="en" dir="ltr" class="mw-content-ltr">
* [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/code-conventions-in-ddnet/ Code conventions in DDraceNetwork]  by [[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://codedoc.ddnet.org/ Auto generated docs]
* [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://www.youtube.com/playlist?list=PLhJkqAQmOh5LyYOfnMy4PJB6CSZltQyTc Teeworlds programming YouTube tutorial] by ChillerDragon
</div>

Revision as of 16:21, 11 February 2023

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.


Your development environment

It is extremely recommended to set up a Linux environment to begin programming in DDNet for the following reasons (as of now):

  • 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.

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.

Some useful resources to learn C++:

The source code of DDNet is managed using Git, a version control system, an essential tool to collaborate with multiple developers.

If you don't have git yet in your Linux distribution, make sure to install it, for example in most debian/ubuntu based distributions: sudo apt install git.


Getting the source code

The source code is located on 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.

If you are not familiar with git/github you can learn the basics here: Hello World - Github


Installing the dependencies

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

For Arch Linux:

sudo pacman -S --needed base-devel cmake curl freetype2 git glew gmock libnotify opusfile python sdl2 sqlite wavpack


Compiling DDNet

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):

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


General information

Here are some general bits of information:

  • 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.
  • std::string is rarely used, char arrays plus using system.h methods for handling them are the norm.
  • Most I/O code, formatting and printing is done using system.h provided methods.


The source code layout

Now that you can build DDNet you can begin editing it.


The src/base directory

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.


The src/engine directory

Here lies the game engine, it handles most stuff that is not gameplay related, such as graphics, sound, network, etc.


The src/game directory

All gameplay related code is here, separated into client and server.


Server side

This game uses its own Entity Component System, the main class to which all other entities derive from is CEntity located in src/game/server/entity.h.

These entities are managed by the game world located here src/game/server/gameworld.h

Some important entities are:

  • CCharacter: Represents a 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 CPlayer.


Client side

The client side is made up of components, these are classes that inherit CComponent: These components can implement the virtual methods such as OnInit, OnMessage, etc. to provide their functionality.


Networking

The network protocol is mostly generated by python scripts that output C++ code, for example, datasrc/network.py defines all network packets.


Code conventions

The ongoing discussion on code conventions is located here: ddnet#2945

Currently, the following applies:


Indentation style

Allman style is used.

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.

while(x == y)
{
    Something();
    SomethingElse();
}
</div>

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


Classes and Structs

Must be prefixed by C (for legacy reasons this is ignored for structs in some places, such as in graphics code) or I for interfaces.

Example:

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


Enums and constants

Should be screaming snake case, for 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,
};


Variable naming

  • The names of variables contain 3 parts: qualifier, prefix and name.
  • Variable names should start with uppercase unless they are 1 char long without any prefix or qualifier, for example: i, x, y.
  • Variables can have more than 1 qualifier (or zero) and more than 1 prefix (or zero).

These are laid out like this: [qualifiers]_[prefixes][Name]


Qualifiers

  • m for member variables: m_MyVariable.
  • s for static variables: s_MyStaticVariable.
  • g for global variables with external linkage: gs_MyGlobalStaticVar.


Prefixes

  • p for pointers: pMyPointer, m_pCharacter, ppMyPointerToPointer.
  • a for arrays: aMyArray, aBuf.
  • fn for functions: pfnMyCallback, m_papfnMyPointerToArrayOfCallbacks.


Common snippets

Here is a list of code that you may frequently see across the codebase:


Formatting text

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


Iterating over all players

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


Printing to the game console

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


Debug printing

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


External resources