lumino trail

ゲームエンジン作ってます。Github:https://github.com/lriki/Lumino Twitter:https://twitter.com/lriki8

開発状況 2019 #7

5~6月は投稿を完全に忘れるくらいお仕事が盛り上がっていました。

実は5~12月くらいで1本ゲーム作る計画を立てて、それに沿って Lumino の開発を進めてたりしたのですが、いきなり仕事の影響で出鼻をくじかれてやる気無くしてた感じです。

マルチプログラミング言語

次の v0.9.0 のメイン機能です。

まず、こんな感じでマクロを使って C++ のクラスやメソッドをタグ付けしておきます。

LN_CLASS()
class Sprite : public VisualObject
{
    ...
};

このコードを clang で解析して、

  • C++ クラスをラップする Flat C API を自動生成
  • さらにそれをラップするクラスライブラリを各言語ごとに自動生成

みたいなことをします。

まずは Ruby をターゲットにしていますが、次のようなコードで、画像を表示することができます。

require 'Lumino'

Engine.initialize

texture1 = Assets.loadTexture("img.png")
sprite1 = Sprite.new(texture1)

while Engine.update do
end

Engine.finalize

こんなふうに、C++ インターフェイスを他の言語に公開するのがすごく簡単になります。

メソッドのオーバーライドやイベント通知もサポートするよ。

エディタ

ゲーム開発を始めて最初のころは「コードだけでもなんとか行けるでしょ」とか思っていましたが、シーン作り出すあたりから限界が見えてきました。 やっぱり微調整のイテレーションオーバーヘッドが主な理由です。

というところで、まずは GUI フレームワークの検討から始めました。

要件は、

ということで、候補は次の通り。

  • Qt Quick
  • Qt Widgets
  • imgui
  • LuminoUI (自作)

Qt Quick

そこそこキレイなアプリが作れるフレームワーク。ロジックを C++、ビューを QML (JavaScriptライク) で書きます。

レガシーなフレームワークありがちな、細かいレイアウトの調整ができない問題がクリアされていて、見た目をかなり自由に作ることができます。

ネックは情報量でしょうか…。バグか仕様かわからずコードまで読みに行ったりしてました。

もうひとつはグラフィック固有の問題ですが、OpenGL などネイティブグラフィックスAPIの呼び出しはレンダリングスレッドで行う必要があるため、 Lumino のような外部のレンダリングライブラリを取り込むときは細心の注意が必要です。

これに対応するため Lumino のマルチスレッド対応とかやってましたが、Qt API (妙なところに const 付いてたりとか) に合わせこむため余計にクラス増やしたり、モノによっては本体のコード追ったりするのに疲れて断念しました。

っていうか、よく考えたらエディタ拡張を書きたいときでも View 作るのに QML 必須になってしまうか…。

Qt Widgets

枯れていつつも長く使われているのは重要な長所です。でも空ウィンドウ開くだけでメモリリークするのはちょっと心に悪いです。

簡単な UI 作るのにはすごく素直に動いてくれるので、Qt Quick に対しては長く使っていました。Ruby ラッパーとかからも呼べるし。

レンダリングライブラリの統合も、OpenGLWidget を使うのもいいし、ネイティブのウィンドウId取ってそこに書くのもいいし、簡単でした。

ただ、ゲーム系というかエンタメ系というかの GUI ツールって結構独特なウィジェットが多くあります。それに耐えられるのか…ってところで、 「結局 QPainter で直書きするくらいなら Lumino で書きたい」みたいな魔が差して断念。

imgui

これの検討を始めるころには、Lumino の UI モジュールがそこそこいい感じに動くようになってきたので、 ものすごく悩んだのですが採用は見送りました。

主な理由は UE4 が Slate を自作した理由とほとんど同じです。 https://docs.unrealengine.com/en-US/Programming/Slate/Architecture/index.html

それでも便利なのは変わらないので、デバッグ用途では使っていくかも。

LuminoUI (自作)

死ぬわアイツ

正直 100% ゲーム用の UI フレームワークとして作っていたので、エディタで使うつもりはありませんでした。

しかし、色々とアレもやりたいコレもやりたいを詰めていった結果、徐々に レイアウト、スタイリング、アニメーション、イベントシステム周りが WPF+HTML(CSS)+Qt みたいなかなりガチ仕様になってきていました。

コンポーネントは圧倒的に足りてないけど、ベースが結構いい感じになってるので、シンプルなエディタなら作れるのでは?ついでにほかの言語のラッパーも簡単に作れるし、エディタ拡張もLuminoだけで完結するし。 …と自惚れた結果、全部 Lumino でやるという(多分地獄の)道を選ぶことにしました。

f:id:lriki:20190731203504p:plain

見た目は雑なシーンビューアですが、ゲームジャンルごとに必要そうな小エディタ(拡張機能)を組み合わせて、作りたいゲームに合わせたエディタを構築できるような仕組みを考えています。

3Dシーンエディタ・2Dモーションエディタ・RPGイベントエディタを組み合わせて、2.5D RPGを作ったりとか。

Effect

ゲーム作りを始めたので、エフェクト出せる仕組みが欲しくなりました。

Lumino はパーティクルシステムを持っていますが、もっと凝ったエフェクトも出せるようにしたいな、ということで Effekseer の組み込みを始めています。

で、Lumino はちょっと前に Vulkan への実験的な対応を行い、開発中は基本的に Vulkan で動かしていますが、Effekseer が Vulkan 対応してない!という状態でした。

対応を待つか、Lumino 側でラップするか… とかいろいろ考えていましたが、せっかくなので Effekseer の本流にコミットすることにしました。

GitHub は長く使っていますが、今回初めて、ほかのプロジェクトへプルリク送る運びとなりました。

f:id:lriki:20190731204358g:plain

Graphics

ロードマップ上では fix 済みのモジュールなのですが、Vulkan 対応を受けて色々思うところがあったので、少し API を変えようとしています。

具体的には RenderPass と CommandList の実装です。

ねらいはこんな感じ。

  • 描画速度向上
  • GPU 機能の並列実行 (特に並列コンピュートシェーダ)
  • 他のアプリへの組み込み易さ

他のアプリへの組み込み

今の Lumino は Graphics や Audio など様々なモジュールがひとつになった巨大なライブラリですが、そのうち小分けにして配布しようと思っています。

  • クロスプラットフォームな3D描画やりたいときは LuminoGraphics 使えるよ
  • オーディオグラフ作りたいときは LuminoAudio 使えるよ
  • ステートフルな UI 作りたいときは LuminoUI 使えるよ

みたいな。

・・・自分のリソース絶対足りてないなぁ