投稿記事

街づくりゲームの記事 (8)

竹林ソフト 2024/03/24 20:00

再建を繰り返す街作りゲーム開発(ゲームの初期化を Lua スクリプトで行う)

だいたいのゲームの仕様を考えたので、ゲームの新規開始の処理を実装していきます。
具体的には、新規ゲーム開始時の「この範囲は解放済みのエリアにして、中心には拠点を建てる」といった処理を Lua スクリプトで実現するあたりを実現します。

やったこと

Lua スクリプトで行うためのクラスを作成する

ゲームの初期化や管理は Lua スクリプトで行うことにします。
まずは「こういう記述で初期化したい」という Lua スクリプト作ります。

次に、この Lua スクリプトを実行するあたりを MoonSharp アセットを駆使して実装します。

そして実装しようとして、MoonSharp や Lua スクリプトで発生するエラー原因がわからなくて時間がかかりました。こういうので時間かかりますが、まぁ、こんなもんです。

そして時間が経過してから原因追及を再開して、問題がわかりました。
MoonSharp を利用する際に呼び出すべきメソッド UserData.RegisterAssembly(); の実行が行われていませんでした。うぐわぁ。

別プロジェクトのコードを参照しつつ作業していたのですが、参照しきれていなかったようです。むつかしい。

拠点の建築までを Lua スクリプトで行う

先ほど Lua スクリプトに記述したメソッドを実装して動作を確認します。
具体的には、MoonSharp の MoonSharpUserData を付けたクラスを実装すればオッケーです。

↓ 実装したクラスの抜粋

そして、ここまでが動作したゲーム画面がこれ↓です。

なんというか MoonSharp の機能を使って

  • Lua スクリプトを C# から実行する。
  • Lua スクリプトから地形や建築の C# のメソッドを呼び出す。

ということを行っています。
見えにくいですが、中央に拠点が配置されているのがわかります。大変よいです。

まとめと今後の予定

ゲームの初期化やイベントなんかを Lua スクリプトで行うことにして、その枠組みを用意して動作するのを確認しました。大変よいです。

次回は Lua スクリプトまわりの続きか、ワーカーが移動したり働くあたりに着手したいと思います。がんばります。

竹林ソフト 2024/03/17 20:00

再建を繰り返す街づくりゲーム開発(セーブと経路探索)

ランダムマップ生成が動作したので、生成したマップの保存と経路探索に着手します。

やったこと

すりガラスっぽいパネルを配置する

Translucent Image - Fast UI Background Blur アセットを適用しました。設定パネルなんかの背景をぼやけた感じにできるアセットです。

↓ UI 含めてぼやけた感じにした上に設定パネルを表示している例

Canvas の管理がすこしだけ小難しくなりますが、許容範囲です。

InteliMap の生成を調整する

前回までのマップ生成の方法だと、マップ境界で川が非接続になることがあったので変更しました。簡単に説明すると、草地を「タイルなし」にしていると川のマップ境界で途切れてしまうことがありました。

そして、マップ生成を試行錯誤していたのですが直線よりの川で学習させるとそういうマップが生成されたりするのは便利だなと思いました。

↓ 直線よりの川を学習させて生成したマップ

↓ 少し川を蛇行させたものを学習させて生成したマップ

他人の作ったアセットについて「こういう使い方はダメだったか、ならこうするかな」みたいにツールの理解が深まるのは悪くはないです。

生成したフィールドを保存できるようにする

今までは建物のみが保存対象でしたが、生成したマップもセーブデータに保存できるあたりをデモシーンで確認しました。よいです。

ただ、マップをどのタイミングで生成するかとかのゲーム仕様を考えてないので、それを決めてからゲームに取り込みます。
なんかこう、指導者が探索するとエリアが新しく開放される仕組みにしたいです。

まとめと今後の予定

今回は雑多なタスクに着手したり、Inteli Map アセットによるマップ生成の理解を深めたりしました。よいです。

次回も雑多な要素技術の動作確認をするか、ゲームの新規開始の流れを考えて実装していこうと思います。がんばります。

竹林ソフト 2024/03/10 20:00

再建を繰り返す街づくりゲーム開発(フィールド生成の実装と仕様決め)

いくつかの要素を実装したり、仕様を決めたりしていきます。

やったこと

建物の建築プレビュー時に色を変える

建物をプレイヤーの操作で配置するときに、建築できるなら緑色、建築できないときには赤色にするあたりを実装します。この実現方法は前回の記事で動作確認したのを取り込むだけでした。

↓ 建築プレビューの建物画像を緑色にした様子

↓ 赤色にした様子

よいです。
緑色の画像が背景画像に溶け込んでいる気がしますが、色はそのうち再調整します。

決めた仕様でフィールドを生成する

InteliMap Pro アセットを使ったマップ生成を、少し広めのエリアに対して行ってみました。

↓ 生成したもの

これは 32x32 のタイルのまとまりを1エリアと呼んだときに、それを 5x5 並べて表示しています。そして、この 25 エリアの生成に 4691 msec かかりました。
1エリアが約 200 msec とすると、生成速度は遅すぎず無視できるほど速くもなくて悩ましいです。

また後でいろいろ考えます。

仕様を決めていく

書き出してみました。

# 建築の流れ

- プレイヤーが建築指示を行う。
- その場所に半透明の建築予約の描画がなされる。
  - そこにある樹木や瓦礫に撤去マークがつく。
  - 撤去が終わったら次のフェーズに遷移する。
- この状態の建物のストレージに必要資材が運び込まれる。
- 建物の搬入が完了したら、ワーカーが寄ってきて建築の進捗を増やす。
- 建築し終わったら、その建物として動作し始める。


# 建物への運搬

- 建物に配属されたワーカーが運搬を行う。
- 工場の場合は、搬入資材の数だけ搬入元を指定する。
  - 搬入すべき資材を、どこから運ぶかを指定する。
- 倉庫の場合は、建物ごとの最大数までの資材を搬入先に指定できる。
  - どこからどの資材を搬入するかを指定する。


# 建物の情報表示

- 作られるアイテムの画像を建物画像に重ねて表示する。
  - 生産の進捗状況を丸いプログレスバー表示する。

- アイコン表示
  - 搬出ストレージに空きがないときのアイコン表示
  - 搬入待ち資材のアイコン表示

- フォーカス時
  - ブーストゲージ
  - 所属しているワーカーが建物外にいるときに、そのワーカーの場所
    - ワーカーは自宅に帰り出した時点で所属でなくなる。
  - 総生産数などの各種情報
  - ワーカーの最大数と所属数


# 住居

- 充実度がある。
  - 薪や食べた食事によって住民の充実度が変わる。
  - 空き家の充実度は市場に所属する住居の充実度の平均値で計算する。
    - 住民がいない場合は、市場の資材を管理する住宅の数で割った平均値から計算する。
  - 仕事帰りと最初に自宅に移住したときに市場で食事をして、薪を持って帰宅する。
  - 帰宅して疲労がなくなったら仕事に出かける。
    - 薪があるときは普通に疲労が回復して、なければ少しの回復にする。


# 市場

- 住民が立ち寄って資材を持っていく特殊な倉庫として扱う。


# 生産施設

農場や牧場など。

- ワーカーの数に応じて資材が生産される工場として扱う。
- 肥料や飼料でのブーストは考えない。


# 日数の経過とワーカーの休息について

- 昼夜の概念はない。
- ワーカーが疲れると帰宅する。
- 帰宅して休憩して出かける際に新しい仕事を選択する。
- 日数の経過で定期的に敵が襲撃してくる。

よいです。

まとめと今後の予定

いくつかの実装をして仕様を考えたりもしました。
次回は敵がわらわらと押し寄せてくるあたりを試作したり、ワーカーが働くあたりに着手しようと思います。がんばります。

竹林ソフト 2024/03/03 20:00

再建を繰り返す街づくりゲーム開発(マップ生成について)

マップは InteliMap Pro アセットで生成したものを使うことにします。
今回は、実際の使い方について定義します。

やったこと

IntelMap Pro でのランタイムマップ生成

このアセットは「こういう感じでマップ生成してね」というものを解析させると、それを元にランダムなマップを生成してくれるものです。

前回から引き続き使ってみた感じ、

  • 指定した範囲のマップを生成できる。
  • 生成の際にシードを指定できる。
  • 同じエリアに複数回の資源配置を行うことで、資源量を上乗せできる。
    • 川なんかの接続は考慮される。

ということがわかりました。

↓ 与えたオブジェクト配置

↓ 生成サンプル(クリア、1回目の生成、2回目の生成、3回目の生成、のループ)

つまり、ランダムシードと資源配置の回数さえ同じなら全く同じマップが生成されるので、例えば 64x64 を1エリアとして、このエリアごとのランダムシードと配置回数とが同じになるようにすればいいだけです。

なので、1つのランダムシードさえセーブデータに保存しておいて、それから他のエリアのためのランダムシードを生成して使う仕組みにします。

あとは、例えば木を伐採したときには「この座標の木は伐採されてあと N ラウンドで復活する」という変更された情報だけ保存するようにします。

実装自体はまた後でやりますが、ベースとなるランダムシードに対して、例えばエリアの座標が (x, y) で表されるとしたら、seed = baseSeed + (y << 16) + x; でいいかなと思っています。資源を生成する回数は (x, y) と原点との距離で決まるようにします。

建物画像へのアウトラインや色のテスト

フィールド上の建物にフォーカスしたときにアウトラインを描画したり、建築のときに建物画像を緑色や赤色にするあたりを実装します。

実装というか、そのあたりの実現のために All In 1 Sprite Shader アセットを利用します。

そして、ドキュメントを読んでアウトライン、全体を緑色にする、赤色にする、を切り替わるデモを作成しました。

        while (true)
        {
            material.EnableKeyword("OUTBASE_ON");
            yield return wait;
            material.DisableKeyword("OUTBASE_ON");

            material.SetColor("_GreyscaleTintColor", Color.green);
            material.EnableKeyword("GREYSCALE_ON");
            yield return wait;
            material.DisableKeyword("GREYSCALE_ON");


            material.SetColor("_GreyscaleTintColor", Color.red);
            material.EnableKeyword("GREYSCALE_ON");
            yield return wait;
            material.DisableKeyword("GREYSCALE_ON");
        }

いずれこのコードを建物の処理まわりに実装すればオッケーです。よいです。

ゲーム仕様の検討

ゲーム仕様というか、ゲーム序盤の流れを書き出しました。

- 新規ゲーム -> シナリオ選択 -> マッププレビュー -> 決定
- 画面下の建物ボタンにカーソルを合わせてツールチップ表示で概要や建築コストを確認できる。
- 建築できない建物のツールチップには「(~の技術)が必要」などと、わかるように表示する。
- setup.lua で指定した資源の総数が画面上に表示できる。
- 資材が足りない場合、建物を赤色プレビュー表示する。
  - 資源が不足していても建築指示は行える。
- 初期に必要になる建物は木材だけで建築できる。
  - 住居など
- 整地ボタンを押してエリアを指定すると、エリア内の木材の伐採や建物の解体を行う。
  - 整地したエリアは道として扱う。
    - 地面の種類: なし(緑)、草、整地、道、舗装路、線路
- 拠点から接続されていない場所の木材の伐採指示が行われたときには警告メッセージを表示する。
  - 「拠点から道がつながっていません」
  - 警告アイコンをフィールドに表示
    - フォーカスでメッセージ表示
  - 画面に警告のリスト表示
- ワーカーの最大数は時間経過や技術で増える。
  - setup.lua で設定できる。
- 拠点は市場として機能して生活品を住居に運搬する。
- 拠点は定期的に食料を生産できる。
- ゲーム開始時に大量の食料を拠点に配備しておいてもいい。
- 研究は専用の建物で行う。
  - Factorio と同様に、必要なアイテムが揃うと研究ポイントが増加する。
- ワーカーは仕事を始めると、帰宅するまで他の仕事を行わない。
  - 仕事は種類優先でワーカーを割り振る。

まだ敵とか防衛とかリーダーの要素など、いろいろと仕様が曖昧なので、引き続きゲームの流れを考えながら仕様を決めていきます。

まとめと今後の予定

仕様を決めながら、使うであろう機能の要素実装を行いました。よいです。
次回もこんな感じで進めていきます。がんばります。

竹林ソフト 2024/02/25 20:00

再建を繰り返す街づくりゲーム開発(見た目の仮作成など)

まだ開発序盤で小難しいことはないので、淡々と実装していきます。

やったこと

建物の画像を作成して適用する

画像に建物名が書かれたアイコン画像で開発していくつもりでしたが、視認性が悪すぎたので建物の仮画像を作成しました。

よいです。
中世ファンタジーにするか文明崩壊後の近未来にするか迷ったのですが、魔法が出てきても違和感がなさそうな中世ファンタジーにしました。

そして、この画像を適用したものがこれ↓です。

よいです。
前回までの実装で建物を UI 操作から配置できるようになっていましたが、セーブとロードもできるようにしました。

ゲームのプレイ速度を変更できるようにする

再生速度については「ポーズ」「1倍速」「2倍速」を切り替えられるようにしました。

↓ 画面右上に表示する UI

↓ playSpeed 変数に応じて再生速度をコントロールするあたりのコード

よいです。

キャラクターの動作デモを作る

MINIFANTASY - Creatures アセットのキャラクターを利用します。Worker クラスや Enemy クラスを作成して適用して、待機モーションと歩行モーションが切り替わるデモシーンを作成しました。

よいです。
キャラクターによって解像度が違うのは私は気にしません。

マップがランダム生成されるようにする

ランダムなマップを生成するのに InteliMap Pro アセットを試してみました。それから資源とかの画像は MINIFANTASY シリーズのアセットを利用しています。

InteliMap アセットを簡単に説明すると「タイル配置を学習して、それに基づいてランダムなタイル配置を生成してくれるアセット」です。
今回の例では、画面左下側が私が手で配置したもの、右側が生成されたもの、です。

これだけだと微妙に思えるのですが、Generate は同じ範囲に繰り返し行うことができ、その際に既存の配置を考慮してくれるのが便利です。例えば、今回の生成結果に追加で2回の Generate を行ったものがこれ↓です。

学習元のタイル配置をもう少し適切にしたうえで「拠点から遠い場所では Generate 回数を増やして資源が多くなるようにする」などの工夫をすれば実用に耐えるように思いました。
もう少し試してみます。よいです。

まとめと今後の予定

今回は、やれば終わる小難しくないタスクに着手しました。よいです。

次回は、道を作成してワーカーがその上を移動するあたりや、そもそもゲームの仕様を考えてドキュメントに書いたりしようと思います。がんばります。

« 1 2

月別アーカイブ

限定特典から探す

記事を検索