Open5

PlaydateのSDKを観察する会

okuokuokuoku

PlaydateのSDKが公開されたので、ネイティブ部分について観察してみる。

既にRustのcrateを書き始めている人もいる https://github.com/rtsuk/crankstart

サマリ

  • ゲームは全てDLLとして作成される。
  • DLLのリンクはエクスポートシンボル eventHandler 1つで賄われる。プラットフォームのAPIはこのハンドラに渡されるポインタを経由して呼び出すことしかできない。
  • システムは(webのように)pull型で動作する 。つまり、ゲームコードから積極的にフレームや音声をpushすることはできず、システムからのコールバック駆動でゲームを作成しなければならない。busy waitする方法は(C SDKには)無い。Luaではcallbackから yield 可能。
  • プラットフォームAPIはcallbackする形でしか呼べない。つまり、 一切の静的ライブラリや動的ライブラリを同梱用に提供しない 。これかなり思い切った設計だよな。。
  • シミュレータは 一切のエミュレーションを提供しない 。シミュレータビルドはプラットフォームネイティブのDLL(や.soや.dyld)を作成させる。このため、ネイティブコードのデバッグやパフォーマンスプロファイリングには通常のデバッガをアタッチして使用することになる。
  • 実機ではLuaおよびCレベルプロファイラが提供されるが、シミュレータはLuaのもののみ。
  • Executableの切り替え、追加ネイティブコードのロード等はサポートしない
  • 以下が存在しない
    • C標準ライブラリ(printf、malloc、fopen等 -- プラットフォームの機能で代替する)
    • スレッドや同期プリミティブ
    • ネットワーク

ゲームは↓のようなイベントハンドラ1つだけを実装すれば良い。プラットフォームAPIは全て構造体PlaydateAPI*を通してアクセスする。

int eventHandler(PlaydateAPI* playdate, PDSystemEvent event, uint32_t arg);

以下が不明:

  • PlaydateAPI 内のAPIへのポインタの寿命。
  • ヘッドホン挿抜やオーディオなどコールバックが呼ばれるコンテキスト。 eventHandler の外と予想するけどどうだろうか。。
okuokuokuoku

Windows用ARMツールチェインの入手

そもそもSDKにはツールチェインが用意されておらず、各自で gcc-arm-none-eabiGCCを用意することになっている。これもまた思い切ったデザインだな。。

ドキュメントではARM公式から入手しろってなってるけど、これかなり難易度高くない。。?

Install the GNU Arm Embedded Toolchain compiler gcc-arm-none-eabi from developer.arm.com, when prompted add to Windows PATH environment variable

現時点では、 https://developer.arm.com → Tools and Software → Opensource → Developer tools → GNU toolchain → Read more → Downloads で https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads に到達できる。

okuokuokuoku

グラフィックス と スプライト

元々Lua側にハイレベルなグラフィックスAPIを出しているからか、C言語側もかなり充実している。基本的に1bitモノクロに特化しているため、カラー化のような拡張は大きな変更が必要だろう。

機能性はプチコン4に近いが、BGの概念がなく、そのかわりステンシルが存在する。つまり大きな描画はいわゆるpainter's algorithmで処理することを想定していて、あくまでmoving objectのためにスプライトを使う流儀を取ったようだ。また、プチコン4にはスプライトのアニメーション機能があるがPlaydateには無い。衝突検出機能はどちらにもある。プチコン4と異なり、ハードコードされたスプライト数制限はない。Playdateは20fpsプラットフォームなのでメモリ制約以外にはあまり制約が無いのだろう。

数値指定は float と整数が混ざっている。回転は 度 単位。

ステンシルのサイズは32 pixelの倍数でなければならない。ただしフルスクリーン(400 x 240)だけは特別扱いしているようで、

If the image is smaller than full screen, its width should be a multiple of 32 pixels. Stencils smaller than full screen will be tiled.

のように 400 x 240 に満たない場合にのみ32ピクセル制約を設けている。 ... 別にメモリ16MiBもあるんだし多少余裕持ってもよくない。。?通常のフルスクリーンビットマップをステンシルとして使えるようにする配慮だとは思うけど。

okuokuokuoku

オーディオ

オーディオはPlaydateにおいてもっともリッチなシステムで、Lua側のドキュメントでも最大のリソースヘビーな要素として警告されている。

The biggest culprit in blowing up game size is audio. If your game is large due to the inclusion of a lot of audio, we recommend

OpenALのようなサブミックスは持たず、単純に加算合成されるいくつかの チャンネル に Source と Effect をアタッチして使用する。Effectはよくあるデジタルフィルタ(LPF等)やディレイがあるが何故かリバーブのようなエフェクトを実現するためのFIRフィルタ類がない。ユーザのコールバックを供給できるので、リバーブ類はそこで適用する方向になるだろう。

ソースとしては IMA ADPCM や MP3(Vorbis は無い) をサポートしたストリームプレーヤとシンセサイザがあり、シンセサイザはエフェクト等を駆動できるエンベロープジェネレータ(ADSR)や基本波形を出力するオシレータで構成される。

システムはMIDIシーケンサを提供するが、音色は提供しないので自前で用意する必要がある。

okuokuokuoku

ネットワーク

公開SDKはリーダーボードのようなネットワーク機能を提供していない。Playdate本体やシミュレータからWebAPIを呼ぶこと自体は可能なようで、 フォーラムの回答 と手元の実験によると

  1. シミュレータ内で適当なWi-Fiに接続する(SSID名がパスワードになっている)
  2. 設定から登録
  3. Webサイトの Register ボタンを押さずに 手動で アクセストークンとデバイス名を登録(Playdate → Device serial number & Token)

Playdateは定期的にゲームを配信するというモデルなのでその配信ゲームが公式ゲームとしてWebAPI等を利用できるのだろう。

Lua/CどちらでもJSONの操作を標準ライブラリに持っているので、HTTPクライアントくらいは今でも装備していて良い気はするけど。。