程式碼樣式方針¶
在參與貢獻 Godot 原始碼時需要遵守下述樣式方針。其中的一些規則會在 CI (持續整合, Continuos Integration) 過程中自動檢查,而審閱者也會要求你修正一些潛在的問題。因此,最好先依照下屬方式設定系統,並確保你的 Commit 都有符合本方針。
C++ 與 Objective-C¶
C++ 與 Objective-C 沒有明文的方針,但我們有由各個開發者認定的樣式,且會依照 clang-format 程式碼美化工具強制套用。該工具會處理我們所有的管理。下面舉例幾個:
縮排與對齊都是使用 Tab 字元 (分別使用 1 個與 2 個 Tab)
在數學與賦值運算子的周圍以及逗號後加上 1 個空格
指標與參照運算子要加到變數識別項前,而不是型別名稱前
有關標頭檔引用,請繼續閱讀以瞭解詳情
clang-format 所使用的規則列在 Godot 儲存庫中的 .clang-format 檔案內。
基本上只要確保你寫的程式碼與周圍程式碼的樣式一致、並且行尾沒有多餘的空格、且不使用空格來縮排就沒什麼問題。如果未來還有打算持續參與貢獻的話,我們強烈建議在本機開發環境上安裝 clang-format 以自動檢查並修正所有的 Commit。
警告
Godot 的程式碼編寫樣式 不應 用於第三方程式碼,即 Godot 原始碼中包含但不是特別為 Godot 專案撰寫的程式碼。這些程式通常來自不同的上游專案,有 (或沒有) 各自的樣式指南,且不應套用 Godot 的樣式以避免造成與上游的不同並難以更新。
第三方程式碼通常放在 thirdparty/
資料夾內,因此可以輕鬆地在格式化腳本中排除掉。但有些稀有的例子,我們可能會直接在 Godot 的檔案中使用第三方程式碼片端,這時候可以使用 /* clang-format off */
與 /* clang-format on */
來讓 clang-format 忽略一段程式碼。
也參考
These guidelines only cover code formatting. See C++ usage guidelines for a list of language features that are permitted in pull requests.
在本機上使用 clang-format¶
First of all, you will need to install clang-format. As of now, you need to use clang-format 13 to be compatible with Godot's format. Later versions might be suitable, but previous versions may not support all used options, or format some things differently, leading to style issues in pull requests.
安裝¶
下列為如何安裝 clang-format:
Linux:通常直接於發行版的 clang 工具鏈中附帶提供。若你使用的發行版提供了不合需求的版本,可以從 LLVM 網站 上下載預先編譯好的版本。而若使用 Debian 衍生版本,則可以使用這個 上游軟體倉 。
macOS 與 Windows:可以從 LLVM 網站 下載預先編譯好的二進位檔。可能會需要將二進位檔的資料夾加到系統的
PATH
環境路徑中以便直接呼叫clang-format
。
要將 clang-format 套用到修改中有幾個方法:
手動使用¶
可以通過下列指令手動將 clang-format 套用至一個或多個檔案:
clang-format -i <path/to/file(s)>
-i
代表改動應直接寫入到檔案內 (clang-format 預設只會將修正後的版本輸出到終端機上)。該路徑可指向多個檔案,可以直接指定多個檔案,或是像一般 Unix Shell 一樣使用萬用字元。在使用萬用字元時請注意不要將 clang-format 套用到 Godot 資料夾內編譯後的物件上 (.o 與 .a 檔案)。因此最好使用
core/*.{cpp,h}
而不是core/*
。
Pre-commit Hook¶
為了更容易使用,我們提供了用於 Git 的 Pre-commit Hook,可以自動在所有 Commit 上執行 clang-format 並進行檢查,然後能將其更改套用到最終 Commit 上。
這個「Hook」是放在 misc/hooks
中的腳本,請參考該資料夾的 README.md 以瞭解詳細的安裝步驟。
如果 clang-format 不在 PATH
中的話,則可能需要編輯 pre-commit-clang-format
來指向正確的二進位檔才能使用。該 Hook 已在 Linux 與 macOS 上測試過,但在 Windows 上的 Git Shell 應該也可以使用。
IDE 外掛¶
大多數 IDE 或程式碼編輯器都有可以設定自動執行 clang-format 的美化插件,如可以在保存檔案時自動執行。
此處僅列出部分用於一些 IDE 的美化外掛:
Qt Creator: Beautifier plugin
Visual Studio Code: Clang-Format
Visual Studio: ClangFormat
vim: vim-clang-format
CLion: Starting from version
2019.1
, no plugin is required. Instead, enable ClangFormat
(歡迎建立 PR 以擴充此列表來包含更多經過測試的外掛。)
標頭引用¶
建立新的 C++ 或 Objective-C 檔案或在現有檔案內引用新標頭檔時,必須遵守下列規則:
檔案的頭幾行必須為 Godot 的版權標頭與 MIT 授權協議,請從其他檔案內複製過來。請記得更改檔案名稱。
在
.h
標頭檔內,Include 防護 (Include Guard) 應為FILENAME_H
的格式。在
.cpp
檔案 (如filename.cpp
) 中,第一個 Include 應為類別定義的檔案 (如#include "filename.h"
),並接上一行空行以作分隔。接下來的是 Godot 程式碼的其他標頭檔,按字母順序引入 (會由
clang-format
強制執行),並使用相對於根目錄的路徑。這些 Include 應以引號包含,如#include "core/object.h"
。Godot 標頭檔 Include 區塊後方應包含一行空行以作分隔。最後接著是第三方標頭檔 (也就是從
thirdparty
或系統 Include 路徑內來的),應以 < 與 > 符號來 Include,如#include <png.h>
。第三方標頭檔區塊後也應加上一行空行以作區隔。Godot 標頭檔與第三方標頭檔都應在需要這些標頭檔的檔案內 Include,也就是當使用宣告式程式碼時應在 .h 標頭內,只有使用命令式程式碼時才應在 .cpp 內引入。
範例:
/*************************************************************************/
/* my_new_file.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef MY_NEW_FILE_H
#define MY_NEW_FILE_H
#include "core/hash_map.h"
#include "core/list.h"
#include "scene/gui/control.h"
#include <png.h>
...
#endif // MY_NEW_FILE_H
/*************************************************************************/
/* my_new_file.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "my_new_file.h"
#include "core/math/math_funcs.h"
#include "scene/gui/line_edit.h"
#include <zlib.h>
#include <zstd.h>
Java¶
Godot 的 Java 程式碼 (大部分都在 platform/android
內) 也會強制由 clang-format
套用,因此請參考上方的說明設定 clang-format。請注意,樣式指南僅套用至由 Godot 撰寫且由 Godot 維護的程式碼,如 java/src/com/google
子資料夾內的第三方程式碼則不應套用。
Python¶
Godot 的 SCons 建置系統是以 Python 撰寫的,而程式碼中還有多個腳本也是使用 Python。
這些檔案,我們遵守 Black style guide 。請使用 Black 來黑化你的 Python 程式碼。
在本機上使用 Black¶
首先,必須要先安裝 Black。要執行 Black 需要至少 Python 3.6.0+。
安裝¶
安裝 Black:
pip3 install black --user
接著有幾種方式可以將 Black 套用至修改上:
手動使用¶
可以使用下列指令手動套用 black
至一個或多個檔案:
black -l 120 <path/to/file(s)>
-l 120
表示每行最多允許 120 個字元。這個數字是由多位開發人員公認的。路徑可以指向多個檔案,可以直接寫出多個檔案,或是使用如一般 Unix Shell 的萬用字元。
Pre-commit Hook¶
為了簡化使用,我們也提供了用於 Git 的 Pre-commit Hook,會在所有 Commit 上自動執行 Black,並允許將這些修改套用至最終的 Commit 上。
該「hook」是放在 misc/hooks
內的一個腳本檔。請參考該資料夾中的 README.md
以瞭解安裝說明。
編輯器整合¶
許多 IDE 與程式碼編輯器都有可設定自動執行 Black 的美化外掛,如可在每次保存檔案時自動執行。詳細資訊可參考 Black editor integration 一頁。
Comment style guide¶
This comment style guide applies to all programming languages used within Godot's codebase.
Begin comments with a space character to distinguish them from disabled code.
Use sentence case for comments. Begin comments with an uppercase character and always end them with a period.
Reference variable/function names and values using backticks.
Wrap comments to ~100 characters.
You can use
TODO:
,FIXME:
,NOTE:
, orHACK:
as adominitions when needed.Example:
Don't repeat what the code says in a comment. Explain the why rather than how.
Bad:
You can use Javadoc-style comments above function or macro definitions. It's recommended to use Javadoc-style comments only for methods which are not exposed to scripting. This is because exposed methods should be documented in the class reference XML instead.
Example:
For member variables, don't use Javadoc-style comments but use single-line comments instead: