savePlayData関数の呼び出しでエラー(バグ報告掲示板

投稿: Icon mini yukino 投稿:2013/08/04 11:51:04(最新:2013/08/06 21:40:06)
下記のとおり、よろしくお願いします。

*-*-*-*-*-*-*-*-*-*-*-*-*
【症状】
savePlayData関数を呼び出すとエラーが発生する。

【再現方法】
ノベルゲームで、下記のスクリプトを実行。
savePlayData()の呼び出しで、
「セーブしますか?」で「はい」を選ぶと、Error #1023 が発生する。

arr1 = createArray()
arr2 = createArray()

arr1[0] = "cake"
arr1[1] = arr2
arr2[0] = "icecream"
arr2[1] = arr1

setVariable("arr1", arr1)
setVariable("arr2", arr2)

savePlayData()    #=> Error #1023

speak("finished!")


【要望】
エラーが発生せずに、正しくセーブされること。

【PC環境】
OS: Windows 7 Home Premium SP1
ブラウザ: Firefox 22.0
Flash: 11.7.700.224
*-*-*-*-*-*-*-*-*-*-*-*-*

私の最近公開したゲームでは、セーブ直前に一時的に、
上のようなデータをエラーの発生しない形に直して、
セーブが終わった時に元に戻すようにしました。

ただ、完全に回避するのが難しく、
今後のためにも、対応よろしくお願いします。

コメントする

コメントするには、ログインする必要があります。

コメント一覧

Material 6858 mini akasata(投稿日:2013/08/05 22:38, 履歴)
お待たせしました。

開発担当のdycoonとも相談したのですが、本件はシステム的な対応は難しいと判断しています。

本件は、理論上は対策が可能なのですが、保存データの基本構造に関わる部分を変更しなくてはならず、バグを作りこんでしまう可能性が低くありません。
その場合、他のゲームの保存データが動かなくなってしまうことになり、リスクを考えると手を下すことができません。

本件のように、arr1 -> arr2 -> arr1 -> arr2 ・・・と無限に続いてしまうデータ構造を循環参照と呼びます。

循環参照には定番ともいえる対策があるので、ぜひ、お試しください。

いただいたコードを元に対策例を紹介します。

arr1 = createArray()
arr2 = createArray()

arr1[0] = "cake"

# 配列への参照ではなく、ラベルを登録します
# ここでは、ラベルには命名規則として接尾語に"_label"をつけます
arr1[1] = "arr2_label"

arr2[0] = "icecream"

# 配列への参照ではなく、ラベルを登録します
arr2[1] = "arr1_label"

setVariable("arr1", arr1)
setVariable("arr2", arr2)

# ラベルから配列を取得する関数です
def get_arr_from_label(label)
  # 接尾語の取得
  arr = splitString(label, "_")
  suffix = popArray(arr)
  
  # 接尾語がlabelの場合
  if suffix == "label"
    s = joinArray(arr, "_")
    return getVariable(s)
  else
    speak("末尾がlabelじゃないのでエラーです")
  end
end

# 実際に使うとき

# arr2_from_arr1とarr2は同じ内容
arr1 = getVariable("arr1")
arr2_from_arr1 = get_arr_from_label(arr1[1])

# arr1とarr1_from_arr2は同じ内容
arr2 = getVariable("arr2")
arr1_from_arr2 = get_arr_from_label(arr2[1])

# ちゃんと値が入っているかどうかチェック
# 配列を表示するのは面倒なので、joinArrayで文字列に変換してしまいます
speak("arr1: " + joinArray(arr1, ", "))
speak("arr2_from_arr1: " + joinArray(arr2_from_arr1, ", "))
speak("arr2: " + joinArray(arr2, ", "))
speak("arr1_from_arr2: " + joinArray(arr1_from_arr2, ", "))

# もちろん、実際に保存してエラーが出ないかチェックしてください


お手数をおかけし、大変申し訳ありません。
問題解決の一助になりましたら、幸いです。
Icon mini yukino(投稿日:2013/08/06 00:58, 履歴)
お忙しいところ、ご検討ありがとうございました。
修正が難しい件は了解しました。

対策例もありがとうございます。

ただ、実際のゲームのスクリプトでは、たくさんの配列をリンクさせた、
連結リストのようなものも作っているので、
すべての配列をsetVariableするのは、たいへんかなと思いました。

いまのところ、問題のない配列に変換しているつもりですが、
手間がかかる上にバグも起きやすいので、
セーブはひとまず諦めようと思います。

"Error #1023" しか出ないのは、ちょっと不親切に思いますが…

それでは。
Material 6858 mini akasata(投稿日:2013/08/06 21:40, 履歴)
>"Error #1023" しか出ないのは、ちょっと不親切に思いますが…
>
こちらはその通りで、わかりやすいエラーメッセージを
入れられないか、検討したいと思います。

よろしくお願いいたします。
Material 6858 mini akasata(投稿日:2013/08/05 22:34, 履歴)
お待たせしました。

開発担当のdycoonとも相談したのですが、本件はシステム的な対応は難しいと判断しています。

本件は、理論上は対策が可能なのですが、保存データの基本構造に関わる部分を変更しなくてはならず、バグを作りこんでしまう可能性が低くありません。

その場合、他のゲームの保存データが動かなくなってしまうことになり、リスクを考えると手を下すことができません。

本件のように、arr1 -> arr2 -> arr1 -> arr2 ・・・と無限に続いてしまうデータ構造を循環参照と呼びます。

循環参照には定番ともいえる対策があるので、ぜひ、お試しください。

いただいたコードを元に対策例を紹介します。

arr1 = createArray()
arr2 = createArray()

arr1[0] = "cake"

# 配列への参照ではなく、ラベルを登録します
# ここでは、ラベルには命名規則として接尾語に"_label"をつけます
arr1[1] = "arr2_label"

arr2[0] = "icecream"

# 配列への参照ではなく、ラベルを登録します
arr2[1] = "arr1_label"

setVariable("arr1", arr1)
setVariable("arr2", arr2)

# ラベルから配列を取得する関数です
def get_arr_from_label(label)
  # 接尾語の取得
  arr = splitString(label, "_")
  suffix = popArray(arr)
  
  # 接尾語がラベルの場合、この変数は
  if suffix == "label"
    s = joinArray(arr, "_")
    return getVariable(s)
  else
    speak("末尾がlabelじゃないのでエラーです")
  end
end

# 実際に使うとき

# arr2_from_arr1とarr2は同じ内容
arr1 = getVariable("arr1")
arr2_from_arr1 = get_arr_from_label(arr1[1])

# arr1とarr1_from_arr2は同じ内容
arr2 = getVariable("arr2")
arr1_from_arr2 = get_arr_from_label(arr2[1])

# ちゃんと値が入っているかどうかチェック
# 配列を表示するのは面倒なので、joinArrayで文字列に変換してしまいます
speak("arr1: " + joinArray(arr1, ", "))
speak("arr2_from_arr1: " + joinArray(arr2_from_arr1, ", "))
speak("arr2: " + joinArray(arr2, ", "))
speak("arr1_from_arr2: " + joinArray(arr1_from_arr2, ", "))

# もちろん、実際に保存してエラーが出ないかチェックしてください


お手数をおかけし、大変申し訳ありません。
問題解決の一助になりましたら、幸いです。
Material 6858 mini akasata(投稿日:2013/08/04 20:54, 履歴)
Rmakeのご利用ありがとうございます。
運営のあかさたです。

変数に設定した値に(この場合はarr1とarr2の間に)循環参照が
含まれている場合に、保存時にエラーが発生するという現象が
あるということですね。

調査したいと思います。

よろしくお願いいたします。