もう2017年も半ば過ぎ、ここらで停滞している
Webベースウェア「イカガカ」の要素技術について一旦軽くまとめてみようかと思います。
なおこれは本来
伺か Advent Calendar 2016 17日目の枠に入るはずの記事でした(ぉ
イカガカは2014年末から2015年初頭にかけて精力的に開発していたですが、その後は仕事とかで忙しくなったのもありユーザーの目に見える進捗はありませんでした。
現在は初期に手探りで作ったコードが色々とイケてなかったのを改めて書き直している感じです。
さて、イカガカはそもそも「デスクトップマスコットソフトウェア(
伺か)をブラウザ上で実現する」というなかなかニッチなことをするソフトウェアです。
Windowsデスクトップ用アプリケーションであるmateria.exeやssp.exe等に渡すのと全く同じnar(キャラクターデータ)をブラウザに放り込んでそのまんま動いている背後では、デスクトップ用のものとほとんど別の技術が動いています。
その辺の技術やライブラリについてざっくりまとめることで、現状を伝えられたらと思います。
- シェル描画系
- さくらスクリプト
- surfaces.txt
- SHIORIサブシステム
- SHIORIプロトコル
- ファイルシステム
- ベースウェア
- デスクトップ・スマートフォン対応
- 技術・ライブラリの一覧
- まとめ
シェル描画系
cuttleboneそもそもイカガカはシェル&バルーン描画ライブラリ「如何か」としてduxcaさんによって作られたのが最初です。
その後自分が参入してベースウェア機能をつけたのを「イカガカ」と呼び始めたので、描画ライブラリは現在
cuttleboneという名前になっています。
描画については、SSPがGDI=Win32APIを直接使って色々なんとかしているのに対し、cuttleboneはブラウザのDOM APIとcanvasを使って同等の機能を実装しようとしています。
基本的にクリック判定&レイヤー付き2次元アニメーションが出来ればいいのでまあ頑張ればおおかた再実装可能かとは思うんですが、アニメーションや着せ替えの仕様とかは複雑で大変そうです。
canvasで主に非透過pngの色抜きとelementの合成を行い、その他レイヤー管理とかバルーンとかはDOMでやってるかんじです。
助かった点としては、
フォント指定(\f)の色指定や
位置移動(\_l)の移動単位などSSP拡張さくらスクリプトのいくつかは、HTML/CSSでの指定と同じ種類のものを使っていて実装がしやすかったあたりがあります。
一方でフォント描画方法としてGDIのSetROP2をそのまま使う感じの指定があったりするのは現状では互換が難しそうなので悩ましい感じです。
なおイカガカ専用というわけではなく、ライブラリ単体をサイトに設置してシェルのプレビューするとかにも使えるようなので、興味あればのぞいてみて下さい。
react-ukagaka-shell-pixi一方もう一つ、
react-ukagaka-shell-pixiというプロジェクトもやっています。シェルを全部VirtualDOM的かつWebGLで描画するのを目標としています。
cuttleboneはもう現状でもかなりの仕様が動くんですが、遅い箇所などもあったりAPIの癖などもあるので、そのあたりを新規に作り直したら……という実験です。
またこちらは低レベルの描画に近いので元々のGDIっぽい描画の指定もすんなり実現できるかもしれません。
現状バルーンの文字描画についてはおおむね出来ているんですが、シェル系やアニメーションの考慮がまだ全く無い感じです。
課題cuttleboneのAPIが色々と密結合で現在作成中のベースウェア部分と整合がいまいちなあたり、react-ukagaka-shell-pixiはシェル系の合成メソッドを実現するためのアーキテクチャが思いついていないあたりが課題だと思っています。
前者はその辺のインターフェース設計をやったことある人……?(ぽなさん……?)
後者あたりはシェルやら描画やらreact-pixiについて造詣が深い人がいると捗りそう……。
reactでやるのがむりだったら捨てるのもアリですが、まだ方法を考えたいです。
さくらスクリプト
伺かの動作は独自のマークアップ言語、さくらスクリプトというものが司っています。
これについては元々雑に正規表現で扱ってたんですか、パーサー「
sakurascript」と時間に沿って実行をするライブラリ「
sakurascript-executer.js」を作りました。
課題単純に未対応スクリプトが結構あります。これはまあ正規表現を書けって話ですね。
ただパーサー未対応とは別にシェルの方で未対応って言うのもあってこっちは悩ましいです。
surfaces.txt
シェルの描画そのものをするのも大変ですが、
伺かにおいて最も大変なことの一つはsurfaces.txtの取り扱いではないでしょうか。
独自形式で複雑な仕様である上に、SSPがかなり寛容に取り扱うおかげで「記述仕様としては誤っているが動いている」というゴーストが結構存在します。
この「誤った記述」の場合記述の場合どのように解釈するかというのが全然分からなかったりしてなかなかつらいところです。
「如何か」時代のduxcaさんも悩んでいたみたいなのですが、自分がイカガカをベースウェアとして開発する前に作っていた
surfaces_txt2yamlというライブラリが(本来想定された用途とは違うのですが案外)役立ち、これを改変したものがcuttleboneで現在使われています。
課題surfaces_txt2yamlはかなりテキトーに作ってあり、控えめに言ってあまり使い勝手が良くはないです。
使い勝手の良いsurfaces.txtのパーサー・ビルダーが出来れば
伺かサーフェスビルダーなんかの夢も広がって良さそうなので、これとは別にどなたかやってみませんかね?
SHIORIサブシステム
SHIORIサブシステムはまさにゴーストの根幹ですが、ここが最も黒魔術を使っている部分です。
なぜならここは伺かの仕様では「こういう入出力を持ったWindowsのDLL」という定義、つまり自由なプログラムが書ける箇所なので、そのプログラムをそのままブラウザで動くようにしないとコストが高すぎる箇所だからです。
幸いにしてPC上で動くプログラムをブラウザ上でも動くように変換するEmscriptenという黒魔術的技術が存在するので、それを使って主要なオープンソース汎用SHIORIサブシステムである「華和梨8」、「華和梨7」、「里々」、「YAYA」、「文5」に関して動作するようにできました。
これはもともとUNIX系OSで伺かを動かそうという
ninix-ayaプロジェクトの為にWindowsに依存しないコードベースが各SHIORIに存在したのが大きく、少数のパッチをあてるだけですんなり変換できました。
なので自分が現状作業したのはその少数のパッチ当てと
kawari.jsにあるようなEmscripten用Makefileの作成くらいです。
ただやはり黒魔術を使う最も自由な仕様の部分なのでまだまだ課題も多いです。
課題1(比較的簡単そう)1つめの課題は、現在も更新を続けている里々やYAYAの更新に自動追従が出来ていないあたりでしょうか。
CIとかでカジュアルに更新をかけていく仕組みを作りたいですね。
課題2(やや難しそう)2つめの課題は、SHIORIのプラグイン機構「SAORI」に対応していない点です。
これはDLLからのDLL呼び出しという機能を実現せねばなりません。Emscriptenにおけるこのあたりの仕様について追っていく必要があります。
またそれを実装したとして、呼び出すSAORI DLLもクローズドソースなものが多いのでそちらの実装工数もバカになりません。
現状はこのインターフェースをつぶすことで動作させている状況です。
おそらく現行のイカガカについてここが最も要望が多く、かつヘルプが欲しいところであります。
自分がSAORIを使ったことがないのでSAORIの利用状況なども把握しておらず、目処が立っていません。
課題3(かなり難しそう)3つめの課題は、クローズドソースな栞、特に主要に使われているSHIORIのうち「美坂」のみクローズドソースなのでエミュレートの目処がたっていない点です。
ninix-ayaではPythonで独自に実装することで回避していたようですが、少なくともこれをJavaScriptに置き換えるなどの作業が必要です。
おそらく新規ゴーストのほとんどは美坂を使っていないようですが、やはり昔のゴーストを動かしたいものです。
いまのところ優先度は高くないですが、よろしければご協力お願いいたします。
またその他の新しいSHIORIサブシステムについてはJavaScriptへの変換が出来れば対応することが出来ますので、イカガカに標準で入れたい場合は言って下さい。
ゴースト独自のSHIORIを使う等の場合も、descript.txtにJavaScript版の指定を追加するなどで使えるようにしたいと思っています。
課題4(ものによっては目処が立たない)4つめの課題は、汎用言語SHIORIへの対応です。
SHIORI独自言語ではなく汎用言語によるSHIORIサブシステムへの対応は是非したいと思っていて、むしろそれを推していきたいんですが、RubyやPythonなどをブラウザ上で動かすというのはなかなか難しいところがあります。
一応lua.vm.jsなどをはじめとしてJavaScriptで動かそうというプロジェクトは各言語にあるんですが、やはりなかなか難しいようです。
よしんば言語レベルで対応できたとしても、イカガカはnarをそのまま動かすのを目標としています。ファイルシステムのエミュレーションなど課題は尽きません。
汎用言語の中でもJavaScriptなら動くのでは?というのも難しい問題で、narをそのまま動かすにはファイルシステムのエミュレーションをしたうえでnode.jsの仕様にあるrequireを動作させなければ実用的ではありません。
このrequire対応については
browserfs-module.jsというのを作ってかなり力業で対応したのですが、まだテストをする時間を取れておらず、本当に動くのかは未知数です。
これはイカガカに限らず、デスクトップアプリケーションをいかにブラウザ上で動作させるかという問題なので、ご興味ある方は是非ご協力下さい。
SHIORIプロトコル
SHIORIプロトコルは前述のSHIORIサブシステムとベースウェアの通信仕様です。
これがないとDLLを変換してもSHIORIサブシステムを動かすことは出来ません。
このSHIORIプロトコルのパーサー・ビルダーはベースウェアであるイカガカだけではなく、SHIORIサブシステム側でも使うものなので、それ用に複数の言語で実装しました。
- JavaScript:
ShioriJK- Ruby:
Shioruby- C:
cshioriの中のcshiori.hとcshiori.c
- Go:
shiori.go各言語でSHIORIサブシステムを作る場合はご活用下さい。
なおJavaScript版は最初にはりきって作ったので、HTTPのようにチャンクで渡ってきても処理できるようなのもパーサーに含まれていたりします(SHIORIプロトコルの仕様にはない)。
参考までに、拙作のSHIORIサブシステムとしては
- JavaScript:
MiyoJS,
SanaJK- Ruby:
Sana(紗凪),
sana-mvcbase- C:
cshiori等があります。
SHIORI/2.x / SHIORI/3.x 両対応またSHIORIにはSHIORI/2.xとSHIORI/3.xというバージョンがあります。
イカガカで対応しているSHIORIサブシステムの中でも、華和梨7と文5は古いSHIORI/2.xで通信をする必要があるので、標準のSHIORI/3.xと両対応する必要があります。
これについては内部的にはSHIORI/3.xで扱いつつ、SHIORI/2.xとの変換レイヤーをもうけることにしました。
2.xと3.xの変換をかけられる
shiori_converterと、リクエストとレスポンスとをひとまとまりとして扱って、そのまとまりを2.xか3.xとして扱う
shiori_transactionを噛ますことでスムーズに判定&変換ができます。
さらに実際にSHIORIサブシステムを呼ぶところを司る
shiorifでこれらを透過的に扱えるようにしています。
課題shiori_converterはうさださくらの資料と華和梨8の実装などを参考に結構手探りで作ったので、バグがあることが予想されます。
あとRequest 3.x→2.x、Response 2.x→3.x以外の変換は現状必要ないので実装していません。
ただ基本的に新しいゴーストには関係ないところなので、あまり問題ではない感じです。
ファイルシステム
一般にデスクトップアプリケーションと同等機能をブラウザで動かすという場合に一番障害になるのがおそらくファイルシステムでしょう。なぜならファイルシステムという概念がブラウザにはそもそも存在しないからです。
「データを保存できる場所」としてLocalStorageやIndexedDBなどいくつかの場所は存在するのですが、ローカルのファイルシステムには基本的にアクセスが不可能です。
というわけで、とくにSHIORI等がファイルシステムを前提として動いている伺かを移植するためには、何らかの方法でファイルシステムをエミュレートしてやる必要があります。
これについては
BrowserFSというファイルシステムをエミュレートするライブラリを利用したうえで、
NanikaStorage(名前が微妙)という伺かベースウェアのファイル操作を担うライブラリを噛まして実現しています。
NanikaStorageは一般のファイルシステムにも使えるので、ベースウェア操作のエミュレートをしたい場合などにも使えるかも知れません。
課題まあ、遅いです。イカガカでのゴースト起動の遅さはこことSHIORI初期化とシェル初期化です。
IndexedDBと言うところから読み出してメモリーに全部コピーして転送する&書き戻すみたいなことやっているので泥臭いしバグい。
ブラウザの非同期ファイルシステムAPIとEmscripten FSのうまいつきあい方を知っている方はいませんかね?
ベースウェア
さて、これら要素技術を組み合わせて「伺かベースウェア」として動作させる存在が必要です。
現在デモで動いている旧バージョンは単体のゴーストを動かす
Nanikaと複数ゴーストを管理する
NanikaManagerがベースです。
現在作り直し中なのは
ghost-kernel.jsで、色々試行錯誤しながら作っています。
Webサイトくらいならイベント駆動といってもサーバーならHTTP通信、ブラウザならユーザー操作のそれぞれ1つなので簡単ですが、伺かベースウェアではシェル(ユーザー入力)、さくらスクリプトの時限実行、毎秒毎分ごとのイベント発行、ユーザーや他ゴーストからのコミュニケート、SSTPによる外部通信など色々な入力ソースがあるので複数入力ソース用のイベント管理ライブラリ
lazy-event-router.jsを作ったりしてなかなか大変です。
自作が目的ではないので、そういう複数入力ソース用のイベント管理ライブラリで良いのがあったら教えていただけると助かります。
課題シェルのインターフェースが定まっていないのでそことのつなぎが止まっていること、イベント駆動の管理の良いアーキテクチャが手探りで色々変わっていることなどの要因で、まあ全く安定していませんし、物量も多いです。
ここに関しては不安定すぎてまだヘルプを請えるような状態でもないので難しいところです……。
デスクトップ・スマートフォン対応
さて、そうして組み上げたイカガカは現状PCブラウザ上で動く事を第一目標としていますが、これを逆にデスクトップアプリケーションにしたり、あるいはスマートフォンで動かすなどにはもう一工夫必要です。
課題は山積みです。
デスクトップアプリケーションそもそもデスクトップにはSSPがあるじゃんって話なんですが、WineをインストールしなくてもLinuxやMacで動くと嬉しいですよね?(たぶん)
あとイカガカのライブラリ群を使ってゴーストエディターとかデバッガーが出来るといいなとも思っています。
過去にはnode-webkit(現nw.js)でサンプルを作ったことがあるんですが、現状だとelectronのほうが知見が多そうなのでそちらでやろうかと考えています。
ブラウザと違って、ファイルシステムをエミュレートせずに実FSを使う、またWindowsでは普通にDLLを読み込んで使うなどが出来るので、そのあたりの対応が必要です。
スマートフォンイカガカのベースウェアはもともとスマートフォンに脅威を感じてはじめたプロジェクトなんですが、現状スマホでいい感じに伺かを使うというのはなかなか難しいところです。
そもそも「デスクトップ」が存在しないのでたぶんアプリとして切り替えるしかなく、大分体感が変わります。
またマウス前提で作られたUIをどうタッチ対応するか、などの考慮も必要です。
ブラウザを立ち上げてタブ切り替え、というのはなかなか手間がかかるので、出来ればCordovaなどでアプリにしたいところですね。
また、そもそもホームアプリに伺かを含んでしまってデスクトップ相当を乗っ取ってしまうという逆転の発想も試してみたいところです。
DOMLauncherや
HTMLauncherなどのブラウザ技術でランチャーが作れるものが存在するらしいので、そのあたりをいじると出来そうな気はしますね。
この辺言っているだけで全く着手など出来ていないです。スマホ対応とか新体感で面白そうなのでおすすめです。
技術・ライブラリの一覧
以上で上げた以外にも、小物的に色々なライブラリを作りつつイカガカは構成されています。
現状イカガカに興味があってもどこからみたらわからない状態だと思うので、俯瞰の為に下記に簡単な一覧をあげておきます。
新しいものはTypeScript、古いものはES2015かCoffeeScriptで書いてある率が多いです。
ベースウェア本体関係
Ikagaka/ghost-kernel.jsベースウェアで単体ゴーストを動作させるカーネル部分。
鋭意制作中です。
Ikagaka/named-kernel-manager.js複数ゴーストを管理する部分です。今はまだほとんど実装がありません。
Ikagaka/ikagaka-applicationたぶん将来的にブートストラップはここからやります。今はまだ何もありません。
Ikagaka/ukagaka-timer-event-source.jsベースウェアが発行する時限イベント(OnSecondChange等)の元となるイベントソース。
ほぼsetIntervalしかしてないですが、モジュールとして切り出すのがきれいだと思ったのでこれだけでライブラリになっています。
Narazaka/lazy-event-router.js複数のイベントソースを持つイカガカのイベント処理の為に作ったイベント管理ライブラリ。
他にそういういいのがあったら教えて下さい。
SHIORIサブシステム関係
Narazaka/shiorijkSHIORIプロトコルパーサー・ビルダー・コンテナ。
ベースウェアでもSHIORIでも使えます。
Narazaka/shiori_converter.jsSHIORI/2.xとSHIORI/3.xを同義変換する為のライブラリ。
現状ベースウェア実装に必要なRequest 3.x→2.x、Response 2.x→3.xの変換のみ実装しています。
Narazaka/shiori_transaction.jsSHIORIプロトコルのリクエストとレスポンスをまとめて扱い、上記変換を便利にするライブラリ。
Ikagaka/ShioriLoaderSHIORIサブシステムをファイルシステムから種類判定してロードする為のライブラリ。
判定関数はプラグイン式で、デフォルトの判定は
Ikagaka/shioridetector-common_namesに書いてあります。
Ikagaka/shiorifロードしたSHIORIサブシステムと通信する為のライブラリ。
shiori_transaction.jsやshiori_converter.jsと連携して、SHIORI/2.x、SHIORI/3.xを変換しつつ透過的に扱えます。
Narazaka/nativeshioriEmscripten変換したSHIORIサブシステムとCのインターフェースで通信する為に、メモリ管理や文字コード変換などを請け負うライブラリ。
イカガカ外でもEmscripten変換したSHIORIサブシステムを単体で扱いたい場合には重宝します。
Narazaka/WorkerClientServerWebWorkersをクライアント・サーバー方式っぽく扱うラッパーライブラリ。
SHIORIプロトコルがクライアント・サーバー方式なので、SHIORIサブシステムをワーカーで使うために作成。
他の良い感じのがあれば教えて下さい。
Narazaka/single-file-worker.jsどこにスクリプトを置いてもWebWorkerが動かせるような仕組みにする為に、文字列で埋め込んだスクリプトを起動する為の仕組みです。
他の良い感じのがあれば教えて下さい。
Ikagaka/NativeShioriWorkerSHIORIをブラウザのWebWorker上で動作させるライブラリをつくるツール&ライブラリ。魔術的な操作をやっているので、たぶん将来的には別の仕組みを作るんじゃないかと思います。
主にsingle-file-worker.jsを使う為に魔術的な変換をかますやつです。
各種SHIORIサブシステム汎用SHIORIサブシステムをEmscriptenで変換したものです。
- 華和梨:
Narazaka/kawari.js- 華和梨7:
Narazaka/kawari7.js- 里々:
Narazaka/libsatori.js- YAYA:
Narazaka/yaya.js- 文5:
Narazaka/aya5.js各種SHIORIサブシステムのワーカー上記をWebWorker上で動くようにしたもの。魔術的なNativeShioriWorkerを使っています。
- 華和梨:
Narazaka/kawariworker.js- 華和梨7:
Narazaka/kawari7worker.js- 里々:
Narazaka/satoriworker.js- YAYA:
Narazaka/yayaworker.js- 文5:
Narazaka/aya5worker.js
シェル関係
Ikagaka/ukagaka-install-descript-info.jsnarに含まれるinstall.txtと各種descript.txtのパーサー・コンテナ。TypeScriptの型定義も含んでいるので、プロパティが便利に参照できます。
ただしまだシェルくらいしか型定義が充実していないので整備する必要はあります。
Ikagaka/cuttleboneシェル描画ライブラリ。従来からのもの。
Ikagakaのグループに
Shell.js,
Balloon.js,
NamedManager.jsというのがありますが、これらはcuttleboneのコンポーネントです。
Ikagaka/react-ukagaka-shell-pixi.jsシェル描画ライブラリ。新規APIの実験。シェルの状態を持ったモデルと実際の描画とを別々にする思想の元設計されています。
react-pixiというものを使っていて、副作用を持たない描画ライブラリです。アニメーションについては都度更新をかける必要があります。
バルーンはある程度出来ていますが、まだシェル部分の多くが開発中です。
Ikagaka/ikagaka-shell-statecuttlebone風のAPIを持ったシェルの状態モデルです。
Ikagaka/ikagaka-shell-loaderシェルをnarからロードするライブラリです。
Ikagaka/ghost-urn.jsシェルの新しいAPIを考える為のリポジトリです。
Narazaka/surfaces_txt2yamlsurfaces.txtをパースして構造化データにするツールです。これを直接ではありませんが、改変したものがcuttleboneで使われているとのことです。
元々はsiurfaces.ymlという構造化データからsurfaces.txtを作る
surfaces_yamlというツールの逆変換ツールでした。
さくらスクリプト関係
Ikagaka/sakurascriptさくらスクリプトパーサー・コンテナ。
これ単体はスクリプトをパースしてオブジェクトにするだけです。
Ikagaka/sakurascript-executer.jsさくらスクリプト実行機。
パースされたさくらスクリプトオブジェクト群のうち時間関係の部分を考慮して、その他のスクリプトを含んだイベントを時限発行してゆくものです。
ファイルシステム関係
Ikagaka/NanikaStorageベースウェアが行うファイルシステムの操作をラップするライブラリです。
narを展開する場所が分かるとか、シェルのフォルダだけ置き換えるとかがメソッド1発で可能です。ukagaka-install-descript-info.jsと連携してdescript.txtの中身なんかも簡単に取れます。
Ikagaka/NarLoadernarを読み込む部分です。jszipでzip展開して、NanikaStorageでnarの中身をファイルシステムのように読み出せるようになっています。
Narazaka/fsoイカガカ用ではありませんが、ファイルシステム操作の為に広く使っています。
jvilk/BrowserFS同じくイカガカ用ではありませんが、ブラウザ上でのファイルシステムエミュレートの為に必須のライブラリです。
その他
Ikagaka/Ikagaka.demoデモ用のWebサイト。旧バージョンのベースウェアシステムが元気に動いている
イカガカのデモですが、SHIORIサブシステムの更新とかはこのリポジトリを細々と書き換えたりしています。
Narazaka/ikadocイカガカの現行仕様まとめのためのリポジトリでした。
今デモで動いている旧バージョンの情報としてはおおむね正しかったはずです。
まとめ
以上、ざっくり技術やライブラリについてまとめてみました。
こんな感じがおおまかな現状です。
全体的に仕様の大きさと異色の難度で大変なことになっていますが、部分的になら意外と出来ているもんです。
イカガカの作業中に作られた色々なライブラリを使って、周辺ツールを作ってみても有益だと思います。
その辺も含めて、イカガカは主に作業時間の不足による開発長期化で割と死んでるので、特に現状の2人の開発勢では対応できないことなど、なにかやってみたいって人がいるといいなって思ってます。
このほかにもSHIOLINKなどで汎用SHIORIサブシステムを作るなどもやっています。
今後10年戦えるベースウェアや周辺ツールを作って伺か文化を振興したい思いはあるので、なんか一家言ある人は色々言って下さい。
以上現状報告でした。