PlaydateのSDKを観察する会
PlaydateのSDKが公開されたので、ネイティブ部分について観察してみる。
- 公式: https://play.date/dev/
- Luaドキュメント: https://sdk.play.date/1.9.0/Inside Playdate.html -- C開発はオプション扱いなので、まずこちらを見る
- Cドキュメント: https://sdk.play.date/1.9.0/Inside Playdate with C.html
- フォーラム: https://devforum.play.date/
- 告知ツイート: https://twitter.com/playdate/status/1498427655175159822
既に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
の外と予想するけどどうだろうか。。
Windows用ARMツールチェインの入手
そもそもSDKにはツールチェインが用意されておらず、各自で gcc-arm-none-eabi
GCCを用意することになっている。これもまた思い切ったデザインだな。。
ドキュメントではARM公式から入手しろってなってるけど、これかなり難易度高くない。。?
Install the GNU Arm Embedded Toolchain compiler
gcc-arm-none-eabi
from developer.arm.com, when prompted add to WindowsPATH
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 に到達できる。
グラフィックス と スプライト
元々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もあるんだし多少余裕持ってもよくない。。?通常のフルスクリーンビットマップをステンシルとして使えるようにする配慮だとは思うけど。
オーディオ
オーディオは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シーケンサを提供するが、音色は提供しないので自前で用意する必要がある。
ネットワーク
公開SDKはリーダーボードのようなネットワーク機能を提供していない。Playdate本体やシミュレータからWebAPIを呼ぶこと自体は可能なようで、 フォーラムの回答 と手元の実験によると
- シミュレータ内で適当なWi-Fiに接続する(SSID名がパスワードになっている)
- 設定から登録
- Webサイトの Register ボタンを押さずに 手動で アクセストークンとデバイス名を登録(Playdate → Device serial number & Token)
Playdateは定期的にゲームを配信するというモデルなのでその配信ゲームが公式ゲームとしてWebAPI等を利用できるのだろう。
Lua/CどちらでもJSONの操作を標準ライブラリに持っているので、HTTPクライアントくらいは今でも装備していて良い気はするけど。。