👩‍🦰

JSでギャルゲー!~JavaScriptでノベルゲームエンジン作った~

に公開

この記事は、https://speakerdeck.com/endohizumi/jsdegiyaruge-javascriptdenoberugeenzinzuo-tutatuta の本を、元に、アドベントカレンダー用に、追記・修正したものです。

初めに

はいどーも、はじめましての方ははじめまして、ご存知の方はそうだよ。ヒズミさんだよ(「10割、はじめてだろ!」「全員じゃねーか!」)
趣味として、OSSでWebノベルゲームエンジンのWebTaleKitを開発しています。

出来たばかりで、まだ、知名度が低いので、名前を覚えていってくれたら、幸いです。
使った感想(@endo_hizumi)まで送ってくれると、泣きます。喜びでな!!

そもそものノベルゲームについて、簡単に説明すると電子紙芝居です。
画面の構成が、下の画像のような背景があって、キャラクターの絵があり、画面の下部に、文章が一文字ずつ出てくるものです。(最近だと、ソシャゲの会話パートの画面と言った方がわかりやすい?)
ノベルゲームの説明

WebTaleKitは、HTML+CSS+JavaScriptのWebフロントエンド技術でノベルゲームを作るソフトウェアです。
意外と、ゼロから作ろうとすると、文字表示の仕方・キャラの表示・セーブ&ロードの仕組みなど、ちゃんと既存のエンジン無しで作ろうとすると、技術者でもめんどくさい実装が多いのです。

開発経緯

ノベルゲームを作りたいなァ

ハァ… 困ったなァ

まさかここまで、既存エンジンの構文学習にやる気が出ないなんてェ…

本当はゲーム作りたいんだけど

もう疲れちゃって 全然動けなくてェ…

覚えるのがめんどくさいなら、自分で作っちゃえばいいかァ…

そんくらいのノリです。(趣味なんだし、自己満足上等!…でも、使ってくれると嬉しいな)
WebAudioで音を鳴らすことができ、Canvasで絵を描くことが可能。そして自分がJavaScriptのプログラマーなので、作ることが可能なんですね。
趣味なんですし、試しに作ってみよう。

大体、1年半後...
カタカタ...ターンッ!\デギダァ!!!/↓↓
https://github.com/EndoHizumi/webTaleKit/releases/tag/0.2.13

そんな横着モノが、技術力を持っていたがために、一年くらいで、基本的な機能を持ったアルファ版がリリース出来たわけですね。(正確には、2023年8月から構想を考えていて、ver.0.1リリースが2024年1月だから、半年も経ってない…マジで?計算ミスってない?設計からリリースまで感覚的には一年半くらいの気持ちなんだけど。)

特徴

特徴①:HTML で自由に UI を作れる

WebTaleKitのUI構成図 - HTMLとCSSでカスタマイズ可能なユーザーインターフェース
WebTaleKitは、ブラウザで動くことを利用して、ユーザーの操作する画面(=ユーザーUI)をHTMLとCSSで構成されています。
これにより、ゲーム開発者は、必要に応じて、画面をカスタマイズすることが容易になります。
また、ただのHTMLなので、デザイナーと分業することも可能です。
加えて、モダンフレームワークのVue.js/React/Svelteを駆使したリッチなUIも構築可能です。

特徴②:オートスケール対応

様々な画面サイズに対応するオートスケール機能の図
今の時代、ゲームの実行環境は様々です。
スマートフォン、タブレット、PC、さらには大画面ディスプレイまで。WebTaleKitのオートスケール機能は、あらゆる画面サイズで同じゲーム体験を提供します。

開発者は複雑なレスポンシブ対応を考える必要はありません。エンジンが自動的に最適な表示を実現します。

特徴③:環境構築が簡単


npm create tale-game your-game-title

たった1行のコマンド。それだけで、あなたのゲーム開発環境が整います。Node.jsさえインストールされていれば、WindowsでもMacでもLinuxでも、すぐに開発を始められます。
お手本用のサンプルゲームも同梱されているので、迷うことなく、ゲーム開発を始められます。

特徴④:とっつきやすい独自言語

<scene> 
    <scenario>
        <text>これは単純なテキスト表示です。</text>
        <text>テキスト内で{{variables}}のような変数を使用することもできます。</text>
        <say name="キャラクター">キャラクターには名前と立ち絵を設定できます。</say>
        <choice prompt=""></choice>
            <item 1abel="タイトルに戻る" onSelect="title"> 
                <route to="title" /> 
            </item>
        </choice>
    </scenario>
    <script>
    export const sceneConfig = {
      name: 'text',
      background: './src/resource/background/library.jpg',
      template: './src/screen/title.html'
    }
    export const variables = "HogeHoge"
  </script>
</scene>

HTMLライクで直感的。英単語ベースで理解しやすい。

    <text>これは単純なテキスト表示です。</text>

文字はこのようにすると、表示されます。

    <text>テキスト内で{{variables}}のような変数を使用することもできます。</text>
    <text speed="10">テキストは異なる速度で表示することができます。</text>
    <text speed="150">または、一文字ずつゆっくりと...</text>
    <say name="キャラクター">キャラクターには名前と立ち絵を設定できます。</say>
    <text><ruby text="ルビ">漢字</ruby>を振ることも可能です。</text>
    <text>
      <color value="red">文字の色を変えたり</color><b>太字にしたり</b><i>斜体にしたり</i>することもできます。
    </text>
    <text>改行も<br>簡単に<br>できます。</text>
    <text>また、テキストの表示中に
      <wait time="1000" />一時停止を入れることもできます。
    </text>

テキスト装飾もたっぷりありますよ。どんなこだわりの方でも大丈夫。
どうぞデコってみて下さい、いい出力でしょう。 余裕の絵だ、馬力が違いますよ。

<!-- 変数の設定 -->
<call method= "playerscore = 100" /> 

<!-- 関数の呼び出し-->
<call func="saveGame()"/>

さらに、JavaScriptのメソッドを直接呼び出せる柔軟性。
呼び出すJSは、npmパッケージも追加可能です。
あなただけに、世界作りにトコトンこだわってください。

<!-- HTTPリクエストの使用例 -->
<text get="https://api.example.com/data">
  <progress>データを読み込み中...</progress>
  <header>
    <content-type>application/json</content-type>
    <authorization>Bearer token</authorization>
  </header>
  <data>
    <query>example</query>
  </data>
  <then>データの読み込みが完了しました。</then>
  <error>データの読み込みに失敗しました。</error>
</text>

REST APIとの連携も属性一つで実現。
今の話題のChatGPTとの連携もこれで可能です。

<scene>
  <scenario>
    <say name="ナレーター">このシーンでは、様々なテキスト表示機能をデモンストレーションします。</say>
    <text>これは単純なテキスト表示です。</text>
    <text>テキスト内で{{variables}}のような変数を使用することもできます。</text>
    <text speed="10">テキストは異なる速度で表示することができます。</text>
    <text speed="150">または、一文字ずつゆっくりと...</text>
    <say name="キャラクター">キャラクターには名前と立ち絵を設定できます。</say>
    <text><ruby text="ルビ">漢字</ruby>を振ることも可能です。</text>
    <text>
      <color value="red">文字の色を変えたり</color><b>太字にしたり</b><i>斜体にしたり</i>することもできます。
    </text>
    <text>改行も<br>簡単に<br>できます。</text>
    <text>また、テキストの表示中に
      <wait time="1000" />一時停止を入れることもできます。
    </text>
    <say name="ナレーター">これらの機能を組み合わせることで、豊かな表現が可能になります。</say>
    <choice prompt="">
      <item label="タイトルに戻る" onSelect="title">
        <route to="title" />
      </item>
    </choice>
  </scenario>

  <script>
    export const sceneConfig = {
      name: 'text',
      background: './src/resource/background/library.jpg',
      template: './src/screen/title.html'
    }

    export const variables = "HogeHoge"
  </script>
</scene>

ビルドの流れ

これをtext.sceneとして、src/sceneディレクトリに保存します。
npm run buildを実行して、ビルドすると、次に示すhoge.jsというJavaScriptファイルに変換されます。
ビルド後のJavaScriptファイル(hoge.js)のコード画面

WebTaleKitのエンジンは、このJavaScriptファイルを読み込んで、ゲームを動作させます。

最後に

WebTaleKitは、プログラマーはもちろん、HTMLに慣れたデザイナーやシナリオライターにも優しい設計です。
ここで、紹介しているタグは、ほんの一部です。
他のタグなどは、参考URLから確認できます。

参考URL

DGBTテックブログ

Discussion