Development/fr: Difference between revisions
(Fixed enums case) |
(Updating to match new version of source page) |
||
(4 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
{{ | {{MigrateTranslation}} | ||
<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> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
== Your development environment == | |||
</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 | <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> | |||
<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> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
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"> | |||
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> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
== 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"> | ||
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> | |||
== | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
mkdir 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"> | |||
<syntaxhighlight lang="bash"> | |||
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 | |||
</syntaxhighlight> | |||
</div> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
For Debian: | |||
</div> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
<syntaxhighlight lang="bash"> | |||
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 python rustc spirv-tools4 | |||
</syntaxhighlight> | |||
</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> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
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> | |||
== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
== The source code layout == | |||
</div> | |||
< | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
Now that you can build DDNet you can begin editing it. | |||
</div> | |||
== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
=== The src/base directory === | |||
</div> | |||
=== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
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"> | ||
=== The src/engine directory === | |||
</div> | |||
=== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
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"> | |||
=== The src/game directory === | |||
</div> | |||
=== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
All gameplay related code is here, separated into client and server. | |||
</div> | |||
== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
==== Server side ==== | |||
</div> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
This game uses its own hierarchical object-oriented entity 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> | |||
=== Indentation === | <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> | |||
while (x == y) | </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(); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
</div> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
=== Classes and Structs === | |||
</div> | |||
<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. New <code>struct</code>s should be prefixed by <code>S</code>. | |||
</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 243: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
</div> | |||
<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 267: | ||
}; | }; | ||
</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> | |||
* <code> | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
* <code> | * <code>m</code> for member variables: <code>m_MyVariable</code>. | ||
* <code> | * <code>s</code> for static variables: <code>s_MyStaticVariable</code>, <code>ms_MyStaticMemberVariable</code>. | ||
* <code>g</code> for global variables with external linkage: <code>gs_MyGlobalStaticVar</code>. | |||
</div> | |||
=== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
<syntaxhighlight lang=" | ==== Prefixes ==== | ||
</div> | |||
<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>v</code> for <code>std::vector</code>s: <code>vMyVector</code>, <code>vpvMyVectorOfPointersToVectors</code>. | |||
* <code>fn</code> for functions: <code>pfnMyCallback</code>, <code>m_papfnMyPointerToArrayOfCallbacks</code>. | |||
</div> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
== Common snippets == | |||
</div> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
Here is a list of code that you may frequently see across the codebase: | |||
</div> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
=== Formatting text === | |||
</div> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
<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> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
See [https://cplusplus.com/reference/cstdio/printf/ printf documentation] for a list of all format specifiers. | |||
=== Iterating over all players === | |||
</div> | |||
=== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
<syntaxhighlight lang=" | <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]; | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
</div> | |||
<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=" | <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> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
=== Debug printing === | |||
</div> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
<syntaxhighlight lang="cpp"> | |||
int i = 2; | |||
dbg_msg("wikiprint", "Hello from the ddnet wiki: %d", i); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
</div> | |||
=== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
<syntaxhighlight lang=" | === Translating text in the client === | ||
<code>Localize</code> can be used in the game client to get the translation for a specific string from the language file selected by the user.<syntaxhighlight lang="cpp"> | |||
DoButton(..., Localize("Connect"), ...); | |||
</syntaxhighlight>The string can also contain format specifiers. The translated string must contain the same format specifiers.<syntaxhighlight lang="cpp"> | |||
char aBuf[128]; | |||
str_format(aBuf, sizeof(aBuf), Localize("%d of %d servers"), NumServers, TotalServers); | |||
</syntaxhighlight>A script is used to scan the code for calls to <code>Localize</code> and collect the strings to update the translation files. For this reason, the call to <code>Localize</code> must not contain any other code, or the script cannot determine the text correctly.<syntaxhighlight lang="cpp"> | |||
// Do NOT do this: | |||
const char *pStr = Localize(Team == TEAM_RED ? "Red team" : "Blue team"); | |||
</div> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
// Do this instead: | |||
const char *pStr = Team == TEAM_RED ? Localize("Red team") : Localize("Blue team"); | |||
</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/ui-code-ddnet/ UI Code in DDraceNetwork] by [[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/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> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
== About Tee Skin Rendering == | |||
</div> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
This section explains how to render a tee skin. | |||
</div> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
Values put together by Patiga | |||
Special Thanks to 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 | |||
</div> |
Latest revision as of 07:26, 3 September 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++:
- learncpp.com
- cppreference.com
- Your search engine of preference
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 ffmpeg freetype2 git glew glslang gmock libnotify libpng opusfile python rust sdl2 spirv-tools sqlite vulkan-headers vulkan-icd-loader wavpack x264
For 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 python rustc spirv-tools4
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 usingsystem.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 hierarchical object-oriented entity 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. New struct
s should be prefixed by S
.
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
,ms_MyStaticMemberVariable
.g
for global variables with external linkage:gs_MyGlobalStaticVar
.
Prefixes
p
for pointers:pMyPointer
,m_pCharacter
,ppMyPointerToPointer
.a
for arrays:aMyArray
,aBuf
.v
forstd::vector
s:vMyVector
,vpvMyVectorOfPointersToVectors
.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);
See printf documentation for a list of all format specifiers.
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);
Translating text in the client
Localize
can be used in the game client to get the translation for a specific string from the language file selected by the user.DoButton(..., Localize("Connect"), ...);
char aBuf[128];
str_format(aBuf, sizeof(aBuf), Localize("%d of %d servers"), NumServers, TotalServers);
Localize
and collect the strings to update the translation files. For this reason, the call to Localize
must not contain any other code, or the script cannot determine the text correctly.// Do NOT do this:
const char *pStr = Localize(Team == TEAM_RED ? "Red team" : "Blue team");
</div>
<div lang="en" dir="ltr" class="mw-content-ltr">
// Do this instead:
const char *pStr = Team == TEAM_RED ? Localize("Red team") : Localize("Blue team");
External resources
- UI Code in DDraceNetwork by Ryozuki
- An intro to the DDraceNetwork game source code by Ryozuki
- Code conventions in DDraceNetwork by Ryozuki
- Implementing a chat command in DDraceNetwork by Ryozuki
- Auto generated docs
- Technical documentation of Teeworlds file formats and network protocol
- The Anatomy of a One Tick Unfreeze
- Teeworlds programming YouTube tutorial by ChillerDragon
About Tee Skin Rendering
This section explains how to render a tee skin.
Values put together by Patiga
Special Thanks to 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