鳥小屋.txt

主に自作ゲームをつくったりしているよ。制作に関することやそうじゃないことのごった煮ブログ

入れ替えパズル『メモリーニミィ』を制作中です

『メモリーニミィ』

久しぶりのパズルゲームです。
『ウヌムマキナ』 以来なので、なんと3年ぶり!やば。

そんな久しぶりのパズルですが、中身はご安心。

  • 基本的にはメインとなるパズルをプレイ
  • プレイに応じて実績&ストーリーがアンロック
  • イメチェンもあるよ

うん!いつもの味です!こういうのでいいんだよこういうので。

入れ替えアクティブ連鎖パズル

フィールドの任意のブロック2箇所を選択&入れ替えて、3つ繋げるというベーシックなパズルです。ルール的にゲームオーバーが無いので、60秒の制限時間でハイスコアを目指すタイプのやつ。

が、今回はブロックの消去中にゲームが止まらず、消去中に次のブロックを動かせます。理論上は後づけ無限連鎖が可能です。

……つまり、めっっっっっっっっっっちゃ忙しいタイプのパズルですわね!

『ウヌムマキナ』はじっくり考えられるタイプだったので、今作は逆に1秒でも悩んだら終わりタイプにしてみました。代わりにワンプレイは短めなので、一気に集中してサクッとプレイする感じを目指してます。

怪文書みたいなポエム実績も健在

過去作『ウヌムマキナ』や『ホシトリの夜』同様に、実績にくっついている再生ボタンを押すことでミニエピソードが閲覧できます。今回は『ホシトリの夜』みたく、すべての実績にミニエピソードがついているので結構な数になりそうですね。総数はまだ未確定ですが、たぶん30個くらいになるかな?

まぁ、エピソード再生機能はまだ未実装なんでね。

本作は、教会の魔導師である少女ニミィが主人公のお話です。鳥小屋ポータRu(toRipota)作品ではときどき名前が出てくる『教会の魔導師』に関するお話になっています。

が、もちろん本作だけで独立したお話なので、他の作品をプレイしていなくても問題はないです!

制作進捗 in YouTube Shorts

そもそも

普段の僕は制作中のゲームの内容をあまり表に出していません。ある日、いきなり公開することが多いです。

これはみんなにサプライズをお届けしたいから……というわけではなく、僕は他人に言ってしまうと有言不実行になりがちだからですね……

↑の話は似たような話かもですね。「人に言いたかったら完成させろ!!!!!!」を自分に強いるしかない……みたいなところから、そういったスタイルになっていました。

まぁ、誰にも言ってないのに普通にエターなってるやつもあるんですけど。

このスタイルの弱点

一方で僕のこのスタイルの弱点として、広報活動に支障があります

本当にリリースできるその日まで人に言えないので、事前広報が一切できないです。

僕が超有名人で1ツイートしたら 1秒毎に9999無量大数<無量大数> リツイートされるなら別に良いんですけど、そういうわけではないので悩ましいところですね。

アツマールがあった頃は、アツマールの新着一覧とか、ニコレポ通知みたいな仕組みに助けられていた部分がありますが、今だとさすがにある日突然サイレントにリリースは厳しそうだなぁ……という気持ちがあります。

そこで YouTube Shorts(なんで?)

そんなわけで YouTube Shorts で週1更新で進捗報告を始めました(???)

いきなり意味不明に見えるかもしれませんが、

  1. 定期的な情報公開を
  2. 軽い気持ちで
  3. 今までやったことの無い方法でやりたい

というところから試しにやってみた感じです。

ひとまず一ヶ月ほどやってみていますが、実際これが良い手段なのかはよくわかっていません!!!!!!!!11111111

まぁ、何事も挑戦だね

そんなわけで

『メモリーニミィ』制作中です。今しばらくお待ち下さい。

制作進捗率としては、まだまだ入口のほうなので、時間はまだまだかかると思います。『ウヌムマキナ』のときは普通に制作1年以上かかったので、さすがにそこまで行かずに出せるといいなぁ……

イメチェン差分もまだぜんぜん描いてない~

かぼちゃ育成日記#12 - おかえりイヤリーズ!

ただいま!

ブラウザ版『空中遊戦イヤリーズ』公開しました

プレポタで『空中遊戦イヤリーズ』のブラウザ版を公開しました。

『空中遊戦イヤリーズ』は2014年に公開した横視点の2Dシューティングゲームです。Flashで作られており、かつてはWebで遊べるFlash版と、Adobe AIRを利用したAndroidアプリ版を公開しておりましたが、Flash の提供終了や Android のアップデートなどの影響で現在は遊べない状態になっていました (◞‸◟)

そんなイヤリーズが、公開から11年の時を経てブラウザ版として復活!

Ruffle

今回復活したイヤリーズは移植を行ったわけではなく、なんと当時の Flash のものが(ほぼ)そのまま動いています

そんな夢のようなことを実現してくれているのが Ruffle という Flash エミュレータです。

Ruffle はオープンソースの Flash Player として開発されており、ブラウザにプラグインなどをいれることなく Flash の swf ファイルを読み込んで再生することができます。やばい技術。

Stage3D

Ruffle 自体は結構昔からあり、Ruffle を使って現代に生き返ったゲーム達もたくさんあります。

が、イヤリーズは内部で Starling という Flash の Stage3D の機能を利用したライブラリを使っており、なかなか動かすのは難しいという背景がありました。僕が Ruffle を知ったころは、まだ Stage3D を動かすことは厳しく、イヤリーズの swf ファイルを読み込んでも未対応のエラーになってしまう状態でした。

定期的に Ruffle のページにアクセスしては、デモページにイヤリーズの swf ファイルを入れて動くか試す……みたいなことをしていました。

そして、ついに動く日が

そして、昨年の春頃に試したところ、ついにイヤリーズのゲームの本編が動くように!

……といっても「起動する」の意味で、一部要素がおかしくなっていたり、めちゃくちゃ重かったりという問題がありました。これは Ruffle が未対応だから……という理由だけではなく、そもそもイヤリーズの作り自体もかなり無茶になっていることが原因になっていました。

そこで、当時僕ができる範囲でイヤリーズ側を修正し、 Ruffle の Windows 版ではかなり良い感じに動くように調整しました。が、まだブラウザ版はかなり重く、フレームレートも10fpsを切るくらいしか出せない状態でした。イヤリーズ、まじで重すぎる……。

そこで諦めてしまっていたのですが、1年経った最近になって試してみたところ、Ruffle側が爆速になっており、同じ swf ファイルで普通にブラウザプレイが可能なくらいまで早くなっていました!すごすぎるだろ…!

こうして、ついにイヤリーズが復活することになったのです。

実はオリジナルと違うイヤリーズ

当時の ActionScript3 のソースコードを元に、一部だけいじっています。

  • 無駄な処理を一部置き換え
    • 去年 Ruffle で動くようにするためにやった調整
  • フレームレートを30fpsから60fpsに
    • Ruffleが爆速になったのでフレームレート上げてみた(なんで?)
  • 一部の行動や攻撃などのパラメータ調整
  • プレポタのクラウドセーブ / ランキングに対応

ActionScript3 内からの ExternalInterface.call が Ruffle でも動くので JavaScript 側と連携したりもしてみました。なお、 ExternalInterface を使う場合は Ruffle で埋め込み時にパラメータで許可する必要があります。このあたりは Ruffle のドキュメントに記載があるので、必要な人は見ておくと良さそうです。

おわり

正直な話、いま『空中遊戦イヤリーズ』を遊ぶとゲームとしては微妙なところがたくさんあります。操作性微妙だし、避けられないし、避けないで敵にゼロ距離で攻撃連打するゲームになってるし……。

ですが、それはそれとして、僕個人にとってイヤリーズは大事なゲームです。その頃の僕としては、初めてちゃんとしっかり複数ステージとかを作ったゲームであり、当時の僕の代表作でした。このゲームの制作経験は、のちの『天翔と剣のウィッチクラフト』 へと繋がっています。つまり、イヤリーズの存在は今の僕の制作に大きく影響を与えており、イヤリーズから貰ったものはたくさんあるんですよね。

そんなイヤリーズが動かなくなってしまったのは、僕としてはとても残念な状態でした。再び動くようになったのはとてもハッピー!

いろいろ古いし、ゲームとしては微妙なところもいっぱいあるけれど、それでも僕にとっては大事なイヤリーズ。今後ともよろしくおねがいします。

おまけ

なお、この記事のタイトルに「かぼちゃ育成日記」という名前がついていますが、これは当時の制作ブログ記事のタイトルにつけていたものです。イヤリーズカテゴリの記事一覧を見ると、当時の記事が見れます。

なつかしいにゃ~

『ニコ生早押しクイズセレクション』を公開しました

1ヶ月くらい前にね!(記事書くの遅すぎ)

『ニコ生早押しクイズセレクション』

そんなわけでクイズゲームです。ゲームというかツールなのか?

名前に露骨に入っているとおり、ニコ生ゲーム向けのやつです。生放送上で配信者が視聴者のみんなと早押しなクイズゲームをできる……みたいなイメージで作ったやつです。

自作クイズを出題しよう!

このゲームにはプリセットのクイズが入っていますが、プリセットだけではなく自作のクイズが使えます(パソコン配信のみ)

クイズのエディタどうしようかな~と思ったのですが、エディタ作るのも大変だし、僕がプリセットのデータを作るために作ってた Google スプレッドシートをもう少しだけ便利にしたテンプレートを公開して、それで作れるようにしました。

作るの面倒くさい~と思うかもしれません。その通りです。でも、僕もプリセットの入力を頑張ったのでキミも頑張ってください(意味不明)

選択肢、大変すぎる。

中身の話

@akashic-extension/coe

@akashic-extension/coe という公式のライブラリがあります。説明には以下みたいなことが書いてあります。

COE フレームワークは Akashic 上で共体験 (co-experience) を実現させるための拡張ライブラリです。 共体験は主に次の機能を提供します。

  1. Akashic コンテンツの容易なマルチプレイ化
    • 各ユーザからのメッセージの集計
    • 各ユーザに対するメッセージのブロードキャスト
  2. コンテンツ内で別のコンテンツを実行

この説明だと「おまえは何を言っているんだ」みたいな感じですが、 通常の Akashic コンテンツとの違い を見てみるともうちょっとわかりやすいです。

Akashic Engine のマルチプレイは「全プレイヤーの操作を全プレイヤーに同期する」みたいな理屈で動いていますが、この @akashic-extension/coe を使うと、プレイヤーの操作が一旦サーバーに送られ、サーバーでゴニョゴニョしてから全プレイヤーに配信したりしなかったりができるようです。

なので、例えばプレイヤーがクイズの回答を送信し、サーバーで採点してからみんなに「Ruたんさんは正解で1234点でした」みたいな情報を配信する……みたいなことができる感じ。

代わりに操作の自動同期が一切行われなくなるので、そのあたりも全部自分で管理する必要が出てきます。普通に大変。

なので、ゲームというよりはツールとかに向いてる気がしますね。ゲームの場合だと、公式の「みんなでつりっくま」みたいな個人戦のやつはいいのかも。

内部的には Game#addEventFilter を使って制御しているみたいです。こんなことできるんだ~、みたいのがわかって普通に面白かったです。 @akashic-extension/coe 自体のコード量はかなり少なくて AkashicEngine 探検隊みたいになった。

g.game.onJoin in ニコ生

これ、まじで悩んだのでブログに書いとく。

ニコ生ゲームにおいて、プレイヤーが join しているかどうかを見ることで配信者なのかどうかを判定することができます。join イベントが発火すると g.game.onJoin が呼ばれるのでそこで拾うか、g.game.joinedPlayerIds を見ることで判定することができます。

が、 @akashic-extension/coe を使っているとき……もとい、 new g.Scene({ tickGenerationMode: 'manual' }) をしているときは注意が必要です。

おそらくなのですが、ローカル動作確認用の akashic serve とニコ生では join イベントが発生するタイミングが若干違います。多分ニコ生のほうがタイミングが遅いです。

遅いと言っても、別に何秒も遅れてくるわけではなく本当に一瞬違うくらいなので通常ゲームは概ね問題なさそうです。一方で @akashic-extension/coe を使うとマルチプレイゲーム内の「時間の流れ」という概念が無くなるので、onJoin を待っていても一生来ません。配信者判定をする処理を一番最初に入れていたので、ニコ生上だと何も動かなかった……。

なので @akashic-extension/coe を使う場合は、ゲーム開始後にサーバー( Controller )から何かしらのデータを broadcast して世界の流れを自分で進めてあげる必要があります。こうすると、そのタイミングで onJoin も一緒に流れてくるので配信者判定ができます。

// イメージ
class MyController extends COEController {
  constructor(param) {
    super();

    this.setTimeout(() => {
      // 開始したあとにテキトーなデータを broadcast しておく
      // こうすることで、このタイミングで `Game#onJoin` も一緒に発火する
      this.broadcast({type: 'ping'});
    }, 500);
  }
}

ニコ生でしか起きないから調べるのめっちゃ大変だった……10個くらいゴミみたいな確認サンプルをアップロードしてしまった。

自作クイズ

自作クイズの読み込みどうなってんねん!というのも書いておきます。

あれの正体は単純に <input type="file"> です

const sprite = new g.Sprite({ /* 略 */ });
sprite.touchable = true;
sprite.onPointDown(() => {
  try {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = '.json';
    input.click(); // ファイルダイアログを開くよ
  } catch (e) {
    // アプリとかは動かない可能性高いので catch して握りつぶす
  }
});

良きタイミングで <input type="file"> の DOM を作って、それを開かせています。なのでスマホアプリからの配信とかでは動かないです。Webページじゃないしね。

選ばれたJSONファイルを読み取って、それを zod でチェックして使う……みたいなことをしています。

設問文の表示

例えば以下の図。どちらが読みやすいでしょうか。

上の表示だと読みづらいですよね。設問文が1行で収まらないときの改行位置をどこにするのか、というのはそこそこ重要です。

すべてのクイズを僕が管理するのであれば、僕が1問ずつ目視で確認して、いい感じの位置に改行をいれるという方法も考えられるかもしれませんが、本作は自作クイズの仕組みがある以上、そういうわけにはいきません。このあたりは作問者ではなくゲーム自体が仕組みとして何かしらの手段を取る必要があります

今回は Google の budoux を使いました。

budoux を使うことで日本語などの文章の改行しても良さそうな部分を推定してくれます。いわゆる「今すぐダウンロー(改行)ド」みたいのを防ぐことができます。

import { Parser, jaModel } from 'budoux';

function parseChunkFromText(text: string) {
  const parser = new Parser(jaModel);
  const chunks =
    parser.parse(text)
      // 英文などスペースを途中に含む場合はスペースで分割する
      .flatMap((chunk) => chunk.split(/( +)/).filter((part) => part !== ''));

  return chunks;
}

parseChunkFromText('Cygamesが運営する、実在の競走馬をモチーフとしたスマートフォン向けゲームは?');
// => [
//  "Cygamesが",
//  "運営する、",
//  "実在の",
//  "競走馬を",
//  "モチーフとした",
//  "スマートフォン向けゲームは?"
// ]

こんな感じで文章を塊ごとに分割できるので、この区切りの部分で改行するように設置してあげています。

もちろん、この仕組みだけだと設問文の最後の「何?」みたいな部分だけ2行目になっちゃうなどの難点はまだありますが、まぁまぁ自動で行われる処理としてはいいところなんじゃないでしょうか…!

おわり

ニコ生早押しクイズセレクション、よろしくおねがいします!

クイズ作るのちょっと大変すぎるのでなかなかハードルあると思いますが、きっと楽しいと思うのでぜひチャレンジしてみてください。が、大量に問題作るのは本当に大変なので、まずは1回プレイできる7問でいいんじゃないかな。

ところで……

実は本作、だいたい3年前に作ってたゲームだったりします。

作るのに3年かかったわけではなく、ほぼ完成してたのに3年放置した、という意味です。なんで。
(時期的にはパズトリの後、ハインダッシュの前)

クイズシーンがほぼ作り上がって、あとはエントリー画面とか結果画面を作れば完成だな!というところで力尽きて放置しちゃってました……それを今年の1月11日に掘り起こしてゴニョゴニョしたり、ロゴ作ったりして1月17日に公開しました。つまりあと一週間頑張れば完成したものを3年も放置してたってことですね!マジでなんで!!!!!111111

いや、本当にゲームを「完成」させるのって難しいんですって……

たかが一週間、されどその一週間の作業を乗り切るためのモチベーション、パワー、そしてヒラメキ、これを揃えられなくてエターなっていくゲームが多数あると言われています[要出典]

でも、本作みたいに3年後に突然覚醒して何とかなることもあるので、みんな奇跡を信じてゲーム作っていこうな! 奇跡駆動開発!!

地下ドールのチャンプ戦の仕組み

【注意】結局のところ、真面目にツクールを使ってる多くの人にとっては参考になりません。ただの腕力による力技なので。

どういうわけか?

こういうマシュマロ をいただきました。

単純な疑問ですみません。
ツクールで非同期対戦ゲームをご制作されているかと存じますが、どのように作られたのでしょうか?
はたまた、プラグインでそのようなものかあるのでしょうか?

僕の作った非同期対戦ゲームとしては、以下の2作品があります。

今回は質問されている『憎悪の獣の地下ドール』にフォーカスして、その仕組みを解説してみます。

前提

まずは『地下ドール』の概要です。わかっている人は飛ばそう!

『憎悪の獣の地下ドール』とは?

『憎悪の獣の地下ドール』は、2019年1月にゲームアツマールで公開したRPGツクール製ゲームです。公開当初はRPGツクールMVで制作し、2021年にMZに移行しました。 ※注:エンジン移行は地獄なのでおすすめしません。セーブデータの互換性も含めて大変です。

本作の特徴は以下の通りです。

  • 50体以上のキャラクター(ドール)から2体を選びパーティを編成
  • スキルや能力強化スロットを設定
  • 他のプレイヤーが作成したパーティと非同期で対戦

戦闘は完全オートバトルで、プレイヤーは戦闘中に一切の操作をしません。非同期対戦とするためにも、リアルタイムな操作は不要なゲームシステムにしています。

チャンプ戦

本作の目玉機能は『チャンプ戦』です。

  • 1人のプレイヤーが「チャンプ」としてサーバーに登録
  • 他のプレイヤーは挑戦者としてチャンプに挑む
  • チャンプに勝利すると新しいチャンプとなり、他プレイヤーの挑戦を受ける

この仕組みは、2000年頃のCGIゲーム『FF Adventure(Free Fight Adventure)』が元ネタになっています。

本題:チャンプ戦の仕組み

ゲームアツマールのAPI

今は亡きゲームアツマールでは、様々な機能が利用できるAPI機能が提供されていました。地下ドールのチャンプ戦で特に重要だったのが以下の2つです。

共有セーブ

共有セーブ機能は、他のプレイヤーが閲覧可能なデータを保存する仕組みです。

  • 保存されるのは共有専用のデータで、通常のセーブデータとは別に保存
  • 他プレイヤーはデータの「読み取り」のみ可能で、変更や更新は不可

シグナル

シグナル機能は、ユーザー間で小さなデータをやり取りする仕組みです。イメージとしては、以下のようなデータが保存されます。

2025/01/05 00:13 に Aさんが「●●」を送信
2025/01/04 22:47 に Bさんが「▲▲」を送信
2025/01/04 18:28 に Cさんが「★★」を送信
...

シグナルには以下の2種類があります。

  • グローバルシグナル:全プレイヤーが登録・閲覧可能(例:掲示板のような仕組み)
  • ユーザーシグナル:登録は自由だが、閲覧は指定された相手のみ(例:メールのような仕組み)

チャンプ戦を共有セーブとシグナルで実現する

チャンプ戦の仕組みは、これらのAPIを組み合わせて実現しています。

共有セーブで編成データを管理

地下ドールでは各プレイヤーが、自分のパーティ編成を共有用セーブデータとして保存するようにしています。このデータを他プレイヤーが取得することで、その人のパーティ編成を再現することが可能になります。

他にも戦闘開始前のセリフやキャラクターの見た目(イメチェン機能のデータ)なども、共有セーブの中に保存されています。

グローバルシグナルでチャンプを管理

チャンプに勝利したプレイヤーが、勝利のタイミングで「私がチャンプです」というデータをグローバルシグナルに登録しています。これによって、他のプレイヤーは最新のシグナルを取得することで、現在のチャンプが誰なのかを判別できます。

つまり、以下のようになります。

  1. プレイヤーが共有セーブ機能でパーティ編成を保存
  2. グローバルシグナルを取得して、現在のチャンプを判定
  3. チャンプの共有セーブデータを取得して対戦
  4. 勝利したら、グローバルシグナルに自分がチャンプに勝利したことを登録

実際には勝利数カウントなどのためにもう少し操作をしていますが、大まかな流れはこのようになっています。

現在の地下ドール

上述の仕組みは、2023年6月までのゲームアツマール上で動作していました。しかし、アツマールが終了した現在では、同じAPIを利用することはできません。

これを何とかするため、僕はアツマールの共有セーブとシグナル機能を再現するサーバーを作りました

  • アカウント登録機能
  • 共有セーブ
  • シグナル(グローバルシグナル・ユーザーシグナル)

などの機能を用意しています。このシステムを僕が借りているサーバーで動かして、プレポタやPLiCy上から呼び出しています。

つまり?

  • 地下ドールの非同期機能は、ゲームアツマールのAPI機能を利用していました
  • アツマール亡き現在は、アツマールのAPI機能のうち必要な部分を再現したサーバーを自分で作って動かしています

というわけで、非同期対戦機能の実現は、かなりの力技でゴリ押しています……!
なのであまり他の方の役には立たないですね……(◞‸◟)

なお、編成まわりの仕組みなどは過去に以下の記事にまとめています。興味があればご確認ください。

おまけ:サーバーを作らない手段

サーバーを自作・運用するのはコストや管理面で大変です。代替案として、Googleスプレッドシート+GAS を活用する方法もありそうです。

上記プラグインでは、GoogleスプレッドシートとGASを組み合わせ、ランキング機能を実現しています。この方法を応用すれば、サーバーを自前で用意せずに機能を実装できるかもしれません。

まぁ、それがラクなのかどうかというと、別にラクではないと思いますが……><;

『憎悪の獣の地下ドール』v.5.1 でのチャンプのドール・スロット使用率調査

やぁ、久しぶりだね!

そんなわけで、憎悪の獣の地下ドール にてチャンプ(Sランク)になった人が使っているドールやスロットの調査レポートです。約3年ぶりの開催。

前回 まではアツマール版で集計を行っていましたが、今回からは PLiCy版 & プレポタ版 での集計になります。PLiCy 版とプレポタ版のチャンプ戦は中身(サーバー)が繋がってるため区別はありません。

※お約束
こっそり集めていたチャンプのデータを利用しています。
とはいえ、ちゃんとした統計データを作れるほどしっかりしたデータは取ってないので雰囲気で!
集計期間は、2024年8月~この記事の執筆開始までです。テキトーだね。

参考:前回(2022年1月19日)

調査1:チャンプが使っているドール

チャンプになった人の編成に入っているドールを調べたものです。「10%=チャンプの10人に1人くらいの割合で使っている」みたいなイメージ!

なお、同じ人が同じ編成で何度もチャンプになったりしているものは、集計が偏るのを防ぐために、それっぽく省くようにして計算しています。

地下ドールv.5.1ではドールは全54種類です。また前回同様に専用スロットを持つ2ドール( [憎悪の領主] ハイン:7種 / [案内人] アムル:3種) は専用スロットごとに別ドールとして集計しているため、全62種のランキングになっています。

それでは早速、上位25件をご紹介します。また、参考情報として前回調査時の順位&使用率も載せています。

こんな感じになりました。以下はRuたんの雑ポエム。

新ドールについて

前回の集計以降に増えたドールの中では、[狂人カード] ひより [狼カード] つゆ の2ドールと、 [憎悪の領主] ハイン(フェアリーコア) が上位に入っていました。

[狂人カード] ひより

[狂人カード] ひより は固有スキルでバッドステートをランダム2つ付与という異端なスキル持ちです。ランダム故に運要素は絡んでしまうものの、地下ドールのバッドステートは回復手段が限られているため、使い方次第ではとても協力です。

[受付人] アムル(グリーンハート)[ふしぎの筆] ありさ などと組み合わせた、毒+耐久パーティなどでも使われていたようです。

[狼カード] つゆ

[狼カード] つゆ は、2ターンかかるけど大ダメージを与えられる固有スキル『夜の襲撃』を持っています。基本威力が 100 で、相手が出血状態の場合は威力が2倍になるため、うまく使えば相手を一撃で落とせる超火力アタッカーになります。

[狂人カード] ひより に出血を付与してもらったり、 後述の [憎悪の領主] ハイン(フェアリーコア) との組み合わせが良く、新ドール同士での相性が良かったことも採用率が高くなった要因かも。

[憎悪の領主] ハイン(フェアリーコア)

[憎悪の領主] ハイン の新コアスロット フェアリーコア です。装備させると特殊演出として名称が [進行役] ハイダー になり見た目も変わります。ちなみに内部処理的には [夏ゾンビ] ネクリア の固有スキル用の処理を流用しています。ナニソレ!ネクリアちゃんのパクリじゃない!!

味方に2回行動を付与する固有スキルによって、動きの遅いドールを支援する使われ方がメインです。前述の [狼カード] つゆ のほか、 [箱の魔導師] レヤック の『コンセントレーション』→『七星の雷』を加速したり、 [VLiver] メイディ の『電子の熱狂』を開幕2ターンで最大強化状態まで持って行くなどの採用例が多かったです。

ところで新ドールの男共は……?

なんと使用率最下位でした。ちょいちょいちょい~~!

[村人カード] ユーシ は出血状態になると逆に回復してくみたいなユニークな使い方ができるのですが、それがチャンプ戦に刺さるかはまた別という感じですねぇ。

[占い師カード] マドヤ[天翔の少女] チリールーフ との組み合わせを期待しているドールですが、そもそもチリーとルーフが下位なので……><;

↑ 集計結果を見て、あわててユーシ君でチャンプを取りに行く作者の図。

利用率が急上昇したドールたち

今回、プラットフォームが変わったことや、前回から年数が経っていることもあって順位がだいぶ変動しています。その中でも利用率(採用率)が大きく増えたドールでいうと、

  • 3位: [疾風の銃士] ルーフェ (4.55% → 9.31%)
  • 12位: ヌノー (2.53% → 5.59%)
  • 16位: [抜刀巫女] るいす (0.51% → 4.26%)
  • 21位: [マジシャン] とらん (1.26% → 2.93%)

あたりでしょうか。

特にこれらのドールについて、何か大きな変化があったわけではないため、プラットフォーム変化によるプレイヤー層の変化みたいなところや、年数が経ち流行が変わったことで動きが出てきている部分かもしれませんね。

逆に利用率が落下した子たち

  • 27位: [地下サマー] ハイン (5.56% → 2.66%)
  • 35位: [巫女サマー] マール (4.55% → 2.13%)
  • 37位: [守護天使] ノルト (5.56% → 1.86%)
  • 49位: マミン (2.78% → 1.06%)
  • 49位: ユンシャ (3.54% → 1.06%)
  • 58位: エンジェルアーチャー (3.28% → 0.27%)

基本的には前回上がってたドールたちがまた下がった、みたいな感じなので、単にブームが終わって安定したという感じに見えます。

マミンなどの星3ドールは元々尖った性能になるためチャンプ戦での使い方は難しいと思いますし、このあたりは仕方ない部分かもしれませんね。刺さる組み合わせはあるけど、向き不向きがだいぶある。

ハイン&アムルの専用スロット別

[憎悪の領主] ハイン

ハインの専用スロットも増えましたねぇ。ということでハインのコアスロットの人気は以下の順でした。

  1. フェアリーコア
  2. キングコア
  3. ルークコア
  4. ボーンコア
  5. ナイトコア
  6. クイーンコア
  7. ビショップコア

ボーンコアに負けてるスロットたち、だめでしょ!

ボーンコアは初期スロット扱いでステータス合計値は他のスロットより低めなんですけどねぇ。ボーンコアに負けてるスロットたちは、ちょっと使い勝手が難しいのかもしれません。

[受付人] アムル

なんと集計範囲内に グリーンハート 以外の採用がありませんでした! 使用率0%!

固有スキルの『魔法素の救済』が緑以外だと微妙になってしまっているので、『魔法素の救済』はグリーンハート専用にして、他のスロットは別の固有スキルにしてしまったほうが良かったかもしれませんねぇ。

調査2:チャンプのドールのスロット装備率

チャンプの人が装備してそうなスロットを調査したものです。こちらも「10%=チャンプの10人に1人くらいの割合で使っている」みたいな感じ。

なお「装備してる個数」じゃなくて「装備しているかどうか」を調べたものです。体力増強を4個積んでたとしても1点としてカウントしています。

こっちは多少の変動はあれど、そこまで極端ではないですね。

『コンセントレーション』が増えたりしているのは [箱の魔導師] レヤック が伸びたから、みたいなところかな?

以上

前回、「一旦ドール・スロットの追加は打ち止めなので~」とか言いつつ、さらなる新ドールが増えての集計でした。アツマールでの集計じゃなくなってしまったので若干集計のされ方が今までと違う部分もあり単純に比較はできないのかもしれませんが、まぁまぁそれっぽい傾向が出て面白いですね。

地下ドールの今後

ちょっといろいろ考えています。

地下ドールは僕自身愛着もあるゲームですし、アツマール時代は僕のゲームの中で一番遊んでもらえたゲームでもあるので、これからも大事にしていきたい気持ちがあります。来月でついに公開6周年ですしね。

一方で、だいぶ増改築を繰り返した状態でもあるため、ここにさらに要素を足したりすると、既存のプレイヤーさんも新規のプレイヤーさんも困惑するような状態にはなるだろうなぁとも思っており、現実には今の地下ドールに何かを足すことは難しいだろうとも思っています。システム的にもかなり無茶しているので、新機能(特殊な効果のスキルなど)をいれるのも難しい。

僕的には 地下ドールを遊んでる人が他の人にオススメしやすい状態 みたいな状態を作りたいなぁと思っているため、来年はちょっとその辺り考えて何かできたりしたらいいなと思っています!

予定は未定!来年のRuたんに任せた!(投げっぱなし)

Steamでフリーゲームを公開して1年経ったので色々まとめてみた

2023年の10月10日に『貴方が狼カードデス!』というゲームをSteamで公開しました。無料のゲームです。

Steamでフリーゲームを公開するのは、僕としては実験的な意味合いもありました。約1年経った今、得られた数値や学びを振り返ってみようと思います。

Steam でフリーゲームを公開した経緯

僕はもともと ゲームアツマール での活動を主体としていました。

『貴方が狼カードデス!』も当初はゲームアツマールでの公開を予定して作成していましたが、制作中にゲームアツマールのサービス終了が発表され、今後の活動方針や公開場所について悩むことになりました

そして『貴方が狼カードデス!』については、一旦は2023年2月にブラウザ版(PLiCy)とスマホアプリ版(AppStore/GooglePlay)をリリースしました。

しかし、今後の活動の方針を考える上では、様々なプラットフォームについての知見や感覚を抑えておくのは重要だと考えました。PCゲームのプラットフォームとしては、やはり Steam は無視できない存在であり、多くのプレイヤーにリーチできるという大きな魅力があります。

一応、過去にコミケで出したゲームを Steam に出したことはありましたが、当時はよくわからないことが多く「とりあえず出せただけ」状態でした。そのため、今回はもう少しいろいろ調べた上で再挑戦してみようと決意しました。

数値で見てみる

Steam とそれ以外のプラットフォームでどういう差が出るのかを感じてみるため、数値で各プラットフォームの比較をしてみます。

2024年9月末ごろの各プラットフォームの数値

プラットフォーム数値
Steamライブラリ追加数:27,985
ユニークプレイヤー数:1,802
iOS(AppStore)ダウンロード数:6,610
Android(GooglePlay)ダウンロード数:1,406
PLiCyプレイ数:5,648
ゲームアツマール
(2023年6月閉鎖)
プレイ数:5,429

こう並べてみると、 Steam のライブラリ追加数が際立って見えます

一方で、Steamで 実際にゲームをプレイしているのは約1,800人(6.4%)です。無料ゲームということもあり、多くの方はとりあえずライブラリに追加しておき、気が向くまで寝かしている状態のようです。僕も有料のゲームすらたくさん積んでる。

ところで Steam には実績機能があり、プレイヤーの実績獲得率が公開されるようになっています。

これを見ると、プレイした人のうち半数以上がエンディングを見ているということがわかります。1800人の半数以上と考えると驚きです。僕の感覚ではフリーゲームのクリア率なんて1割くらいかな、と思っていたため、これは本当に衝撃でした。

余談:iOSとAndroid

今回の主題からは少し逸れますが、今作は何故か iOS 版のダウンロード数が Android 版より遥かに多いという状態になっています。過去に公開したゲームでも iOS と Android でここまで差が出ることはなかったので正直謎です。

ストアの掲載アルゴリズムとかの影響なのかな……?

Steamでの公開で得られたこと

今まで届かなかった層にリーチできた

Steam経由で遊んでいただいた方々の感じを見ると、プレイヤーの大半は僕のゲームを今まで遊んだことない人っぽい感触があります。僕はブラウザゲームのプラットフォームでの活動が中心だったため「PCゲームをよくやる人たち」との接点が得られたのは大きな収穫です。

また、今回Steam版の公開のタイミングでいくつかのメディアさんにプレスリリースを送ったところ、記事を掲載していただけたことも大きな要因かもしれません。

ゲーム実況の増加

Steamでの公開後、実況動画が増加しました

単にデスゲームというジャンルが実況向きであることもあるでしょうが、ブラウザ版よりPC版のほうが実況がしやすいという理由もあるかもしれません。

また、そこそこ視聴数があるライブ配信とかで実況されたタイミングでスマホ版のダウンロード数がちょっと増えている気がします。

たしかに動画の視聴者はPCゲーマーじゃない可能性高そうなので、そこで知った人の着地先はSteamじゃないのかもしれませんね。

公開作業はやっぱり大変

Steamでのゲーム公開はやはり作業が多いです。ストアページの設定や画像、ゲームの審査、場合によってはSteamの中の人とメッセージでのやり取りが必要になることもあります。

ただ、このあたりは慣れなのかもしれません。実際、今回はSteamで出すの2回目だったこともあり、ストアページの審査については、特に問題なく進めることができました。

「Steam完全に理解した!」になるためには、あと何作リリースすればいけるんだろうか。

レビューのアイコンが怖い(?)

このアイコン、見ると心臓がビクッとするんですけど、怖くないですか!? なんで真っ赤なの!?

レビュー自体はありがたいのですが、このアイコンが本当に怖い。Valveちゃん、なんとかならんか……!?

次やるとしたら?

今回の学びを経て、「次やるならこうかな?」と思ったことをまとめてみます。

事前準備はやっぱり大事

掲載情報や画像を大量に作る必要があるため、事前にそのあたりは念頭に置いて準備しておくのが良いですね。

今回、Photoshopのアートボード機能 を使っていろいろなサイズの画像を用意してみたのはうまくいったので、そういったツールも活用していきたいです。

なお、Steam に限った話ではないですが、ストアに掲載する画像などにおいては過激な表現とかは注意を払う必要があります。『貴方が狼カードデス!』は題材がデスゲームという関係上、血の表現が入ったスクリーンショットは使わないなどの注意をしていましたが、Google Play においてはアイコンで審査NGになりました。

たしかにね。。。

メディアのお世話にはなろう

今回、プレスリリースをメディアの方々に送ったところ、いくつかのメディアで記事にしてもらえ、それが大きな助けになりました

僕自身には発信力があるわけではないため、このあたりは力を借りることができると非常に助かります。

なお、実際に送ったプレスリリースの内容は以下のものです。これらをPDFやZIPなどにしてメールなどでお送りしていました。10社ちょいほど送ってたはずです。

なお、プレスリリースの作成にあたっては、ChatGPTくんのお世話になりました。真面目で正式っぽい文章の場合、言い回しとか、重複表現とかを指摘してもらえると助かる。

遊んでもらうための手段を考える

無料ゲームとはいえ、積みゲー率94%は課題ですよね……!

無料という部分で気軽にポチはしてもらえるかもしれませんが、やっぱりそこから一歩踏み込むための工夫は必要そうです。実際にすぐ触ってみたくなるような何かとか考えられると良いけど……うーん、むずい!

現代のゲームは『体験』が非常に重要だなというのは日々感じていることなので、そういった部分を意識して考えていきたいところです。

おわり

Steam でのゲームの公開には100ドルほどかかります。フリーゲームだと1円も売上にならないため、100ドルは完全な出費になりますが、それでもいろいろな経験ができたため、挑戦してよかったと思います。

一方で、やっぱり Steam での公開はカロリーが高いなという気はします。少なくとも年に何本もSteamで出す!とかはちょっとしんどそう。

メインの戦場として Steam だけで生活していくのは僕には難しいかもですが、また別の機会で挑戦はし続けていきたいですね!

『パズトリ』のCPUプレイヤーの中身の話

たまには開発ブログみたいなことしてみる。

前提:対戦!連鎖パズル『パズトリ』

僕が作った落ち物パズルです。 AkashicEngine で作られており、ニコ生上で最大21人のオンライン対戦ができます。

で、オンライン対戦はいいのですが、1人で遊ぶときにも対戦相手がいないと困ります。そのため、このゲームでは対戦用のCPUプレイヤーを実装しています

この記事は、パズトリのCPUプレイヤーがどういう仕組みなんだっけ?という記事です。

パズトリのCPUプレイヤーの仕様

パズトリのCPUプレイヤーはタイマン戦のみ実装しています。

CPUプレイヤーは難易度別に存在しており、「よわい」「ふつう」「つよい」「ヤババ」の4種類がいます。「ヤババ」は「つよい」を倒すと出てくるオマケモードです。

つまり4つのCPUルーチンが実装されている……というわけではなく、実はルーチン自体は1つしかありません。ルーチンは1つだけでパラメータ違いで4種類いるという仕組みになっています。

パズトリCPUのパラメータ

パズトリCPUには大きく分けて以下の4種類の設定があります

  • 目標連鎖数
    • そのCPUが目指す連鎖数
    • この連鎖数に至るまでは、なるべく連鎖を伸ばす
  • 最大連鎖数
    • そのCPUの指し手として採用可能な最大連鎖数
    • この連鎖数を超える手はなるべく採用しないようにする
      • が、どうにもならない場合は選択されることもある
  • 操作にかかる時間
    • ブロック落下操作開始までの待ち時間
    • スワップ(ブロック入れ替え)をする場合は追加でどのくらい遅くするかなども設定する
  • 指し手選択の失敗率
    • 最終的な指し手選択をする際に選択を誤る確率(後述)

具体的なパラメータは以下のような感じになっています。

目標連鎖数 最大連鎖数 操作にかかる時間 指し手選択の失敗率
よわい 1 3 60~120フレーム
スワップ遅延:60フレーム
50%
ふつう 3 5 45~90フレーム
スワップ遅延:40フレーム
10%
つよい 4 制限無し 20~60フレーム
スワップ遅延:20フレーム
5%
ヤババ 5 制限無し 0~40フレーム
スワップ遅延:5フレーム
0%

こう見ると、ヤババはだいぶズルですね……最短0フレームって……

CPUルーチンの基本

基本的には「脳内で落下させてみて、その状態の良し悪しを判定し、一番良さげなやつを選ぶ」という仕組みです。普通だね。

パズトリのCPUルーチンでは、「確定指し手」と「暫定指し手」という2つの指し手を計算します。

  1. 一手目(ネクスト)を計算する
    • この時点で最大連鎖制限を超える手は除外する
    • 目標連鎖を超える OR 状況が危険な場合はこの時点での最終スコア判定をして、確定指し手一覧に登録
    • そうでない場合は、2手目を計算する
      • ここで最大連鎖制限を超える手は除外する
      • 目標連鎖を超える OR 状況が危険な場合はこの時点での最終スコア判定をして、指し手に登録
      • 未達&危険でない場合は、暫定指し手一覧に登録
  2. 指し手の選択
    • 確定指し手がある場合は確定指し手の中から、ない場合は暫定指し手の中から一番良いものを選択する
    • ただしCPUの選択ミス率が設定されている場合は、確率でテキトーに指し手を選択する

大きく分けてこの2ステップの処理が行われています。なお、実際の実装は処理負荷の関係もあり、もうちょっと細かくステップを分割しています。

CPUのスコア判定

先ほどのルーチンの中で「スコア判定」という言葉が出てきましたが、ここで言うスコアはゲーム中に表示されているスコアとは完全に別のものです。CPUのためだけに定義している内部的な値です。

具体的には以下のような値をもとに計算をしています。

  • 連鎖数によるスコア
  • 消せるブロック数によるスコア
    • 連鎖とか色とか関係なく数だけ見る
    • つまり、同時消しかどうかは見てない
  • フィールドの形状によるスコア
    • ど真ん中に積み重なったりしてると減点
  • 2個以上つながってるブロックの数によるスコア
    • たくさんあったほうが連鎖しやすい
  • 次のブロックを置いたときに連鎖数が伸びるかによるスコア
    • 実際のネクスト表示のブロックではなく、4色それぞれを調べる
      • 実は5色目のピンクの飴を考慮してない
      • 意図的ではなく、僕の実装ミス><;

指し手ごとにこれらの値を合算した評価用のスコアを計算し、良いものを選択しているわけですね。つながったブロックや、連鎖数が伸びることにスコアを与えているので、パズトリのCPUは基本的に連鎖をどんどん作ろうとする動きをします

ここからわかるパズトリのCPU

以上がパズトリのCPUの仕組みです。ここから以下のような特徴がわかります。

相手のフィールドを一切見てない

パズトリのCPUのルーチンの中には相手のフィールドの概念がありません。そのため、いわゆる「潰し」みたいな駆け引きをする能力がないです。

同時消しと5色目が弱点

実装的に同時消しを考慮してブロックを配置していくことができません

パズトリのスコア計算式は色数ボーナスが強いため、同時消しは非常に重要です。それが狙えないというこの部分は明確に人間より弱い部分になっているため、CPUに付け入るチャンスがあります。

また、実装上の不備が原因で5色目のピンクの飴のスコア評価がうまくできていません><;
なので2分以上経つとCPUは若干弱くなっていきます。

このあたりをうまく突くと、ヤババを倒せるかもですね!僕は倒せてないが。

「よわい」でもたまに強い場合がある()

ルーチン自体は一緒でパラメータ制限があるだけなので、場合によっては大連鎖が飛び出してしまう場合があります。特にパズトリはフィールドがそんなに広くないこともあり、どこ置いても連鎖になってくるような状態になると、大連鎖の手を選んでしまうケースがあります。

……許してね(てへぺろ)

以上

そんなわけでパズトリのCPUプレイヤーの中身についてでした。

落ち物パズルのCPUは昔書いたことがあり、そのときとあんまり変わらない非常に愚直な実装です。もっと頭良く書いてあげればいろいろなことできると思うけど、僕にそこまでのロジカルが無かった!!

また似たようなゲーム作る機会があったら、この経験を活かしてもうちょっと面白いCPUプレイヤーを作ってみたいですね。

おまけ:最強のCPUプレイヤー

パラメータを全部全開にしたデバッグ用のCPU、 [MAX] ルエルマ というデータがあります。

  • 目標連鎖数:10
  • 最大連鎖数:制限無し
  • 操作にかかる時間:0フレーム(スワップ遅延0フレーム)
  • 指し手選択の失敗率:0%

つまり、このCPUプレイヤーの実装での限界の状態ですね。

これは普通にズルなのでゲーム内では戦えません。なんなんだこいつ!

『そらとび大作戦!』を公開しました

来たぜ、公開しました記事!

『そらとび大作戦!』

久しぶりの新作ゲームです。
60秒の時間制限でハイスコアを目指すSTG風のゲーム!

画面をタッチした場所に移動するので、うまい位置取りをしつつ、スワイプのレーザー攻撃や、一度だけ打てる必殺スキルを駆使してコンボを増やしてハイスコアを目指そう!……という感じのゲーム。

AkashicEngine製なので、ニコ生ゲームで遊ぶことができます。……が、この記事を書いてる時点ではニコ生が使えないので遊べない、悲しすぎる(◞‸◟)
→ ニコ生で遊べるようになったので遊んでくれ!!!!!!

プレポタおよびPLiCyで公開しているので、今はぼっちプレイを楽しんじゃってください!

イヤリーズ再び!

本作のロゴにあるとおり、サブタイトルが『ザ・フライトミッション・オブ・イヤリーズ』となっています。

空中遊戦イヤリーズ(2014年)

イヤリーズというのは、僕が2014年に公開したゲームである『空中遊戦イヤリーズ』から来ています。

Adobe Flash / AIR 製のゲームで、残念ながら現在はもう遊ぶことができません(◞‸◟)

正直、今見るといろいろ「うーん…」と思うところが多いゲームではありますが、当時の僕としては結構頑張ったゲームなので、思い入れはあったりします。ですが、動く環境がなくなってしまった以上、どうしようもありません。

イヤリーズ、移植プロジェクト!(未完)

そんなわけで今年のGWごろに、イヤリーズの移植にチャレンジしてみました!

↑こんなかんじで。画像とかはほぼそのままに、システムはJavaScript(AkashicEngine)で作り直し。

で、これを作っている最中に「うーん、どうせ作るならゲームの中身も前と同じじゃない方がいいかもしれないな……」みたいな余計なことを考え始め、紆余曲折あった結果として『そらとび大作戦!』が生まれました。別物じゃん!

そらとびテーマ

『そらとび大作戦!』はあまりランダム要素がないゲームです。

その代わり、『完全同一操作』は難しいです。レーザー攻撃はスワイプなので、角度がちょっと違えば動きが違いますし、クリックによる移動もそう。スコア獲得も1フレームずれれば計算結果が全然違います。

ニコ生ゲームはパーティーゲームとしての側面が強いと思っていますが、たまにはあまり運に左右されずに実力でバトル!みたいな感じのゲーム性も面白いかな、ということで本作はそういう感じのゲーム性にしてみました。

とはいえ、あまり固定過ぎると、それはそれでプレイ中の緊張感が逆になくなってしまうため、唯一のハプニング要素としてレアオバケ(ゲーミングオバケ)が存在しています。あの瞬間だけアドリブでうまく対応が必要。

本作、基本的には過去作のドット絵が流用されているのですが、ゲーミングオバケだけ新規だったりします。こんなの地下ドールにいない。


開発中の僕はだいたい7万点くらいで、理論上は10万いけるか…?みたいなこと思っていたら、公開初日に10万超えてる人いて、世界はすごいなぁと思いました。。。。

ニコ生が元気になったら、ニコ生ゲームでみんなで遊んでほしいな。

自分用のブラウザゲーム置き場を作った話

『プレポタ』

僕が今までつくったブラウザゲームを公開するサイトを作りました

それが、↑この『プレポタ』です。『プレイ!鳥小屋Ru』の略で『プレポタ』。
このブログを書いている現時点で、過去10年くらいに作った16作品を置いています。思ったより増えたね。

PCやスマホのブラウザでゲームが遊べることはもちろんのこと、

  • ブラウザ内全画面やフルスクリーン表示対応
  • GoogleDrive連携でクラウドセーブができる
  • SNSシェア用のスクリーンショット撮影機能
  • ハイスコアランキング機能

みたいなところを用意しています。イメージは僕専用のアツマールのパチモン。

パチモンにも程があるだろ!

作るに至るモチベーション

ポエムパートです。ポエムに興味ない方は次の章まで読み飛ばしてください。

そもそもブラウザゲームの利点とは

ブラウザゲームの最大の利点は『自由』である ことだと思っています。

例えば iPhone のアプリは Apple に許可されたものしか公開することができませんが、ブラウザゲームはたとえ世界が認めなかったとしても、自分でサーバーを用意すれば自分の責任の元にインターネットで公開することができます

※そういった意味では PC用のソフトは基本的に自由に公開できて素晴らしいですね

理想と現実

……と言いつつ、現実問題としては他の方が運営するプラットフォームで公開する場合がほとんどかと思います。

アツマールや PLiCy 、 ふりーむ! など、既存のプラットフォームを使う利点としては、

  1. 集客が見込める
    • 既存のプラットフォームには既に人が存在しているため、その層にリーチできる
  2. 各プラットフォームが提供する機能が利用できる
    • 例:アツマールのAPI機能、PLiCy のミニ実況機能など
  3. 運用コストが比較的安い
    • 自分で公開場所を用意するのはそれなりに大変

などがあります。

このあたりがうまく自分にハマっているプラットフォームがある場合、そういったプラットフォームを活用するほうがメリットは大きいと思います。

実際、僕はこのあたりの観点で、アツマール と PLiCy を中心にゲームを公開していました。
(ふりーむ!も試してたけど、あんまり向いてなさそうだったのでやめました)

アツマールが忘れられない

その中でもアツマールは、本当に僕にハマる最高のプラットフォームでした。

僕のゲームの代表的な作風は『実績蓄積によるシナリオ進行のパズルゲーム』です。
パズルを繰り返しプレイすることで、実績がアンロックされていってシナリオが進む……というやつ。

まず、『パズルゲーム』はスマートフォンとの相性がとても良いです。そのため、スマートフォンからのゲームの遊びやすさというのは非常に重要でした。
特にスマホのブラウザはストレージ制限が厳しく、普通にブラウザゲームを公開すると、勝手にセーブデータが消されることがよくあります。この部分において、アツマールにはサーバーセーブ機能があったため非常にスマホにマッチしていました

そして、パズルを繰り返し遊ぶ以上、簡単に『スコアランキング』のような機能を作れるのも魅力的でした。
ゲーム側で何もしなくてもモードを1つ増やすことができるため、これは非常に助かりました。

こういったところから、僕の作風と非常にマッチしていて良いサービスだったのですが、残念ながら2023年にサービス終了してしまいました。かなしすぎる(◞‸◟)

もうサービス終了から1年近く経ちますが、僕の中では今でもアツマールで開いた穴がぽっかりと残っていました。

僕のゲームをもう一度『あの形』で遊べるようにしたい

僕の作ったブラウザゲームたち。
これをもう一度『アツマールでできた体験』で遊べるようにしたい!

この気持ちがどうしても止まらず、様々な手段を考えました。

とはいえ、あまりコストがかかる手段は維持が難しいです。
サーバー代が毎月何万円もかかったりしたら困りますし、僕がスキマ時間で面倒を見れない規模になったら破綻します。

いろいろ考えた結果、自分専用のブラウザ公開スペースを作り、そこに最低限必要な機能を追加するというのが一番低コストにやりたいことを実現できそうだと考え、2024年2月ごろから準備を始めることになりました。

おまけ:考えたけどやめたこと

以下は考えたけどやめたことです

  • PLiCy で外部APIを頑張る
    • PLiCy は外部通信が許可されているため、外のサーバと通信していろいろできます
    • これを使って、外部のサーバと通信してサーバーセーブやランキングなどを作ることを考えました
    • が、ログインの仕組みとか作ろうとすると様々な制約から実現が厳しいことがわかり、諦めました
  • ブラウザゲーム投稿サイトを作る
    • いっそアツマールみたいな機能を持つ投稿サイトを作っちゃえばいいのでは!?(バカ)
    • 雑に試算してみたら、笑っちゃうくらいお金かかることがわかったのでやめました
      • 一般的には『大量のファイルの書き込みや配信』は高コストです
      • でもブラウザゲームってファイル数1000とか余裕であるよね、ウケる
    • そもそも僕ひとりだと監視とかできないから運営ができないですね

続けられない方法を選んじゃうと意味がないので、このあたりのことは考えるだけ考えてやめました。

どう実現するか?

要求を定義する

優先順位順に並べると以下のようになります

  1. 長期的に運用ができること
    • 僕が個人でやる以上、続けられなくなってしまうと困ります
    • お金がかかり過ぎたりしないか?
    • 面倒を見るのが大変すぎたりしないか?
    • 使うサービスが終了とかしたときに引っ越しができるか?
  2. セーブデータをサーバ保存できること
    • スマホのことを考えると必須
  3. ランキングなどの追加機能が用意できること
    • これがあって、あの体験が帰ってくるため

ここに書いてないこと、具体的には『集客』と『収益』は無視します
そこを狙うなら既存のプラットフォームを使ったほうが確実に良いからです。

あくまで僕の実現したいことは、アツマールでできた『あのプレイ体験』の再現 です。
『アツマールの再現』ではない ため、サービスと良くするとか重視しません。

要求をもとに手段を選定

低コストかつ、引っ越し可能な構成にするため、以下のような構成としました。

デプロイ先は Cloudflare Pages

Cloudflare の提供するホスティングサービスです。
無料でかなり制限ゆるく使うことができるため、最近は個人サイトは全部ここに置いています。

単にHTMLなどを置くだけではなく、Workersの機能を利用してサーバサイドの処理を動かすことができるのも魅力的です。

その中で、特に決め手となったのは、D1データベースの存在です。

D1データベースを使うと、Cloudflare Pages(Workers)上でSQLiteが利用できます。スコアランキングなどの各種機能を実現する上では、馴染み深いリレーショナルDBが利用できるのは大きなメリットです。

また SQLite のインタフェースであることから、将来D1データベースが使えなくなるようなことが起きたとしても、自分のサーバーに引っ越せば同等のコードをそのまま動かすことができる可能性が高そう、というところも良い部分です。

なお、無料で使えるのですが、僕は Workers の $5/月 は払うことにしました。いろいろ制限も少なくなるし、お世話になってるしね。

SSG(Static Site Generator) + 小さなAPI という構成

サイト全体をでかいアプリケーションとして作ると保守が難しくなります。
特にWebフロントはブラウザのアップデートなど様々な外的要因によって大きな変化が発生する可能性は高いです。どこかでのタイミングで作り直しに近いことが発生する可能性は考慮する必要があります。

そう考えると『静的なHTML/JS/CSSのページ』と『小さなAPIサーバー』という2つのアプリケーション構成になるのが良いのではないかと考えました。

ページ部分とAPI部分を分けることで、それぞれ独立した技術を利用してサイト全体を構築することができます。また、静的なHTMLはデプロイ手段も無数にあることから、引っ越しの面でも良さそうです。

今回は SSG 用に Sveltekit 、 API用に Hono を使うことにしました

Sveltekit はSSG専用のフレームワークではないですが、SSGの機能を持っています。
僕自身、結構 Svelte の記法が好きであることや、別のサイトを作る際にも Sveltekit を使っていたことから今回も採用しました。

Hono については、Cloudflare Pages を使うと決めた時点で、やはり Hono が良いだろうなと考えました。
非常に軽量ですし、書き味も良いです。 Hono をちゃんと使ったのは今回が初めてでしたが、人気が出るのも頷ける『良さみ』を感じました。

なお、ちょうど2月上旬に Honox が公開されていたため、途中までフロントは Honox で作っていました。が、ちょっと機能要求的に Single Page Application にしたほうがいろいろ都合が良いな……という点が出てきたことから、途中で Sveltekit にしました。Honoxはまたの機会に。

ゲームファイルの配信はCloudflare R2で

ゲームファイル自体は別途 Cloudflare R2 にアップロードして配信することにしました。

もともと個人サイトで公開していたゲームは Cloudfront + S3 構成だったのですが、R2のほうが用途的に無料になる部分が大きかったことから今回は R2 を使ってみています。

ちなみに、今回は R2 のバケット自体をパブリックアクセス可能にして使っているのですが、なんかたまーに 503 を返す場合があり気になる。Worker 通したほうが良いのかしら?

サーバーセーブはGoogle Driveに任せる

サーバーセーブをどうするかは悩みのタネでした。

D1データベースに突っ込むにはセーブデータはちょっとでかい。が、R2に保存するには細かい。
そもそもいろんな人のセーブデータが大量にサーバに溜まっていくのも、それはそれで保守の観点では困るところです。

そんな中、Google Drive に appdata という連携アプリケーションが固有のデータを保存できる仕組みがあることを知りました。

これを使うと、僕がみんなのセーブデータを管理する必要もないですし、ユーザーもアプリケーションの連携を切ればゲームのサーバーセーブを自分の意志で消せるし良さそうです。

そのため、セーブデータのマスターはあくまでブラウザのストレージとして、『クラウドバックアップ機能』として Google Drive を利用したサーバーセーブ機能を提供することにしました。

頑張る

頑張る話は楽しくないので割愛します。

ところで、Google Drive の API の叩き方とかは全然知らなかったのでうーん……と思っていたのですが、 GitHub Copilot がほとんど書いてくれました。天才かよ。

そんなこんなでできた『プレポタ』

思ったよりいい感じにできて嬉しかったので、PVみたいな動画作っちゃいました。

まだできたばかりで、もしかしたら細かいところおかしいかもしれませんが、温かい目で見守ってね。

https://play.toripota.com/


よーし、そろそろ次のゲーム作るぞ!

各作品の舞台と時間軸まとめ(2024年3月時点)

どういうわけか?

こういうマシュマロをいただきました。

こんにちは、貴方が狼カードデスから色々ゲームをやらせてもらっています!素晴らしいゲームをありがとうございます!
ゲームをしている中で、ハインの時系列がどのように進んでいるか興味を持ったので教えていただけたら幸いです。

プレイありがとうございます!

時系列については、以前『ウヌムマキナ』を公開したときにブログに少し書いていました。

↑の記事のURLをペタリしようかと思ったのですが、少しアップデートしたほうがいいかもしれないなと思ったので2024年3月版をまとめてみることにしました。

各舞台の世界と時間軸の関係図

2024年3月最新版がこちら。

現在は、主に3つの世界のいずれかを舞台としています。
※各世界の名前は僕が区別するために付けているもので、各世界の住民がこの名前で呼んでるわけではないです

特に物語のメインとなっていてゲームの数が多いのは中央の『三月の世界』です。いわゆる魔法のファンタジー世界。3つの世界の中では一番時系列が長く表現されており、前半の方は魔法が中心のお話、後半の方は機術が中心のお話になっています。

その世界とは別に、現代日本をモチーフとした舞台となる『現の世界』があります。『ホシトリの夜』『貴方が狼カードデス!』はこの世界でのお話で、時系列的には近い関係にあります。

そして、死霊の世界はオバケたちが住む世界です。現状は『パズルネクリア』のみです。本当はもう一作作ってたんだけどエターなっちゃった。

本来、これら3つの世界は別の世界なので相互に干渉することはないはずのものです。が、ハインのように世界の壁を越えて活動をしている者たちの影響で、これらの世界の要素が微妙に影響を及ぼし合っています。

ハインの時系列

※『憎悪の獣の地下ドール』『貴方が狼カードデス!』を始めとした複数の作品のネタバレを含みます

【クリックして文章を表示】

各作品の中でハイン『達』は何人か登場しています。

  • マザーハイン
  • 長女:メイカーハイン
  • 五女:ハイダー(ハイダーハイン)
  • 六女:オーナーハイン
  • その他のモブハイン(ハインドール)

このうち、複数の作品に出ているハインは『オーナーハイン』と『ハイダー』の2人です。この2人にとっての時系列で並べると

『ウヌムマキナ』(オーナーハイン)
→ 『貴方が狼カードデス!』(ハイダー)
→『憎悪の獣の地下ドール』(オーナーハイン / ハイダー)

の順番になります。

6人いる初期型(プロト)ハインドールのうち、現時点ではメイカー / ハイダー / オーナーの3人しか出ていないので、どこかで他の3人も出てくるかもしれませんね。

おわり

そんなわけで徐々に広がりつつあるRuたんワールドをよろしくお願いします(?)

なお、あくまで設定上の繋がりがあるというだけで、ゲームとしては基本的にはそれぞれ単体で完結したい気持ちではあります。が、たまにどうしようもないこともあるので、それは許して欲しい。

Ruたん2023年の世界へ

今年も年末ですね。

去年の振り返り記事

2023年について雑多に振り返る

去年の振り返り記事では以下のようなことを書いていました。

ここ数年、僕がメインの活動場所としていたゲームアツマールが2023年6月でサービス終了と発表されました。悲しすぎる…(◞‸◟)

もちろんアツマール以前も僕はゲームを作っていましたが、鳴かず飛ばずというか本当にひっそりとやっていました。そんな中でアツマールという活動の場ができて色んな方に僕のゲームを遊んでもらえたり、同じようにゲームを作っている方々と知り合えたりしたのはとても良いことだったなぁと思っています。

アツマールがなくなってしまう以上、僕も活動のベースを変えないといけないため、2023年のRuたんの目標は「僕にあった次の活動スタイルを見つける」みたいな感じでしょうか。

今までもコミケに出てみたり、Steamにゲーム出してみたり、スマホアプリ出してみたりしたものの、どれも「これだ~~~」というほどしっくりは来ていないので、もうちょっと色々なことに挑戦してみたりしないとですね。

去年の振り返り記事から引用

僕がメインの活動場所としていたゲームアツマールが無くなってしまったことは、非常に大きな変化です(◞‸◟)

もちろん「ブラウザゲームは場所を選ばない」というのが武器であり、アツマールが無くなってしまったからといってゲーム自体が無くなってしまうものではありません。ただ、ゲームの周囲の環境や体験といったものはコンテンツではなく場に強く依存するものであり、その場が無くなってしまうことは決して無視できない変化です。

僕がアツマールで最初に投稿したのは『魔導箱のグリモワール』でしたが、とても多くの方に遊んでいただき、アツマール上ではたくさんのコメントを頂いたりしました。あの反応があったからこそ 『ホシトリの夜』『ウヌムマキナ』 へと続いていく「実績でシナリオが進んでく、いつものRuたんパズル」の流れが確立できたと思っています。

また、春のパズルゲームあつまーる企画が無ければ『双星ペアマール』は生まれるはずがないですし、課金ゲームのお誘いが無ければ『パズルネクリア』を作ることも絶対になかったでしょう。

そして何よりアツマールAPIが無ければ『憎悪の獣の地下ドール』が生まれない!
地下ドールの存在は僕の活動に対して人生最大級に影響を与えており、まさにそれはアツマールから貰った最高の宝だったと思います。ありがとう、ゲームアツマール……!頼むからうっかり生き返ってくれ。

そしてアツマールが無い世界で生きていくことになってしまった2023年、僕は色々ともがいていました。

個別の話

『貴方が狼カードデス!』

2022年秋に開催されたアツマール上のユーザーイベントである『ゲームジャム30』に参加するために作ったゲームです。30日では結末まで作れなくて、つゆちゃんが狼になる1ゲーム分だけ実装して公開していたものを、最後まで完結させて2023年2月に公開しました。

実は本作は結末とそこまでの流れが当初予定していたものとだいぶ変わっています。もともとアツマールに投稿することを前提としていたため、アツマール上で僕のゲームを遊んでいる人に向けたゲームという側面がありました。しかし、アツマール以外での活動を考える上で、その前提なくても成立する形に流れを変更することになり、そこがかなり難産でした。最初は『最後のゲーム』も作るつもりなかったですしね。

本作は2月にアツマール、PLiCy、App Store、Google Playで公開をしました。スマホアプリについては去年『ウヌムマキナ』をやっていたので、同じやり方で割と低コストにできそうというところでチャレンジしています。スマホアプリは普段の僕の活動の場とはだいぶ違うため、届けられる層もかなり違いますしね。

その中でいろいろと感想を頂いたり、ゲーム実況していただいたこともあって、ダウンロード版(Windows版)も作ってみようかなと思いました。過去に地下ドールのダウンロード版を作った際は、ふりーむ! で配布していましたが、あんまり良い感触が無かったなぁ……というところで今回は Steam でやってみることにしました。「Steam でフリーゲームを配布する」っていうのやってみたかったというのも大きいです。

無料ということもあり、ライブラリ追加数は1万を軽く超えててSteamすげぇ~……となりました。もちろん、実際のプレイヤー数はそのうちの10%切るので、多くの方は積みゲーコレクションの中に加えて頂いている感じですね。みんな積みゲーしてるんだと思うと、罪悪感が無くなって良いですね。(買ったのにまだやってないSteamゲーの山を見ながら)

そんなわけで『貴方が狼カードデス』はいろいろやってみてところどころ手応えはあったりしました。一方で、本作は制作期間が意図せず長期化したこともあって、僕のメンタルにものすごい量のダメージも入ってしまった、というバッドな一面もあります><;

一旦は本作については落ち着いた、というところで少し休んでから次のことを考えようかな……と思います。

『憎悪の獣の地下ドール』

そんなわけで『貴方が狼カードデス!』の連中も参戦しました
まぁ地下ドールを先にやってた人にとっては、お前はデスゲームの進行してないでこっちに出てろって感じですしね……

もともとドール50体で終わりのつもりでしたが、54体になっちゃったぜHAHAHAHA!
各色のドールがちゃんと同じ数ずつになるようにしてたのに、4体増やしたせいで赤ドールが1体多くなっちゃったのでどうしましょうねコレ?()

アツマールは無くなっちゃいましたが、PLiCy版で引き続き非同期オンラインバトルはできるので、これからもチャンプを目指して!

『ウヌムマキナ』

実はこっそり英語対応してました

ただ、英語としてちゃんとしてるかはわかりません。何故なら ChatGPT に翻訳してもらってるからです!()
まぁなんか僕の目線だとそこまでボロボロという感じもしないし、僕よりは翻訳うまそうだから大丈夫でしょう…!

突然英語対応したのは itch.io に置くためです。一応、itch.io に置くときはなんちゃって英語対応をすることにしてます。英語圏のプレイヤーに届くかは別として一応……。

ブログを書く!

活動の多様化の一環として、『月に1本はブログを書く』という目標を立てていました

とりあえず目標自体は達成してるかな……!

ブログを書くこと自体は結構自分の中の思考を整理するという意味でもよいと思っているので、来年もできる限り続けていきたいですね。最近はしずかなインターネットにもポエム書いてたりするのでアレですが。

2024年は……?

むずい…!
1年いろいろ試行錯誤してみましたが、安寧の地は見つからない!

そんなわけで、もうちょっともがいてみようかな……という感じになりそうですね。一方で、慣れないこと無理してやると滅茶苦茶キツイということもわかったので、もう少しゆったりペースで生きていこうかな……。

作りたいモノはいくつかあったりするので、しばらくはその辺りをこねこねしたり、下地を作ったりして、来るべきタイミングに備えていこうかな~と思います。


そんなわけで、2024年もよろしくなのじゃ!

ツクールと最大公約数と鳥小屋プラグイン

ツクールは最大公約数

RPGツクールは『最大公約数』の取り方が非常にすごいなと思っています。
ここで言う『最大公約数』とは「多くのゲームで共通となる部分」の意味です。

正直、ゲームの中身は多くの場合ゲームごとに全く異なっていて、その中の共通点を見つけ出した上で 限界まで削ぎ落とす というのは非常に難しいです。特に『削ぎ落とす』というのはツールの作り手にとっては怖い行為です。なぜならば、機能をそぎ落とせば「◯◯機能がない」という不満を投げつけられる可能性があるためです。

しかし、機能はあればあるだけあらゆるケースにおいて良いというようなものではありません

主たる思想はどこにあるのか

例えば、僕らの身近な例だとRPGツクール2000WOLF RPGエディター(ウディタ)を比べるといいかもしれません。ウディタはRPGツクール2000と比べると非常に多くの機能をほぼ無制限に利用することができます。一方で「初めてゲームを作るよ!」という人にとっては、ウディタは結構難しいツールでもあると思います。

これは当然の話で、主たる思想が違うためです。ウディタは公式サイトにも書かれている通り ツールで想定されている範囲を越えた自由度が欲しい という想いから作られているもので、思想の主は「自由」であることだからです。一方でRPGツクール2000は 操作は簡単!手軽にクリエイト! を謳っており、思想の主は「手軽」であることがわかります。

どちらが優れてるとかそういう話ではないですし、そもそもとして 0 か 1 かなんて話でもありません。実際、ウディタにも初心者向けの部分はありますし、RPGツクール2000にも上級者のための機能もあります。
重要なのは「ツールが目指している場所がどこなのか」という部分です。

RPGツクールの目指している場所と最大公約数

ちょっと Unite がどこ目指してんのかは僕もよくわかんないので置いときますが、
RPGツクールは一貫して「手軽」であることを目指していると思われます。そう考えると、他のプロユースに近いツール達(ウディタやUnityなど)とは異なり、ゲームの最大公約数を見つけ、機能と情報を制限することで、初心者にも全体がわかりやすくする……といったことを目指しているのだと思います。

多くの場合にとって必要なものというツールや機能が厳選されているということは、裏を返すと個々人が開発しているゲームの中だと「微妙にコレできたらいいのにな~」ということはあるかもしれません。しかし、その要望をすべて受け入れるとRPGツクールが目指している場所とはズレてしまうことでしょう。

ここのバランス感覚は非常に難しいと思うのですが、RPGツクールはとても良い場所にいるなと感じており、僕が今でもRPGツクールに惹かれ続けている理由の1つです。

プラグイン

ところで、RPGツクールにはプラグイン機能(XP~VXAceだとスクリプト)があります。

おそらく本来コレはRPGツクールの中における上級者のための機能だったんじゃないかなと思いますが、ユーザーコミュニティの中で発展していく中でプラグイン素材(スクリプト素材)が多く生まれ、自分でスクリプトを書かない初心者でも割と気軽に使いがちな機能になっていますね。

僕とプラグイン素材

僕自身も、RPGツクールVX(RGSS2)のときに自分のゲーム用に書いたスクリプトをブログで少し公開したりしており、RPGツクールVXAce(RGSS3)以降はスクリプト素材屋さんみたいなことをして活動しています。

正直、RGSS3の頃やMVプラグインの初期とかは僕もテキトーなことやってたのであんまり思想もクソも無かったのですが、いろいろと振り返ったりした中でRPGツクールが実現している「最大公約数」を見習いたいなと思い、現在鳥小屋プラグイン置き場で公開しているプラグインの多くはちょっと意識をしています。

鳥小屋プラグインの最大公約数

現在の鳥小屋プラグインでは以下の2つのルールを意識するようにしています。

  1. UIの変更を主としたプラグインは作成しない
  2. UIの豊富なカスタマイズ機能を提供しない

共にUIにまつわる部分です。

(1) UIの変更を主としたプラグインは作成しない

例えば「鳥小屋カッコいいバトル画面プラグイン」みたいなもので、既存のRPGツクールが提供している画面を大きく作り変えるようなプラグインという意味です。

これは「RPGツクールが提供している画面は最大公約数である」ということを考えると、ここから狭めていった先にあるべきなのは「そのゲームのためにオーダーメイドされた画面」であるべきだと考えたためです。そこまで行くとプラグイン「素材」じゃない……!

例えば、地下ドールの戦闘画面は地下ドールのゲームシステム上(2vs2 / 自動戦闘)でしか成立しない。

そのため、鳥小屋プラグインでは既存UIを変更することを目的としたプラグインは作っていません。

ただし「何かを追加する」という形のものはいくつか作っています。例えば『通知メッセージプラグイン』は、マップ画面に通知UIを追加するプラグインです。

(2) UIの豊富なカスタマイズ機能を提供しない

一方で『通知メッセージプラグイン』のような何かのUIを追加するプラグインにおいては、『豊富なカスタマイズ機能を提供しない』というルールを作っています。もちろん最低限のフォントサイズの設定とかはプラグイン設定で提供していますが、この見た目を大きく変えるような機能をプラグインの機能としては提供していません。

これも先ほどと同じで、鳥小屋プラグインにおいて追加するUIにおいても最大公約数を目指す、という思想からです。

あらゆる要望に応えられるようなプラグイン設定を作ることは非常に難しいですし、使う側の人にとってもわかりにくいものになるでしょう。そのため、プラグインとしては多くのゲームでそのまま使える状態を目指すというルールでやっています。

なお、この思想はプラグイン作成上の思想であり、「利用者の人も最大公約数のまま使うべきである」というものではありません

鳥小屋プラグインでは、画面UIに関わる処理はすべて window.Torigoya.プラグイン名 以下からいじることができるようになっており、「鳥小屋プラグインの処理/見た目を変更するプラグイン」が作れるようになっています。実際、僕が自分のゲームで使う場合は、ゲームにあわせていじっています。

『貴方が狼カードデス!』の実績画面は 実績プラグイン を使っていますが、見た目の部分はこのゲーム専用のプラグインで処理を上書きしています。

そのルール守ってどうすんの?

最大公約数を意識することで、以下の2つを実現できたらなと思っています。

  1. 様々な人が気軽に使いやすいプラグインにしたい
  2. 僕が今後も保守していきやすくしたい

(1) 様々な人が気軽に使いやすいプラグインにしたい

RPGツクールのように、誰もが気軽に使いやすいプラグインにしたいです。

それこそ可能であれば、プラグイン設定などは一切しなくても動くことが理想です。もちろん実績プラグインなどは実績自体を作ってもらう必要はありますが、それ以外の設定というのはしなくても使えるようなわかりやすいプラグインにできたらいいなと思っています。

多くのゲームでそのまま使えるものを考える、ということ自体はとても難しいことで失敗することも多々ありますが、今後も意識してやっていきたいです。

(2) 僕が今後も保守していきやすくしたい

大前提として、僕は自分のプラグインを自分のゲームで使いたいと思っています
逆に言えば、僕が使わないプラグインは作るつもりはないです

これは簡単な理由で、僕が使わないプラグインは僕が保守しなくなっちゃうからですね。僕はプラグイン作者ですが、そのプラグインの一番の利用者でもありたいと思っており、そうすることでプラグインの不具合修正などを継続して行っていけるようにしたいと思っています。

これを実現するためには、鳥小屋プラグインはなるべく多くのゲームで使えるようなものであることが望ましいです。最大公約数を意識することで、僕が過去に作ったゲームはもちろんのこと今後作るゲームでも使っていきたいと思えるようなプラグインにしていきたいです。

まとめ

  • RPGツクールの『最大公約数』はすごい
  • 僕はRPGツクールを見習いたい!
  • 鳥小屋プラグインでも『最大公約数』を意識してやってます

くっそ長いブログ書いたけど3行で済む話だった!!!!!!!!!!111111111
ブログの最大公約数も意識したほうがいいかもしれないね(?)

Steam版『貴方が狼カードデス!』2023年10月10日に出ます!

Steam版『貴方が狼カードデス!』

6月に公開予定だったのに延期になってたSteam版『貴方が狼カードデス!』がついに2023年10月10日に公開になります!やったぜ!

公開のタイミングは僕が手動でポチポチやったりするのでピッタリ0時ちょうどではないと思いますが、だいたいそんな感じの時間に公開することになるんじゃないかなと思っています、たぶん。Steamでゲーム公開するのだいぶ久しぶりなので、もしかしたら色々ミスるかもしれません><;

ちなみに Steam 版もブラウザ版やアプリ版と同様に無料のフリーゲームとして公開されます。お気軽にダウンロードして遊んでもらえると嬉しいです!

Q&A

Q. そもそも『貴方が狼カードデス!』って?

動画を超がんばって作ったので見て!

『貴方が狼カードデス!』 は人狼をモチーフにしたデスゲームADVです。

キャラクター達の議論を聞いて、誰が狼なのかを当てるというシンプルなアドベンチャーゲームです。1プレイあたり5分程度の狼ゲームを繰り返すことで、徐々にデスゲームの真実が明らかになっていく……!いつものRuたんじゃねぇか!

既にブラウザ版やスマホアプリ版は公開していましたが、今回パワーアップしてSteamに登場します!

Q. ブラウザ版やスマホアプリ版からの変更点は?

主に以下のような変更をしました!

  • ゲームの画面解像度が大きくなりました(800x450 → 1280x720)
    • それにあわせて全体的なUIのブラッシュアップをしました
  • 背景やカードイラストが変更になりました
    • AIくんが作ってくれた画像がなくなった
  • ゲーム内のイベントシーンを一部変更しました
    • 画像を追加したり、セリフを調整したり
  • Steamの実績機能に対応しました
    • 多分クラウドセーブも動くと思いますが、うまく動かなかったらごめん!

Q. ブラウザ版やスマホアプリ版はどうなるの?

Steam版公開のあと、ブラウザ版やスマホアプリ版もv.2.0にアップデート予定です!
アプリは審査とかもあるから、アップデートされるタイミングはバラバラになると思います。少なくとも10月中にはアップデートされるんじゃないかな!

Q. でもお高いんでしょう?

無料のフリーゲームだよ!

Steamくんでゲームを1つ公開するためには1万円くらいの場所代を払う必要があるためド直球に赤字ではあるのですが、新しいことにいろいろ挑戦してみるということで試しにやってみる感じです!

そんなわけで

今度こそ予定通り出るはずなので、よろしくおねがいします!

ウィッシュリストに登録してもらえると、僕のモチベがバク上げします。

Electron + RPGツクールMZ なゲームで Steam の実績に対応する

【注意】こんなタイトルですが、真面目にツクールを使ってる多くの人にとっては参考になりません

Steam には実績機能があります。正確にはこの辺りの機能には、

  • ゲームのスコア的な内部数値を格納できる Stats
  • PS系で言うところのトロフィー的な Achievements

の2つがありますが、今回の話は Achievements のほうです。

せっかく Steam でリリースするからには実績機能に対応したいため、いろいろやった記事です。

前提

Electron

RPGツクールMZのゲームは内部的にはHTML5なブラウザゲームとして動作します。そのため Steam でリリースをするためには、まず何らかの方法で Windows 等向けのアプリケーションにする必要があります

RPGツクール側の標準では NW.js が使われています。RPGツクール上でテストプレイを押したときに開くのも、この NW.js です。

しかし一般的にはこういったWebアプリケーションのアプリ化には Electron が使われることが多く、インターネットで得られる記事やツールも Electron を対象としたものが多いと思われます。そのため、僕も NW.js ではなく Electron を使うことにしました。

なお、RPGツクールMZのゲームを Electron を使ってアプリ化する方法は、トリアコンタンさんが詳しい記事を書いているためそちらを見ると良いです。

Steamworks.js

Steamの機能を使うためには、Steamworks SDK の機能を呼び出す必要があります。しかし Steamworks SDK は C++ のコードのため、JavaScript の世界……というか node.js の世界からそのまま呼び出すことはできません。

以前は node.js から Steamworks SDK を呼び出す方法として Greenworks というライブラリが有名でした。ただ結構使うのが難しかった印象が強いです……前の僕は挫折した><;
また、現在は Greenworks は開発が停止状態になっており、他のライブラリの利用が推奨されています。

Steamworks.js は Greenworks のページから移行先の1つとして紹介されているライブラリです。 Rust で書かれたブリッジのライブラリになっており、とてもシンプルでわかりやすい印象があったため使うことにしました。

Steamworks APIを呼び出す

プロジェクトのフォルダ構成

過去の記事 でも触れましたが、僕のゲームのプロジェクトのフォルダ構成はざっくり以下のようになっています。

├── app/     …… RPGツクールのプロジェクトフォルダ
│   ├── audio/
│   (略)
│   └── game.rmmzproject
├── android/ …… Capacitor Android の作成するフォルダ
├── ios/     …… Capacitor iOS の作成するフォルダ
├── windows/ …… Electron 用のフォルダ
│   ├── main/     …… Electron用のJavaScriptが入るフォルダ
│   ├── public/   …… ゲームが入るフォルダ(後述) 
│   └── package.json 
└── package.json

※説明に不要な部分は割愛

Capacitor

僕はスマホアプリも作りたいので Capacitor を使っています。 Capacitor はプロジェクトフォルダの直下にプラットフォーム名(android / ios)のフォルダを作るため、それに習って Electron 用のフォルダに windows という名前をつけています。

Capacitor では cap sync というコマンドを実行すると、 android / ios のそれぞれのフォルダの中にゲームのデータがコピーされるようになっています。そのため、同じように windows/public のフォルダの中にもゲームのデータが自動的にコピーされるようにしています。

Steamworks.js を組み込む

Steamworks.js の README では BrowserWindow を nodeIntegration: true にする方法が記載されていますが、あまり nodeIntegration を有効にはしたくないため、以下のようにして組み込みます。

// main.js

const { app, BrowserWindow, ipcMain } = require('electron');
const steamworks = require('steamworks.js');

// Steamで発行される App ID
const STEAM_APP_ID = xxxxxxx;

let browserWindow = null;

const createWindow = async () => {
  if (browserWindow) return;

  const win = new BrowserWindow({
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      nodeIntegration: false,  // 強い意志で false にする!
      contextIsolation: true,   // 代わりに contextIsolation は使います
    },
    show: false,
  });

  // ウィンドウサイズをいい感じに
  win.removeMenu();
  win.setContentSize(1280, 720);
  win.setMinimumSize(...win.getSize());

  // ページを読み込む
  await win.loadFile(path.join(__dirname, '..', 'public', 'index.html'));
  win.show();

  browserWindow = win;
};

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});

(async () => {
  // Steam経由起動でない場合はゲームを終了する
  if (steamworks.restartAppIfNecessary(STEAM_APP_ID)) {
    app.exit();
    return;
  }

  // Steamworksの初期化&オーバーレイメニューの有効化
  const steamClient = steamworks.init(STEAM_APP_ID);
  steamworks.electronEnableSteamOverlay();

  await app.whenReady();

  // ゲーム内から実績獲得の呼び出し用の口を作る
  ipcMain.handle('activate-steam-achievement', (_event, name) => {
    steamClient.achievement.activate(name);
  });

  // ウィンドウを作る
  await createWindow();
})();

ポイントは steamworks.restartAppIfNecessary steamworks.electronEnableSteamOverlay() を呼ぶタイミングです。

この2つはアプリケーションが立ち上がってすぐに呼び出さないとうまく動かない場合があります。そのため BrowserWindow の作成よりも先に呼び出すようにします。

また、 ゲーム内から呼び出すためのコードを preload.js に追加します。以下は window.steam.activateAchievement(実績名) で先程用意したSteam実績を追加するための口を呼び出すようにしています。

// preload.js

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('steam', {
  activateAchievement(name) {
    return ipcRenderer.invoke('activate-steam-achievement', name);
  },
});

あとはゲーム内から良きタイミングで window.steam.activateAchievement(実績名) を呼ぶだけです!

その他

パッケージ化するときの注意

Electronのアプリをパッケージ化する際に、ASAR アーカイブ を使用する場合は1点注意が必要です。

Steamworks.js の中には DLL などのバイナリを含むため、それらがASARアーカイブの中に含まれてしまうと正常に動作しなくなってしまいます。そのため node_modules/steamworks.js/dist/ 以下のファイルは ASAR アーカイブに含まないようにします。

僕はパッケージ化に electron-forge を使っているので、 unpackDir の設定に steamworks.js のディレクトリを指定しました。もしくは Auto Unpack Native Modules Plugin でもできるのかも? 試してないけど。

おまけ:実績プラグインと連携する

Torigoya_Achievement2 というRPGツクールに実績機能を追加するプラグインがありますね(ダイマ)。

Torigoya_Achievement2 には「実績獲得時に実行される処理を追加する」機能があるため、以下のようなアドオンプラグインを用意すると、実績獲得時に自動的に Steam 上の実績も獲得状態にできます。

(() => {
  Torigoya.Achievement2.Manager.on(({achievement}) => {
    if (!window.steam) return;
    window.steam.activateAchievement(achievement.key);
  });
})();

なんて便利なプラグインなんだ!!!!!!1111(自画自賛)

できた!

左上と右下から実績が出てくるゲーム。

僕は他に少し色々とやりたいことがあるので実際はもうちょっとややこしいコードを書いていますが、大筋はこんな感じになっています。

Steamworks.js はとてもシンプルで扱いやすいので、Steamの機能をElectron + HTML5ゲームから呼び出すときには手軽で便利です。特に Steamworks SDK のビルド環境なども用意しなくて良いため、今後もお世話になりたいですね。


昔、Steamで公開した『天翔と剣のウィッチクラフト』というゲームはこの辺りがうまく解決できず、Steam実績に未対応だったりしました。少しずつ世界は便利になっていく。