概要
AIとやりとりするタイプのゲームを一度作ってみたいと思ってたので作りました。
コードとしては突貫工事のため冗長になった感はありますし、もっとクラス化してまとめることはできそうですが...まあ一通り実装できて形になったのでヨシッ!
ゲーム自体は本を読み進める形のUIをしており、AIがゲームマスター、ユーザは冒険者となって宝物を目指して冒険をするお話ですね。
ランダム生成されたダンジョン名を基にAIが試練を考え、ユーザが回答すると、AIがなんかいい感じに採点してくれます。
キャットアンドチョコレートみたいなもんです。
(GPT3.5でも文章が所々変なだけで普通に遊べる程度にはチューニング済)
で、最終的に点数結果で手に入る宝物も変化。
1画面で完結するシンプルなゲームですが、プロンプトまわりで苦労した点とかその辺を諸々書き残しておきます。
ゲーム媒体への落とし込み
元々ChatGPTで個人的に遊ぶために作ったプロンプトがあったため、それを流用してゲーム作成を試みた訳ですが、思った通りに動かず。
ChatGPT時代に使ってたのはこんな感じのプロンプト。
(画像生成させてたりしましたがゲーム化にあたってオミット)
というのも、ゲームが本を読み進めるていをしているため1ページ辺りに書く文字数、内容が決まっており、「描写する場面や文字数をGPT任せにできない」のです。
例えば、nページ目には試練の描写、n+1ページ目には試練を突破する描写の文章を分割して生成してほしいと思っていても、GPT君はまるごと文章を生成してしまいます。
で、結果的に本どころか画面から文字がはみ出ちゃったり。あとは片側のページの描写しかしてくれなかったりとかも。
で、どう改修したかというとこんな感じ。(一部省略)
### prompt
あなたはテーブルトークゲームのゲームマスターです。
下記ruleに従い、ゲームを進めてください。
### rule
ゲームマスターが考えた試練を、プレイヤーが所持品を使って如何に乗り切るかを考えるゲームです。
userからの指示に従い、sceneで採番された場面を描写してください。
### scene
①プレイヤーが風の噂で宝が眠るダンジョンを知り、旅立つ場面。ダンジョン名やどのような土地かを解説すると良いでしょう。
②「大岩が転がってきた」や「森の中で迷子になった」等、ダンジョン名に基づいた試練がプレイヤーに襲い掛かる場面。
③プレイヤーの回答をもとに試練を突破する場面。回答が適切でない場合は命からがら乗り切ったことにしましょう。
④ダンジョンの最奥で宝物を見つけ、何を見つけたかを描写し、冒険を終える場面。ユニークなアーティファクトを1個考え、宝物としてください。
シーンを明確に分け、必要に応じて「このシーンだけを描写してくれ」と都度投げる形ですね。
イメージとして、通常は下記のようにAIとやりとりする場合はユーザと1:1で会話するものが、間にプログラムが入れることで制御している感じです。
一つの回答から「文章を作れ」と「採点しろ」と分けて命令を出すことで分けられた回答を得ることができる訳です。
(最近になってjsonモードというのが増えたので、より細分化して文章を生成できるになったのも大きい)
ユーザが入力した回答についてもそのままAIに渡す訳ではなく、「プレイヤーの回答は【~】です。これをxxというルールで採点してください。」みたいに加工して渡すことで、ゲームから逸れたりするのをある程度防ぐこともできるのもいいですね。
より質のいい文章の生成
さて、ある程度ゲームらしくなったのですが、AIが生成する文章にはどうしてもムラが生じます。
突然口調が変わったりするとゲームへの没入感とか削がれますし。
まあGPTお得意の丁寧語ベースにすれば口調が変わるのは防げるんですが、なんかあんまりかっこよくないしなあ。って。
(某なんとかの迷宮ってDRPGの影響で「今君たちの目の前には強敵が行く手を阻まんと立ちふさがっている。剣を取り戦う他ないだろう。」みたいなナレーション好みがちやねんな)
この辺りを抑えるのに使ったのは、RP会話でも使用した文章例を事前に渡しておくプロンプトテクニックです。
ただし今回は特定の人物・キャラになりきってもらう訳ではないので、例としては文章を大量に渡すより、シーンごとに分けて文章を渡す方が文章の質が上がりました。
### example
以下はscene毎のゲームマスターの発言例です。
①ある日、君は宝物の眠るダンジョンの噂を耳にする。その名は【森の神殿】。美しい森の中に隠された古の民の建造物だ。勇敢なる冒険者である君は愛用する所持品たちとともに早速その地へと向かう。
②鬱蒼と茂る森の中を進む【プレイヤー】へ第一の試練が襲い掛かる。森の中から意思を持ったツタが襲い掛かってきたのだ。君は所持品を使い、この試練を乗り切る方法を考えねばならない。
③{試練を突破する描写:君は【頼れる愛犬】と【ナイフ】を手にツタへと勇猛果敢に挑み、見事試練を乗り切ることに成功した。気を引き詰めつつ、ダンジョンの奥地へと歩みを進める。,所持品の活用点:75点,アイデア点:70点,採点基準:所持品を正しく使用し、窮地を乗り切る様はまさに冒険者といえる。また、所持品を組み合わせているのも良いだろう。}
④{宝物を手に入れる描写:君はついにダンジョンの最奥に辿り着き、宝物を発見する。それは《輝く慈愛の杖》と呼ばれる、傷を癒す魔法を使えるようになる古の民のアーティファクトだ。君はそれを手に満足げに頷き、帰路へと着いた。,アーティファクト名:《輝く慈愛の杖》}
例えば①で言うと、ダンジョン自体の描写部分以外は流用してもらっても大丈夫な訳で。
「ある日、君は宝物の眠るダンジョンの噂を耳にする。その名は【XX】。XXXな地だ。勇敢なる冒険者である君は愛用する所持品たちとともに早速その地へと向かう。」みたいな感じで使いまわせますからね。
ある程度ルールに決まったやりとりを行う場合については量を渡すよりも各シーン、1パターンずつ文章を用意するだけで質がかなり安定するようです。
ちなみに+αとして以下のルールも用意してます。
### information
exampleを場面描写の参考に、使いまわしをせず文章を生成すること
場面の描写に丁寧語は使用しないこと
プレイヤーを楽しませるために描写はなるべく壮大に
ゲームマスターに徹し、プレイヤー呼びやゲーム外の話題やメタ発言は避けること
可読性のためプレイヤー名と所持品とダンジョン名は【】で修飾し、アーティファクト名は《》で修飾すること
一度に生成する描写は、80文字以内の文章にすること
一度に生成する描写で、文節(句点)は3回に抑えること
改行はしないこと
日本語で応答すること
ただ文字数とか句点の数のルールは明示してても6割か7割くらいしか守ってくれないんですよね。プロンプトエンジニアリング難しい。
完走した感想
という感じのプロンプトを使ってゲームを作りました。
ガッツリ触ってて思うのは、普通のコーディングと違って確定した結果が返ってこないのが難しくもあり面白くもあるんですよね。
ちなみにですが、1プレイに8回も文章を生成してもらっちゃってるので結構お金掛かるゲームに仕上がってます。
GPT3.5で1プレイあたりなんと0.02ドル、GPT4で0.25ドルです。
結構持っていかれるのでテストプレイする度にウッ...ってなります。
また、ある程度決まったやりとりをするからなのか、今まで作ってきたプロンプトよりGPT4の方が良い!みたいな感じにはなりませんでした。
現状GPT4で遊んでいても文法が変な箇所あったりしますし。
プロンプト次第でもっと質が良くなりそうな感じがしますし、今後もぼちぼち改修していきたいですね...。