ゼロから始めるアドベンチャーゲーム製作日記
タイトルが某ラノベに似ていますが、まあラノベの話は別の機会に…、笑
いろんな話題を取り扱うブログにしようと決めたのはいいのですが何にするかなぁ、と思っていたところ、先にブログをしている先輩友達に「始めなんて誰も見てないし気にすることはない!」というアドバイスももらったので、自分が一番興味がある内容のゲームづくりについて、以前作ったゲームのことを題材にして書いてみようかなと思います。
実は、この記事は一番始めの記事の予定で書き始めていたのですが、忙しさもあって順番は変わってしまいました。それになんか内容で悩むと公開できなくなるので、拙い文章で内容も未熟ではありますが、とりあえず公開していくのを目標にブログを続けようと思っています。なのでながーーーーい目でよろしくお願いします!
アドベンチャーゲームはiアプリの時代に友達である仲間が制作したのですが、その時に僕もガッツリ協力していたので、その時の事を思い出しながらアドベンチャーをゼロから作った時の苦労なども交えながらお伝えします。題して『ゼロから始めるアドベンチャーゲームの製作日記』です!
基本的には当時の事を振り返りながらアドベンチャーゲームを作っていた時の事を書いていきますが、アドベンチャーゲームを作りたいと思っている人の参考にもなればいいなと思っています。
長くなるかもしれないので一度に全ては書かず不定期連載的にしていこうかなと思っているので、興味のある方はしばらくお付き合い願えたら嬉しいです。よろしくお願いします!
という事で、アドベンチャーゲームの題材としては、以前iアプリで制作した『女子高生探偵来栖レイ』です。このゲームはDOCOMO 901以上(つまりメガアプリ)で『RPG大集合』という有料サイトで公開されていたものです。
このスクリーンショットは以前公開したものから持ってきましたが、コピーライトが書いてありますが2011年、つまりもう9年前になってしまうんですね…。早いものです…。
ということで今回は、このゲームの制作秘話?を中心に、ゲームを作る時の苦労や作り方などを書いていきたいと思います。思い出しながらなので間違っていることや一般的でないやり方なども含まれているかもしれませんが、その辺は一つの例ぐらいに思って多目にみてもらえると助かります。
このゲームは冒頭にも書いたように当時の仲間が制作したものです。なので一番苦労しているのはその友達なのです。ただ僕も微力ながら協力してプログラムもしているので、その時のことを書いてきます。
まず始めに言っておきますがゲームの基本的な部分やシナリオなどはその仲間が作っています。なので僕はプログラム寄りの話が多くなりそうです。ただ一部ディレクション的な立場も兼ねていた部分もあるので、その辺の話題も出てくるかもしれません。
という事で始まります。よろしくお願いします!
第一章『プロジェクト・スタート』
RPG大集合では、別の仲間が『ガラクタ工房』というゲームを出していました。その流れからそのサイトで他のゲームも出そうという話になり、その時にもうひとりの仲間がゲームを作ることになりました。当時、無責任商会に居た『画伯』という男です。
画伯はプログラマーではあるのですが主に業務系の仕事をしていたのでゲーム作りの経験はあまりありませんでした。そこで僕がサポートとして参加し一緒に作ることになり、その時に色々検討した結果、アドベンチャーゲームを作ると決まりました。
無責任商会第3の男(だった男)
残念ながらこのアドベンチャーゲームを最後に引退してしまいました…。
まず僕がゲームシステムをどうするかと考えて、携帯電話ですし、なるべくシンプルに遊べるゲームという方向性でノベル系+αぐらいの感覚で作れるベースのシステムを作ろうと思いシステムのベースを作りました。
ただこのシステムはアドベンチャーツクールほどの汎用性はないですが、どう作るかは作り手次第なところがあって、画伯がこれを使って制作した結果、最終的には僕のイメージとは違う感じのゲームになりました。僕の初期のイメージよりもっとしっかり昔のアドベンチャーゲームっぽくなった感じでしたね。これはこれで画伯の独創性が出てきていていいなと思っています。
そして次に上記の方向性によりコマンドの数を減らすことにしました。でもやりたいことは出来るような感じで、なるべく必要最低限に絞って考えて最終的に以下の4つにしました。
- 『話す』 やっぱり会話は必要ですよね。
- 『調べる』 捜査の基本は調べることから!(って刑事モノではないですが)
- 『移動』 いろんな場所に行きたいですよね。
- 『持ち物』 見つけたものを使うのはアドベンチャーの基本かな。
これを画面上に常に出しておくことでカーソルで選択します。なのでちょっとタブ風UIにもしてみました。この辺りは画伯とも相談して決めていたかもしれません。
実際には選んだ内容によってまた選択肢やカーソルが出てくるので幅広い操作が出来るようにもなっています。もともとはゲームの途中で選択肢が出てくるぐらいの使われ方を考えていましたが、画伯がこの選択肢の使い方を想定よりも多く使い、昔のアドベンチャーゲームっぽい雰囲気になった感じでした。
とまあゲームの内容はこのぐらいで伝わりましたかね? 基本はアドベンチャーなので大きくこのフォーマットが変わっているという事はないです。この内容を元に、これをどのように作っていったかなどの話を中心にしながらゲームの作り方のようなものが伝わる記事になればいいなと思っています。
ちなみにキャラクターデザインや音楽はまた別の方にお願いしています。ただ背景やアイテムなどの小物系は画伯(と奥さん)が実際の写真などを参考に作ったようです。
と、ここまで話しましたが、古い話なのでiアプリと言われてもピンとこない人がいるかもしれませんね。iアプリとはこんな感じです。
iアプリは昔のDoCoMoの携帯電話で遊べるアプリのことです。画面が小さく、とくに容量が少ないので作るのには苦労がいる感じでした。ただこのゲームはiアプリとしては後期のメガアプリというものたったのでメモリは1MB使えてiアプリの中では贅沢な感じでした。と言っても1MBなんてスマホ時代の写真1枚分にもならないですけどね…。
実際には、200KB+1MBだったかもしれません。200KBというのはプログラムの部分に使える最大容量で、1MBの方はデータエリアとしてしか使えません。それにメインメモリも多くないので一度に全てのデータを読み込むことは出来ず、必要になったデータを必要なタイミングで読み込む必要があります。この辺は、さらにデータを圧縮しておくなど色々と面倒くさい部分もありますが、以前作ったリソース管理のシステムなどもあったので、それを再利用して手間を軽減したりしました。
まあ大なり小なり今のゲームでもメモリ圧縮などのリソース管理は必要になるのですが、この時代はそれが少なくて大変だったということですねー…。
でもファミコンなどの時代はもっとメモリが少なかったわけで、僕よりも先代の方々の苦労が忍ばれます…。
ちなみにこのアドベンチャーゲームはプログラムとデータ(シナリオ)を完全には切り離せていません。それは容量などの問題もあったうえでの作り方の工夫でもあるのですが、それでも上記のようにプログラム領域は大きくないので、なるべくデータ化はしてリソース領域の方にいれています。基本的な構成はうろ覚えですが、こんな感じだったと思います。
- メインプログラム(エンジンベース)
- 各シーン(場面)プログラム。(1シーン1クラス)
- スクリプト(シナリオ)ファイル(独自仕様のテキストファイルをバイナリー変換)
- 画像やサウンドなどのリソース
スクリプトファイルは独自の簡易スクリプト言語を作りました。きちんとした構文解析をしているわけではないのですが、手っ取り早くPHPで作成し、ある程度解析してバイナリー化することで容量を少なくしています。
ただ簡易的な処理なので一般的な構文解析・字句解析をきちんとしている感じではなく、この辺はプログラムの都合に合わせて正規表現を利用した処理になっています。
正規表現を利用するスクリプト解析は真面目にやるよりもかなり簡略化できて作るのも楽です。その代わりやりづらいこと(出来ないこと)も多いので、その辺は解析しやすいデータにするように解析側の都合に合わせた設計にしました。
一応シナリオファイルの拡張子は.gscにしました。ゲームスクリプトの略だったかな? とりあえずそんな感じです。これをPHPによる処理をかけてバイナリーデータに変換しています。
基本はシナリオファイルの内容を元に処理されるのですが、部分的に直接シーンプログラムに書いた内容と連携しています。なので全くプログラムが出来ない人では作れないのですが、ある程度簡単には作れるようにしています。
そのような感じでプロジェクトがスタートしました。また詳しい内容は次回に続きますが、最後にシナリオファイルの一部を載せておきます。これは冒頭の1シーンですが、こんな風に書いてあるファイルが変換されてアドベンチャーになっているんだなぁ、とイメージしてもらえたらという感じです。
長くなってしまいましたが、読んでいただきありがとうございました! 不定期連載なので、次の内容が続きとは限りませんが、また次回もよろしくお願いします!
次はもうちょっとプログラム寄りの話にしてみようかな〜? 蔵出し的な制作資料を載せてみるのもいいかも…。まあでも、その辺は気分次第です!
以下、シナリオファイルの一部です! それではまた次回!!
#include "def.gsc"
#include "mrd_def.gsc"
// エピソード0:シーン開始:来栖家 リビング
IF EP0_KURUSU_L_FIRST:OFF
EFFECT SCREEN_FADE_IN, 15
BGM MRD_BGM_MAIN2, true, 2
MSG "ここはどこなんだろう…", CHARA_TAKERU, 0
MSG "全く見覚えのない部屋だ…", CHARA_TAKERU, 0
MSG "……そういえば、僕の|n手足って、こんなに細かったっけ?", CHARA_TAKERU, 0
MSG "それになんだか、やけに|n肌もツルツルしてるし…", CHARA_TAKERU, 0
MSG "うーん、訳がわからない…", CHARA_TAKERU, 0
MSG "ふぅ、喉が渇いた…|n水が飲みたい……", CHARA_TAKERU, 0
WAIT KEY
FLAG_ON EP0_KURUSU_L_FIRST
EFFECT SCREEN_FADE_OUT, 10
SCENE BG_KURUSU_WASHROOM, CHANGE_NONE
//→e00s02.gscへ
ELSE_IF EP0_KURUSU_L_SECOND:OFF
EFFECT SCREEN_FADE_IN, 10
MSG "|w4――夕方。|n|w1― 自宅リビング ―", CHARA_EMPTY, 0
WAIT KEY
SHOW_CHARA CHARA_REI, C_REI_SMILE, TYPE_LEFT, POS_CENTER
MSG "ただいまー", CHARA_REI, C_REI_SMILE
WAIT KEY
BGM MRD_BGM_EP_START, true, 0
MSG "さて……とりあえず、|n今日一日で分かったことを整理しようか。", CHARA_REI, C_REI_KANGAERU
MSG "あなたの名前は、|n|c1『西ノ宮(にしのみや)|nたける』|c0でいいんだよね?", CHARA_REI, C_REI_KANGAERU
MSG "|c1『たける』|c0って呼ぶことにするね。", CHARA_REI, C_REI_SMILE
MSG "ああ。君は、|n|c1『来栖(くるす)レイ』|c0|nだね。", CHARA_TAKERU, 0
MSG "|c1『レイ』|c0って呼んでいいかな?", CHARA_TAKERU, 0
MSG "うん、いいよ。", CHARA_REI, C_REI_SMILE
MSG "たけるは、こうなった原因は分からないんだよね?", CHARA_REI, C_REI_KANGAERU
MSG "ああ、僕にもさっぱり分からないよ。|n気づいたらこうなっていたからね。", CHARA_TAKERU, 0
MSG "そもそも、たけるってば|n何者なの?", CHARA_REI, C_REI_KANGAERU
MSG "うーん、あまり記憶が|nハッキリしないんだけど…", CHARA_TAKERU, 0
MSG "僕は探偵をしていたはずなんだ。", CHARA_TAKERU, 0
MSG "まだ新しく事務所を開いたばかりで、買い物に行こうとして外に出た時に、事故に遭ったんだ。", CHARA_TAKERU, 0
MSG "その事故で意識を失ったあと、気づいたらわたしの中に入ってたんだよね?", CHARA_REI, C_REI_KANGAERU
MSG "あぁ。……たぶん僕は、|nその事故で死んでいると|n思うんだ…", CHARA_TAKERU, 0
MSG "じゃ、たけるは幽霊なの?", CHARA_REI, C_REI_KANGAERU
MSG "分からない……|n記憶はあるんだけど、|n実体がないから……", CHARA_TAKERU, 0
MSG "………………………………", CHARA_TAKERU, 0
MSG "……お願いがあるんだが、病院に行って僕がどうなったのか確かめてみてくれないか?", CHARA_TAKERU, 0
MSG "病院へ?", CHARA_REI, 0
MSG "病院で、僕が本当に存在していたのかを確かめて欲しいんだ。", CHARA_TAKERU, 0
MSG "それはいいけど……|n病院に行って、たけるなんて人が、もしもいなかったら…", CHARA_REI, C_REI_KANGAERU
MSG "それって、いよいよわたしの頭が変になっちゃったってことじゃない!?", CHARA_REI, C_REI_ODOROKI
MSG "はははは…|n恐ろしいこと言わないで|nくれよ。", CHARA_TAKERU, 0
MSG "それを確かめるためにも、病院に行って欲しいんだ。", CHARA_TAKERU, 0
MSG "わかったよ!|nそれじゃ病院に行って|n確かめよう!!", CHARA_REI, C_REI_HIRAMEKU
MSG "|c1【総合病院】|c0|nが移動場所に追加された!!", CHARA_EMPTY, 0
SE MRD_JG_POINT
FLAG_ON EP0_KURUSU_L_SECOND
MOVE_ON BG_HOSPITAL
BGM MRD_BGM_MAIN1,true,0
ELSE_IF EP0_KURUSU_L_SECOND:ON
SHOW_CHARA CHARA_REI, C_REI_SMILE, TYPE_LEFT, POS_CENTER
ENDIF
ディスカッション
コメント一覧
まだ、コメントがありません