データはどこに置くのか問題

もくじへ戻る


「ゲーム開始から終了までの間,あるデータがずっと存在していて,いろんなところがそれを必要とする」的な性質のものをどう実装するのかという問題.
そういうのは多分下記の2種類があって,どっち側かによって実装の仕方が変わるかも的な.


固定的なデータの実装

ちょっとしたRPGを作るのにも{ゲーム開始時点でのキャラクタのステータス,アイテムや魔法の定義,敵の強さ,etc…}という感じで様々な定義情報が必要だ. そういったゲームのコンテンツ(? という言葉で合っているのか?)データというのは,(実装方法的な意味で)どこに置くのが良いのかな?

グローバルですか?→はい,それでいいと思います

コンテンツのデータとは性格的には「定数」だ.「不特定の個所から好き勝手に定数の値を参照されてたら困るよね!」なんてことは無いと思うから, こういうのはグローバル気味な何かとして実装してしまって良いと思う.

//[SomeDefinition.h]

//何らかの定義データにアクセスできるから,定義情報が必要な奴は勝手に参照しろよ!
const AAA &AAA_Definition();

くらいの話でOKであろう.
この関数の実装の側は

//[SomeDefinition.cpp]

namespace
{  const AAA TheDefinition;  }  //←定義データ

const AAA &AAA_Definition(){  return TheDefinition;  }

だとか

//[SomeDefinition.cpp]

const AAA &AAA_Definition()
{
  static const AAA TheDefinition;  //←定義データ
  return TheDefinition;
}

とかで良かろう.
どっちにするかは TheDefinition の初期化タイミングをどうしたいのかで決めればいいのかな.

外部ファイルから定義データを読み込む系のやつとかでも,読むべきファイル名(パス)は固定的に決まってるだろうから,

const BBB &BBB_Definition()
{  //ctor でファイル読込.失敗時は容赦なく例外を投げる(その場合はどうせゲームプレイ続行不可能なのだし)
  static const BBB TheDefinition{ 固定のファイルパス };
  return TheDefinition;
}

って感じで.

画像データとかも「それぞれの画像が最初に必要になった時点でロードして→以降はずっと保持」でとりあえずいいんじゃないかな.
(本当に一時的にしか使わないやつを除いては).


プレイ中の状態データ

こっちは,今現在のキャラクタの状態とか持ち物とかゲームの進捗情報とかそういうやつ.ざっくりと「セーブ/ロード」の対象になるデータといえば良いか.
これは多分,エントリポイント( WinMain() )から割と近いあたりのどこかの場所で持つ感じだろう.

最初の準備の例でいえば,例えば MyGame クラスがメンバとして持っとけばそれでよいだろう.

class MyGame
{
  /* なんやかんや */
  
private:
  std::unique_ptr<PlayData> m_pPlayData;  //プレイ状況のデータ
};

で,ここにあるプレイ状況のデータを各所がどうやって参照するのか? という点に関しては, ゲームプレイ状態のロード処理が

というあたりで,扱い方が変わる可能性があるかな.

前者ならば,各所に m_pPlayData が指すオブジェクトへの参照を配ってしまっても構わない(そのオブジェクトはゲーム中ずっと生存しているってことなので).
後者の場合だとそうもいかないので

class MyGame
{
public:
  //m_pPlayData が「今現在」指しているオブジェクトへの参照を返す.
  //(※「今現在」って書いとけば,これを呼ぶ側は「返されてきた参照を長期間保持し続けてやろう」とか考えないだろう.きっと.)
  PlayData &CurrPlayData(){  return *m_pPlayData;  }
private:
  //プレイ状況のデータ
  //ロードすると直前までの PlayData オブジェクトは破棄され,新しいオブジェクトにすげ替えられる
  std::unique_ptr<PlayData> m_pPlayData;
};

とか,あるいはもうちょっと粒度が細かい単位でデータにアクセスさせるためのメソッドを持つ必要があるか.


でもまぁ

固定的なデータを MyGame が保持しているのでもよいだろうし,逆にプレイ状況データがもうちょっとグローバルっぽい扱いになってても別に構わんと思う.
「構わん」というのは,それで何か致命的な問題を引き起こすこともなかろう,っていう.