開發
本文皆在教你如何對 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