はじめまして、"Data structure with index does not exist " エラーについての質問になります。
GameMakerで作成してsteamで販売しているゲームなのですが、ユーザーより下記添付画像エラーが出て起動しないとのスレッドをもらいました。
エラー文に表記されているオブジェクト名「o_gm_00base」は基本進行度などのベース機能を含んだオブジェクトになります。
以前に2022年4月のGameMakerアップデート(steamAPIなどに関する機能の変更)があった際、それ以前のバージョンのGameMakerで作ったexeで同じエラーが出て起動しませんでした。
その時は、バージョンの新しいGameMakerでプロジェクトを開き直し、ついでsteamAPIなどに関する関数削除の後、GameMaker上で起動確認、再度exeを作成し起動チェックをするとそれも起動できました。
それから新たにsteamに関する機能を設定し直してから起動テスト後、steamに登録しました。
その後、自分自身の環境では毎日steamにて起動テストをしていたのですが、同じ起動エラーは出ていませんでした。
ご報告いただいたユーザーに確認したところ、起動しなくなった前のバージョンではなく、最新のバージョンをダウンロードしているとのことです。(PC環境によってエラーが出る?)
もし似たエラーを見たことがあったり、何かアドバイスをいただけると大変ありがたいです…
--
▼私の環境(この環境下では正常に起動)
OS:windows11 home
CPU:Intel(R) Core(TM) i7-12700 2.10 GHz
RAM:32.0 GB
▼報告してもらった環境+コメント
エラーが発生している使用PCは以下の通りです。
OS:Windows11
CPU:Intel Core i5-11400F
RAMメモリ:16GB(DDR4)
もしかしたらOSでエラーが発生している可能性が高いです。
エラー内容からはデータ構造系(ds系や構造体)の変数の中身が存在しないと言われているのでその変数の初期化忘れの可能性があります。
CreateイベントでのエラーとのことなのでCreateの実行順番が原因かもです。
o_gm_00baseのCreateの中で他のオブジェクトの変数を利用していたら、そのオブジェクトのCreateがまだ呼ばれてなくてそのようなエラーになっているということです。
ルームに配置しているオブジェクトのCreateの実行順番はPCによって違った気がしましたので今回のやつに該当しそうですね。
他に考えられるのは新しいSteamAPIの仕様が守られていないとかですかね。
たとえばSteamAPIを使うときはまず初期化処理をしないとダメでそれも実行順番によってエラーになってしまっていたりといった感じです。
エラーのlineが-1になってるのは、リリースビルドの実行ファイルだからちゃんとしたエラー情報が得られないからだと思います。
開発中にエラーが出たらどの箇所かわかるかもしれません。
dsを使ってる箇所があるか
async_load(GameMakerが内部で持つds_mapです)を使ってる箇所があるか
エラーが出る環境のパスに日本語や記号、スペースは含まれているか
といったところを確認してみてはどうでしょう。
アドバイスありがとうございます!大変ありがたいです…
一旦応急処置とはなるのですが、「exeを起動できない」は解決しました。
■方法:steamセーブデータにあたる「save.dat」を\AppData\Local\"ゲーム名"から削除
原因はお二人にご指摘いただいたように「ds系のエラー」でした。
・「o_gm_base」にて初回起動時セーブデータを「ds_map_create()」で作成
・作成したセーブデータを「o_gm_base」のcreateイベントで次回から読み込み
・そのセーブデータが何らかの理由で破損などしたため、読み込めず起動エラー
起動エラーの報告を頂いた方には、steamクラウドを切ってセーブデータ「save.dat」を削除していただいたら、一応起動できたとのご報告をもらいました。
…今回作ったゲームは6ステージでプレイ時間が20分~30分と短いゲームだったので少しマシですが、これが長いゲームで進行度を消すこととなったらかなり遊ぶ人も嫌だったと思います…。
「エラーのlineが-1になってるのは、リリースビルドの実行ファイルだから」←その通りでした。
アップデート前のプロジェクト(起動しなくなったもの)でsteam関連の関数を消去。
そしてデバッグ起動したところ、「ds_map_find_value」のところでエラーが出て原因がわかりました。
今回使用していたコード
■「o_gm_base」のcreateイベント
if(!file_exists("save.dat"))//saveデータが存在しなかったら
{
//各レベルのクリア状態のフラグ初期化
fl_lvCleared = 0;
//saveデータ(一時保存)を作成
saveData = ds_map_create();
//Progress進捗データ
ds_map_add(saveData,"fl_lvCleared",fl_lvCleared);
}
if(file_exists("save.dat"))//saveデータが存在したら
{
saveData = ds_map_secure_load("save.dat");//saveデータをロード
//各レベルのクリア状態をセーブデータから読み込み
fl_lvCleared = ds_map_find_value(saveData,"fl_lvCleared");
}
■「o_gm_base」のstepイベント(レベルクリア後に1回だけ実行)
ds_map_replace(saveData,"fl_lvCleared",fl_lvCleared);
ds_map_secure_save(saveData,"save.dat");
また下記も今後アップデート・別ゲームの作成時に確認したいと思います
・「SteamAPIを使うときはまず初期化処理」←これはしていませんでした…
アドバイス、本当にありがとうございました!
よかったです!👍