TypeScript NovelGame Framework

BlueSNovel

モダンなWeb標準技術で再構築した
ノベルゲームフレームワーク

Free for Commercial Use Browser / Electron Windows macOS
121の移植済みタグ
SKYNovelプロジェクトが
ほぼそのまま動く
1787の単体テスト(全pass)
ブラウザを立ち上げず実行
299のE2Eテスト
Playwrightで実ブラウザ検証
MITライセンス
npmで公開
Who is this for

人によって、気になる場所は違う

気になるところからどうぞ。

動きを見たい人へ

ブラウザでそのまま試せる。

動くサンプルを見る →

物語を書く人へ

原作テキストにタグを並べてスクリプトが書ける。ルビも禁則処理もサポート。

書く人向けの機能を見る →

技術面が気になる人へ

TypeScript / React 上に構築された、テスト済みのコード。

技術的な特徴を見る →

作る人と、書く人が同じ

BlueSNovel(および元エンジンのSKYNovel)の開発者は、
ノベルゲーム作家としても活動している。

Developer

famibee

SKYNovel/BlueSNovelの開発者。

famibee.blog.fc2.com →
Novelgame Writer

夕街昇雪

同じ作者の創作名義。自作エンジンで実際に物語を書く。

ugainovel.blog.fc2.com →

作る人と書く人が同じだから、使う人の気持ちが分かる。

For Scripter

書く人がうれしい、細部のこだわり

本文中のルビも書きやすい記法。

彼は雷の指ひげこがしを彼女はいかずちの指を一期一会いちごいちえ冬虫夏草とうちゅうかそう
一応いちおう何時いつもの一瀉千里いっしゃせんり

彼は|雷の指《ひげこがし》を
彼女は雷《いかずち》の指を
一期一会《いち ご いち え》
冬虫夏草《とう ちゅう か そう》[r]
一応《いちおう》
何時《い つ》もの一瀉千里《いっ しゃ せん り》

参考にしたのは青空文庫のルビ記述。「人力での打ち込みやすさ」を重視した優れた仕様。

NScripter (記述/きじゅつ) |記述《きじゅつ》
吉里吉里 [ruby text="ひ"]向[ruby text="まわ"]日[ruby text="り"]葵 |向日葵《ひまわり》

タグ文法は吉里吉里2/KAG3ベース

文法の系統は同じで、用意された組み込みタグが違う、というイメージ。

; *** テキストレイヤ縦書き左設定 ***
[txt_lay_v_left]
[grp l0=F_kuchimoto rule=r_uzumaki]
[アルバム解放 name=F_kuchimoto]

 これは信じていいことなんだよ。何故つて、桜の花があんなにも見事に咲くなんて信じられないことぢやないか。[l]

※吉里吉里2がそのまま動くわけではなく、互換性はない。変更点や独自タグもある。
(例文:梶井基次郎「櫻の樹の下には」)

一文字マクロ

NScripterは「@」がクリック待ち、「¥」が改ページという、一文字が特殊な意味を持つ書きやすさで知られていた。char2macroは、その書きやすさを受け継ぐ機能。

[char2macro char=@ name=l] [char2macro char=¥ name=plc]

不覚を[l]生ずるゆえんを考えうるに、[plc] 不覚を@生ずるゆえんを考えうるに、¥

短く書けるだけで、動作はまったく同じ。

タグリファレンス全体を見る →

For Programmer

特徴

長年運用してきた SKYNovel, AIRNovel の設計資産を引き継ぎつつ、
React・TypeScriptで書き直したことで得られた特徴。

WebGL不要な基本表示

既定の画面転換・フィルタはCSS/SVGだけ。WebGLが無くても崩れない。GLSLシェーダ演出([add_fx]等)を使う場合のみWebGLが必要。

宣言的な状態管理

React 19 + Zustandの単一store。差分だけが流れる一方向データフロー。

純粋なシナリオエンジン

DOMもfetchも持たない純粋関数。ブラウザ抜きでシナリオ処理だけを単体テストでき、同じ入力なら必ず同じ結果になる。

strict TypeScript

noUncheckedIndexedAccessまで含む可能な限り厳しいstrict設定。型の緩みはコンパイル時に落ちる。

自前のWeb Audio層

音声ライブラリを積まず、Web Audio APIを直接制御。停止=破棄の1パターン。

1ソースツリーから2プラットフォーム

同じソースコードから、ブラウザ版とアプリ版を両方出力。

SKYNovel互換プラグイン機構

SKYNovelの3D/Live2DプラグインをDOM版へ移植できる土台を用意。

基本設計

中心にあるのは「純粋なシナリオエンジンとUIの分離」。
緑枠の1ステップだけが、ブラウザや通信を一切知らない純粋関数。

SysWeb読み込み完了
ScriptMng.load(fn)
ScriptEngine.step()
(pure)
T_ENGINE_ACTION[]差分アクション
storeへ反映
Reactが再描画

状態はstep()だけが持ち、戻り値はstoreへの差分アクションの配列。 step()自身はDOMもfetchも触らない。

ブラウザ無しでテスト

シナリオ処理だけを切り出して検証。1787本の単体テストが、ヘッドレスブラウザもGPUも使わずNode上で回る。

結果が決定的

同じスクリプトと同じ状態からは必ず同じアクション列。描画や通信のタイミングに左右されず、フレーキーテストが構造的に出ない。

移植のズレを機械検出

SKYNovelとの挙動一致を、画面を一切描かずアクション列の比較だけで確認できる。

SKYNovelからの設計改善

BlueSNovelは、作者の旧エンジン SKYNovel(本家)の設計を土台にしている。 書き直しの過程で、本家自身が抱えていた課題への対処も行われた。

画面転換・フィルタ Pixi.js + WebGL SVGフィルタ + CSSマスク

基本機能をWebGL非依存に(GLSL演出を使う場合のみWebGLが要る)

サウンドの状態モデル 6状態の状態機械 停止=破棄の1パターン

退場処理漏れの温床になりやすい状態遷移を単純化

ページ読み戻り時の画面更新 pixiの表示ツリーをタグ順に組み直す storeを更新するだけ。Reactが差分だけ再描画

設計自体は本家から継承([page]タグは両方にある)。戻り先が近くても遠くても表示更新の仕組みは同じで済み、Reactの宣言的再描画が構造的に有利に働く。

3種の外部ライブラリを
自前実装に置き換え

ライセンス・保守・バンドルサイズを増やさない。
(描画・画面転換の置き換えは上記の通り)。

音声 howler等 Web Audio API直接制御
ジェスチャー判定 tinygesture等 自作 detectSwipe
型定義出力 vite-plugin-dts等 tsc標準機能のみ
100%SKYNovelタグの
移植カバー率

標準タグ121種すべてが実装済み。タグリファレンスの目次で 🟢/🟡/🔴 のマークとして実装状況を確認できる。

🟢 実装済み 121

ノベルゲームエンジンとしての立ち位置

特定製品との優劣ではなく、設計方針として有利になりやすい点を挙げる。

観点ノベルゲームエンジンで多いパターンBlueSNovel
実行方式 独自のバイトコード/インタプリタをアプリに同梱 ブラウザ・Node標準のJS/TSとしてそのまま実行
描画方式 Pixi.js/WebGL等、GPU前提のレンダラを内蔵 基本描画はCSS/SVGベース。GLSLシェーダ演出を使わない限りWebGLは不要
エンジンのテスト シナリオ処理がUI(DOM/GUI)と密結合で、実機確認に頼りがち エンジンをDOM/fetchから分離し、ヘッドレスで単体テストを自動化(1787件・全pass)
配布形態 プラットフォームごとに別ビルド・別管理になりやすい 1つのソースツリーからブラウザ版・Electron版を同時出力
型の保証 JavaScriptのみ、または型定義が後付け strict TypeScriptをソース全体に適用
Get Started

始める

まずは動くサンプルを触るのが早い。書き方はタグリファレンスへ。