どうもこんにちは。14の らりお と申します。
この記事は春の新歓ブログリレー19日目の記事です。進捗どうですか!
このブログを読んでいる人には、ロ技研に入りたい人も、入るか迷っている人も、関係ない人もいることと思います。この記事では、ゲーム製作やプログラミングに興味がある新入生(ゲーム製作初心者)に向けて、私の試みと後悔と、そこから得た微妙な教訓を綴ります。
題して『ゲーム製作で最初に試みない方がいいn個のこと』です。
ケーススタディ
入出力ライブラリから作ろうとする
- やろうとしたこと:
std::iostream
のインターフェースで、透過的に圧縮・展開を行う I/O ライブラリを作りたかった - 想定用途: ネットワーク通信、セーブデータやリソース圧縮など
- できたもの: 思った通りのもの
- 苦労: C++ 標準ライブラリ実装の defect を踏んだ
- 結果: 使わなかった(使う部分までゲームを作らなかった)
たしか、ちょうど gcc-5 が出る前あたりのことだったように記憶しています。
C++11 は gcc-4.9 からの対応となっていたので、「時代は C++11」と思って C++11 を使っていたわけですが、実は libstdc++ が gcc-4.9 時点では若干標準に非準拠の部分が残されていて苦労したという話です。
(なお、これは意図して(互換性のため?)そのように維持されていたコードであり、 gcc-5 相当のバージョン以降では直されていたはずです。)
結局 clang / llvm と一緒に開発されている libc++ を使うことで解決した(逃げた)ような気もしますが、なにぶん昔のことなので記憶が曖昧です。
教訓
- 最新の処理系に飛び付くと、個人ではどうしようもない不具合を踏みがち
- C++ のコードを書くときは、複数の標準ライブラリ実装に対応していた方がいざというとき幸せになれる
- 入出力ライブラリから作らない
マルチウィンドウに憧れる
- やろうとしたこと: マルチウィンドウ
- 想定用途: ゲーム画面とデバッグ用画面を別々に用意してかっこいい感じにしたい
- できたもの: 虚無
- 苦労: グラフィックドライバのバグ(と思われるもの)を踏んで X server (グラフィカル環境の基礎部分)を巻き込んで落ちるようになった
- 結果: 挫折(マルチウィンドウは諦めた)
はい。
ゲームの横で謎の統計とかグラフとかワイヤーフレームとか表示するの、かっこよくないですか?(中二病)
あれがやりたかったのですが、まさかこのレイヤーのバグを踏むとは。
余計な機能のついたものから始めると、そのせいでドライバ等のバグを踏んだとき、にっちもさっちもいかなくなります。
教訓
- マルチウィンドウは厄介(個人の感想)
- 自分に原因のないどうしようもないバグを踏む確率を低くするよう、最初はシンプルなものから始めた方が良い
複雑な 3D ファイルフォーマットを自力で読もうとする
ケース1: COLLADA
- やろうとしたこと: COLLADA 形式ファイルを読み込むライブラリの作成 (ただし既存ツールキット / SDK を使わない)
- 想定用途: 高品質 3D モデルの読み込み
- できたもの: XML パーサ
- 苦労: COLLADA が複雑すぎる / そもそも COLLADA をまともに吐き出せるソフトウェアが稀 / 無料で手に入るかわいい女の子の 3D モデルは、通常 COLLADA 形式ではない
- 結果: 使わなかった
はい……はい。
オープン標準にこだわって、実際に使いたいデータを何も用意していなかった間抜けな人の末路です。
ケース2: FBX
- やろうとしたこと: FBX 形式ファイルを読み込むライブラリの作成 (ただし既存ツールキット / SDK を使わない)
- 想定用途: 高品質 3D モデルの読み込み (特に、ネットで無料で入手できるかわいい女の子の 3D モデル!)
- できたもの: FBX パーサ、 FBX データ構造可視化ツール2種類
- 苦労: FBX 形式はプロプライエタリなので規格が非公開(よって解析とか必要) / データ形式が複雑すぎる
- 結果: デフォルトポーズで静止状態の FBX モデルを表示できた / FBX 形式についてそこそこ深く理解できた(ただしアニメーション関連除く) / ライブラリとツールを OSS として公開した / ゲーム製作はアニメーションの実装で行き詰まって途中で止まっている
なんで一度目で懲りなかったの……
今回は使いたいデータはありましたが規格が非公開だったので、 SDK のドキュメント(誤りあり)やヘッダを読んだり、 blender の wiki を読んだり(なお誤りあり)、データ構造を可視化するツールを作ったり、唐突なファイルバージョンアップデートで非互換な変更が行われたのにパーサを追従させたり……いろいろ苦労しました。
教訓
- 3D データ形式のローダ / パーサは自作しない方がいい
- Unity はいいやつだよ……
- 独自形式や特殊な形式のデータファイルを使おうとすると、デバッグや観察・解析用のツールを作りがちなので脱線しやすい
並列処理と相性の良い描画ライブラリを作ろうとする
- やろうとしたこと: 最初からマルチスレッドで動く描画フレームワークの作成
- 想定用途: ゲームとか(なんとなく)マルチスレッドで動いてほしい / 技術的興味
- できたもの: 虚無
- 苦労: 安全な並列処理はただでさえ厄介なのに、描画処理は相性が良くない / 用いていた OpenGL ラッパーのコマンドバッファ実装がスレッドセーフでなかったため、余計なスレッド間通信と描画コマンドの抽象を用意することになった
- 結果: 挫折
Rust という言語で書こうとしていたので、「並列処理も安全に書けるし、いけるっしょwwww」と思っていたのですが、甘かったようです。
「安全なコードしか書けない」ということは、「並列処理と相性が悪い処理はそもそも記述が困難」ということでもあります。
バグのないコードはコンパイルの通らないコードだけだ、ってね。
教訓
- 描画周辺のコードは素直に素朴にシングルスレッドで書いた方がいい
- そもそも並列化に夢を見すぎない方がいい
- バックエンドライブラリでできることを最初に確認しておいた方がいい
GUI ツールキットを作ろうとする
- やろうとしたこと: 画面描画を抽象化したい
- 想定用途: UI
- できたもの: レイアウトとスタイルを指定したテキスト描画ノード / OSS へのプルリクエスト
- 苦労: 描画ライブラリと同様 / そもそも木構造が並列処理と相性が悪い / 実行時オーバーヘッドとか不可避でつらい
- 結果: 挫折
厳しいですね。
そもそも根本的なことを言うと、ツールキットを作ろうとしてテキストレイアウトから始めることになる辺りで既に問題があったような気もします。
このまま実装を継続しても、本質的な困難に行き当たる気はしなかったのですが、どうも並列化が難しそうだということで設計に魅力を感じなくなり、打ち切りました。
教訓
- 最初のうちは泥臭く描画した方がいい
- テキストレンダリングは完全に外部ライブラリに任せた方がいい
全体的な教訓
- ライブラリを作ると、ライブラリ完成や一段落の時点で満足して、ゲーム実装そのものは止まりがち
- 最初から複雑で安全なコードを書こうとすると、動くところまで持っていくのが大変
- 動く成果物が欲しければ、汚いコードを受け入れる耐性を付けた方がいい
- 「私が作りたいのはライブラリではなくゲームである」という意思を強く保つ必要がある
- 成果物を作れなくてもロ技研には居場所がある😄
おわりに
ネガティブな記事になりました。
べつに進捗がないわけではないのですが(一部は公開していたりします)、設計が気に入らなくて進捗を revert したりすると「進捗が負になった」などという状況が頻発し、非常にメンタルに悪影響があります。
動くモノを作り上げたいなら、汚くてもとにかく動かすという意思が大事かもしれません。
それから、ロ技研では成果物が完成しなくても居場所があるので、ゆったり進捗をしながら雑談をすることもできます。
進捗が負になりがちな方も是非いらっしゃいませ。
それでは皆様が私の二の轍を踏まずゲームを作れるよう、心からお祈りしております。