機能解説

コメント

編集

概要

ゲームアツマールでは、ユーザーのゲーム体験を共有するためにコメント機能を提供しています。設計はRPGツクールシリーズでの利用を想定していますがAPIは汎用的にも利用可能です。

なにができるのか

ゲームの内容に合わせてコメントを投稿・表示できます。

コメント機能は「コメントシステム」にゲーム状態を伝えると、コメントがゲーム上に流れます。ゲームは動画と異なり、時系列のようにプレイヤー全員が共有しているコンテンツの内部状態が存在しないため、ゲームでは逐次ゲーム状態をコメントシステムに伝える必要があります。この「ゲーム状態」のことを本システムではgame position(gpos)と呼んでいます。

RPGツクールシリーズにおいては、イベントごとにgposをコメントシステムに伝達しています。そのため、例えば「ヒロインのセリフ」など特定の状態をプレイヤー間で共有できます。もし、あなたがアクションゲームをつくるなら「敵を倒した」「アイテムを得た」などのイベントをgposとしてコメントシステムに伝えることになります。

なお、ギフトが贈られると画面上にギフト演出が発生し、同じシーンに差し掛かると他のユーザーにもそのギフト演出が発生します。これもコメントのgposシステムを共用しています。

RPGツクールMV/MZ製ゲームの場合、ゲームアツマールが挿入する rpgatsumaru.js によって自動的にこの機能を利用しています。

例えば以下のゲームで、この機能を利用してゲーム上にコメントを表示しています。

詳細

gpos v1(gm16980以前の場合)

本機能を実行した際に、次のような操作を行います。

  • コメントシステムのscene設定
  • sceneの切り替え
  • contextfactorの設定
  • contextの設定
  • minorcontextの設定

gpos は scene と contextfactor と minorcontext という3つのパラメーターで表現します。プログラム的に書けば以下のようになります。

gpos(scene, context(contextfactor[0,-1,-2]), minorcontext)

scene はコメントデータ群を表しています。scene 1つあたりで最新1,000件(※変更可能性有り)で、直近5つの scene をAPI側でキャッシュ(※変更可能性有り)します。一般的なゲームではマップや戦闘画面、メニュー画面に相当します。

scene のコメントを、context の値で指定し取得することでコメントが描画されます。context は状態遷移マシンになっており、contextfactor を push することで状態が1つ進みます。状態は最新の contextfactor 3つの複合キーで表されています。context をさらに細かく分割する場合、たとえば「あるイベント内の時間」などを示すには minorcontext が便利です。minorcontext を push するごとに状態が細かく進み、それに応じたコメントが描画されます。

RPGツクールMVにおいては scene は map の id に対応します。contextfactor は「セリフ」コマンドと「選択肢」コマンドで、minorcontext は「ウェイト」コマンドと、コマンド内の wait に対応します。minorcontext があることで、「セリフのあとにキャラクターが移動して演技する」ような演出に対して細かくコメントができます。

概念図

gpos v1の問題点

ゲームアツマールのサービス開始当初より、前節にあるようなgpos自動設定(区別のためgpos v1と呼びます)を実施しており、RPGツクールシリーズのゲームにおいて「ゲームシーンに対応したコメントを投稿&閲覧できる」という目的を達成することについては一定の成果がありました。

しかし細かく検討していくと、明らかに同じゲームの状態である(例:「こんにちは」と言っている村人に話しかけている)のにも関わらず、違うgpos状態を持つことがままありました。違うgposを持つということは、その同じ村人に話しかけてもプレイヤーによってはコメントが表示されないこともあるわけですから、せっかくのコメントが他人に見てもらえないという問題が起こります。また、実際のコメント投稿数の割には、コメントが少ないような印象を与えてしまいます。

また、gpos v1の難解さも問題でした。gpos v1はまさに前節に解説してはいますが、複雑な構成となっており、理解するのには時間がかかります。APIを用いてゲーム作者がコメントシステムやgposを活用したくても、gpos v1の全容がつかめないとうまくいきません。更に、gpos v1の状態からゲームの状態を復元することができないため、せっかく理解してもコメントがどのシーンについてるのか結局わからないという問題もありました。

そこで諸々の問題を解決し、「同じシーンを正しく同じgposにする」「システムをわかりやすくする」「gposを解読(ゲーム状態の復元)可能にする」ため、あるタイミング以降に投稿されたゲーム(gm16980以降)では以下に示すgpos v2を採用するようにしています。

gpos v2の詳細(gm16980以降の場合)

gpos v2では、gposはシンプルに scenecontext の2つの値で表現されます。 scene はゲームのシーンを分ける大まかな区切りで、その値は map1 map2 ...といったように原則「どのマップにいるのか」が map + マップID の形で表されます。なお、例外的にゲーム開始直後のタイトル画面のみ __title という値を持ちます。

context は各sceneごとに存在する更に細かい区切りで、主に「どのイベントのどの文章まで表示されたか」を値として持ちます。具体的には /v2/イベントID/ページ番号/文章の要約 の形で表されます。

文章の要約

文章の要約は、イベントコマンド「文章の表示」において表示される文章の 各行の先頭文字と終了文字をつなげたもの となります。ただしgposはascii以外の文字(日本語など)を持てない仕様となっているため文章の要約はURLエンコード(encodeURIComponent())されます。この仕様のため、逆に違う文章が同じgposになってしまう可能性が多少あります。(例:同じ村人イベントが 同じページで 「こんにちは」と言ったり「こんばんは」と言ったりする場合。ページが違うならセーフ)

以下にいくつか、具体的なゲームの状態とその際にgpos v2でどのようなgposを持つか(表示は RPGAtsumaru.comment.verbose = true とした際の表示に準拠)を掲載します。

タイトル画面

gpos v2 updated.
  scene: __title
  context: v2/
  context(decoded): v2/

タイトル画面のみ、sceneは特別に __title となりcontextも特別に v2/ のみとなります。

最初の村(マップID:1)で最初の村人(マップイベントID:1)が「こんにちは」と話す

gpos v2 updated.
  scene: map1
  context: v2/MapEvent1/page1/%E3%81%93%E3%81%AF
  context(decoded): v2/MapEvent1/page1/こは

んにちを取ってこはが文章の要約となります。

廃墟(マップID:2-4)内で一定時間ごとに「振り子時計から鐘の音が聞こえた…」と表示されるイベント(コモンイベントID:2)

gpos v2 updated.
  scene: map4
  context: v2/CommonEvent2/page-/%E6%8C%AF%E2%80%A6
  context(decoded): v2/CommonEvent2/page-/振…

コモンイベントにはページがありませんから-で表されます。また、sceneはその時にいたマップIDに依存します。同じイベントを起動しても、マップが違えばgposは違うものになることにご注意ください。

廃墟屋上(マップID:5)での戦闘でボス(敵グループID:10)が「ぼくアツマライオン!(改行)みんなでゲームを作って楽しもう」と話しかけてくる

gpos v2 updated.
  scene: map5
  context: v2/BattleEvent10/page1/%E3%81%BC%EF%BC%81%E3%81%BF%E3%81%86
  context(decoded): v2/BattleEvent10/page1/ぼ!みう

バトルイベントでも、sceneは戦闘開始時にいたマップのIDとなります。

gpos v3(gm18478以降)

v3では、v1の「同じシーンでもコメントが出てこない場合がある問題」とv2の「違うシーンなのに同じシーンと判定されてしまう問題」(それ故に「同じコメントが何度も流れてしまう不具合」としても認知されています)の両方を解決します。

gpos v3では、gposはシンプルに scenecontext の2つの値で表現されます。 scene はゲームのシーンを分ける大まかな区切りで、その値は map1 map2 ...といったように原則「どのマップにいるのか」が map + マップID の形で表されます。なお、例外的にゲーム開始直後のタイトル画面のみ __title という値を持ちます。(つまり scene については、v1, v2, v3でルールは共通です)

context は各sceneごとに存在する更に細かい区切りで、「文章の表示」コマンドでどの文章が表示されたかを値として持ちます。詳しくは以下の例をご参照ください。

◆文章:なし, ウィンドウ, 下
:  :やあ\N[1]!
:  :今日はいい天気だなあ、なんてね。
:  :ぼく\C[6]アツマライオン\C[0]!
:  :みんなでゲームを作って楽しもう。

このような文章があるとき、まず置き換え可能な制御文字を置き換え済みとします。例えば一人目のアクターの名前がハロルドであれば、以下のようになります。

◆文章:なし, ウィンドウ, 下
:  :やあハロルド!
:  :今日はいい天気だなあ、なんてね。
:  :ぼく\C[6]アツマライオン\C[0]!
:  :みんなでゲームを作って楽しもう。

色替え制御文字\C[n]は文字で置き換えられるコマンドではないため、そのままとなります。またプラグインで制御命令を増やしている場合そちらも置き換えられる場合があります。(プログラム的には、 Window_Base.prototype.convertEscapeCharacters が適応されることになるため)

置き換え後、次に文章を一列に直して12等分し、各領域の左端と重なった12文字をピックアップします。(改行は一文字と数える)

あハロル!(改行)今日いい天気なあ、なてね。(改行)く\C[6]アツマラオン\C[0]!(改行)んなでゲムを作っ楽しもう。

やドはだんぼ]イ[みーて

最後にURLエンコード(encodeURIComponent())して、先頭に v3/ を付け加えます。

v3/%E3%82%84%E3%83%89%E3%81%AF%E3%81%A0%E3%82%93%E3%81%BC%5D%E3%82%A4%5B%E3%81%BF%E3%83%BC%E3%81%A6

利用方法

方式利用方法備考
プラグインでの利用方法プラグインでの利用方法RPGツクールシリーズユーザー向け
APIAPIでの利用方法の「コメント」項を参考に、APIを実装してください他ゲームエンジンやより高度な利用を必要とするユーザー向け

最終更新日

  • 2021/02/09