C++20 で Siv3D v0.6.0 の開発をしたときのふりかえり
Abstract
C++20 で Siv3D v0.6.0 を利用した開発をしました。
自分はファイルシステムと画面描画を少し触っただけなのですけれど、Siv3D を用いた開発一般、ひいてはゲームプログラミングに関して学びを得ることができました。
このスクラップでは、自分の復習を目的として、この作業を通して得た知見についてまとめます。
Topics
このスクラップでは、主に以下のようなトピックを扱います。
- C++20 の開発手法
- Siv3D の開発手法
- おすすめのリファレンス
- 環境構築
- フォーマッタの設定
- clang-format
- EditorConfig
- IDE の設定
- Visual Studio 2019
- CLion Nova
- Visual Studio Code for the Web (on GitHub Codespaces)
- CI
- フォーマッタを GitHub Actions で動かす
- Git
.gitignore
- Git LFS
- フォーマッタの設定
TBU
それぞれについて Comparison や Best Practice なんかが書かれる予定です。
Disclaimer
このスクラップの内容は、usagiga 個人の推測が多分に含まれます
Siv3D v0.6.0 について
Siv3D とは
- OSS のゲームエンジン
- C++20 製
- Boost や最新の標準ライブラリなど、モダンなもので構成されている
- シンプル
- Unity や UE などと異なり、小さく平易なエコシステム
- マルチプラットフォーム
- Windows / Mac / Linux / Web で動くらしい
現行の Siv3D との差分
自分が使っている Siv3D v0.6.0 は、現行である Siv3D v0.6.13 よりも古いものになります。
現行との違いはリリースノートを読めば差分がわかります。
大きな差分としては以下の通りです:
- Siv3D v0.6.0 は Siv3D August 2016 v2 とも呼ばれる
- レポジトリやリファレンスの所在が異なる
- 開発環境が異なる
- Visual Studio 2015 / 2019
- Windows 7 SP1 / 8.1 / 10
- Windows 10 SDK 10.0.17763.0
リンク集
- レポジトリ: https://github.com/Siv3D/siv6
- リファレンス(公式): https://github.com/Siv3D/Reference-JP/wiki
- どちらかというとガイドやチュートリアルの性質が強く、全機能に対するリファレンス・仕様はレポジトリのソースコードを直接参照したほうがよい
環境構築
IDE やライブラリの準備
まずはこれをやれば IDE やライブラリ群、テンプレートとなるソリューションやプロジェクトを作成できます。
ダウンロードとインストール · Siv3D/Reference-JP Wiki
.gitignore
公式ドキュメント にも記述がありますが、一応書いておきます。
# Siv3D
[Ee]ngine/
[Ee]xample/
[Ss]creenshot/
[Aa]ssets/
*.html
*.s3a
# その他、Visual Studio の自動生成ファイルなどを記述しておく
# gibo dump VisualStudio でばちっとやってしまうのがおすすめ
Git LFS
大きめのアセットを Git で利用するなら、Git LFS を使うとレポジトリ操作を高速に実行してくれます。
なお、GitHub では LFS について制約やクォータが存在するので、GitHub を利用する方はドキュメントを参照してください。
C++20 を使う
せっかく Siv3D 本体が C++20 で作られているので、ソースコードも C++20 で作ってみましょう。
VC++ コンパイラ(cl
) の実行時引数に /std:c++latest
を指定すればよいです。
これで、本記事作成時点では C++20 の機能が有効化されます。
/std (言語の標準バージョンの指定) | Microsoft Learn
手順
Visual Studio のプロジェクトのプロパティをよしなに操作し、「追加のオプション」内に引数を記述してやれば OK です。
ヘッダファイルをインクルードできるようにする
テンプレートのプロジェクトそのままだと、cl
に /I
オプションが特に指定されていないので、プロジェクト内のヘッダファイルを #include <...>
を使ってインクルードすることができません。したがって、#include "..."
を使って相対パスでインクルードをすることになります。
#include ディレクティブ (C/C++) | Microsoft Learn
とはいえ、これだと使い勝手が悪いので、コンパイラの引数をいじっておきます。
今回は、プロジェクトルートディレクトリをベースとする相対パスで指定できるようにします。
以下のようなものを想定しています:
$ pwd
/mnt/c/Users/maris/source/repos/siv3d-file-open-multiplatform
$ tree .
.
├── LICENSE
├── README.md
├── siv3d-file-open-multiplatform
│ ├── Main.cpp
│ ├── Models
│ │ ├── Poetry.cpp
│ │ └── Poetry.hpp ... #include <Model/Poetry.hpp> で読み込む
│ └── siv3d-file-open-multiplatform.vcxproj
└── siv3d-file-open-multiplatform.sln
ディレクトリ構成に関しては各自よきように設定してください。
手順
Visual Studio についているプロジェクトのプロパティの GUI を開きます。
C/C++
-> 全般
に 追加のインクルードディレクトリ
というのがあるので、それを編集しましょう。
ここでは、${ProjectDir}
というマクロを使って、プロジェクトのルートディレクトリを指定しておきます。
フォーマッタなどの設定
フォーマッタとして、clang-format と EditorConfig を導入します。
フォーマッタを設定しておくと、ファイルごとの表記ゆれや文字コード・改行コードのブレが少なくなり、複数人での開発やエディタの違いをいい感じに吸収してくれて便利です。
なお、Visual Studio にもある程度フォーマットに関する設定はありますが、自分はエディタに強く依存した操作をするのをあまり好まないため、今回は IDE が clang-format / EditorConfig を使ってくれるように設定することにします。
clang-format を設定する
まず、C++に関連するファイルのフォーマッタである clang-format を設定します。
Visual Studio 2019 以降には clang-format (v5) が内蔵されており、既定で動いてくれています。
これは IDE 側でいくらか設定がなされたものになるので、別途コンフィグを書いて設定項目を上書きし、環境依存を減らしておくことにします。
BasedOnStyle: LLVM
---
Language: Cpp
DerivePointerAlignment: false
PointerAlignment: Left
FixNamespaceComments: false
NamespaceIndentation: All
BreakBeforeBraces: Allman
ここは各自お好みで変更してください。
- [オプション]、[テキスト エディター]、[C/C++]、[書式設定] - Visual Studio (Windows) | Microsoft Learn
- Clang-Format Style Options — Clang 19.0.0git documentation
補足: CLI での操作
WSL など、 Linux 実行環境がある場合は、以下のコマンドでソースコードのフォーマットを実行できます。
find . -regextype posix-extended -regex ".*\.(c|cpp|h|hpp)" | xargs -IX clang-format -i --verbose X
EditorConfig
次に、文字コード・改行コードや行末を整えてくれる EditorConfig を設定します。
Visual Studio では、IDE 内に類似の設定項目があり、よしなに設定されていますが、EditorConfig のコンフィグがある場合は EditorConfig の設定値を優先して読み込むような挙動をします。そういうわけで、自分でコンフィグを書いていきます。
root = true
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
trim_trailing_whitespace = true
indent_style = space
indent_size = 4
[Makefile]
# Makefile のインデントは Tab のみ許容
indent_style = tab
[*.md]
# Markdown のリストではいくつかの実装でインデント幅が2でないと正しく動かない
indent_size = 2
[*.{c,cpp,h,hpp}]
# C++ のファイルでは clang-format がよしなにやってくれるので、
# 衝突するようなものは読みやすさのために明示的に無効としておく
# なお、衝突するコンフィグは clang-format のバージョンにより異なる
indent_style = unset
indent_size = unset
Windows Native 向けの Siv3D プロジェクトならこんなかんじでいいと思います。
お好みで変更してください。
ファイル保存時にフォーマットを自動実行する
ここまでの設定ではフォーマッタが動かないシチュエーションがあるので、ファイル保存時にフォーマットを自動実行するようにします。VSCode や IntelliJ のようなよくあるエディタの挙動ですね。
ここでは、拡張機能を導入して解決します。
Format on Save - Visual Studio Marketplace
導入するだけで、保存時に自動的にコードクリーンナップが実行されるようになります。
コードクリーンナップ内ではデフォルトでIDE内蔵フォーマッタが走り、IDE内蔵フォーマッタは clang-format と EditorConfig のコンフィグがある場合はそれらを走らせる、という挙動になっています。なお、実行順番は EditorConfig → clang-format になっており、コンフリクトした設定項目がある場合、後勝ちします。
フォーマットが通っているか検査する
フォーマットが通っていないファイルがレポジトリに混入しないことを保証しましょう。
よくあるのは CI でフォーマッタを回すか、Git Hooks で pre-commit Hook で蹴ってしまう(保証にはなっていないが)ことです。
今回は、GitHub Actions を使ってフォーマッタを回してみます。
clang-format を GitHub Actions 上で走らせる
ubuntu-latest ランナーには clang-format がデフォルトで入っている [1] ので、一瞬で実現できます。
今回は、 .clang-format
ルールにそぐわないファイルがあった場合に Fail するワークフローを定義してみました。
name: "clang-format"
on:
push:
pull_request:
jobs:
check-format:
name: "Run clang-format"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: "Run clang-format"
run: find . -regextype posix-extended -regex ".*\.(c|cpp|h|hpp)" | xargs -IX clang-format --Werror --dry-run X
これで、CI 上で clang-format を走らせることができました。
EditorConfig がうまく通っているかを GitHub Actions 上でチェックする
今回は Windows Native での開発が前提になるので、文字コード・改行コードのブレがないかもチェックしておきたいところです。そこで、先ほど設定した EditorConfig に活躍してもらうことにします。
実現方法について触れます。
まず、EditorConfig はエディタの拡張機能であり、公式の CLI ツールがありません。
そこで、editorconfig-checker という、各ファイルが EditorConfig のルールに従っているかをチェックする趣旨の CLI ツールを使います。
まず、editorconfig-checker 自体のコンフィグを書いていきます。
特に重要なのが Exclude
で、素のままだとあらゆるファイルに対してチェックを走らせてしまうので、フォーマッタが通っていなくてもよいファイルを例外としておきます。
{
"Verbose": false,
"IgnoreDefaults": false,
"Exclude": [
"^\\.ecrc$",
"\\.sln$",
"\\.vcxproj$",
"\\.vcxproj\\.filters$",
"Resource\\.rc$",
"^<siv3d-project-dir>/Engine"
],
"SpacesAfterTabs": false,
"Disable": {
"EndOfLine": false,
"Indentation": false,
"IndentSize": false,
"InsertFinalNewline": false,
"TrimTrailingWhitespace": false,
"MaxLineLength": false
}
}
次に、EditorConfig のルールに従わないファイルがあった場合に Fail するワークフローを定義していきます。
editorconfig-checker は公式の Action が存在するので、すぐに書くことができます。
name: "editorconfig-checker"
on:
push:
pull_request:
jobs:
check-format:
name: "Run editorconfig-checker"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: editorconfig-checker/action-editorconfig-checker@main
- name: "Run editorconfig-checker"
run: editorconfig-checker
これで、EditorConfig がうまく通っているかを GitHub Actions 上でチェックすることができました。
CLion Nova をつかう
キーマップや操作感が JetBrains ライクなほうが好みだったので、CLion Nova を使うことにしました。
記事にもありますが、CLion Nova は ReSharper C++ / Rider のエンジンを流用した IDE で、AppCode 向けのレガシーな CLion を置き換えるために開発されています。
ここでは、若干トリッキーな使い方にはなりますが、CLion Nova で VS2019 の Windows Native App な設定を構築してみます。
Open Project Wizard
プロジェクトを開くと、その時点で導入されている開発環境を選択するウィザードが開かれます。以下のような環境があります:
- MinGW で CMake を使うもの(CLion Nova に Bundle されている)
- Visual Studio の VC++ などを使うもの
ここでは、VC++ Compiler を使いたいので、Visual Studio 2019 の開発環境を設定しておきます。
フォーマッタ関連の設定
- clang-format
- デフォルトでプラグインがバンドルされており、よしなにコンフィグを読んでくれる
- ClangFormat as alternative formatter | CLion Documentation
- clang-format のバイナリは CLion Nova 内蔵のもののほか、独自に指定することも可能
- デフォルトでプラグインがバンドルされており、よしなにコンフィグを読んでくれる
- EditorConfig
- JetBrains 純正のプラグインがあるので、それを導入すれば OK
これらのプラグインを導入していてコンフィグも存在しているときは、CLion はすべての Code Style の設定を EditorConfig や clang-format のものでオーバーライドするという仕組みになっています。
なお、Visual Studio 2019 と違い、EditorConfig や clang-format の間で衝突する設定項目があった場合にも不穏な動作をせず、うまく競合を解決してフォーマットを実行してくれます。とてもモダンですね。
保存時の自動フォーマットは、Settings の中にある Actions on Save
から設定可能です。
いろいろなものをトリガーすることができますが、ここでは Reformat と Import の最適化のみ実施することにします。
ビルド設定
CLion Nova は vcxproj を読んでくれないので、ビルドはイチから設定してやる必要があります。
デフォルトだと、CMake を前提としているので、CMakeLists や make を作ってあげることになります。
TBU
補完の設定
Siv3D のライブラリ群を補完してあげるように設定してあげます。
(たぶん↑をやってあげると、勝手に Siv3d.hpp にぶらさがってるやつが External Libraries に追加されて補完がきくようになるはず)
TBU
GitHub Codespaces をつかう
ふとしたときにコードを編集したくなったときのために、
メインマシンの開発環境とは別に、Codespaces (Visual Studio Code for the Web) を使えるようにしておきます。
Codespaces の設定をする
Codespaces は特にコンフィグを書かなくても動いてくれます。
しかし、毎度同じような環境を構築するのは面倒なので、コンフィグを書いておきましょう。
まず、Codespaces をプリセットの状態で作成し、内部の VSCode で C++ 向けの Dev Container を作っておきます。
そうすると、.devcontainer
ディレクトリが切られ、 Dockerfile
や devcontainer.json
が自動的につくられると思いますので、それをベースに編集していきます。
手始めに、コンテナ作成と同時に VSCode に clang-format と EditorConfig が入っている拡張機能のインストールをやってもらうことにします。
{
"name": "C++",
"build": {
"dockerfile": "Dockerfile"
},
"customizations": {
"vscode": {
"extensions": [
"ms-vscode.cpptools",
"EditorConfig.EditorConfig"
]
}
}
}
次に、VSCode で Format On Save が動くようにしておきます。
{
"editor.formatOnSave": true
}
これで、他の投稿に書いたような Visual Studio / CLion Nova のようなフォーマッタが整いました。
Siv3D のライブラリを補完できるようにする
TBU
これが一番大事な気がするけれど、書ければよいというところを優先したので、そのうちじぶんのなかで需要がでてきたときにやります~