- 個人プロジェクトのすべてのゲームを**「純粋なC」**で開発しており、これは現在では珍しい選択である
- 言語選択の中核となる基準は信頼性、移植性、長期的な持続可能性であり、特定のOSやプラットフォームに縛られない
- シンプルさと高速なコンパイル速度、そして厳格な型検査と強力な警告システムを重視している
- C++・C#・Java・Go・Haxeなどの代替言語も検討したが、複雑さ・GC・OOPの強制などの理由で適していないと判断した
- Cは危険だがシンプルで高速であり、幅広いプラットフォーム対応と堅牢なライブラリエコシステムのおかげで、今なお最適な選択である
言語選択の基準
- 必須条件は信頼性と安定性であり、自分が作っていないバグに時間を無駄にしないためである
- 過去にはFlashベースのゲームを開発していたが、Flashの衰退により、新しいプラットフォームへの移植よりも新しいゲーム制作に集中したいと考えている
- 特定のOSに依存せず、コンソール開発の可能性も残しておくために、移植性と汎用ライブラリのサポートを重視している
- 望ましい条件としては、シンプルな文法と覚えやすい構造を挙げている
- 複雑なAPIや言語機能をいちいち調べ続ける過程を避けたいからである
- 厳格な型検査、強力な警告、静的解析によってバグを減らし、優れたデバッガと動的解析ツールで問題を簡単に見つけたいと考えている
- コンパイル速度を非常に重要視している
- **オブジェクト指向(OOP)**には懐疑的で、データとコードを分離して状況に応じて処理する方式を好む
主な代替言語の評価
- C++
- ゲーム開発では依然として標準だが、複雑さと遅いコンパイル速度のため不満がある
- 高い性能と多様な機能を提供するが、望まない機能が多く、複雑さのコストが大きい
- C#とJava
- 冗長で複雑であり、強いOOP中心の構造のため自由度が低い
- 高水準言語の性質上、複雑さを隠してはくれるが、根本的な問題を防ぐことはできない
- Go
- Cの現代的な再解釈として好意的に評価しているが、stop-the-worldガベージコレクションはゲーム開発に不向きである
- ゲーム向けライブラリの不足と、長期的な持続性への懸念がある
- JavaScript
- Web開発環境の変化の速さとFlashの終焉により、不安定に感じられる
- 緩い文法のため、大規模ソフトウェアの作成には不向きだと判断している
- Haxe
- Web開発では有望だと評価しているが、比較的新しい言語であるため持続性への懸念がある
- 独自言語の開発
- 魅力的な発想ではあるが、既存ライブラリを捨てることと互換性維持の負担のため現実的ではないと判断している
Cを選ぶ理由
- 危険だが信頼できる言語であり、シンプルな構造のおかげで注意深く使えば安定している
- 「鋭いナイフ」にたとえ、扱いは難しいが熟練すれば強力な道具であることを強調している
- コンパイル速度が非常に速く、ほぼすべてのプラットフォームで動作する
- 移植の過程も比較的簡単で、長期的にも持続可能性が高い
- ライブラリとツールのサポートが強力で、継続的に保守されている
- 個人的にはすでに多くの**「純粋なC」コードの経験**があり、慣れている
- 他人にCの使用を勧めるつもりはなく、これは個人的な好みと作業スタイルに最適化された選択である
1件のコメント
Hacker Newsの意見
自分は主にCスタイルでコードを書くが、必要なときだけC++の機能を使う
なので一見するとRustのコードのように見えることもある
ゲームをCで書くという人たちは、C++の機能を嫌いながら、結局は仮想インターフェースを自前で実装したり巨大なswitch文を作ったりして、似たようなことをしている
言語にある機能を使わなければいいだけで、その存在自体に文句を言うのは意味がないと思う
C++はテンプレートを乱用しなければコンパイルは遅くならない
時間が経つにつれてメンバーが入れ替わり、リーダーも変わると、使われる機能の集合はどんどん広がっていく
いったん増えた機能を減らすのは非常に難しい
さらに、望まない機能を使っているライブラリを使わざるを得ないこともある
たとえば自分は暗黙の呼び出し(デストラクタ、演算子オーバーロードなど)が嫌いだが、ライブラリがそれを使っていれば結局合わせるしかない
C++の最悪な点の一つは、自動生成される隠れたコードが多すぎることだ
コードの大半が具体型(Goose、Duckなど)を扱っているとしても、すべてのオブジェクトがvtableポインタを持ち歩く
一方Rustは必要な箇所でだけvtableを使うので、メモリを節約できる
Cプログラマは必要な機能だけを自分で実装するので、言語が強制する構造にあまり縛られない
<vector>を一つインクルードしただけでも数万行のコードが入ってくるそのため標準ライブラリを使わないと、「なぜまた車輪の再発明をするのか」という議論が起きる
こういう議論が何度も起こるくらいなら、Cに戻るほうがずっと楽だ
自分も2017年ごろにCへ戻り、今でもC++ライブラリを使うたびに疲れる
例外的にDear ImGuiは悪くないが、それでもCバインディングのほうを好む
拡張子を.cに変えたらコンパイル時間が半分になった
自分はCの荒削りで単純な性格が好きだが、プリプロセッサは嫌いだ
だからZigはまさに天の恵みのように感じる。Cより単純なのに、さらに正確な言語設計を持っている
たとえばZigは単一ポインタと配列ポインタを区別する
Cライブラリを取り込んでより使いやすくできるので、ゲーム開発でとても役に立つ
たいていのC++ライブラリもCヘッダを一緒に提供している
zig-gamedevには、こうしたZig化されたCライブラリが多い
プリプロセッサの代わりに、Zigのcomptime機能のほうがはるかに優れており、単に「コンパイル時に実行されるZigコード」にすぎない
自分も筆者の考えに共感する
言語を好きになる最大の理由は単純さだ
だからC、Go、Odin、Zigのような言語を好む
ただし、必要な複雑さを上手に扱える言語も重要だ
メモリ安全性や並行性、関数型パターンが必要なネットワークコードではRustが自然だ
一方で、インディーゲームのような単純で速いコードにはCやOdinが合っている
OdinはGoの単純さとCの性能を組み合わせたような感じで、おすすめできる
Raylibでゲームを作るのも簡単だ
OdinのほうがZigよりその位置にうまく当てはまると思うのか気になる
元記事ではGoのゲームライブラリ支援が弱いとされていたが、それは2015年ごろの記事のように見える
今では状況が変わっているかもしれない
当時作ったゲームのスクリーンショットも見られる
たとえばKnossuは独特な3Dスタイルを持っている
2026年にCでゲームを作るのは少し狂気の沙汰かもしれないが、自分もそうしている
たとえばChrysalisをCで開発した(GLFW3、FMODを使用)
idTech3ベースだが、戦闘システムがあまりにも精密で、小さな変更でも全体のバランスが崩れる
なんと
i++を一つ追加するだけでもタイミングが変わるそのため22年前のコンパイラをそのまま使っている
モダナイズされたフォークもあるが、元の感覚が失われている
idTech3はまさにCの真髄を示すエンジンだ
何千本ものゲームがCで書かれてきたし、OpenGL、Vulkan、DXのようなグラフィックスAPIもすべてCベースだ
だからまったく不思議ではない
ほとんどのゲームエンジンもC/C++で書かれている
コンソールは世代ごとに異なる
Linuxプログラミングとは違って、ゲーム開発は30年以上にわたってC++中心だった
自分は根っからのC好きだ
何十年もうまく使ってきたが、チームでCコードを管理すると苦しさが増す
それに、現代的な言語に比べると開発速度も遅い
それでも単純さの魅力は変わらない
自分の経験では、C++よりCのほうがまだ苦痛は少なかった
その事実は、Cの協業上の限界という主張を弱める
「もう誰もCでゲームを作らない」というのは誇張だ
今では主流ではないが、それでも多くの人がCでゲームを作っている
あなたは例外にすぎず、その発言は統計的には依然として正しい
自分はCが好きだ
メモリ管理を完全に制御でき、予測可能な動作を得られる
MISRAの規則のように事前確保が求められる環境では特に有用だ
ハードウェアレベルの例外やエラーを直接扱うのにも向いている
単体テストも書きやすい
Cは参入障壁が低いが、メモリ管理の知識は必須だ
Java開発者の自分が、.hと.soだけ渡された状況で素早くコネクタを作る必要があったとき、C++ではなくCを選んだ
Cが鋭いナイフだとすれば、C++は回転するナイフの柱のようなものだ――油断すると傷を負う
ただ文字列処理はCだとあまりにつらいので、C++の文字列システムを借りたくなる