2023/12/15 core/Runtimeの設計
2023/12/15 core/Runtimeの設計
core/Runtimeに求められるもの
生のJavaScriptである必要はない
でも、JavaScriptでも良い
描画をどうするか?
Testablityの観点から、テストツールがビルトインで含まれているRustを使いたいと感じる canvasへの描画が必要と考えられ、描画速度が難点である
WebAssemblyはMain threadで実行されるのか?
この記事を読むと、Main threadで動作すると読める
WebWorkerを使用することで実現している
とりあえず、WebWorkerで書く?t6o_o6t.icon
WebWorker上でWebAssemblyを動かすのでも問題はないのではないか
WebWorkerでcore/Runtimeを動かすことには違いない
記述する言語はなんでもよくなった
WebAssemblyでのcanvas描画が遅い原因は何か?
17:28 上述2点について調査する。
WebAssemblyで描画を行う必要はないのではないか?
Main Thread
一般的なUI計算、canvasの実体に対する描画を行う。
WebWorkerに、Offscreen canvasの描画依頼を行う。
web/UIと呼ぶ
WebWorker
Offscreen canvasに対する描画を行う。
WebAssemblyに、現在フレームのGame Objectの状態を計算させる。
オブジェクトの状態もWebWorkerで持つ?(パフォーマンス測定し比較)。
web/Rendererと呼ぶ
WebAssembly
現在フレームにおけるGame Objectの状態を計算する。
いま、これをcore/Runtimeと呼ぶことにする
実装の順番
core/Runtimeの実装がもっとも重要
このアーキテクチャを採用する場合、core/Runtimeの実装がある程度できていないと、デモが成立しない。
次いで、web/Rendererの実装が重要
core/Runtimeとweb/Rendererの実装ができれば、「ゲームが動作する」というデモを行うことは可能になる
GameRuntimeSource
GameRuntimeに渡される初期入力を指す。
GameRuntimeContext
GameRuntimeのある状態を表す。
core/Runtimeのインターフェース
code:runtime.ts
interface Runtime {
generateNextContext: (source: GameRuntimeSource, context: GameRuntimeContext) => GameRuntimeContext;
}
17:52 ある程度インターフェースを固める
code:source.ts
interface GameRuntimeSource {
gameRuntimeSoourceObjectHierarchy: GameRuntimeSourceObject
}
interface GameRuntimeSourceObject {
children: GameRuntimeSourceObject[],
id: string,
components: GameRuntimeSourceObjectComponent[],
type: string
}
interface GameRuntimeSourceObjectComponent {
id: string,
scriptSrc: string,
inputValue: {
}
}
scriptの内容をどのように渡し、実行するのか
scriptは、実行時compile(JIT)する必要はない 必ずしもdynamic linkingする必要はないのではないか?
実行にあたり外部ライブラリが必要になった場合は、それらをdynamic linkingする必要性が生じる
Componentへの入力値への渡し方はどのようにするのか?
wasmで実現する難しさ
Component
Current Valueと、GameRuntimeContextから、新しい値を評価する
Component間の依存
あるComponentが、他のComponentにより計算された値を利用したいときがある
依存関係を考慮するには?
たとえば、あるComponentから、別のComponentが参照されたら、そのComponentに先に値を評価させる必要がある
wasmで実現する場合、他の関数を適切に参照できなければならない
事前にいかに上手くbuildできるかが重要かもしれない?
実行時に、他の関数を検索するのは困難である
build時に、参照先のComponentのscriptの関数をbindできれば問題ない
build時には、参照先Componentの関数を解決するようにlinkする必要がある
すなわち、これは、複数のscriptを事前にリンクすることにより解決する
valueとscriptは完全に分かれるべきである
どのような構造にするのが望ましい?
あまり難しくないかもしれない?
aComponent.functions.hoge()
aComponent.valueGetter.hoge()
関数呼び出しとCurrent Valueの取得は、本質的に変わらない
メモ化をシステム側で行う必要がある?
すなわち、あらゆる値取得を、メモ化関数の呼び出しに置き替える必要がある
Componentのscript実体をwasmで表現することの問題点
すべてのscriptをリンクして、一つのwasmにまとめることで、script間の参照を実現する必要がある
scriptをwasmにコンパイルする必要がある
コンパイラ、リンカをブラウザ上で動かす必要となる
wasmで実行するメリットがデメリットよりも少ない?
ComponentのscriptをJavaScriptで記述する
coreもまた、JavaScriptで記述することにする
実行はWebWorker
コードの編集、コンパイルはWebで行わなくて良いのではないか?
ゴールはライブコーディングだから
コードを書く主体はあくまで発表者であり聞き手ではない
コンパイル・リンクは保存時に行えば良い
単一のwasmバイナリへのリンクは、Compile Serverを立てて行えば良いだろう
コーディングセッションの流れ
事前準備段階
CLIを起動し、sessionを作成
自動的に、srcディレクトリを含むディレクトリ構造が作成される
Build Serverが起動する
srcディレクトリを任意のコードエディタで開く
componentsディレクトリに、新しいディレクトリを作る
作ったディレクトリの中に、index.jsを作る
index.jsに記述する
Build Serverにより、build.jsへのコンパイルが行われる
発表段階
Build Serverを
メモ
Runtimeには、計算に必要な情報のみあれば良い?
デバッグ情報として名前もあったほうが良い?
web/UIでidとdisplayNameとの関連付けをすれば問題ない
脆弱性の問題
悪意のあるコードがスクリプトとして保存されると、蓄積型XSSのように、聞き手全員に悪意あるコードを実行させることができてしまう wasm containerだから大丈夫?
built-in components
render2D
physics2D
snapshotのsaveは、一つのみエンドポイントを設ける
シンプルに考えてほしい
https://scrapbox.io/files/657ee6844fb0d90023f8c436.svg
図において、明示的に「OnDemand」と書いていないpullは、リアルタイムに行われるものである
たとえば、Player Next.js Serverは、Snapshot Serverから定期的なpullを行う
Snapshotは、Editingとdeliveredの2つの状態を持っている
EditingなSnapshot
Editorは、Source snapshotを操作することのできるアプリケーションである
PCブラウザ向けであり、Component Build Serverとの連携も行う
EditingなSnapshotは、保存されるたびにSnapshot Serverにdeliverされる
DeliveredなSnapshot
Playerは、Delivered snapshotを表示するアプリケーションである\
スマートフォン向けである
PlayerにとってDelivered snapshotは、Source snapshotのcopyであり、直接変更を加えることはもはやできない。
これに忠実に作る必要はない
ここまで作り込めば、十分にアプリが機能するだろうという図である
実際に必要なのは、
EditorとPlayerの性質の違い
Editorは、ローカルに立てたサーバーから、構築したアプリケーションをdeliverするまでが本質である
アプリケーションの構築には、Player以上の機能が必要である
Playerは、deliverされたアプリケーションを表示することが本質である
Editorの機能のうち、アプリケーションを構築するための機能の一部だけが必要である
ゲームエンジンを作ることは本質であろうか?
本質的ではない
deliver用のローカルサーバー、および、deliverされたアプリケーションにローカルな編集を行えるプラットフォームを作ることが使命である
ただし、ローカルな編集を行えることが要件となるから、採用するゲームエンジンは、ブラウザで編集できなければならない