【ChatGPT×SceneXplain】大乱闘AIバトルシミュレータを作成して遊んだ!【画像からファイターを自動作成してAIバトル】
◆最終的に出来るゲームの概要
先にゲームの内容を知りたい人向け。
◆初期画面
◆生成されるキャラデータのサンプル
◆2~4人揃えてバトルロワイヤル!!
↓
◆戦闘結果表示画面
◆ゲーム作成のきっかけ
ある日、以下のリンクがツイッターに流れているのを目撃した。
このゲームをプレイした事が、今回のゲーム作成のきっかけだった。
ドハマりした。
内容は文章で説明するよりキャラ作成ページを見せたほうが早い。
つまりこういうことだ!↓
各々が"自分の好きなキャラクター"を実現するために能力値や紹介文を直接入力し、ChatGPTへ送信。
それらファイターの戦闘結果をChatGPTが生み出すバトルシミュレーターだ。
ある人は「最高にかっこいい/かわいい」キャラを作り、ある人は「この能力あったら最強じゃね?」とインチキキャラを作り、ある人は「能力記述欄でChatGPTをハック」して強制勝利していた。(反則)
ChatGPTを土台にすることで成立した「攻略の方法を自然言語で無尽蔵に生み出せるシステム」は、とっかかりのハードルが低く、遊び方は奥深い。
コロナで寝込みながら一人でずっと対戦してた。
攻略が盛り上がっているDiscordもあり、割と盛況しているぞ!
友達に紹介したら、「小学生に戻るな」と一蹴され、一緒にやってくれませんでした。
!!!もっとこういうゲーム欲しい!!!!
ということで、自分なりにAIバトラーにはない面白さを持った、スーパーAIバトルゲームを考え、勉強がてら個人で遊ぶ用に作成してみることにした。
!!!!GO!!!!
1.自分なりのAIバトルシステムを考える
1.1.画像を使いたい!
まず、思ったのが「AIバトルに画像を使いたい」ということ。
文字だけのバトルよりは、ファイターのビジュアルが欲しくなる。
自作の絵、好きなキャラの画像、写真・・・
戦わせたいものはたくさんある。
文字情報から画像生成AIに絵を作らせるという方向を考えたものの、それで理想のファイターが出来るか?というと、そうは思えない。
生成AIのモデルに画風が左右されすぎてしまうし、どこか奇妙なものが出てくるに違いない。
なので、好きな画像や絵を使って戦わせる方向をまずは模索した。
・
・
・
すぐに答えが見つかった。
以下のChatGPTの受け答えは、試しに自作のイラスト(恥)をChatGPT*SceneXplainプラグインに解説してもらった時の画像である・・・
上記の画像1枚から、ファンタジーな世界観を持つキャラ設定を導けている。
着目したいのが、画像では木が一本も生えていないのに「森に棲んでいる」と推測している所。
耳の長い金髪=エルフ=森の住人であるという知識があるのだ。
知識や観察力が必要な部分までAIはプロファイリング出来る。
これだけで、AIバトラーとはまた違ったゲームが作れると確信できた。
AIの"画像分析能力"を生かしたバトルシミュレーターを作るという方向性は決まった。
1.2.バトルロワイヤルしたい
AIバトラーにおける対戦はあくまで1vs1だった。
だが、AIならキャラが揃っていればごく自然にバトルロワイヤルが出来るのでは?と思う。
人の意思から生まれる戦略とはまた違った戦闘風景が見れるのではないか。
戦略的に立ち回る人のように、まずリンチして敵の数を減らしに行くのか、公平にみんなで殴り合うのか、情報が錯綜して訳分からんことになるのか。AIの表現する乱闘が楽しみだ。
サムスのようなファイターが生み出されたら、遠くからチャージショットを打ち続けて欲しい。(文字で表現出来るのか知らないが)
これ以上考える前に作りたくなってしまったので、次の章から早速ゲーム作りの内容に移っていく。
素人の開発過程なんて興味ねえ!という方は、3章「AI大乱闘ゲームを遊ぶ」まで飛ばして良いです。
2.ゲームシステムを作る
2.1.仕様案の策定
使うのは以下のソフト・サービス。
このゲームは、AIバトラーのようにブラウザから気軽に遊べるようにしたい。
また、ChatGPTなどのAPIを使うこともあり、オンラインのストレージは欲しい。
更にはunityのお勉強も兼ねるぞということでwebGL形式での制作に挑戦する。
webGL形式でビルドしたunityゲームはAzureにデプロイして動かす事を目標とする。
ということで製作開始。
以下、主に壁にぶち当たった時の開発過程を紹介していこうと思う。
2.2.Unity分からん。Azure分からん。どうする?
いきなりだが、コーディング能力が全然ない。
Unityが分からない。Azureも知らん。(ゴミ)
ということでGPT-4先生に聞いてみた。
全部教えてくれるし作ってくれる!!!
ということで、開発はChatGPT先生と組んで進めました。
また、開発していく中でこのような記事も発見↓
コード内のプロンプトも励まし仕様にしました。
これのせいでトークンが増えてAPI料金が上がる・・・
GPTは抜け目のないヤツだ
2.3.画面の設計(ステータスパネル)
ひとまず、キャラクター同士の対戦ということで、対戦に必要な要素を考えて「ステータスパネル」を仮組で作成してみる。
1つのパネルには1キャラ分のデータが入る。
各項目の詳細は以下の通り。
上記の通り、キャラクターのステータスや画像を表示する箱は作成できたので、次はゲームの起点となる「画像のアップロード」機能を実装していく。
2.4.Azureに画像をアップロードする機能の作成
◆UnityのWebGLビルドにおけるファイル選択ダイアログの実装
いきなりハマった落とし穴。
Unityエディタ上でアップロードする画像ファイルを選択するダイアログを出す処理は、UnityのライブラリのOpenFilePanel機能を使っていれば簡単。
開発中盤程度までそのまま進めていたのだが、途中である問題に気が付く。
WebGLビルドではOpenFilePanelがWindowsビルド向けのため使えない!
当然なんだろうが、自分にとっては大きな壁だった。
幸い、以下のブログを見つけることが出来、一命をとりとめた。
ありがとうございます。。。
ビルド環境に依存せず、ファイル選択ダイアログを実装できるというのは今後必要となる場面が多そうなので覚えておきたい。
◆Azure Blob Strageに画像をアップロードする
画像をプログラム内に取り込む手段は出来たので、Azureにアップロードするための処理を実装する。
NuGet for UnityをUnityプロジェクトへインストールし、Azure Blob Strage というSDKを使用して画像のアップロードを行えばOK。SDKあれば簡単!
以下のブログを参考にしたおかげで簡単にAzureへのアップロードコードが書けました。
https://blog.jbs.co.jp/entry/2022/08/08/125541s
2.5.AIに画像を渡してプロファイルの作成をしてもらう
Azureにアップロードした画像は、URLでSceneXplainAPIに送信することで、その外見の分析結果について解説文を得ることができる。
Azureへの画像アップロードが完了次第、そのURLをSceneXplainAPIに飛ばして応答となる画像解析文章を待つだけ。
UnityにおけるAPI通信のやり方はChatGPTさんが丁寧に答えてくれます。
2.1に載せたカスの設計図にもあった通り、応答を貰った後はChatGPTに解析文章を送り、それを基に生い立ちや能力を考えてもらうというシステムになっている。
2.6.GPTのfunction_call機能を用いたキャラデータの作成
容姿の分析結果を受け取ったら、次はその内容に基づいて「キャラの名前・能力・必殺技」をChatGPTに決めてもらう。
しかし、GPTの返す結果が「たまにHP項目が欠損している」とか「たまに必殺技を奥義と書いている」など、あいまいな状態だと非常に困る。
そこで、キャラクタープロファイルの作成にはChatGPTに新しく実装された機能である「function_call」機能を使用した。
以下のブログを参考にさせて頂き、作成しました。
プロンプトを送る[messages]項目とは別に存在する[functions]項目には、ChatGPTによる応答を"必ず"、指定された「ラベル名:内容」のペアでJSONファイル出力できる活用方法があるらしい。
これを活用して、2.5でSceneXplainが作成した「キャラクターの容姿分析結果」を入力情報とし、期待する応答として「キャラクターのパラメータ名:内容」のJSONフォーマットが返ってくるようなfunctionsを以下の通り作成した。
functions = new object[]
{
new
{
name = "character_profile",
description = "キャラクターのプロファイリングデータです。日本語で書かれています。",
parameters = new {
type = "object",
properties = new {
FighterID = new {
type = "string",
description = "このキャラクターのIDです。\""+fighterID+"\"です。",
},
character_name = new {
type = "string",
description = "このキャラクターの名前です。15文字以内となっています。",
},
character_background = new {
type = "string",
description = "このキャラクターの生まれ育った生い立ちや現在の状態について、日本語で300字程度の小説形式で改行を入れつつ出力してください。想像力を働かせて、物語を描いてください。キャラクターの名前はcharacter_nameと同じです。",
},
character_skill = new {
type = "string",
description = "このキャラクターの特殊能力について日本語で100字程度で書かれています。想像力を働かせて、character_backgroundの内容も踏まえて作成してください。出力する文章については、「特殊能力:特殊能力名」を冒頭にまず提示し、改行してから解説してください。",
},
character_special = new {
type = "string",
description = "このキャラクターの必殺技について日本語で100字程度で書かれています。想像力を働かせて、character_backgroundの内容も踏まえて作成してください。出力する文章については、「必殺技:必殺技名」を冒頭にまず提示し、改行してから解説してください。",
},
character_HP = new {
type = "string",
description = "このキャラクターの体力の数値です。一般的な素手の成人男性の数値は300です。character_backgroundやcharacter_skillの内容も踏まえて、1桁単位の数値で正確に能力値を見積もり、1~9999までの値で決定してください。",
},
character_ATK = new {
type = "string",
description = "このキャラクターの攻撃力の数値です。一般的な素手の成人男性の数値は100です。character_backgroundやcharacter_skillの内容も踏まえて、1桁単位の数値で正確に能力値を見積もり、1~999までの値で決定してください。",
},
character_DEF = new {
type = "string",
description = "このキャラクターの防御力の数値です。一般的な素手の成人男性の数値は100です。character_backgroundやcharacter_skillの内容も踏まえて、1桁単位の数値で正確に能力値を見積もり、1~999までの値で決定してください。",
},
character_MATK = new {
type = "string",
description = "このキャラクターの魔力の数値です。一般的な素手の成人男性の数値は100です。character_backgroundやcharacter_skillの内容も踏まえて、1桁単位の数値で正確に能力値を見積もり、1~999までの値で決定してください。",
},
character_MDEF = new {
type = "string",
description = "このキャラクターの魔法防御力の数値です。一般的な素手の成人男性の数値は100です。character_backgroundやcharacter_skillの内容も踏まえて、1桁単位の数値で正確に能力値を見積もり、1~999までの値で決定してください。",
},
character_SPD = new {
type = "string",
description = "このキャラクターの素早さの数値です。一般的な素手の成人男性の数値は100です。character_backgroundやcharacter_skillの内容も踏まえて、1桁単位の数値で正確に能力値を見積もり、1~999までの値で決定してください。",
}
},
required = new object[] {"FighterID","character_name", "character_background", "character_skill","character_special","character_HP","character_ATK","character_DEF","character_MATK","character_MDEF","character_SPD" },
}
}
}
GPTより出力されるJSON文字列の例:
{
"FighterID": "1",
"character_name": "アザレア",
"character_background": "アザレアの頬にふいた風は、鮮やかな花畑の香りを運んできました。彼女は遠い森の中で生まれ育った、一変の妖精としての特性をもつ少女です。青空のような透明な青い瞳、金髪の長い髪にはいつも一輪の蒼い花が優雅に飾られています。\n\nどこからともなくやってきた彼女の存在は、いつの間にか村の人々にとって欠かせない存在となりました。彼女の魅力は、単に外見だけではなく、内面の力も含んでいました。子供たちは彼女の優しい物語に夢中になり、大人たちは彼女の賢明な助言に感謝していました。そして、そのひとつひとつがアザレアの魅力を引き立てていました。",
"character_skill": "特殊能力:母なる大地の感覚\n\nアザレアには、自然と一体となる特殊能力があります。彼女はこれらの力を駆使することで、周囲の動植物からの微細な信号を感じ取り、それに応じて行動することができます。花が咲く時期、草が枯れる瞬間を知り、風の流れを感じ取り、雨が降る前にはそれを予知することができます。この力のおかげで、彼女は常に最適のタイミングで行動し、予期せぬ事態を未然に防ぐことができます。",
"character_special": "必殺技:花吹雪舞\n\n「花吹雪舞」はアザレアの必殺技で、彼女が自然の力を最大限に引き出し、美しくも力強い攻撃を放つ技です。彼女の周りには花びらが舞い上がり、それは強力な花の爆発に変わります。この攻撃は見た目の美しさとは裏腹に、強大な破壊力を秘めています。一度この技が発動すると、敵は息の根を止められるばかりか、深い眠りに落ちます。",
"character_HP": "750",
"character_ATK": "300",
"character_DEF": "350",
"character_MATK": "500",
"character_MDEF": "400",
"character_SPD": "450"
}
この機能は"モデル名"-0613以降のバージョンで使用できるようだ。
入力トークン数が大きすぎるとか、ひとまず考えないことにする・・・
これにより、画面上のボタンから画像を送るだけで"AIがファイター用ステータスデータを自動作成する"内部のシステムは完成した。
ここからは、受信したJSONファイルを分解して、2.3で作成したステータスパネルにデータを展開していくことになる。
ChatGPTには、集まったキャラ達で"大乱闘"を起こすために後でもう一度活躍してもらうことになる。
◆自動作成されたキャラクターを試しに見てみる。
以下は、まだ受信したJSONファイルをステータスパネルに展開できていない開発中の画像だが、いらすとやの赤い竜を見て「炎龍焦熱爆発」なる必殺技を生み出してくれてテンションが上がった。そういうノリも行けるんだ。
2.7.JSONデータを基にステータスパネルを完成させる
GPTより受信したJSONデータを分解して、ファイターのパラメータを管理するインスタンスに値を入れ込んでいく。
先程見せたように、GPTからの応答データはJSON形式で成型されているため、NewtonSoft.JSONライブラリのデシリアライズ用の関数を用いて、ファイター用のパラメータクラスインスタンスに簡単に格納できる。
function_callで生み出されたJSONだけを取り出すコードは以下の通り。
public string ExtractContent(string jsonText)
{
var jObject = JObject.Parse(jsonText);
var arguments = jObject["choices"][0]["message"]["function_call"]["arguments"].ToString();
Debug.Log(arguments);
return arguments;
}
「ラベル名:値」となっているJSONデータに対して、ラベル名と同じ名前・データ型のメンバ変数を持つクラスとなっていればOKだ。
1つのFighterクラスインスタンスに1パネルが対応する形となるため、最終的に以下の画像の通り、各フォームの値が埋まることになる。
2.8.バトルシミュレーター機能の実装
キャラクターのステータスが決まれば、後はそれらの情報をChatGPTに渡して戦闘の内容を創作してもらうだけとなる。
ChatGPTに戦闘内容を描画してもらうプロンプトは「AIバトラー」で学習済だ。
以下のようなプロンプトで実行した。
"以上の各キャラクターが戦闘を行います。生い立ち・特殊能力・必殺技・能力値を踏まえた上で勝敗を決定し、その戦闘過程の描写を[邂逅]、[会話劇]、[戦闘開始]、[戦闘終盤]、[決着]、[その後]の6章構成の創造性溢れる小説形式にて、2400字程度の日本語で出力してください。\n"
本当は戦闘に参加する各キャラのステータス文章を展開する下りなど、プロンプト全文は長いのだが、for文で人数分出力してるだけなので割愛。
上記の通り、入力は通常のプロンプトだが、戦闘描写の出力については2.6で説明したfunction call機能を用いて形式を指定し、章ごとに分解した形で受信することにした。
必ず以下のような流れでストーリーが進行することになる。
[邂逅]→[会話劇]→[戦闘開始]→[戦闘中盤]→[決着]→[その後]
3.AI大乱闘ゲームを遊ぶ
3.1.タイマンでテストプレイ
本来、テストプレイは2章に入れるべきかと思うが、もうほぼ遊んでるようなものなので章を分けた。
まだ、戦闘の結果を出力ログの形でコンソールからコピペするくらいしか出来ないが、ゲーム画面上に表示されているか否かの違いしかない。
戦闘描写の内容を確かめるためにも早速テストを開始!
3.1.1.タイマンバトル(テストデータ 同キャラ戦)
GPTとのAPI通信や、戦闘プロンプトが上手く動くかも分からないので、キャラ作成の手間とコストを省いたテストデータ同士でタイマン。
AIバトルシミュレータの初シミュレーションの結果は如何に・・・
↓
↓
↓
何でこうなった。
予想外なことに、キャラ同士の戦闘が発生することはなかった。
しかしまあ、こういう揺らぎが発生することはAIに任せることの面白さの一つだとも思う。
「AとBが戦闘する」という命令に対して、
「AとBが(力を合わせて無から発生した闇エネルギーと)戦闘する」
という答えを返してきたということだ。
肝心の会話劇は正直面白くなかったが、全く同じキャラのタイマンというテストデータのため、仕方ない気がする。
それよりも、テストとしては同キャラであることを不思議なことと捉えて会話劇を展開した上、名前も「リリエン1」と自動でナンバリングして個体を識別することで、物語を読みやすくしていることに着目したい。
このまま色々な組み合わせを試して良いと思える出来だった。
強いて問題点を挙げるならば、
1.文字数が極端に少ない章がある
2.まともに戦闘が発生しない可能性がある。
3.必殺技や特殊能力を使わなかった
くらいだろうか。
1,3は、function call機能で章ごとに最低文字数を設定する他、戦闘の章で必殺技・特殊能力を活用するようにプロンプトを調整すれば良い。
2は、他の組み合わせを見ていくことではっきりするだろう。
3.1.2.タイマン2(エルフ少女 vs いらすとやドラゴン)
テストデータはひとまず卒業し、ちゃんとキャラ生成からバトルまで通しでやってみる。
今回は新しくいらすとやのドラゴンを加え、タイマンだ。
ドラゴンはファンシーな見た目に反して、非常に強い能力で生成された。
バトルの結果は如何に・・・
↓
↓
↓
エルフの少女の勝利。ステータスは飾りか?
しかし、読み物としてはなかなかエキサイティングだったと思う。
クソほど強そうな赤き炎竜の必殺技「爆炎の咆哮」が「既に移動していた」でなかったことにされたのは悲しい。自然と一体になれば最強なんだろう。
3.1.1のテストタイマンとは打って変わり、必死の戦いを両者が繰り広げ、特殊能力を駆使し、必殺技も派手に打ち合ってくれた。
最後の改心展開も含め、赤き炎竜はアザレアに完膚なきまでにボコボコにされている。
プロンプト等の作りこみが浅い中で、ここまでの戦闘描写が出来るとは思っていなかったので、個人的には満足している。
しかし、ステータスの数値ですべてが決まらないのもいいかもしれないが、何回もステータス最強の赤き炎竜が負け続けるのだとしたら悲しい…
パラメータによる有利不利の重み付けはどこまで命令に組み込んでいいのか、判断が難しい所だ。
何回もトライしたいのだが、2体のキャラ作成→戦闘の一連の流れを実行した結果、0.4ドル消えてた。(?)
↓
0.4円ではなく、ドル。1$150円換算で約60円だ。ゲーセンか。
ChatGPTをコスト度外視で利用すると、こうなるらしい。。
下手にトライしまくると、お財布がイッてしまうので、ちょっとずつプレイしながらの改良が必要だ。
ちなみに、AIバトラー界隈では「ChatGPTによるバトルシミュレーションは倫理的に正しいほうが勝ちやすい」という説が囁かれているとか、ないとか。
画像を上げてGPTからバトル結果の返答をもらうという基本の流れは、満足のいくレベルになっているので、UIを整えてちゃんとしたゲームの形に仕上げていく。
直した結果は以下の通り。
◆画面一覧
・キャラ一覧画面
・戦闘待機画面
・戦闘結果表示
・勝敗表示
色々と完成してきたので、どんどん遊んでいく。
3.2.三つ巴戦(ミノタウロス vs いらすとやクノイチ vs 俺)
3.1でタイマンは問題なくこなせることが分かったので、次は三つ巴戦をプレイしていく。
今回はメンバーをガラッと変えていこうと思う。
このゲームを作るにあたって、一つ考えていたのは「画像をアップロードする」というのがトリガーなら、それはそこら辺で撮った写真でも構わないということだ。
話題のネタ作りとして、友人を撮ってドラゴンと戦わせてみる。そういう遊び方も出来るはず。これは文字情報を入力するだけのバトルシミュレータでは出来ない芸当だろう。
ということで・・・
記事に載せたり勝手に戦わせる事に関して、何一つ問題がない実写の人間
=俺。
強くなれ・・・と念を込めて握った拳、その思いはAIに届くのだろうか。
その他の参戦者は以下の通りだ。
◆ミノタウロス(https://commons.nicovideo.jp/works/nc318362)
◆くのいち
↓
↓
↓
色々と強すぎるホーク・ブラヴァード vs 普通過ぎる女ユキカ vs 魔法大国レジスタニア()の革命家レヴァンの異色マッチ。
ホークに蹂躙されつくしてしまうのか。勝負の結果や如何に。
革命の炎、ファイアリー・レヴォルシオンの発動に期待したい。
ちょいちょい挟まれるホークの性転換願望が光る深い作品となっていたが、ユキカとレヴァンが完全にグルで肝心の勝者がよく分からない。
結果表示で見てみると・・・
勝者が一人に決まらないことがあるらしい・・・
しかし、強すぎるミノタウロスが二人の協力プレイにより倒されるという展開は面白かった。
ChatGPTは乱戦もちゃんと処理できる創作力があるようだ。
勝者が一人に決まらない点についてはプロンプトを修正し、必ず一人に決まるよう調整することにする。
3.3.バトルロワイヤル(エルフ vs いらすとや竜 vs 俺 vs ク○ウド)
3.2の内容から、実写の画像を入れたとしても、三つ巴の戦いだとしてもバトルシミュレーションは上手く行くことが分かった。
よって、ついに4人参加でのバトルロワイヤルをする時が来た。
果たしてまともに勝負がつくのだろうか。
ここで更に、新しいメンバーを加えたい。
4人対戦の大乱闘とくればあのキャラが必要だろう・・・!
ク○ウドだ!!!!!!
許して欲しい、一人で遊ぶ用のゲームだから・・・
カッコいいキャラが欲しくなったし、実際ク○ウドがどのようにAIに解釈され、戦闘するのか物凄い気になってしまった。
騎士でもなければ筋骨隆々の男でもない、謎のバカでかい剣を持っているクールなこのキャラは、一体どのようなプロファイルをされるのだろうか。
↓
↓
↓
一応3回はやり直しました。が、クラウド・ストライフ、クラウド・ストライフ、クラウドという結果に。
SceneXplain(容姿分析)では、ファイナルファンタジーという固有名詞は出るものの、クラウドであると明言していない。
それにもかかわらず、ChatGPTは絶対クラウドだと確信しているのが色々と凄い部分だ。
特殊能力:マテリアマスタリ 必殺技:オムニスラッシュ(超究武神覇斬の英訳)というのも、原作準拠な作りこみだ。
おまけ程度に載せると、以下が容姿解析の全文である。長いので飛ばした方が良いかも。
なぜか銃を持っているとされているが、これでも絶対クラウドらしい。
こう断言されると、クラウドは本当に銃を持っていたんじゃないか、俺の記憶違いではないかと不安になる。
最強の元ソルジャー(?)を加えたところで、いざ戦闘へ。
他のメンバーは自作エルフ、いらすとや竜、実写の俺に決めた。
絵面の混沌具合が良い。やはり赤竜はステータス上最強だ。
GPTも自作絵エルフのキャラ生成は慣れた物なのか、春心(はるこころ)と奇妙なセンスを発揮してきている。
実写の俺は怒りがテーマのようだ。レイジというのは怒りと日本男性名のダブルミーニング感があって、少し洒落ている。憎い
一体この謎の集まりで形成されたバトルロワイヤルはどうなるのだろうか。
↓
↓
↓
主人公ツラして色々語っていた春心(はるこころ)さん
まさかの全員回復で大戦犯に。
新参戦のクラウドも全くいいところがなかった。
「それに、結局最後に勝つのは我だ!」と言い放ちキャラ崩壊した上、オムニスラッシュを撃てずに散っていった・・・
三人の見せ場がなく、赤竜に処理されるというなかなか塩辛い勝負ではあったが、春心(はるこころ)のドジというイベントがあり、まずまずの面白さはあったのではないか。
ステータスを考慮すると、何らおかしくない結果ではある。
とはいえ、この勝負については少し物足りないイメージはある。人数に応じて制限文字数を増やすべきだろうか。
何かモヤモヤするので、同じメンツでもう一戦。
クラウドとレイジは二人組で旅をしているかのような設定で乱入してくるし、赤竜が完全なヒール役を引き受けたせいで戦闘が赤竜 vs 三人組となっている等、ツッコミ所が多い試合だったが全員が活躍するアツいバトルだったと思う。
何より、春心(はるこころ)とレイジのサポートを受け、炎のブレスを突破したクラウドが超究武神覇斬で赤竜にトドメを刺すという展開は、先程の塩試合を経た今、期待通りだった。
ステータスで勝る赤竜が敗れるパターンとしては、先程のミノタウロス同様納得性が高いものであった。
ステータス差が開いていると結託するのだろうか?単純に人類3人と魔物の組み合わせだからだろうか。まだまだ遊ぶ余地はありそうだ。
このゲームで遊べるパターンはこれで一通り終了。
開発中にこっそり友人と以下のような遊びもやったりした。
左から、俺・友人の好きなキャラ・友人の飼い猫1・友人の飼い猫2
十分、当初の目的である「画像を上げるだけのAIバトルシミュレータ」は完成したと個人的に思う。
予想できない試合展開は面白かった。一人遊びの道具としてはなかなかの完成度となった。
この後は感想や改善点・問題点の考察なので、蛇足みたいなものです。
長々とここまで読み進めて頂き、ありがとうございました。
よろしければ、いいねとフォローの程、お願いいたします。
4.制作を終えての感想・改善案
◆オンライン対戦したい
やっぱり、色々な人が作ったファイターと戦いたい。
しかし、記事の中でも言及した通り、APIに掛かるコストが尋常でない上、ユーザーが上げる画像によっては著作権や肖像権やら色々なリスクが発生することになるだろう・・・
遠い夢である
◆人力で介入出来る要素を増やしたい
AIがすべてを決めるのも楽しいっちゃ楽しいが、ゲームとしては人力の介入要素も欲しい。
例えば、キャラに対して「戦略カード」を選択して専用のプロンプトを与えることで、戦闘の立ち回りに少しでも影響を与えられるようにするとか。
いっそ、パ〇プロのサクセスのようにキャラを育成してパラメータを鍛えるとか。。。
特能スキルはプロンプトに追加され、有利に働くとか。
ここまでストーリーを作れるGPTなら、ランダムイベントもたくさん作れるだろう。
鍛え上げたキャラをオンラインバトルロワイヤルに送り出してみたい所だ。
AIを利用したゲームの追求は今後も考え続けていきたいところ。。。
◆コストがヤバい
コストがヤバい(2回目)
1キャラ作成文の入出力トークン数について以下にレポートを乗せる
ちなみに、開発中は全くコストのことは考えていない。
モデルは"gpt4-0613"
トークン数については、GPTAPIからのResponse内に情報が含まれているので、それを参考にする。
結果
一回実行すると、キャラ一体につき約0.09$(14円くらい?)消えていたので、詳しい計算は分からんが高すぎることは分かる。
4人作ったら60円も消える。キャラを作るだけで・・・
戦闘描画の方は全キャラ分のプロファイルデータを入力として、戦闘結果の長文を出力する都合上もっと高い。
しかし、これはすべて"日本語"でやってるが故、英語にするとトークン数は減るという。
というわけで、入力プロンプトをすべて英語にして、同じようなキャラを作成してみた結果がこちら
入力について、約500トークンの削減に成功した。
GPT-4のトークンの料金は以下の通り。約0.015ドルの削減となった。
料金表によると、出力も英語にすれば更なる効果が期待できる。
しかし、そこにはいくつか問題点がある。
翻訳を挟むことにより、出力されてくる文章のニュアンスが大きく変わってしまうのだ。
物語を重視するゲーム性が故に、翻訳された文章は堅苦しい上にヘンテコな物になる確率が高い。
定量的なところで言えば、文字数指定が非常に難しくなる点が挙げられる。英文の出力を行う際に、日本語に翻訳した時の文字数を指定する方法はあるのだろうか。
プロンプトのトークン量の削減は、LLMをサービスに組み込む事を考える際、重要な課題になると考えている。
単に日本語を英語にする、など小手先でどうにかする課題ではなく、専用の勉強が必要になる領域として見るべきだと感じた。
今回取り扱ったfunction_call機能など、プロンプトの技法については注意深く観察していきたい。
◆WebGLビルドを本番環境で動かした結果
ローカルのテスト環境ではちゃんと動くし、後はWebGLビルドのUnityプロジェクトをAzureにリリースするだけ。
そう思っていた・・・
以下のブログの方法を参考にしながら、CORS設定に苦戦しつつもデプロイは成功した。
◆結果
ローカルで出来ていたことが本番環境で出来ないタイプのバグが、雪崩の如く襲い掛かる。
無念、Windows64bit向けにビルドし、本当に個人用のアプリとなりました。
元々セキュリティも何も考えずに作っていた物なので、公開する気はありませんでしたが、悔いの残る形に。
タブレットで持ち運んで遊びます。
もっとWebGLを勉強してリベンジしたい。
多分すぐ出来るだろう、起動までは出来ているのだから・・・(死亡フラグ)
◆おわり
以上、画像認識力の向上・創作能力などヤバい勢いで進化するAIの力を今回のゲーム作りで実感した。
マネタイズなど大人の問題を乗り越え、一人遊び用のおもちゃではないサービスがAIで作れるようになる日を夢見つつ。。
アドバイスなどあれば、コメントお願いします!!
この記事を楽しめて頂けたら、いいね、フォローの程よろしくお願い致します。
この記事が参加している募集
この記事が気に入ったらサポートをしてみませんか?