DDraceNetwork 是一款开源免费的多人合作平台跳跃游戏(其前身是 Teeworlds 的一个叫 DDRace 的模组),上限高游戏性强,是一个非常独特的合作游戏。本项目依赖众多好心的程序员进行维护,作为一个基本成熟稳定的 C++ 游戏项目,我们可以从这个项目中学习到很多开发相关的知识,甚至如果你有什么改进,也可以为原代码仓库提出 Issue 贡献 PR。
克隆代码
bashgit clone --recursive git@github.com:ZerolAcqua/ddnet.git
安装依赖
bashsudo 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
构建项目
bashcmake -Bbuild cmake --build build
如果构建的客户端无法连接服务端,有一种可能是你的 TUN 模式没关。
代码格式化检查,运行 scripts/fix_style.py
脚本。由于 Ubuntu 24.04 已经找不到 clang-format-10 的安装包,我们需要自行编译或通过其他途径安装:
使用 pip 安装(官方推荐)
A lot of the style offenses can be fixed automatically by running the fix script ./scripts/fix_style.py
We use clang-format 10. If your package manager no longer provides this version, you can download it from https://pypi.org/project/clang-format/10.0.1.1/.
由于执行检查脚本使用的是 python,我们可以通过 pip 安装。如果是用 conda 安装的,在执行 python 脚本时指定 python 环境,就可以顺利运行检查。
bashpip install clang-format==10.0.1.1
通过源码编译
bashgit clone https://github.com/llvm/llvm-project.git
cd llvm-project
git checkout llvmorg-10.0.1
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=clang ../llvm
make -j$(nproc)
sudo make install
编译过程中可能出现部分报错:
std:numeric_limits
不是 std
成员。在相关文件中包含 #include <limits>
即可uintptr_t
未声明,在相关文件中包含 #include <cstdint>
即可运行单元测试
按项目自述文件操作
bashsudo apt install libgtest-dev
cd /usr/src/gtest
sudo cmake CMakeLists.txt
sudo make
# copy or symlink libgtest.a and libgtest_main.a to your /usr/lib folder
sudo cp lib/*.a /usr/lib
在我运行时,还需要安装 gmock
bashsudo apt install libgmock-dev
使用 AddressSanitizer + UndefinedBehaviourSanitizer
安装 Clang
bashsudo apt install clang
编译命令
CC=clang CXX=clang++ CXXFLAGS="-fsanitize=address,undefined -fsanitize-recover=address,undefined -fno-omit-frame-pointer" CFLAGS="-fsanitize=address,undefined -fsanitize-recover=address,undefined -fno-omit-frame-pointer" cmake -DCMAKE_BUILD_TYPE=Debug . make
运行命令
bashUBSAN_OPTIONS=suppressions=./ubsan.supp:log_path=./SAN:print_stacktrace=1:halt_on_errors=0 ASAN_OPTIONS=log_path=./SAN:print_stacktrace=1:check_initialization_order=1:detect_leaks=1:halt_on_errors=0 LSAN_OPTIONS=suppressions=./lsan.supp ./DDNet
结果检查
运行后,检查生成的 SAN.*
文件以查看详细的问题报告。ASan + UBSan 能够发现比 Memcheck 更多的问题,尤其是在内存错误和未定义行为方面。
src/base
目录
由于DDNet是一个跨平台游戏,需要一个抽象层来简化开发,因此该目录包含许多有用的函数来处理这一问题。
src/engine
目录
游戏引擎所在位置,它处理大多数与玩法无关的东西,比如图形、声音、网络等。
src/game
目录
所有玩法的代码所在位置,分为客户端和服务器。
服务器端
这个游戏使用自己的面向对象的实体分级系统,所有其他实体源于主类 CEntity
,位于 src/game/server/entity.h
目录。
游戏世界在 src/game/server/gameworld.h
路径下,管理这些实体。
一些重要实体有:
CCharacter
:代表一个活着的 Tee, 当一个 Tee 生成时会被实例化,当它死亡时会被删除。CPlayer
:包含了其他没有关联 Tee 的信息(昵称、国籍等)。有关玩家在死亡之间的信息,请参阅此项。客户端
客户端由许多组件构成,都是在 src/game/client/component.h
中定义的继承 CComponent
的类:这些组件通过实现视觉方法来提供功能,例如 OnInit
,OnMessage
等等。
网络
网络协议几乎由 python 脚本生成并输出 c++ 代码,例如说,datasrc/network.py
定义了所有网络包。
贡献前的准备
在编写代码前,建议先开一个 issue 讨论想法,确保贡献符合 DDNet 项目的理念。常见的被拒绝贡献包括:
编程语言
DDNet 主要使用 C++,少量使用 Rust,Python 用于代码生成和工具,CMake 用于构建。平台特定代码可能使用 Java(Android)或 Objective-C++(macOS),但不接受其他语言的代码。
代码风格
命名规则:变量、方法和类名使用大驼峰命名法(如 MaxLength
),避免单字母变量名。
匈牙利命名法:继承自 Teeworlds,使用前缀如 m_
(类成员)、g_
(全局变量)、p
(指针)等。
现代 C++ 实践:优先使用 nullptr
、true
/false
,避免 goto
、默认参数和方法重载。
代码格式化:使用 clang-format 10 自动格式化代码。
最佳实践
避免在 if
语句中赋值:明确分离变量赋值和条件判断。
Getter 方法命名:避免使用 Get 前缀(如 MyVariable()
优于 GetMyVariable()
)。
类成员初始化:在声明时直接初始化类成员变量。
文件命名:使用小写字母和下划线分隔(如 foo_bar.cpp
)。
提交消息
提交消息应描述对玩家/用户的影响,而非技术细节,以便直接用于变更日志。
goog first issue 的作用是什么?
比如我找的这个 issue:https://github.com/ddnet/ddnet/issues/9583 是个很简单的工作,只需要把描述文本修改一下就行。
另外,这个网站可以帮助你查看流行开源项目中可能的 goog first issue。
参与代码贡献是一件令人振奋的事情,但中间也会遇到一些会让你感到受挫的事情,你需要以平常心看待它们。
项目维护者对你的 PR 的 review 可能比较严格
一般是因为你的提交存在一些问题,或者不规范的地方,如要求你压缩你的提交,修改提交信息等。正视它们,这些直率的建议也能让你进步的更快。
社区的评价不一定都是中听的
社区对你的贡献的评价也可能让你不舒服,尽管他们看起来并没有恶意。比如我贡献一个提交,想获取 dev 身份组时,会有人用 “commit: readme typo fix” 来打趣我(而且这种开源贡献笑话还挺常见的,时不时就会出现一次)。
面对这种情况,还是要调整好心态,如果想要做长期的贡献还是从简单的 issue 开始的。跟进时间长了自然会做出有价值的提交。而且即使是简单的拼写修复提交,仓库的维护人员也一直欢迎和接纳,不要太受社区人员的影响。同时也需要自己提升心理承受能力。
开源社区终究也是社区,你并不突出
社区总有光彩夺目的人,你需要降低期待做好无人理睬的准备。在 Manim 幼儿园的时候就已经有这种无力感了,更别说外国社区,英语蹩脚没有熟人更会让你觉得自己是被无视了。DDNet 社区里虽然有几位国人版主和贡献者,但也都根本没有接触过,颇有一种孤军奋战的感觉。
本文作者:Zerol Acqua
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!