Development/zh: Difference between revisions
No edit summary |
No edit summary Tags: mobile web edit mobile edit |
||
Line 73: | Line 73: | ||
<span id="The_src/base_directory"></span> | <span id="The_src/base_directory"></span> | ||
=== src/base | === src/base 目录 === | ||
由于DDNet是一个跨平台游戏,需要一个抽象层来简化开发,因此该目录包含许多有用的函数来处理这一问题。 | 由于DDNet是一个跨平台游戏,需要一个抽象层来简化开发,因此该目录包含许多有用的函数来处理这一问题。 | ||
Line 79: | Line 79: | ||
<span id="The_src/engine_directory"></span> | <span id="The_src/engine_directory"></span> | ||
=== src/engine | === src/engine 目录 === | ||
游戏引擎就在这里,它处理大多数与游戏无关的东西,比如图形、声音、网络等。 | 游戏引擎就在这里,它处理大多数与游戏无关的东西,比如图形、声音、网络等。 | ||
Line 91: | Line 91: | ||
<span id="Server_side"></span> | <span id="Server_side"></span> | ||
==== 服务器 ==== | ==== 服务器端 ==== | ||
<div class="mw-translate-fuzzy"> | <div class="mw-translate-fuzzy"> |
Revision as of 20:46, 27 May 2023
本文皆在教你如何对 DDNet 开发 ,因为这是一款开源游戏(源代码公开),它依赖于一些善良的人们来用他们的放松时间贡献。
你的开发环境
截至目前,处于一下原因,我们强烈建议使用Linux环境在DDNet中开发:
- 大多数DDNet贡献者实际上使用Linux来贡献。
- 更容易的软件包管理,您可以轻松地安装所有需要的库并开始贡献。
- 本文还没有Windows版本,主要关注Linux。
首先,DDNet是使用 C++ 语言编写的,您需要相当熟悉它,但您也可以了解基础知识并了解更多信息。
学习C++的一些有用资源:
DDNet的源代码使用Git托管,这是一个版本控制系统,也是与多个开发人员协作的重要工具。
如果您的Linux发行版中还没有git,请安装它,例如在大多数基于debian/ubuntu的发行版中,你可以打开终端,输入:sudo-apt-install git
。
获取源代码
源代码位于Github,您可以在不需要帐户的情况下通过Clone获得源代码,但如果您想将更改放入官方源代码,则需要一个账号。
如果您不熟悉git/github,可以在这里学习基本知识: Hello World - Github
下载依赖项
如果您在Linux上,您可以通过阅读DDNet github页面上的自述文件来安装所有需要的依赖项:https://github.com/ddnet/ddnet#dependencies-在linux上--macos
对于Arch Linux:
控制台输入
sudo pacman -S --needed base-devel cmake curl freetype2 git glew gmock libnotify opusfile python sdl2 sqlite wavpack
编译DDNet
我们使用CMake来控制编译进程,如果你所有的依赖项都下载了,那么它会很简单,只要输入这些命令(确保你在DDNet文件夹下):
mkdir build
cd build
cmake ..
make -j$(nproc)
通用信息
以下是一些通用信息:
- 目前,源代码是使用C++17标准编译的,但您会看到代码的许多部分更像C,因为只有大多数新代码使用C++17。
std::string
很少使用,字符数组加system.h
方法才是常态。- 大多数输入输出代码、格式化和Print都是使用
system.h
提供的方法完成的。
源代码布局
现在你可以构建DDNet了,可以开始编辑它了。
src/base 目录
由于DDNet是一个跨平台游戏,需要一个抽象层来简化开发,因此该目录包含许多有用的函数来处理这一问题。
src/engine 目录
游戏引擎就在这里,它处理大多数与游戏无关的东西,比如图形、声音、网络等。
src/game 目录
所有玩游戏的代码都在这里,分为客户端和服务器。
服务器端
这个游戏使用自己的实体组件系统,所有其他实体派生到的主类是CEntity
,位于src/game/server/Entity.h
中。
这些实体由位于此处的游戏世界管理src/game/server/gameworld.h
一些重要实体有:
CCharacter: 代表着一个tee 是活着的, 当一个tee产生时它被实例化,当它死亡时它被删除。有关玩家在死亡之间的信息,请参阅CPlayer.
客户端
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);
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
- 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