test(dev-save): 添加 Day2Sleep 测试存档与晋升脚本

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-13 20:57:03 +08:00
co-authored by Cursor
parent b98214632e
commit 26cfa5d886
38 changed files with 362 additions and 0 deletions
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a34027949a9d4a940a239367a3dcbbcb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f05882650e300e6459a642eca7ff875b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
{
"slotIndex": -1,
"savedAt": "2026-07-13 16:13:41",
"sceneName": "Scene/梦境",
"sceneSoName": "Day2_sleep",
"yarnProjectId": "FP_Day2_sleep",
"nodeName": "Start",
"schemaVersion": 1,
"gameVersion": "0.5.2.1-20260705-010933",
"thumbnailFile": "thumbnail.png"
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8eb5a6ddcffafaf499390b6d3082c462
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1 @@
{"schemaVersion":1,"gameVersion":"0.5.2.1-20260705-010933","savedAt":"2026-07-13 16:13:41","scene":{"sceneName":"Scene/梦境"},"anchor":{"sceneSoName":"Day2_sleep","yarnProjectId":"FP_Day2_sleep","nodeName":"Start"},"yarnVariables":{"floats":{},"strings":{},"bools":{}},"sections":{"audio":{"musicPaths":{},"sfxPaths":{},"ambState":"Dream"},"timeline":{"entries":[{"directorName":"星空到海浪","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"姐姐","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"惊醒","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"醒来","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false}]},"screen":{"saturationWeight":0.0,"isFadeScreenCovered":true}}}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2a6eda4ba4a848b4fb8417f8305827cc
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: eb00153eed3e95e46b3c2337a8c24198
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
{
"slotIndex": -1,
"savedAt": "2026-07-13 16:13:47",
"sceneName": "Scene/梦境",
"sceneSoName": "Day2_sleep",
"yarnProjectId": "FP_Day2_sleep",
"nodeName": "醒来",
"schemaVersion": 1,
"gameVersion": "0.5.2.1-20260705-010933",
"thumbnailFile": "thumbnail.png"
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4211e1fdf91dc3140b5adb57b07e63f9
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1 @@
{"schemaVersion":1,"gameVersion":"0.5.2.1-20260705-010933","savedAt":"2026-07-13 16:13:47","scene":{"sceneName":"Scene/梦境"},"anchor":{"sceneSoName":"Day2_sleep","yarnProjectId":"FP_Day2_sleep","nodeName":"醒来"},"yarnVariables":{"floats":{},"strings":{},"bools":{}},"sections":{"audio":{"musicPaths":{},"sfxPaths":{},"ambState":"Dream"},"timeline":{"entries":[{"directorName":"星空到海浪","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"姐姐","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"惊醒","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"醒来","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false}]},"screen":{"saturationWeight":0.0,"isFadeScreenCovered":true}}}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8189dfd1e1a78f94b886c00a6739731c
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 93c310515c15c25419d4c44ef7fd3dcb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
{
"slotIndex": -1,
"savedAt": "2026-07-13 16:15:07",
"sceneName": "Scene/梦境",
"sceneSoName": "Day2_sleep",
"yarnProjectId": "FP_Day2_sleep",
"nodeName": "广场",
"schemaVersion": 1,
"gameVersion": "0.5.2.1-20260705-010933",
"thumbnailFile": "thumbnail.png"
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9c9d6a573c62681409d09e6ae6b6638f
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1 @@
{"schemaVersion":1,"gameVersion":"0.5.2.1-20260705-010933","savedAt":"2026-07-13 16:15:07","scene":{"sceneName":"Scene/梦境"},"anchor":{"sceneSoName":"Day2_sleep","yarnProjectId":"FP_Day2_sleep","nodeName":"广场"},"yarnVariables":{"floats":{"$gameStage":3.0,"$t":2.0,"$h":0.0,"$wind":-1.0},"strings":{},"bools":{"$fzAccend":false}},"sections":{"audio":{"musicPaths":{},"sfxPaths":{},"ambState":"Dream"},"timeline":{"entries":[{"directorName":"星空到海浪","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"姐姐","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"惊醒","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"醒来","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false}]},"screen":{"saturationWeight":0.0,"isFadeScreenCovered":false}}}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: dfc3eec8f35feb9459afb96f6401ec73
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 651337893daf62c46833212badc3f82a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
{
"slotIndex": -1,
"savedAt": "2026-07-13 16:13:52",
"sceneName": "Scene/梦境",
"sceneSoName": "Day2_sleep",
"yarnProjectId": "FP_Day2_sleep",
"nodeName": "树",
"schemaVersion": 1,
"gameVersion": "0.5.2.1-20260705-010933",
"thumbnailFile": "thumbnail.png"
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f72e69bd9fc2e024a9a9c7e235821e92
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1 @@
{"schemaVersion":1,"gameVersion":"0.5.2.1-20260705-010933","savedAt":"2026-07-13 16:13:52","scene":{"sceneName":"Scene/梦境"},"anchor":{"sceneSoName":"Day2_sleep","yarnProjectId":"FP_Day2_sleep","nodeName":"树"},"yarnVariables":{"floats":{"$gameStage":2.0},"strings":{},"bools":{}},"sections":{"audio":{"musicPaths":{},"sfxPaths":{},"ambState":"Dream"},"timeline":{"entries":[{"directorName":"星空到海浪","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"姐姐","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"惊醒","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"醒来","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false}]},"screen":{"saturationWeight":0.0,"isFadeScreenCovered":false}}}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d41f320601771f94cab7c79925e25174
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cfc6d4b351fe38b49a2103b4d7419bfb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
{
"slotIndex": -1,
"savedAt": "2026-07-13 16:14:24",
"sceneName": "Scene/梦境",
"sceneSoName": "Day2_sleep",
"yarnProjectId": "FP_Day2_sleep",
"nodeName": "风筝1",
"schemaVersion": 1,
"gameVersion": "0.5.2.1-20260705-010933",
"thumbnailFile": "thumbnail.png"
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 90d6be4097d207b4198337a04ed428c4
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1 @@
{"schemaVersion":1,"gameVersion":"0.5.2.1-20260705-010933","savedAt":"2026-07-13 16:14:24","scene":{"sceneName":"Scene/梦境"},"anchor":{"sceneSoName":"Day2_sleep","yarnProjectId":"FP_Day2_sleep","nodeName":"风筝1"},"yarnVariables":{"floats":{"$gameStage":2.0,"$t":4.0},"strings":{},"bools":{}},"sections":{"audio":{"musicPaths":{},"sfxPaths":{},"ambState":"Dream"},"timeline":{"entries":[{"directorName":"星空到海浪","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"姐姐","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"惊醒","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"醒来","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false}]},"screen":{"saturationWeight":0.0,"isFadeScreenCovered":false}}}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4bff3a97faec00b419c31b9322c90a36
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4a254ec7f75628b4f9b0b3b77ce6ca34
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
{
"slotIndex": -1,
"savedAt": "2026-07-13 16:16:30",
"sceneName": "Scene/梦境",
"sceneSoName": "Day2_sleep",
"yarnProjectId": "FP_Day2_sleep",
"nodeName": "风筝2",
"schemaVersion": 1,
"gameVersion": "0.5.2.1-20260705-010933",
"thumbnailFile": "thumbnail.png"
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1bc759b1e33cf60448784c2c98c86ab0
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1 @@
{"schemaVersion":1,"gameVersion":"0.5.2.1-20260705-010933","savedAt":"2026-07-13 16:16:30","scene":{"sceneName":"Scene/梦境"},"anchor":{"sceneSoName":"Day2_sleep","yarnProjectId":"FP_Day2_sleep","nodeName":"风筝2"},"yarnVariables":{"floats":{"$gameStage":3.0,"$t":10.0,"$h":11.0,"$wind":1.0},"strings":{},"bools":{"$fzAccend":true}},"sections":{"audio":{"musicPaths":{},"sfxPaths":{},"ambState":"Dream"},"timeline":{"entries":[{"directorName":"星空到海浪","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"姐姐","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"惊醒","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"醒来","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false}]},"screen":{"saturationWeight":0.0,"isFadeScreenCovered":false}}}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 60e3b2e98c4fdd04cbfd084a63cb60c4
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b200c1477efb99c478e96c331f287194
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
{
"slotIndex": -1,
"savedAt": "2026-07-13 15:10:47",
"sceneName": "Scene/梦境",
"sceneSoName": "Day2_sleep",
"yarnProjectId": "FP_Day2_sleep",
"nodeName": "上升",
"schemaVersion": 1,
"gameVersion": "0.5.2.1-20260705-010933",
"thumbnailFile": "thumbnail.png"
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d7acccfabd4bca2478319700d7748db5
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1 @@
{"schemaVersion":1,"gameVersion":"0.5.2.1-20260705-010933","savedAt":"2026-07-13 15:10:47","scene":{"sceneName":"Scene/梦境"},"anchor":{"sceneSoName":"Day2_sleep","yarnProjectId":"FP_Day2_sleep","nodeName":"上升"},"yarnVariables":{"floats":{"$gameStage":3.0,"$t":10.0,"$h":11.0,"$wind":1.0},"strings":{},"bools":{"$fzAccend":true}},"sections":{"audio":{"musicPaths":{},"sfxPaths":{},"ambState":"Dream"},"timeline":{"entries":[{"directorName":"星空到海浪","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"姐姐","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"惊醒","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false},{"directorName":"醒来","isActive":true,"phase":"Stopped","hasEverAppliedPlayback":false}]},"screen":{"saturationWeight":0.0,"isFadeScreenCovered":false}}}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 58a72b337c94e0c40933c02fa504a9b9
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -11,6 +11,10 @@
{
"id": "Huoshan1",
"title": "Huoshan 1"
},
{
"id": "Day2Sleep",
"title": "Day2 Sleep"
}
]
}
+112
View File
@@ -0,0 +1,112 @@
# -*- coding: utf-8 -*-
"""Promote latest FP_Day2_sleep testsavs into StreamingAssets/TestSaveFiles/Day2Sleep."""
from __future__ import annotations
import json
import shutil
from pathlib import Path
TESTSAVS = Path.home() / "AppData/LocalLow/Tin Bird/AllOurBrokenParts/AllOurBrokenParts/testsavs"
DEST = Path("Assets/StreamingAssets/TestSaveFiles/Day2Sleep")
CATALOG = Path("Assets/StreamingAssets/TestSaveFiles/catalog.json")
YARN = "FP_Day2_sleep"
SCENE = "Scene/梦境"
# Preferred display / folder order for DevJumpTool.
NODE_ORDER = [
"Start",
"醒来",
"广场",
"",
"拿下风筝",
"风筝1",
"风筝2",
"上升",
"裂隙",
"记忆空间",
"",
"end",
"靠近黑暗",
"苏醒",
]
def sanitize(name: str) -> str:
bad = '<>:"/\\|?*'
for c in bad:
name = name.replace(c, "_")
name = name.replace(" ", "_")
if len(name) > 48:
name = name[:48]
return name or "no_node"
def node_sort_key(node: str, saved_at: str) -> tuple:
try:
order = NODE_ORDER.index(node)
except ValueError:
order = 1000
return (order, saved_at, node)
def main() -> None:
by_node: dict[str, dict] = {}
for d in TESTSAVS.iterdir():
if not d.is_dir():
continue
meta_path = d / "meta.json"
snap_path = d / "snapshot.json"
if not snap_path.exists() or not meta_path.exists():
continue
meta = json.loads(meta_path.read_text(encoding="utf-8"))
if meta.get("yarnProjectId") != YARN:
continue
if meta.get("sceneName") != SCENE:
continue
node = meta.get("nodeName") or "no_node"
saved_at = meta.get("savedAt") or ""
prev = by_node.get(node)
if prev is None or saved_at >= prev["saved_at"]:
by_node[node] = {
"dir": d,
"node": node,
"saved_at": saved_at,
"so": meta.get("sceneSoName") or "",
}
if DEST.exists():
shutil.rmtree(DEST)
DEST.mkdir(parents=True, exist_ok=True)
ordered = sorted(by_node.values(), key=lambda x: node_sort_key(x["node"], x["saved_at"]))
print(f"unique nodes: {len(ordered)}")
for i, item in enumerate(ordered, start=1):
folder = f"{i:02d}_{sanitize(item['node'])}"
out = DEST / folder
out.mkdir(parents=True, exist_ok=True)
shutil.copy2(item["dir"] / "snapshot.json", out / "snapshot.json")
shutil.copy2(item["dir"] / "meta.json", out / "meta.json")
print(f"OK {folder} | {item['saved_at']} | so={item['so']} | node={item['node']}")
if CATALOG.exists():
catalog = json.loads(CATALOG.read_text(encoding="utf-8"))
else:
catalog = {"sections": []}
sections = catalog.setdefault("sections", [])
if not any(s.get("id") == "Day2Sleep" for s in sections):
sections.append({"id": "Day2Sleep", "title": "Day2 Sleep"})
CATALOG.write_text(
json.dumps(catalog, ensure_ascii=False, indent=2) + "\n",
encoding="utf-8",
)
print("catalog: added Day2Sleep")
else:
print("catalog: Day2Sleep already present")
print("done")
if __name__ == "__main__":
main()