ゲームプログラミング/RPG/データベースとは

デーテベース的なこと

編集

ゲームに関すること

編集

試作ゲームならデータ分離は後回しに

編集

よく、「データとロジックを分離せよ」とか、軽々しく言う人がいます。

しかし、次の配列をよく考えてください。

{3,5,2,1,0,2,3};

あなたは他人の書いた上記の配列を見て、 これが

「RPGゲームのモンスターの設定データで、id3番の敵は、最大HP=5で出現,攻撃力は2,素早さは1,防御力は0,倒して得られる経験値は2,得られるゴールドは3のつもりのデータです!」

であると、即座に意味が分かりますか?

データとロジックの分離によって分離されたデータとは、こういうものです。 つまり、アルゴリズムなどのロジックを、データと分離したのだから、結果として変数名などのデータの意味のヒントとなる情報からも、データは分離されます。変数の宣言や式はロジックでありますので。


もちろん、たとえばモンスターが200種類もいるような長編ゲームなら、 最終的に、CSVファイルなどのデータをうまく配列に変換する必要などがあります。なので、膨大なデータの作品では、分離が必要です。


ですが、その分離は、

{
  ・・・前略
  {3,5,2,1,0,2,3},
  {4,6,1,3,1,3,2},
  {5,4,3,3,4,5,4},
  ・・・後略
};

のようなデータを生み出します。これは人間が目で見ても意味が不明です。

なので、けっして開発の当初でいきなり、このような意味不明な数値の羅列データを作るべきではありません。

いきなりこのような羅列データを作ると、数値の意味を思い出すのに時間が掛かったり、数値の何番目かを数えるのにデバッグのたびに時間が毎回掛かるので、いきなりの分離された配列データ羅列のせいで開発の効率が低下します。

なので上記のようなデータベース分離はするとしたら、けっして開発当初ではなく、そうでなく、開発の中盤以降で、要素の無数にあるのような配列データ(または同等のCSVファイル)を、デバッグ時に仕様書などとニラメっこしながらデバッグモードでゲーム起動して間違いが無いかをした上で、実装することです。こういう思考力をあまり使わない作業は、なるべく後回しにすべきです。

けっして、いきなり設計の最初からデータとロジックを軽々しく分離するべきではありません。

いきなり「データとロジックを分離」しようとすると、上記のような無数の数値だけの配列データと格闘することになります。

項目ごとには、まとめない

編集

なお、けっして攻撃力同士をまとめて攻撃力配列 {5,6,4, ・・・後略 } のような配列を作るべきではありません。

「攻撃力配列」のようなものを避けるべきは理由は、C言語の配列の機能だけを見ていても分かりませんし、ゲーム知識だけでは分かりません。

まず、ゲームに限らずIT企業でデータベース一般を管理するときに、たとえば、なんらかのデータベース管理ソフトで、

在庫データベース画面 1/1
ID  品名   メーカー名  種類  在庫  定価  コメント                       
単位  数量  単位  定価 
0 オイシー牛乳 ヤマダ乳業  牛乳  本   10 本  150 円
1 ごくごくオレンジ  ヤマダ乳業 ジュース  8 本  120 円

みたいにデータが並んでいて、小さな事業所でも商品種(上記ソフトならタテ方向のデータ)が100個とか1000個とかある一方で(画面内に収まりきらないので、マウスなどでスクロールして続きを見たり、あるいはボタン「次のページ」「前のページ」などを押す)、

一方でデータベースの横の項目数は上記ソフト画面のように画面内に収まりきる程度の数です(上記データ例なら項目数は9個)。

※ 説明の都合上、読者がイメージしやすいようにスーパーマーケットで説明しましたが。果たして現実のスーパーマーケットで在庫管理ソフトが用いられているか否かは知りません。あくまで説明のための仮イメージです。

もし、ゲームで「攻撃力配列」のようなものを作るとしたら、これは上の在庫管理的データベースでは「品名配列」{"オイシー牛乳","ごくごくオレンジ", ・・・後略 }を作るようなものであり、もしその商店が1000個の商品を扱っているなら、品名配列も要素数1000という巨大配列になってしまいます。

在庫管理ソフトは、もし在庫数の入力ミスがあったら、そのミスのある商品の置いてある現場に行って確認するわけです。

この際、けっして1000現場の確認をするわけにはいきません。(なお、帳簿や在庫管理ソフトなどにある在庫管理データを、データが本当に正しいか否かを現場で確認することを「棚卸し」(たなおろし)と言います。)

そうではなく、もし「ごくごくオレンジ」の個数に入力ミスがあったら、オレンジジュース置き場だけを確認すれば済むように設計すべきなのです。

「攻撃力配列」の問題も同様です。もし攻撃力配列にミスがあった場合、モンスター種類が300体の長編ゲームなら、300体ぶんの攻撃力をチェックする必要が生じます。仕様書でモンスター300体ぶんの300ページをめくりたくないです。これは大変にデバッグ非効率です。

もし、モンスター1体にバグが発見されても、モンスター仕様書の1体ぶんの1ページを見れば済むように設計しましょう。

つまり、int a[1000][9]int[9][1000]とは、ハードウェアのアドレスなどに与える実態の影響が違います。 配列はint a[2次元目][1次元目]というように右のカッコから数えますし、アドレスもそのように配置されます。

なので、{"オイシー牛乳", "ヤマダ乳業", "牛乳"} といった並びになるようにプログラミングしたほうが、アドレスも同じ商品の情報が隣同士になるし、また人間がコードを見てても分かりやすいです。

要するに、デバッグのためにコードを読むのも人間なのです。だから人間が読みやすいコードを書きましょう。 なので、「攻撃力配列」のようなものは、なるべく避けるべきです。仕様書やら設計書を読むのも人間です

例外として、ゲーム内で「攻撃力の高い順にキャラを(あるいはモンスター図鑑中のモンスターを)並び替えたい」などの特別な操作をする場合があるなら、 その操作の直前で「攻撃力配列」に読み込ませるべきであり、大元のキャラクターのパラメータ配列自体は、キャラごとに管理すべきです。

つまり、なるべく、キャラクターのID番号を中心軸としてデータベースなどの紐付けしましょう。アニメ産業もマンガ産業もキャラクターの魅力によって産業が成り立ってます。キャラクターを中心に紐付けしたほうが、共同作業者などにとっても分かりやすくなります。

プログラム上では、キャラクターのID番号を中心に紐付けされるでしょうか。「ID=0、ID=1、ID=2にそれぞれ紐付け」と言うと抽象的で一見すると分かりづらそうですが、しかし「アリス(0番のキャラ)、ボブ(1番のキャラ)、クレア(2番のキャラ)に紐付け」といえば、とても具体的になり分かりやすくなります。

クレアの攻撃力を参照したい場合、「クレア配列構造体の攻撃力パラメータを参照させる」というふうにプログラム設計したほうが、ゲーム作者がクレアさんに「あなたの攻撃力はいくつ?」と擬人的にたずねる行為に似ているので分かりやすくなります。

一方、「攻撃力配列」のような、擬人化したとしたら、攻撃力しか調べられない探偵さんに「クレアについて調べて来い」と依頼する方式は、少し発想が飛躍的です。このような項目専門の探偵さん方式のプログラムも不可能ではありませんが、わざわざ採用するほどのメリットもないでしょう。


ただし、C言語系以外のプログラム言語では、もしかしたら「攻撃力配列」のような項目ごとにマトメざるを得ない場合もあります。言語によっては「構造体」に相当するクラスの概念がなかったり、名称上では(構造体に相当する)「クラス」の機能がある言語でも機能がC言語のクラス・構造体とは大きく違っている場合もあるからです。

とりあえず本ページではC言語系を想定して説明しているので、これ以上の説明の深入りは避けます。

攻撃力配列を作ってしまった場合の修正法

もし、すでに「攻撃力配列」や「守備力配列」のようなものを多く作ってしまっても、消す必要はありません。安心してください。

なぜなら最終的には、それは構造体の配列に変更できるからです(C言語系統の言語なら)。

たとえば、すでに攻撃力配列を

int kougekiR[temp]

のように作ってあって、それで様々なコードを書いたとしましょう。

これを、本文で説明した方式へと直すなら、単に構造体で味方の能力値をまとめて扱う構造体配列 Mikata[temp] でも作っておいて、その構造体の要素に

構造体

{
 int kougekiR;
 int syubiR;
};

などを入れておけば充分だからです。

そして、コンパイラにある一括変換の機能で

kougekiR[temp]Mikata[temp].kougekiR

と一括変換すれば終わるからです。

なので、攻撃力配列を作っても、けっして無駄にはなりません。


キャラクター(登場人物)のID番号は、一変数だけにすべきです。

たとえば、もしゲーム中の登場人物たちが2つのチームに分かれて対戦していても、

たとえば、アリス、ボブ、クレアの3人が「アリスチーム」所属だとして、

ゴンザレス、ポンドロチョン、サンチョス、マリオの4人が「ゴンザレスチーム」所属だとしても、

キャラクターのID設定は断じて

アリス=0、 ボブ=1、クレア=2、ゴンザレス=3、 ポンドロチョン=4、(以下略)

のように通し番号にすべきです。


けっして、c[Ateam][number] みたいにチーム名とチーム内番号のように二変数にしてキャラ登録すべきではありません。

なぜなら、もしゲーム中でチーム移籍とかあったら、二変数でアクセスする方式だとプログラムが混乱するからです。


たとえば「もしボブ(男性キャラ)が、男どうしのゴンザレスチームに移籍したら?」、というような場合があります。


RPGなら、裏切りとか精神操作とかキャラクターが他チームに移動することがあります。(商業ゲームなら、FF4の竜騎士カインみたいな)

歴史シミュレーションゲームなら、三国志の呂布(りょふ)とか太史慈(たいしじ)とか、元・主君への裏切りは史実でもよくあります。(太史慈は孫堅チームに加わる前の主君を謀反で殺して孫堅に差し出しています。)

なお、ゲームに限らず私たちの生きている現実世界でも、IDは一変数にするのが慣例です。だからマイナンバー制度でも、国民それぞれのマイナンバーは一変数なわけです。

どうしてもチームの構成メンバーの情報をプログラム内に入れたいなら、

あらかじめキャラクターの登録そのものは上記のように通し番号で行ったうえで、別途、

チーム番号をアリスチーム=0、ゴンザレスチーム=1 とでもしておいて、

アリスの所属チーム=0、 (アリスチーム)

ボブの所属チーム=0、

クレアの所属チーム=0、

ゴンザレスの所属チーム=1、

ポンドロチョンの所属チーム=1、

以下略

のようにすべきです。これなら、もしキャラクターがチーム移籍しても、

ボブの所属チーム=1、

のように、該当キャラだけ所属チームの設定を書き換えすれば済むので安心です。


ただし、もしかしたら三国志ゲームのようにキャラクター数が多いゲームの場合は、検索スピードを早くする必要があるので、キャラクターごとに所属チームを設定する方法はしづらいかもしれません。

市販の三国志ゲームを作ってるゲーム会社がソース非公開なので仕組みは不明ですが、想像ですが、たとえば

劉備=0、関羽=1、張飛=2、 、曹操=3、夏侯惇=4、 孫堅=5、黄蓋=6、

みたいにして

蜀チーム={0, 1, 2, -99}

魏チーム={3, 4, -99}

呉チーム={5, 6, -99}

とかのようにチーム設定の配列を用意しておけば、もしチーム内の武将が今後に数百人くらいに増えても安心です。


ともかく、IDは一変数にすべきです。

このことはコンピュータ業界の暗黙の前提ですので、市販の書籍でデータベース論の専門書を見ても、書いていません。

しかし、IDはどの書籍でも一変数のはずです(まともな専門書なら)。


なお、IDを一変数にすることで、画面表示のさいは平面ディスプレイで一覧表示などで表示しやすくなります。

一方、もしIDを二変数以上にしてしまうと、平面ディスプレイでの一覧表示が不可能になってしまい、確認しづらくなります。印刷でも、二変数以上だと紙面で一覧しづらくなり、確認しづらくなります。

C言語の都合

編集

さて、

{id=3,HP=5,atk=2,agi=1,def=0,exp=2,gold=3}

みたいな記述をしようとしても、しかし標準C言語では使えません。(「名前付き引数」 (named arguments) という機能は、標準CおよびC++にはない。C#には書式は違うが名前つき引数はある。)

Windowsが実行ファイルのビルドに使える言語として標準採用しているプログラミング言語は C++ です。

なので、処理速度が必要なゲームを作る場合には、標準C言語およびC++で使えない記法を夢想するのは、やめましょう。


また、データベースファイルなどにある"id"などの文字列をインタプリタ的に読み取ってプログラムに条件分岐させるのは、処理に時間が掛かりますので、 ゲームのような速度が必要なジャンルでは不向きです。

実際、プログラミング言語の python が似たような変数名と変数値を一体にした配列のようなものを利用でき、 いろんな業界でpythonは利用されていますが、しかしpythonで商業ゲームの基幹部分を作るという話は聞きません。また、pythonの文法に互換の機能を自前で実装する手間なども掛かります。初心者には無理ですし、初心者いは方針が間違っています。(ゲーム以外のビジネス目的なら、用途によっては時間が掛かってもいいですが、しかしゲームでは不適切でしょう。)

これがたとえば、数値配列ではなく文字列型データの配列なら、

{"アレフ","へたっぴ剣士","伝説の勇者ゴンザレスにあこがれて冒険を始めただけの新米冒険者"}

という配列なら、一目見ただけで「ああ、これはキャラクター設定のデータの配列だな」とか「意味は {キャラ名、職業、キャラ解説} だな」とか分かりますが、しかし{3,5,2,1,0,2,3}のような数値パラメータのデータベース配列となると、そうはイキマセン。

もちろん、たとえば数値配列の意味を説明する別の文字配列を用意して、

{"id","HP","atk","agi","def","exp","gold"}

のような説明用の文字配列を用意して、それと {3,5,2,1,0,2,3} 以下略などを連動させることで意味を分かるようにするという方法もあります。

なお、上記 {"id","HP","atk","agi","def","exp","gold"} のようにデータベースの意味を説明するための特殊なデータのことをデータベース専門用語で「属性」(アトリビュート)という。

id番号はゲーム産業以外でも使う

id番号は別にゲーム業界だけの慣習ではなく、一般のIT産業でもデータベースでも使います。

その証拠の文献として、たとえばプログラミング技術書籍『確かな力が身につくPHP「超」入門』(出版:SBクリテイティブ株式会社)でも、 書籍中のデータベース作成例の図表『Fig データの追加』の図中に何気なくid番号の項目があります[1]

特に、文献中で何気なく図にあるのがポイントです。なぜなら一般に、その業界・界隈で本当に普及しているもの程、当事者は「これは当然である」と思ってるので、なんの説明がありません。

歴史研究では「日常ほど歴史に残らない」という格言があるほどです。なので歴史研究家や古典文学研究者などは、読むべき文献として、けっして有名な史料だけでなく、さらに世間一般の人が読まないマニアックな古文書、果ては古い時代の日記や、単なる記録簿など、さまざまなものに目を通して、なんとか過去の歴史の実態を探ろうとするほどです。

ツクールとかウディタとかのゲームを見ると、たとえばゲームによって、あるゲームでは「攻撃力」だったのが別ゲームでは「ちから」だったりと表記が作品ごとに違うので、 このような編集機能を実装したいならアトリビュート名を編集すれば類似の機能が実装できると思いますが、 さて、ではゲーム開発当初に、そんなデータベース編集実装なんてしてる暇があるでしょうか?

「モンスターidの3番」とか言われても、それが「人食いコウモリ」なのか「人食いオオカミ」なのか、第三者には知りえません。

「データベース配列3番の2項目め」とかいわれて、それが「あっ、人食いコウモリのHPだな」とか、なかなか開発者本人ですら、覚えられません。

データベース編集機能の設計で手間をかけるくらいなら、まずゲーム開発当初ならコード中に直接的に

koumoriHP = 5;

とかベタ書きで書いてデータベース構築すべきです。

そしてデータベースを読み取るコードでは、ベタ書きした変数を下記のように構造体配列などに代入して、

monster[3].HP = koumoriHP;
monster[4].HP = ookamiHP;

とすれば、以降のコードの記述量が構造体配列を使って減らせて短くなる上に、短い割にはコードも分かりやすく、開発の見通しも良くなります。

ただし、この方式だと、全てのモンスターごとに代入の手間が必要です。なのでモンスター数の少ない開発序盤にのみ有効な手法です。

最終的には、冒頭の配列 {3,5,2,1,0,2,3} のようなデータベースを作成せざるを得ません。

ですが、そういう配列データベース作成は、それが必要になってから実装すれば十分です。


さて、キャラクター設定などで、初期設定として

ID=0番, 名前=アレフ, 職業=ヘタッピ剣士, レベル=1, HP=20, 最大HP=20, 攻撃力=8, 素早さ=7

のような初期設定を考えたとしましょう。(他にもMPや初期経験値などパラメータはあるが、説明簡略のため割愛。)

(2人目以降のキャラの初期設定は省略。説明簡略のため。)

ついつい

{0,"アレフ","ヘタッピ剣士",1,20,20,8,7}

のように書きたくなりますが、よくよく考えればC言語の配列では、文字列型と数値型とは混在できません。

しかしこれの解決は単純で、

char* キャラクター文字配列[10] = {
  {"0","アレフ","ヘタッピ剣士"},
  {"1","ベス","魔女"},
  {"2","エイミー","戦士"}
};

および

int キャラクター設定値配列[10][6] = {
  {0,1,20,20,8,7},
  {1,1,13,13,5,18},
  {2,3,25,25,8,10}
};

を両方とも定義すれば済みます。(なお、実際のVIsual C++言語での配列の定義のしかたは、上記の記法とは多少異なる。 この節の本筋とは関係ないので説明割愛。)

ID番号が無いとデバッグしづらくなるので(おそらく、ほぼデバッグ不可能)、定義時に配列の冒頭にID番号をつけましょう。

文字配列のほうにも「"0"」のようにID番号と同じ文字列をつけておくことで、デバッグしやすくなります。

データベース変数の利用とデバッグ

編集

データベースの運用の際には、参照時の番号ズレによるバグを注意しないといけません。

このため、なるべくデータベースからの読み込みを減らすようにプログラムする手法も、よくアマチュアの無料ゲーム制作などで用いられます。

つまり、データベースおよびデータベース変数を作ってはあるものの、しかし、なるべくそのデータベース変数を最低限におさえる開発姿勢で、ゲームを作っていく方法です。具体例は、下記のような事例です。

実際、たとえばソース公開しているフリーゲーム作家のソースコードを見てみると、たとえばゲーム中の会話文などで、町民が道具をプレゼントするイベントがあって、たとえば「毒消し草」を主人公にプレゼントするシーンでは、毒消し草の道具ID番号(\item[6]などの記述)ではなく、直接ソースコードの会話文の箇所に会話メッセージ

"おっ、勇者さんじゃないか!\nほら、毒消し草をプレゼントするよ!!\nこれで毒くらっても治せるさ!"

などとコードが書かれている場合もよくあります。

もし、道具ID番号の方式で書いてしまうと、デバッグの際に、ID番号がいかなる状態でもズレないかのバグを検証する手間が発生するからです。

このように、なるべくデバッグの手間を減らすために、データベースからの読み込みを意図的に減らすコードを書く場合もあります。

たとえばゲーム中で、これから毒の沼地ばかりある森林に向かって主人公たちが旅をするイベントについて話している街での会話イベントなら、「毒消し草」以外のアイテム「メガネ」や「通行手形」をもらっても無意味です。「メガネ」でどう毒を治せというのか?

プログラム時、どうしても会話中にアイテムiD番号の変数を入れる場合とは、たとえば道具屋の主人が、主人公が買いたい道具を選択したあとに

"おっ、\item[v] を買うのか!\n\itemgold[v]ゴールドだよ"

みたいな、毒消し以外にも何十種類もある様々なアイテムにも同じメッセージを場合だけです。

だからもし、ゲーム中であるメッセージ・パターンが適用される道具が2種類か3種類くらいしかない場合(たとえば「毒消し草」と「通行手形」だけにしか適用されないパターン)、いっそ変数を使わずに1個ずつ、

"ほら、毒消し草をプレゼントするよ!"
"ほら、通行手形をプレゼントするよ!"

のように、1個ずつベタ書きするという手も、よく同人フリーゲームのソースコードなどで見かけます。このようなベタ書きによって、テストプレイの負担を事前に減らせるからせるからです。

普通のRPGゲームでは、アイテム名が不変なほか、モンスター名や街や洞窟などのエリア名などもプレイヤーは変更不能なので、そういうのは会話文中では変数にせずに、会話中に直接的に要素名を記入するのも手です。

未実装部分のあるデータベースの対処

編集

初期能力値のデータベース化の実装を進めていくと、 たとえば、まだ「魔力」を作るかとか「運のよさ」を作るとか一切、味方の能力値の変数の設計をどうしようか決めてないのに、 すでに初期装備が決まっていたりする場合もあります。

もし実装した順にデータベースに左詰めをしようとしていくと、

{攻撃力,武器,守備力,防具,素早さ,魔力,運のよさ}

のような順序になりかねず、能力値と別の能力値のなかに装備品があったりして、今後のメンテナンス性を下げそうです。

このため、データベース配列内の順序に悩む場合があります。

しかし解決法は簡単です。単に、新たに「初期初期装備のデータベース」を分けて作ればいいのです。 そして、初期装備データベースと、味方の能力値のデータベースとを分ければいいのです。 つまり

DataBese1[10] = {攻撃力,守備力,素早さ,魔力,運のよさ}
DataBese2[10] = {武器,盾,}

という2段構成です。 こうすれば、まだ未定の初期能力値データベースの構造を無視して、初期装備データベースを作れます。

同様のテクニックは、他の場合にも使えます。たとえば1キャラあたりの能力値自体がいくつもある場合なども、必要に応じて「能力値グループ1データベース」、「能力値2グループデータベース」のように分割すれば、もし能力値の設計が変わっても、コード修正の作業が、他グループの能力値には波及しないで済みます。

たとえば、

{id,レベル,HP,最大HP,MP,最大MP,}などの能力値1グループ、
{id,攻撃力,素早さ,守備力,}などの能力値2グループ、

などのように、必要に応じて分割することになると思います。

こうすれば、たとえばもし「気が変わって、ロマサガ2みたいに魔法限定のMPのほかに、物理技用のTP(あるいはWPなど)を作りたくなったぞ」となった時にも、 修正作業が攻撃力などの能力値2グループに波及しないで済むので、最小限で済みます。


読者には不安で「ゲーム中での能力値を呼び出す各シーンに影響を与えないか」と心配かもしれませんが、大丈夫です。 なぜなら初期値のデータベースは、ニューゲーム時にしか使いません。または実装によっては新キャラが仲間になった場合しか使いません。

なので、HP用のデータベースと攻撃力などのデータベースを分けても、たとえばゲーム中の戦闘シーンには一切の影響をしません。(ゲーム本編中では既に、たとえば構造体配列変数など(←実装による)の別変数に置き換えられているので。)

ステータスは和製英語

余談ですが、日本のゲームや異世界転生アニメでは「攻撃力」や「守備力」などを確認できる画面のことを「ステータス画面」といいますが、和製英語です。

西洋ゲームでは、攻撃力や守備力などの一覧のことをスタッツ(stats、統計の意味)といいます。ステータス status とは、西洋ゲームでは、「毒」とか「麻痺」とか、ああいう状態(これがステータス)のことを言います。

日本のゲームでも、この事を理解しているゲームはあって、よく見ると「ステータス画面」とは一切言わずに「能力値の画面」とか説明書で記載しているゲームも昔からあります。

自作ゲームで変数名とか付けるときに、知ったかぶりして"StatusAtk"(ステータス・アタック)とか"StatusDef"とか付けないようにしましょう。

データベースに関する豆知識

編集
※ コラムが長いので別のセクション化。
※ タイトルに「コラム」ではなく「豆知識」としたのは、「コラム」だとIT用語か何かだと紛らわしいので、

欠番データなどの扱い

編集

ゲーム業界では、没アイテムなどがデータベースから消さずに残されていることが、バグ技などで確認できる場合もあります。

たとえばファミコン版のドラクエ3では、バグ技によってアイテムをID番号順に変換していく裏技があるのですが、これによって没アイテムの「死のオルゴール」というアイテムを入手できました。

なお、この「死のオルゴール」は、使用すると味方パーティ全員が全滅してゲームオーバーになるという、何の役にも立たないアイテムです(おそらくテストプレイ用)。

なお、「死のオルゴール」はけっしてネット上の単なるウワサの類ではなく、けっして改造ロム版でもなく、すでに1980年代の時点で(攻略本ではなく)ドラクエ3のファンブック『ドラゴンクエスト3マスターズクラブ』にその没アイテムとバグ技の存在が、作者の堀井雄二氏によって紹介されています。

没アイテムなどでもゲームデータからの登録を消さない理由については、まったく製作元のエニックス(現スクウェア・エニックス)からは言明されていませんが、おそらく、没相手アイテム以降のid番号を維持することにより、デバッグの手間を減らすためだろうと思います。


配列の次元の設計では仕様書の印刷しやすさを考えて

編集
配列の次元は増やしすぎないほうが確認しやすい

C言語では、仕様上は原理的には配列の次元を3次元でも4次元でも増やせます。

ただし問題点は、どうやって配列の中身の一覧を画面で見るかです。なぜならパソコンのディスプレイは2次元の平面です。また、紙に印刷した場合なら、紙も2次元の平面です。また画面だけでなく、マウスなどの操作機器も、2次元の画面で情報閲覧することを前提にしています。

このため、あまり、配列を武器情報などのデータベース的に用いる場合には、配列の次元を増やさない設計にするほうが、のちのち確認しやすくなります。(一方、3Dゲームなどの幾何学的な用途に対応する場合なら、主人公の位置は[z][y][x] と3次元にまとめたほうが合理的です。あくまで。3次元以上にしないほうが安全というのは、武器情報などの幾何学的実態をもたない場合での、それもデータベース部分に限定してのハナシです。)


なお、CSVファイル化した場合は表計算ソフト(エクセルなど)の操作で確認したり編集したりするわけです。

だからデータベース目的の配列なら、要素数が多くなっても、なるべく2次元配列までで止める等の工夫が必要でしょう。特別な理由があって配列の次元を増やす場合でも3次元までにすべきでしょう(表計算ソフトのエクセルでなら、3次元目はシート番号に対応させられる)。

4次元以上は、表計算ソフトでの実現が難しいので、なるべく控えるほうが安全かと思います。


一応、データベースのファイル名を連番にするなどして4次元に対応させられたり、さらに5次元目もそのファイルを保管するフォルダの番号にするなどして対応させられますが、しかしもはやCSVファイルの外に出てしまいます。

どうしても4次元以上を使う場合には、なるべく4次元目以降の要素数を増やさないようにしましょう(もし4次元目を増やすと、シート番号やフォルダが膨大に増えてしまうことに対応するので)。

だから4次元目とか5次元目が100個とかあるデータ構造は、おそらく論外でしょう。そうではなく、紙の仕様書などで印刷可能なデータベース構造を考えるべきです。


パラメータが多くてキャラの強さに関する1行ではあらわせない場合でも、 おそらく仕様書では、なんらかの方法で、なるべく1ページ以内に記載する必要があるだろう。

なお、仕様書ではなく「発注リスト」という書類ですが、書籍『ゲームデザイン プロフェッショナル』では、モンスターのデータの概要について、書籍の本文中では特に断ってないものの、図表により発注項目の各データを1行ずつのエクセルなどにまとめて発注することを紹介しています[2]。(あくまでモンスターデータの概要。さすがに詳細データまで1行にまとめるのは無理か・・・)

ただし『ゲームプランとデザインの教科書』によると、1ページに収まらない仕様書をエクセルの電子データで渡してプログラマーに発注することもよくあるようです[3]

どちらにせよ、「この仕様は1ページに収まるか否か?」と言った事にもプランナーが気づいている事には変わりません。


もっとも、通常のRPGでは、いわゆる「ステータス画面」において、一画面内に強さ関連のパラメータがすべて表示されるのが普通なので、少なくともステータス機能の詳細データの設計では、それを参考にすればいいだろう。

もし一画面以内に表示しきれないと、プレイヤーの操作を増やすことになるので、テンポ感が悪化するだろう。 そのためか、多くのゲームは、一画面内に一キャラの強さ関連のパラメータをすべて表示しきれる仕様になっている作品が多い。


これはつまり、ゲームデザイン側の視点で見れば、ゲームデザイン時に、強さ関連のパラメータの数は、原則、1つのステータス画面に表示しきれる量に制限しなければならないことを実質的に意味する。

もし隠しデータ(「マスクデータ」という)なども含めれば(たとえば「相性」パラメータとかを隠すとか)、 一画面の情報量を超える仕様も決定できるが、そういうのは例外なので、このセクションでは議論しないとする。

ただし、これはあくまでRPGの場合の議論であり、けっして『信長の野望』のようなシミュレーションゲームには当てはまらない。本セクションではもうシミュレーションゲームのデータベースについては深入りしない。

  1. ^ 松浦健一郎・司ゆき 共著『確かな力が身につくPHP「超」入門』、SBクリテイティブ株式会社、2016年10月3日 初版 第1刷発行、P.189、
  2. ^ 『ゲームデザイン プロフェッショナル』、P141
  3. ^ 『ゲームプランとデザインの教科書』,P129