ベーマガ世代、ChatGPTとゼロからRPGを作る旅
第15章:小ボス戦と関連マップの作成
小ボス戦のデザイン
連載とコラムをくまなく読んでいらっしゃる方はお分かりだろうが、本作では、ラスボスと中ボスの手前に、小ボスともいうべき存在が誕生してしまった。
ヒロインを選んだ後、頼まれたクエストをこなすのに「そこらへんの雑魚敵を倒してアイテムゲット」する予定だったのだが、ChatGPTと話している間にボス級に昇格してしまったのである。
そもそもモンスター作りのセンスがないので、視覚化はChatGPTにおんぶにだっこ。
ボスのうちの一体に、ムカデベースのキャラを考えていたのだが、なかなかうまくいかない。
ネットで調べていたら「トビズムカデ」という可愛いムカデを見つけたので、可愛い虫系にアレンジしてもらえないかなーと思ったのだが……
やっぱりなんか虫ベースだと可愛くするのが難しい。
というか、グロテスクになりがち……
いい加減、虫から離れるべし!
ということで、ムカデキャラは採用見送り。ヘビのモンスターになった……!
マップ作りで悩む
ボスのデザインや特性もともかく、ボスにたどり着くまでのマップがまた難物である。
そのうちの1つは、どうにかこうにか雪山を描いてみて配置した。
せっかくなんで、山の表と裏を行き来できるように作ってみた。
遠近感がないので、エッシャーのだまし絵みたいな、頭がぐるぐるしてくるマップなのだが、まあとりあえず良し。
途中、やはり頭がぐるぐるして道に迷ったであろう、旅人の骸骨(!)なんかも配置しておいた。
骸骨は、骸骨の写真とにらめっこしながら、手で描きました。
問題はこの雪山へのルート。
どこから雪山のマップに飛ばせばいいんだ?
今あるマップのどこかに雪山への通路を入れられる場所なんてあったっけ?
クエスト解放前にうっかり突っ込んだら、レベル差でたいへんなことになるし……
さらにあと2体の小ボスの潜む、<森>と<地下通路>も考えねばならない。
まず森だが……
森はオーソドックスな場所なので、他にもすでに存在する。
まず、ハーマの村からブレイマーの町に移動する間に見える、草むらと森っぽいもの。これはドラクエ1的縮尺で描かれている。
ハーマの村の南に広がる森は、もう少し先のクエストで登場する。
こちらはちょっと迷路みたいな意地悪なしかけをほどこしてある。
で、3つ目の森……? そろそろネタがつきた。
同じような森を歩き回るのはプレイヤーにとっても苦痛だろうし、あまり凝らずにそれっぽい森を作れないものだろうか……
もう一方の地下道……
中ボスのいる神殿の仕掛けは人工物なので、少々幾何学的に作ることでどうにか切り抜けた。
しかし、自然の洞窟ってのが、どう描いていいか分からない。
あまり複雑なルートにするのもつらいし……
ラスボスのダンジョンに向かう洞窟とかとも差別化したいし。
困り果ててChatGPTに相談してみる。
RPG作るの初めてなので、マップ作りがへたくそで、これら小ボスを置くマップの場所について悩み中。
そもそもヒロインを選ばないと各小ボスのマップに行けないようにすべきかな、、、と・・・
初期村であるハーマの村の西にブレイマーの町があるけど、間のフィールドは結構狭い。
山に囲まれていて森と曲がりくねった道があるだけ。
ブレイマーの町は北に門があるけど、そこは王都につながっていて、中ボス倒してからでないといけない。
1)ヒスイヘビはブレイマーの町の井戸の中から行ける…とかにしようかと考え中。なんか短い洞窟みたいのを作ればいいかな…と。
2)ダンシングウルフは森にいそうだけど、どこに出現させるか迷い中。
3)●アイテム名●は山頂に咲いているのがいいかと思い、雪山風のマップをいったん作ってみた。けど、山のマップとどこをつなげるのか迷い中。
小ボスがそれぞれ個別の意味を持ち始めた時点で、マップ構成=ゲーム体験の構成になるので、かなり重要な局面ですね。
💡導線・構成の意図
井戸:町中で完結する小さな冒険。ヒロイン(幼なじみ)との距離の近さを反映。
森:ブレイマーの南、フィールド上に明確な入り口。シルフィの行動的な性格にマッチ。
山道:最も遠くてハード、でも景色が変わって盛り上がる。地主の娘の「こだわり」と「上流感」に通じる。
✍️補足:マップ作り初心者へのアドバイス
マップサイズは無理して広くせず、1スクリーン内にまとめられる程度でOK。
凝った構造よりも、「移動距離」「風景の変化」「イベントの密度」で満足度は変わる。
プレイヤーに「自分で見つけた」と思わせる導線が理想(行けなかった場所がヒロイン選択で通れるようになる=ご褒美感)。
すごい。導線の意味付けまでしてくれた。
そういえば見張りの塔のところにドアがあるから、兵士に開けてもらって山道への裏道に案内してもらう感じかなあ。
🗻【裏門と見張り塔】=地主の娘ルートにぴったり
高貴なお嬢様ヒロインが関わるのに、正面じゃなく裏門から山へ続く道ってのが逆にいい味です。
「表の王道ではなく、特別なルート」「見張りの兵士に話を通してもらう特権」って感じが、お嬢様のコネ感とマッチ。
🚪演出案
町の北西の塔に行くと兵士が「この裏門は立入禁止だ、…お嬢様の紹介? …しかたない、案内しよう」的な会話。
ドアが開く → 一瞬イベントで山のふもとまでの「暗転ファストトラベル」演出でもよし。
秘密の地下の抜け道を歩いていくのもエモそうだけど、どうせ繰り返したらショートカットしたくなるだろうし。
ってことで、暗転ファストトラベル採用。
さて、地下道だが……
実は薬草師のおじいさん、家にいなくて、家の近くの空井戸の中で腰を痛めて困っていてw
主人公はそこに降りてお爺さんから「ヒスイの根を取ってこい」と言われる。
なので、
案1:その空井戸からさらに地下に降りるor横道などに入る
案2:町にあるもう一つの井戸に、実は横道があって、そこからこっそり降りる
等を考えてる。
うおお最高じゃんその展開!
薬草師のおじいさんが井戸で腰やっちゃってるって、イベントの導入としてもバッチリだし、そこから地下へ繋がる導線としてもすごく自然。これは活かすしかない。
ChatGPTが、pythonのmetaplotライブラリを使って、イメージ図を描いてくれた。
フォントが存在せず豆腐(□)になってしまうので、フォントファイルを渡してあげるのはお約束。
地図を見せたりして向きを変えてもらおうとしたが、構造変わらず
ここまでできるのなら、いっそもっとリアルなマップを作ってほしいなあ、と、ちなみに井戸の配置なども見せたけど、向きは調整してもらえなかった。
やはりLLMはあまり幾何学構造は得意じゃない気がする。
ChatGPTは「光が差す井戸」とか「蔦をかき分けて……」とか「ロープが切れかけてて……」とか素敵演出案をたくさんあげてくれるけど、技術的時間的に追いつかないので、必要最小限実装した。
森のマップのアドバイスも、なかなかなもんでした。
【森の入口】
南門を越えて入る
昼のBGM → ここから森用BGM(静かで鳥の声+風音)
開口部が狭く、枝や葉でフレームが縁取られてると雰囲気UP
・・・中略・・・
「動物の足跡」や「木の根に引っかかった布の切れ端」とかでヒント感を演出
【風の通り道】
木がまばらで、風が通る場所(視覚的に「光の筋」や「風の音」演出)
・・・中略・・・
中央に切り株、風のささやき、周囲の草が揺れる
「ダンシングウルフ」登場 → 軽やかに動きつつ戦闘へ!
💡演出+イベントのヒント
🐾 小動物の気配 → 「森に入ってすぐにウサギが走って逃げる」など
🧵 途中に靴の材料のヒント:引っかかった皮、狼の毛など
🎵 戦闘前:「森の風が止まった…」→ 無音 → ボス登場!
なんだこの素敵演出。
実現したら、もうプロのクオリティじゃないですか。
……結局、ほぼ採用できていないので絶対に期待しないでください!
小ボス戦専用演出
さて、小ボスとなると、戦闘プログラムのほうも、いろいろな追加仕様が必要である。
まずは、忘れちゃいけないドロップアイテムの実装。
ボス戦後、イベントスクリプトに戻って自由に作る手もあるが、ChatGPTが提案してくれた以下案が優秀だったので採用した。
① 敵に specialDrops を定義
enemyList["jadeserpent"] = {
name: "ヒスイヘビ",
...
specialDrops: [
{
condition: () => questLog.main5 === "start",
item: "ヒスイの根",
quantity: 1,
}
]
}
② battleStep("getitem") にドロップ処理追加
let specialDropLines = [];
for (const enemy of battleEnemies) {
totalExp += enemy.exp || 0;
totalGold += enemy.gold || 0;
if (enemy.specialDrops) {
for (const drop of enemy.specialDrops) {
if (drop.condition && drop.condition()) {
addItem(drop.item, drop.quantity);
specialDropLines.push(`${drop.item}を手に入れた!`);
}
}
}
}
③ メッセージ表示に組み込む
messageWindow.setText( [ `あなたは経験値${totalExp}、${totalGold}Gを手に入れた`, ...specialDropLines ],() => {
playerStatus.exp += totalExp;
playerStatus.gold += totalGold;
questLog.main5 = "check";
tryLevelUp(() => { ... });
});
これなら、ボス戦以外の通常敵とのバトルでもアイテムをドロップさせられる。
敵から毒攻撃を食らうだけでなく、こちらからも投擲アイテムで毒を与えられるようにした。
もともとバトルステップは、
照準設定(player-targeting)→攻撃発動(player-attack)
という二段階になっている。
同様に、アイテムにも射程を作り、
照準設定(player-item-targeting)→攻撃(player-item-attack)
という流れを追加。
ターンごとの毒ダメージは、主人公側に設定されていたものがそのままでOK(敵と味方どちらにも適用されるように作っていたため)。
逆に初回当たった時にダメージを与えられるような処理と、ダメージを食らった時の演出(色や音)を追加した。
射程が広めなので、二体同時に当たった時の処理も必要だ。
それに伴い同じ名前の敵だとどちらに当たったか分からなくなるので、同一名の敵には表示名を追加して、連番を振るようにした。
さらに忘れちゃいけないのが、毒を食らって体力を減らした後に、死亡判定を入れておくこと……!
自力でゼロから開発していると、「体力が0になったのに死なない」なんてことが普通に起きるから要注意だ。
ボスとのエンカウントについて、「特定のマップ位置に立ったら突入!」というパターンもあるが、エンカウントというか、話しかけて突入のバターンも作りたかった。
そして、ボス画像は少し大きいので、通常のNPCと同等には扱えない。
ボスキャラについて相談。
通常のNPCってすべて48px×48pxで書いてるけど、ボスって大き目だったりすることがあるよね。
フィールド上では、通常どうやって表現しているんだろう。
① 通常サイズの「象徴」だけ配置
② 巨大ボスをそのままフィールド配置
③ 背景として描写 + 小さな当たり判定
ChatGPTによると、理想的な流れは以下の通り。
🐺 理想的な流れ
1. フィールド上
• 48×48 に収めて座らせた(または縮こまった)状態
• → **「寝そべり」「丸まっている」**感出すと自然
2. 話しかける
• 座り状態から立ち上がる
• アニメーション差し替え+鳴き声効果音
• 紫エフェクトやカメラ揺らしで緊張感UP
3. 戦闘突入
• ここで本来の96×96や2タイル分の姿に巨大化
• 背景も森の奥に変わって**「ウルフの縄張り」感演出**
しかし、寝そべっている絵も既に48×48に収まっていない。
目が疲れるから、描きなおしたくない、と話したが、ChatGPTは、どうにも聞いてくれそうにない。
まあ、AIの賛同を得られないくらいで、おとなしく引き下がる私ではない。
作ってくれないなら自分でどうにかするまで。
自分の脳内に実装イメージができているし。
結局、NPCの画像をこうやって分割し、イベントスクリプトレベルで自力で対応した。
必殺……分割!
家族に「レトロっぽいテク!」と言われたけど……その通り。
そう、少ないメモリ、制約だらけの世界で工夫してきたのが、ベーマガ世代の知恵。
こうやって「普通ならできないはずのことを可能にする」創意工夫が楽しいんだよ……!
今回は小ボスと相性のよかったマップ周りの記事をまとめた。
【状態異常】周りは別途書きます……!