Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fd904ea144 | |||
| 299877b197 | |||
| b67cb18b45 | |||
| 8ba9835d10 | |||
| 02ff914bd3 | |||
| dd36de3aa6 | |||
| 9d2ad69a75 | |||
| 7df526868c | |||
| 3c1711c7df |
@@ -40,6 +40,8 @@ temp*build*/
|
|||||||
/apps/ai-game-creator-shell/src-tauri/resources/codex/win-x64/codex-path/
|
/apps/ai-game-creator-shell/src-tauri/resources/codex/win-x64/codex-path/
|
||||||
/apps/ai-game-creator-shell/src-tauri/resources/codex/win-x64/codex-resources/
|
/apps/ai-game-creator-shell/src-tauri/resources/codex/win-x64/codex-resources/
|
||||||
/apps/ai-game-creator-shell/src-tauri/resources/codex/win-x64/codex-package.json
|
/apps/ai-game-creator-shell/src-tauri/resources/codex/win-x64/codex-package.json
|
||||||
|
/apps/ai-game-creator-shell/src-tauri/resources/plugins/
|
||||||
|
/plugins/agc-cocos-editor/native/payload/
|
||||||
/apps/ai-game-creator-shell/logs/
|
/apps/ai-game-creator-shell/logs/
|
||||||
/apps/ai-game-creator-shell/.llm-drafts/
|
/apps/ai-game-creator-shell/.llm-drafts/
|
||||||
/apps/ai-game-creator-shell/game-creator.config.local.json
|
/apps/ai-game-creator-shell/game-creator.config.local.json
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# resources/plugins 由 build.rs 从 plugins/ 复制生成,属于构建产物。
|
||||||
|
# 它在 dev 监听范围内,重新生成会让 Tauri dev 误判为源码改动而触发
|
||||||
|
# “构建 -> 监听 -> 再构建”的自触发循环。
|
||||||
|
resources/plugins/
|
||||||
@@ -117,6 +117,16 @@ const allowedUncalledTauriCommands = [
|
|||||||
'stop_local_game_preview_if_matches',
|
'stop_local_game_preview_if_matches',
|
||||||
'start_game_creator_external_mcp',
|
'start_game_creator_external_mcp',
|
||||||
'stop_game_creator_external_mcp',
|
'stop_game_creator_external_mcp',
|
||||||
|
'list_agc_plugins',
|
||||||
|
'list_agc_extensions',
|
||||||
|
'refresh_agc_plugins',
|
||||||
|
'start_agc_plugin',
|
||||||
|
'stop_agc_plugin',
|
||||||
|
'reload_agc_plugin',
|
||||||
|
'call_agc_plugin',
|
||||||
|
'read_agc_plugin_panel',
|
||||||
|
'set_agc_plugin_project_path',
|
||||||
|
'set_agc_plugin_enabled',
|
||||||
];
|
];
|
||||||
const sourceExtensions = new Set([
|
const sourceExtensions = new Set([
|
||||||
'.json',
|
'.json',
|
||||||
@@ -1285,10 +1295,7 @@ if (tauriConfig.identifier !== 'world.genarrative.ai-game-creator') {
|
|||||||
throw new Error('AI game creator shell identifier drifted');
|
throw new Error('AI game creator shell identifier drifted');
|
||||||
}
|
}
|
||||||
|
|
||||||
const expectedBundledDesignAgentResources = {
|
const expectedBundledWindowsResources = {
|
||||||
'design-agent': 'design-agent',
|
|
||||||
};
|
|
||||||
const expectedBundledCodexResources = {
|
|
||||||
'resources/codex/win-x64/bin/codex.exe': 'codex/win-x64/bin/codex.exe',
|
'resources/codex/win-x64/bin/codex.exe': 'codex/win-x64/bin/codex.exe',
|
||||||
'resources/codex/win-x64/bin/codex-code-mode-host.exe':
|
'resources/codex/win-x64/bin/codex-code-mode-host.exe':
|
||||||
'codex/win-x64/bin/codex-code-mode-host.exe',
|
'codex/win-x64/bin/codex-code-mode-host.exe',
|
||||||
@@ -1302,34 +1309,18 @@ const expectedBundledCodexResources = {
|
|||||||
'codex/win-x64/codex-package.json',
|
'codex/win-x64/codex-package.json',
|
||||||
'resources/codex/win-x64/NOTICE.md': 'codex/win-x64/NOTICE.md',
|
'resources/codex/win-x64/NOTICE.md': 'codex/win-x64/NOTICE.md',
|
||||||
'resources/codex/win-x64/manifest.json': 'codex/win-x64/manifest.json',
|
'resources/codex/win-x64/manifest.json': 'codex/win-x64/manifest.json',
|
||||||
|
'resources/plugins': 'plugins',
|
||||||
};
|
};
|
||||||
assert.deepEqual(
|
if (tauriConfig.bundle?.resources !== undefined) {
|
||||||
tauriConfig.bundle?.resources,
|
throw new Error(
|
||||||
expectedBundledDesignAgentResources,
|
'AI game creator shell base Tauri config must not require Windows-only Codex resources',
|
||||||
'AI game creator shell base Tauri config must bundle the design-agent resource pack',
|
);
|
||||||
);
|
|
||||||
for (const key of Object.keys(tauriConfig.bundle?.resources ?? {})) {
|
|
||||||
if (String(key).includes('codex')) {
|
|
||||||
throw new Error(
|
|
||||||
'AI game creator shell base Tauri config must not require Windows-only Codex resources',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
windowsTauriConfig.bundle?.resources,
|
windowsTauriConfig.bundle?.resources,
|
||||||
expectedBundledCodexResources,
|
expectedBundledWindowsResources,
|
||||||
'AI game creator shell Windows Tauri config must bundle the complete pinned Codex resource set',
|
'AI game creator shell Windows Tauri config must bundle the complete pinned Codex resource set and Cocos bridge payload directory',
|
||||||
);
|
);
|
||||||
if (
|
|
||||||
Object.prototype.hasOwnProperty.call(
|
|
||||||
windowsTauriConfig.bundle?.resources ?? {},
|
|
||||||
'design-agent',
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
throw new Error(
|
|
||||||
'design-agent resource pack must not be mixed into the Windows Codex sidecar bundle',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (windowsTauriConfig.bundle?.useLocalToolsDir !== true) {
|
if (windowsTauriConfig.bundle?.useLocalToolsDir !== true) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'AI game creator shell Windows Tauri config must cache bundling tools in the project target directory',
|
'AI game creator shell Windows Tauri config must cache bundling tools in the project target directory',
|
||||||
|
|||||||
@@ -436,6 +436,10 @@ function spawnChild(command, args, options, spawnImpl = spawn) {
|
|||||||
const child = spawnImpl(command, args, {
|
const child = spawnImpl(command, args, {
|
||||||
...options,
|
...options,
|
||||||
shell: useShell,
|
shell: useShell,
|
||||||
|
// npm.cmd and the Windows shell otherwise create a visible console for
|
||||||
|
// every service in the dev stack. Their stdout/stderr is already inherited
|
||||||
|
// by the launcher, so no separate terminal window is useful.
|
||||||
|
windowsHide: process.platform === 'win32' ? true : options.windowsHide,
|
||||||
// POSIX 下让每个长驻服务拥有独立进程组,退出时可以连同 npm、
|
// POSIX 下让每个长驻服务拥有独立进程组,退出时可以连同 npm、
|
||||||
// Node、Cargo 及其子进程一起清理,避免残留订阅任务持续刷日志。
|
// Node、Cargo 及其子进程一起清理,避免残留订阅任务持续刷日志。
|
||||||
detached: isPosix,
|
detached: isPosix,
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import {
|
|||||||
const appRoot = fileURLToPath(new URL('..', import.meta.url));
|
const appRoot = fileURLToPath(new URL('..', import.meta.url));
|
||||||
const repoRoot = resolve(appRoot, '../..');
|
const repoRoot = resolve(appRoot, '../..');
|
||||||
const tauriCliPath = resolve(repoRoot, 'node_modules/@tauri-apps/cli/tauri.js');
|
const tauriCliPath = resolve(repoRoot, 'node_modules/@tauri-apps/cli/tauri.js');
|
||||||
const AGC_DESIGN_DEBUG_ENV = 'GENARRATIVE_AGC_DESIGN_DEBUG';
|
|
||||||
|
|
||||||
function buildTauriArguments(argv, devUrl = readAgcDevEndpoint().url) {
|
function buildTauriArguments(argv, devUrl = readAgcDevEndpoint().url) {
|
||||||
const args = [...argv];
|
const args = [...argv];
|
||||||
@@ -44,6 +43,28 @@ function buildTauriArguments(argv, devUrl = readAgcDevEndpoint().url) {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `agc_cocos_execute` 与 Cocos 编辑器适配器只在 `cocos-editor-execute` feature 下
|
||||||
|
// 注册。开发构建默认在 Windows 打开它,否则 Agent 的工具清单里根本没有该工具,
|
||||||
|
// 只能退化成改写脚本。可用 AGC_DEV_CARGO_FEATURES(逗号分隔)覆盖,传空串即关闭。
|
||||||
|
function readDevCargoFeatures(env = process.env) {
|
||||||
|
const override = env.AGC_DEV_CARGO_FEATURES;
|
||||||
|
if (override !== undefined) {
|
||||||
|
return override
|
||||||
|
.split(',')
|
||||||
|
.map((value) => value.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
}
|
||||||
|
return process.platform === 'win32' ? ['cocos-editor-execute'] : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function withDevCargoFeatures(argv, features = readDevCargoFeatures()) {
|
||||||
|
if (features.length === 0) return argv;
|
||||||
|
if (argv.some((value) => value === '--features' || value === '-f')) {
|
||||||
|
return argv;
|
||||||
|
}
|
||||||
|
return [`--features=${features.join(',')}`, ...argv];
|
||||||
|
}
|
||||||
|
|
||||||
function spawnTauriCli(argv, { env = process.env } = {}) {
|
function spawnTauriCli(argv, { env = process.env } = {}) {
|
||||||
return spawnChild(process.execPath, [tauriCliPath, ...argv], {
|
return spawnChild(process.execPath, [tauriCliPath, ...argv], {
|
||||||
cwd: appRoot,
|
cwd: appRoot,
|
||||||
@@ -107,12 +128,12 @@ async function runTauriDev(
|
|||||||
shutdownRequested.then(() => false),
|
shutdownRequested.then(() => false),
|
||||||
]);
|
]);
|
||||||
if (!prepared || shutdownSignal) return 1;
|
if (!prepared || shutdownSignal) return 1;
|
||||||
const tauriArguments = buildTauriArguments(argv, endpoint.url);
|
const tauriArguments = buildTauriArguments(
|
||||||
|
withDevCargoFeatures(argv),
|
||||||
|
endpoint.url,
|
||||||
|
);
|
||||||
child = spawnCli(tauriArguments, {
|
child = spawnCli(tauriArguments, {
|
||||||
env: {
|
env: withAgcDevEndpointEnv(endpoint),
|
||||||
...withAgcDevEndpointEnv(endpoint),
|
|
||||||
[AGC_DESIGN_DEBUG_ENV]: '1',
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
const childResult = waitForCli(child);
|
const childResult = waitForCli(child);
|
||||||
const outcome = await Promise.race([
|
const outcome = await Promise.race([
|
||||||
@@ -197,6 +218,7 @@ export {
|
|||||||
isDirectModuleExecution,
|
isDirectModuleExecution,
|
||||||
runTauriDev,
|
runTauriDev,
|
||||||
spawnTauriCli,
|
spawnTauriCli,
|
||||||
|
withDevCargoFeatures,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isDirectModuleExecution()) {
|
if (isDirectModuleExecution()) {
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# resources/plugins 由 build.rs 从 plugins/ 复制生成,属于构建产物。
|
||||||
|
# 它在 dev 监听范围内,重新生成会让 Tauri dev 误判为源码改动而触发
|
||||||
|
# “构建 -> 监听 -> 再构建”的自触发循环。
|
||||||
|
resources/plugins/
|
||||||
+22
@@ -733,6 +733,18 @@ dependencies = [
|
|||||||
"error-code",
|
"error-code",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cocos-editor-bridge"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"editor-adapter-api",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sha2",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "combine"
|
name = "combine"
|
||||||
version = "4.6.7"
|
version = "4.6.7"
|
||||||
@@ -1205,6 +1217,14 @@ version = "1.0.20"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
|
checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "editor-adapter-api"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
@@ -1709,6 +1729,8 @@ dependencies = [
|
|||||||
"axum",
|
"axum",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"chromiumoxide",
|
"chromiumoxide",
|
||||||
|
"cocos-editor-bridge",
|
||||||
|
"editor-adapter-api",
|
||||||
"futures",
|
"futures",
|
||||||
"getrandom 0.3.4",
|
"getrandom 0.3.4",
|
||||||
"http",
|
"http",
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ publish = false
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
cocos-editor = ["cocos-editor-bridge/process-discovery"]
|
||||||
|
cocos-editor-execute = ["cocos-editor", "cocos-editor-bridge/windows-transport"]
|
||||||
|
cocos-editor-injection = ["cocos-editor-execute", "cocos-editor-bridge/windows-injection"]
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
@@ -19,6 +22,8 @@ ts-rs = "12.0.1"
|
|||||||
typed_floats = { version = "1.0.7", features = ["serde"] }
|
typed_floats = { version = "1.0.7", features = ["serde"] }
|
||||||
nalgebra = { version = "0.35.0", features = ["serde-serialize"] }
|
nalgebra = { version = "0.35.0", features = ["serde-serialize"] }
|
||||||
agent-runtime-core = { path = "../../../server-rs/crates/agent-runtime-core" }
|
agent-runtime-core = { path = "../../../server-rs/crates/agent-runtime-core" }
|
||||||
|
cocos-editor-bridge = { path = "../../../plugins/agc-cocos-editor/native/cocos-editor-bridge", default-features = false }
|
||||||
|
editor-adapter-api = { path = "../../../server-rs/crates/editor-adapter-api" }
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
axum = "0.8"
|
axum = "0.8"
|
||||||
chromiumoxide = "0.9.1"
|
chromiumoxide = "0.9.1"
|
||||||
|
|||||||
@@ -182,6 +182,8 @@ fn main() {
|
|||||||
);
|
);
|
||||||
let manifest_path = manifest_dir.join("prompts/runtime/manifest.json");
|
let manifest_path = manifest_dir.join("prompts/runtime/manifest.json");
|
||||||
stage_bundled_codex_cli(&manifest_dir);
|
stage_bundled_codex_cli(&manifest_dir);
|
||||||
|
stage_plugin_workspace(&manifest_dir);
|
||||||
|
stage_cocos_editor_payload(&manifest_dir);
|
||||||
let compiled = runtime_prompt_bundle::compile_manifest(&manifest_path)
|
let compiled = runtime_prompt_bundle::compile_manifest(&manifest_path)
|
||||||
.unwrap_or_else(|error| panic!("Prompt Bundle 编译失败:{error}"));
|
.unwrap_or_else(|error| panic!("Prompt Bundle 编译失败:{error}"));
|
||||||
validate_seed_task_catalog(&compiled);
|
validate_seed_task_catalog(&compiled);
|
||||||
@@ -203,3 +205,146 @@ fn main() {
|
|||||||
}
|
}
|
||||||
tauri_build::build()
|
tauri_build::build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn stage_cocos_editor_payload(manifest_dir: &std::path::Path) {
|
||||||
|
if std::env::var_os("CARGO_FEATURE_COCOS_EDITOR_INJECTION").is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let out_dir = std::path::PathBuf::from(std::env::var_os("OUT_DIR").expect("OUT_DIR"));
|
||||||
|
let profile_dir = out_dir
|
||||||
|
.ancestors()
|
||||||
|
.find(|path| path.file_name().is_some_and(|name| name == "build"))
|
||||||
|
.and_then(|build_dir| build_dir.parent())
|
||||||
|
.expect("AGC Cargo profile directory not found");
|
||||||
|
let candidates = [
|
||||||
|
profile_dir.join("deps/cocos_editor_bridge.dll"),
|
||||||
|
profile_dir.join("cocos_editor_bridge.dll"),
|
||||||
|
];
|
||||||
|
let source = candidates
|
||||||
|
.iter()
|
||||||
|
.find(|path| path.is_file())
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
panic!(
|
||||||
|
"Cocos bridge native payload 未构建:{}",
|
||||||
|
candidates
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.display().to_string())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(";")
|
||||||
|
)
|
||||||
|
});
|
||||||
|
for destination in [
|
||||||
|
// 插件工作区里的 payload 是开发态与打包态的唯一真源。
|
||||||
|
manifest_dir
|
||||||
|
.join("../../../plugins/agc-cocos-editor/native/payload/cocos-editor-bridge.dll"),
|
||||||
|
// 随包资源目录与 tauri.windows.conf.json 的 `resources/plugins` 映射保持一致。
|
||||||
|
manifest_dir
|
||||||
|
.join("resources/plugins/agc-cocos-editor/native/payload/cocos-editor-bridge.dll"),
|
||||||
|
] {
|
||||||
|
std::fs::create_dir_all(destination.parent().expect("payload resource parent"))
|
||||||
|
.expect("创建 Cocos bridge payload 目录失败");
|
||||||
|
std::fs::copy(source, &destination).expect("复制 Cocos bridge native payload 失败");
|
||||||
|
}
|
||||||
|
println!("cargo:rerun-if-changed={}", source.display());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
fn stage_cocos_editor_payload(_manifest_dir: &std::path::Path) {}
|
||||||
|
|
||||||
|
/// 把 `plugins/` 工作区里的插件包随包映射到应用资源目录。
|
||||||
|
///
|
||||||
|
/// 只复制插件运行需要的清单、入口、面板和 native payload,不复制 native 源码、
|
||||||
|
/// Cargo target 目录或 node_modules。
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn stage_plugin_workspace(manifest_dir: &std::path::Path) {
|
||||||
|
let repo_root = manifest_dir
|
||||||
|
.parent()
|
||||||
|
.and_then(|app_root| app_root.parent())
|
||||||
|
.and_then(|apps_dir| apps_dir.parent())
|
||||||
|
.expect("AGC 应用必须位于仓库 apps 目录下")
|
||||||
|
.to_path_buf();
|
||||||
|
let workspace = repo_root.join("plugins");
|
||||||
|
let destination_root = manifest_dir.join("resources/plugins");
|
||||||
|
std::fs::create_dir_all(&destination_root).expect("创建插件资源目录失败");
|
||||||
|
let entries = match std::fs::read_dir(&workspace) {
|
||||||
|
Ok(entries) => entries,
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
for entry in entries.flatten() {
|
||||||
|
let plugin_root = entry.path();
|
||||||
|
if !plugin_root.is_dir() || !plugin_root.join("plugin.json").is_file() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let name = entry.file_name();
|
||||||
|
let destination = destination_root.join(&name);
|
||||||
|
copy_plugin_file(
|
||||||
|
&plugin_root.join("plugin.json"),
|
||||||
|
&destination.join("plugin.json"),
|
||||||
|
);
|
||||||
|
for relative in [
|
||||||
|
std::path::PathBuf::from("src"),
|
||||||
|
std::path::PathBuf::from("panels"),
|
||||||
|
std::path::PathBuf::from("native/payload"),
|
||||||
|
] {
|
||||||
|
copy_plugin_tree(&plugin_root.join(&relative), &destination.join(&relative));
|
||||||
|
}
|
||||||
|
println!("cargo:rerun-if-changed={}", plugin_root.display());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn stage_plugin_file(source: &std::path::Path, destination: &std::path::Path) {
|
||||||
|
let Ok(bytes) = std::fs::read(source) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if std::fs::read(destination).is_ok_and(|existing| existing == bytes) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if let Some(parent) = destination.parent() {
|
||||||
|
std::fs::create_dir_all(parent).expect("创建插件资源目录失败");
|
||||||
|
}
|
||||||
|
std::fs::write(destination, bytes).expect("复制插件资源失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn copy_plugin_tree(source: &std::path::Path, destination: &std::path::Path) {
|
||||||
|
let entries = match std::fs::read_dir(source) {
|
||||||
|
Ok(entries) => entries,
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
for entry in entries.flatten() {
|
||||||
|
let target = destination.join(entry.file_name());
|
||||||
|
let path = entry.path();
|
||||||
|
if path.is_dir() {
|
||||||
|
let name = entry.file_name();
|
||||||
|
let name = name.to_string_lossy();
|
||||||
|
if matches!(name.as_ref(), "target" | "node_modules" | ".git") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::fs::create_dir_all(&target).expect("创建插件资源目录失败");
|
||||||
|
copy_plugin_tree(&path, &target);
|
||||||
|
} else {
|
||||||
|
// 测试文件不随包分发。
|
||||||
|
let name = entry.file_name();
|
||||||
|
let name = name.to_string_lossy();
|
||||||
|
if name.contains(".test.") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
stage_plugin_file(&path, &target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn copy_plugin_file(source: &std::path::Path, destination: &std::path::Path) {
|
||||||
|
if !source.is_file() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::fs::create_dir_all(destination.parent().expect("插件资源父目录"))
|
||||||
|
.expect("创建插件资源目录失败");
|
||||||
|
std::fs::copy(source, destination).expect("复制插件资源失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
fn stage_plugin_workspace(_manifest_dir: &std::path::Path) {}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
当前阶段:系统架构。明确系统清单、职责边界、依赖和数据归属。
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
共享过程文件(如需维护,请使用这些相对路径):
|
|
||||||
- project/analysis.md
|
|
||||||
- project/决策台账.md
|
|
||||||
- project/dialog.md
|
|
||||||
不要把正式产物写在工作区根目录,也不要等审批失败后再迁移。
|
|
||||||
阶段审批工具:当你判断本阶段必需产物已完成时,必须提交阶段审批。用户批准后 Runtime 自动进入下一阶段;你不能自行切换阶段。
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
当前阶段:概念设计。明确游戏是什么、不是什么,并形成概念设计产物。
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
顾问阶段不需要继续自主推动项目或主动安排下一步;遵照用户的具体指示行动。
|
|
||||||
根据用户指示回答问题、读取相关文档、修改工作区文件,并说明改动可能影响的已有产物。
|
|
||||||
涉及方向性变化或多个可行方案时,先向用户说明影响并等待用户决定;不要替用户做决定。
|
|
||||||
顾问阶段没有下一层,也不需要提交阶段审批。
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
当前阶段:项目顾问。五个策划阶段已经完成,后续由用户指示驱动协作。
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
概念阶段定稿时,还必须创建或更新 `project/速览卡.md`。Runtime 只检查该文件是否存在,不检查内容。请使用下面的固定结构,不要加入审批操作说明或独立的决定状态段落:
|
|
||||||
|
|
||||||
# 速览卡:《游戏名》
|
|
||||||
|
|
||||||
## 1. 游戏名称
|
|
||||||
|
|
||||||
## 2. 游戏分类
|
|
||||||
|
|
||||||
## 3. 美术风格
|
|
||||||
- 视觉类型:
|
|
||||||
- 风格关键词:
|
|
||||||
- 色彩与氛围:
|
|
||||||
- MVP 美术边界:
|
|
||||||
|
|
||||||
## 4. 一句话描述
|
|
||||||
|
|
||||||
## 5. 游戏支柱
|
|
||||||
| 支柱 | 玩家感受 | 实现机制 |
|
|
||||||
|---|---|---|
|
|
||||||
|
|
||||||
## 6. 核心循环
|
|
||||||
|
|
||||||
## 7. 目标用户
|
|
||||||
- 核心用户:
|
|
||||||
- 游戏偏好:
|
|
||||||
- 单次游玩时长:
|
|
||||||
- 参考游戏与参考点:
|
|
||||||
|
|
||||||
## 8. 平台事实
|
|
||||||
|
|
||||||
## 9. 最小 MVP 系统
|
|
||||||
| 系统 | 最小功能 | 为什么必须有 | 验证方法 |
|
|
||||||
|---|---|---|---|
|
|
||||||
|
|
||||||
## 10. 给创作者的关键提示
|
|
||||||
- 先做:
|
|
||||||
- 暂时不做:
|
|
||||||
- 这样验证:
|
|
||||||
- 达标再扩展:
|
|
||||||
|
|
||||||
### 待原型验证项
|
|
||||||
- 问题:
|
|
||||||
- 原型:
|
|
||||||
- 观察:
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
当前阶段:系统文档。逐个完成已确定系统的内部规则、接口和验证标准。
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
当前阶段:技术文档。完成数据与配表、技术实现、美术圣经和总册。
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
当前阶段:顶层设计。明确玩家持续游玩的循环、资源流、节奏和系统范围。
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,384 +0,0 @@
|
|||||||
{
|
|
||||||
"version": 1,
|
|
||||||
"resources": [
|
|
||||||
{
|
|
||||||
"path": "skills/concept.md",
|
|
||||||
"id": "skills.concept",
|
|
||||||
"summary": "概念阶段写作规则。",
|
|
||||||
"category": "skills",
|
|
||||||
"title": "概念设计分册",
|
|
||||||
"inject_phases": [
|
|
||||||
"concept"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "skills/top_design.md",
|
|
||||||
"id": "skills.top_design",
|
|
||||||
"summary": "顶层设计阶段写作规则。",
|
|
||||||
"category": "skills",
|
|
||||||
"title": "顶层设计分册",
|
|
||||||
"inject_phases": [
|
|
||||||
"top_design"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "skills/architecture.md",
|
|
||||||
"id": "skills.architecture",
|
|
||||||
"summary": "系统架构阶段写作规则。",
|
|
||||||
"category": "skills",
|
|
||||||
"title": "系统架构分册",
|
|
||||||
"inject_phases": [
|
|
||||||
"architecture"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "skills/systems.md",
|
|
||||||
"id": "skills.systems",
|
|
||||||
"summary": "系统文档阶段写作规则。",
|
|
||||||
"category": "skills",
|
|
||||||
"title": "系统文档分册",
|
|
||||||
"inject_phases": [
|
|
||||||
"systems"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "skills/tdd.md",
|
|
||||||
"id": "skills.tdd",
|
|
||||||
"summary": "技术文档阶段写作规则。",
|
|
||||||
"category": "skills",
|
|
||||||
"title": "技术文档分册",
|
|
||||||
"inject_phases": [
|
|
||||||
"tdd"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "templates.analysis",
|
|
||||||
"category": "templates",
|
|
||||||
"title": "analysis",
|
|
||||||
"summary": "策划文档结构模板。",
|
|
||||||
"path": "templates/analysis.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "templates.architecture",
|
|
||||||
"category": "templates",
|
|
||||||
"title": "architecture",
|
|
||||||
"summary": "策划文档结构模板。",
|
|
||||||
"path": "templates/architecture.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "templates.concept_design",
|
|
||||||
"category": "templates",
|
|
||||||
"title": "concept-design",
|
|
||||||
"summary": "策划文档结构模板。",
|
|
||||||
"path": "templates/concept-design.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "templates.stardew_analysis",
|
|
||||||
"category": "templates",
|
|
||||||
"title": "stardew-analysis",
|
|
||||||
"summary": "策划文档结构模板。",
|
|
||||||
"path": "templates/stardew-analysis.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "templates.tdd_art_bible",
|
|
||||||
"category": "templates",
|
|
||||||
"title": "tdd-art-bible",
|
|
||||||
"summary": "策划文档结构模板。",
|
|
||||||
"path": "templates/tdd-art-bible.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "templates.tdd_data",
|
|
||||||
"category": "templates",
|
|
||||||
"title": "tdd-data",
|
|
||||||
"summary": "策划文档结构模板。",
|
|
||||||
"path": "templates/tdd-data.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "templates.tdd_master",
|
|
||||||
"category": "templates",
|
|
||||||
"title": "tdd-master",
|
|
||||||
"summary": "策划文档结构模板。",
|
|
||||||
"path": "templates/tdd-master.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "templates.tdd_tech",
|
|
||||||
"category": "templates",
|
|
||||||
"title": "tdd-tech",
|
|
||||||
"summary": "策划文档结构模板。",
|
|
||||||
"path": "templates/tdd-tech.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "templates.top_design",
|
|
||||||
"category": "templates",
|
|
||||||
"title": "top-design",
|
|
||||||
"summary": "策划文档结构模板。",
|
|
||||||
"path": "templates/top-design.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "exemplars.decision_log",
|
|
||||||
"category": "exemplars",
|
|
||||||
"title": "decision-log",
|
|
||||||
"summary": "策划文档范例或需求附件。",
|
|
||||||
"path": "exemplars/decision-log.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "exemplars.fast_gdd",
|
|
||||||
"category": "exemplars",
|
|
||||||
"title": "fast-gdd",
|
|
||||||
"summary": "策划文档范例或需求附件。",
|
|
||||||
"path": "exemplars/fast-gdd.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "exemplars.overview_card",
|
|
||||||
"category": "exemplars",
|
|
||||||
"title": "overview-card",
|
|
||||||
"summary": "策划文档范例或需求附件。",
|
|
||||||
"path": "exemplars/overview-card.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "exemplars.stardew_architecture",
|
|
||||||
"category": "exemplars",
|
|
||||||
"title": "stardew-architecture",
|
|
||||||
"summary": "策划文档范例或需求附件。",
|
|
||||||
"path": "exemplars/stardew-architecture.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "exemplars.stardew_concept",
|
|
||||||
"category": "exemplars",
|
|
||||||
"title": "stardew-concept",
|
|
||||||
"summary": "策划文档范例或需求附件。",
|
|
||||||
"path": "exemplars/stardew-concept.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "exemplars.stardew_s06_combat",
|
|
||||||
"category": "exemplars",
|
|
||||||
"title": "stardew-s06-combat",
|
|
||||||
"summary": "策划文档范例或需求附件。",
|
|
||||||
"path": "exemplars/stardew-s06-combat.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "exemplars.stardew_tdd_art_bible",
|
|
||||||
"category": "exemplars",
|
|
||||||
"title": "stardew-tdd-art-bible",
|
|
||||||
"summary": "策划文档范例或需求附件。",
|
|
||||||
"path": "exemplars/stardew-tdd-art-bible.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "exemplars.stardew_tdd_data",
|
|
||||||
"category": "exemplars",
|
|
||||||
"title": "stardew-tdd-data",
|
|
||||||
"summary": "策划文档范例或需求附件。",
|
|
||||||
"path": "exemplars/stardew-tdd-data.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "exemplars.stardew_tdd_master",
|
|
||||||
"category": "exemplars",
|
|
||||||
"title": "stardew-tdd-master",
|
|
||||||
"summary": "策划文档范例或需求附件。",
|
|
||||||
"path": "exemplars/stardew-tdd-master.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "exemplars.stardew_tdd_tech",
|
|
||||||
"category": "exemplars",
|
|
||||||
"title": "stardew-tdd-tech",
|
|
||||||
"summary": "策划文档范例或需求附件。",
|
|
||||||
"path": "exemplars/stardew-tdd-tech.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "exemplars.stardew_top_design",
|
|
||||||
"category": "exemplars",
|
|
||||||
"title": "stardew-top-design",
|
|
||||||
"summary": "策划文档范例或需求附件。",
|
|
||||||
"path": "exemplars/stardew-top-design.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "exemplars.tdd_art_bible_SKILL",
|
|
||||||
"category": "exemplars",
|
|
||||||
"title": "tdd-art-bible-SKILL",
|
|
||||||
"summary": "策划文档范例或需求附件。",
|
|
||||||
"path": "exemplars/tdd-art-bible-SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "exemplars.tdd_data_SKILL",
|
|
||||||
"category": "exemplars",
|
|
||||||
"title": "tdd-data-SKILL",
|
|
||||||
"summary": "策划文档范例或需求附件。",
|
|
||||||
"path": "exemplars/tdd-data-SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "exemplars.tdd_tech_SKILL",
|
|
||||||
"category": "exemplars",
|
|
||||||
"title": "tdd-tech-SKILL",
|
|
||||||
"summary": "策划文档范例或需求附件。",
|
|
||||||
"path": "exemplars/tdd-tech-SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.核心玩法编排.skill",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "01_核心玩法编排 skill",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/01_核心玩法编排/SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.核心玩法编排.template",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "01_核心玩法编排 template",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/01_核心玩法编排/模板.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.时间与日程.skill",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "02_时间与日程 skill",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/02_时间与日程/SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.时间与日程.template",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "02_时间与日程 template",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/02_时间与日程/模板.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.生产种植经营.skill",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "03_生产种植经营 skill",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/03_生产种植经营/SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.生产种植经营.template",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "03_生产种植经营 template",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/03_生产种植经营/模板.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.地图与探索.skill",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "04_地图与探索 skill",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/04_地图与探索/SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.地图与探索.template",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "04_地图与探索 template",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/04_地图与探索/模板.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.采集与支线活动.skill",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "05_采集与支线活动 skill",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/05_采集与支线活动/SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.采集与支线活动.template",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "05_采集与支线活动 template",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/05_采集与支线活动/模板.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.战斗与敌人.skill",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "06_战斗与敌人 skill",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/06_战斗与敌人/SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.战斗与敌人.template",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "06_战斗与敌人 template",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/06_战斗与敌人/模板.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.物品背包与制作.skill",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "07_物品背包与制作 skill",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/07_物品背包与制作/SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.物品背包与制作.template",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "07_物品背包与制作 template",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/07_物品背包与制作/模板.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.成长与技能.skill",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "08_成长与技能 skill",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/08_成长与技能/SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.成长与技能.template",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "08_成长与技能 template",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/08_成长与技能/模板.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.NPC关系与任务.skill",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "09_NPC关系与任务 skill",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/09_NPC关系与任务/SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.NPC关系与任务.template",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "09_NPC关系与任务 template",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/09_NPC关系与任务/模板.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.经济与商店.skill",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "10_经济与商店 skill",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/10_经济与商店/SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.经济与商店.template",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "10_经济与商店 template",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/10_经济与商店/模板.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.事件与节日.skill",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "11_事件与节日 skill",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/11_事件与节日/SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.事件与节日.template",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "11_事件与节日 template",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/11_事件与节日/模板.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.UI与文本呈现.skill",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "12_UI与文本呈现 skill",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/12_UI与文本呈现/SKILL.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "system_types.UI与文本呈现.template",
|
|
||||||
"category": "system_types",
|
|
||||||
"title": "12_UI与文本呈现 template",
|
|
||||||
"summary": "系统类型写法规则或模板。",
|
|
||||||
"path": "modules/system-types/12_UI与文本呈现/模板.md"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
# 决策台账:《星露谷物语》金样项目
|
|
||||||
|
|
||||||
版本:v3 | 规则:台账放活队列——design 只放结论、分析只放论证、决定与开放问题住这里。编号连续不复用;被推翻的行标 overturned 挂新行,不删行。
|
|
||||||
状态六态:`confirmed`(用户亲口/亲选)/ `auto_decided`(技术类代决,必带理由+推翻条件,用户一键可翻)/ `default_pending`(默认建议兜底,用户未点头)/ `prototype_pending`(待原型验证)/ `pending_user`(等用户拍板)/ `overturned`(被推翻,挂旧行编号)。
|
|
||||||
|
|
||||||
> 编号口径:D-01~D-13 与 exemplars/stardew-analysis.md 台账节选一致(D-04~D-06、D-08~D-10、D-12 原为"就地小权衡,直接登记未开条目",此处按登记口径展开);D-14 起为技术文档期新增,与 stardew-tdd-tech.md 开放问题回执互引。
|
|
||||||
|
|
||||||
## 当前待办(活队列)
|
|
||||||
|
|
||||||
### 等用户拍板(pending_user)
|
|
||||||
|
|
||||||
| 编号 | 决定 | 层 | 谁 | 依据 | 推翻条件 | 状态 |
|
|
||||||
|---|---|---|---|---|---|---|
|
|
||||||
| D-14 | 体力与战斗共享单池 | TDD | user | 风险资源统一制造取舍(概念张力一);**暂按共享实现,改单拆只需改 S02 成本入口** | 战斗参与率实测过低(玩家回避矿井) | pending_user(暂按共享实现) |
|
|
||||||
| D-15 | 背包格子制 vs 重量制 | TDD | user | 格子制直觉、重量制焦虑感与 T5"休闲不打卡"冲突;暂按格子制实现、存档预留 capacity_type 字段 | 格子管理成为主要负面反馈 | pending_user(B 级阻断存档结构,暂按格子制) |
|
|
||||||
|
|
||||||
### 待原型验证(prototype_pending)
|
|
||||||
|
|
||||||
| 编号 | 决定 | 层 | 谁 | 依据 | 推翻条件 | 状态 |
|
|
||||||
|---|---|---|---|---|---|---|
|
|
||||||
| D-13b | 战斗判定窗口手感(前摇帧数/无敌帧 450ms 基准) | 系统 | user | 数值可定、手感不可纸面验证 | 原型显示节奏拖慢/玩家困惑 | prototype_pending(规则本体见 D-13 confirmed) |
|
|
||||||
|
|
||||||
### 默认建议兜底(default_pending)
|
|
||||||
|
|
||||||
| 编号 | 决定 | 层 | 谁 | 依据 | 推翻条件 | 状态 |
|
|
||||||
|---|---|---|---|---|---|---|
|
|
||||||
| D-19 | 天气权重表具体数值(晴/雨/风暴按季节) | TDD | agent | 概念层只定"雨免浇水"定性;数值推内容期填 | 前 5 日出现连续 3 日雨/全无雨 | default_pending(默认值已进数据表,带 designer_note) |
|
|
||||||
|
|
||||||
## 已采用决定
|
|
||||||
|
|
||||||
### 用户确认(confirmed)
|
|
||||||
|
|
||||||
| 编号 | 决定 | 层 | 谁 | 依据 | 推翻条件 | 状态 |
|
|
||||||
|---|---|---|---|---|---|---|
|
|
||||||
| D-01 | 定调:牧场物语系参照、治愈慢节奏 | 概念 | user | 用户原始需求 | — | confirmed |
|
|
||||||
| D-02 | 单人体验,无多人 | 概念 | user | 概念层非目标 | — | confirmed |
|
|
||||||
| D-03 | 战斗保持伴生风险,不做装备驱动主轴 | 概念 | user | 概念期问题一 | 矿井流失率过半且归因战斗 | confirmed |
|
|
||||||
| D-07 | 日目标自设,季节与社区提供低频牵引 | 顶层 | user | 顶层期问题一 | 新手周流失归因无方向 | confirmed |
|
|
||||||
| D-11 | 采集/钓鱼/战斗统一"活动结果"接口 | 架构 | user | 架构期问题一 | 第三活动类型出现结构性差异 | confirmed |
|
|
||||||
| D-13 | 战斗采用节奏/指令判定 | 系统 | user | S06 问题一 | 原型显示节奏拖慢/玩家困惑 | confirmed(手感部分拆 D-13b prototype_pending) |
|
|
||||||
|
|
||||||
### 技术代决(auto_decided——带理由与推翻条件,用户一键可翻)
|
|
||||||
|
|
||||||
| 编号 | 决定 | 层 | 谁 | 依据(理由) | 推翻条件 | 状态 |
|
|
||||||
|---|---|---|---|---|---|---|
|
|
||||||
| D-04 | 时间片制:700ms=10 游戏分钟 | 概念 | agent | 原作实证节拍;一天≈14 分钟真实时间贴合 T5"休闲" | 内测一天体感过短/过长 | auto_decided |
|
|
||||||
| D-05 | 分区域切换(区域独立场景,非连续地图) | 概念 | agent | 概念层"不是什么:无边界开放世界";区域小网络全部步行可达 | 场景切换成为移动负担反馈 | auto_decided |
|
|
||||||
| D-06 | 28 日/季、四季/年 | 顶层 | agent | 季节窗口制造"本季计划"节奏(支柱二) | 换季频率在测试中被无视 | auto_decided |
|
|
||||||
| D-09 | 商店营业时段走条件表 | 架构 | agent | 与配方/区域解锁共用 check(condition_id) 单一入口 | 条件表规模膨胀难维护 | auto_decided |
|
|
||||||
| D-10 | 出货箱日终统一结算 | 架构 | agent | 收入集中进日终面板,强化"一天一结算"叙事;商店现卖保留即时通道 | 玩家普遍绕开出货箱 | auto_decided |
|
|
||||||
| D-12 | 工具升级期间该工具不可用 | 系统 | agent | 升级=时间成本换效率(顶层张力二);备用旧工具暂不做(开放问题) | 升级期挫败感集中爆发 | auto_decided |
|
|
||||||
| D-16 | 矿井逐层生成本期不做(P2) | TDD | agent | GDD 已标"不做无限地牢";首期按布局池 8~12 模板拼装 | 内测要求深度爬塔玩法 | auto_decided |
|
|
||||||
| D-17 | 换装首期 5 层(基础体/裤/衣/发型/饰件),非 19 层 | TDD | agent | 外观自定义非首期卖点;层结构预留到 19 层 | 外观系统成核心诉求 | auto_decided |
|
|
||||||
| D-18 | 作物品质三档:普通/银/金 | TDD | agent | 经济分层需要(即时变现 vs 等待升值的取舍) | 银金档无人区分、一律普通出售 | auto_decided |
|
|
||||||
|
|
||||||
### 已推翻(overturned——旧行保留,挂新行)
|
|
||||||
|
|
||||||
| 编号 | 决定 | 层 | 谁 | 依据 | 推翻条件 | 状态 |
|
|
||||||
|---|---|---|---|---|---|---|
|
|
||||||
| D-08 | 作物品质两档:普通/银 | TDD | agent | 早期小权衡:两档最简 | — | **overturned → D-18**(经济分层不足,改三档;铱档留 P1) |
|
|
||||||
|
|
||||||
## 队列纪律(给 agent 的使用说明)
|
|
||||||
|
|
||||||
- 新决定入队:拿下一号(当前最大 D-19,下一号 D-20);就现代决可登记不开条目,但状态必须写 auto_decided 并带理由+推翻条件。
|
|
||||||
- 用户翻案:旧行标 overturned 挂新行,受影响文档节重写(本台账只记录,不代改)。
|
|
||||||
- 概念层变更定稿后:速览卡"决定状态与原型验证项"字段随本文件最新版同步(prompt 级纪律)。
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
# 脉冲荒原:节点争夺战
|
|
||||||
|
|
||||||
> Fast GDD v1 · 状态:ready\_for\_approval
|
|
||||||
> gddId:`gdd-a5309290-edd4-4232-9c7c-d99024e0fa42`
|
|
||||||
> fingerprint:`sha256-serde-json-v2:1d34b0cbee5f623a224102e4d832ad6ecc10ffbf27b876d9bc1e24a5483f06a3`
|
|
||||||
> approvalRequestId:`gdd-approval-6f5de673-553d-499f-8ca1-8c32f4841bc0`
|
|
||||||
|
|
||||||
## 决定状态
|
|
||||||
|
|
||||||
- **初始需求**(confirmed,user\_freeform,第 0 轮):用户提出制作原创、可落地的2D坦克大战MVP。
|
|
||||||
- **坦克对战的胜负目标**(confirmed,user\_option,第 1 轮):采用区域争夺作为每局主要胜负目标。
|
|
||||||
- **区域争夺的占领方式**(confirmed,user\_option,第 2 轮):采用少量多节点轮换占领,迫使双方在路线间转移争夺。
|
|
||||||
- **轮换节点的结束规则**(confirmed,user\_option,第 3 轮):控制当前节点持续得分,任一方先达到目标分即获胜。
|
|
||||||
- **目标用户**(default\_pending,default,第 0 轮):默认面向喜欢短局、直接操控、位置博弈和可重复挑战的休闲动作玩家。
|
|
||||||
- **美术方向**(default\_pending,default,第 0 轮):默认采用风格化、轮廓清晰的原创战场与占位资产,优先验证可读性。
|
|
||||||
- **成长范围**(default\_pending,default,第 0 轮):默认设置一条轻量成长线,仅提供少量战后选择,不影响单局闭环。
|
|
||||||
- **MVP内容边界**(default\_pending,default,第 0 轮):默认首个版本只做单人对抗一名基础AI、单张地图和一套坦克配置。
|
|
||||||
|
|
||||||
## 一句话描述
|
|
||||||
|
|
||||||
驾驶原创装甲穿越掩体,在轮换能量节点间交火夺分,先达目标分者赢得一局紧凑的2D坦克区域争夺战。
|
|
||||||
|
|
||||||
## 游戏分类与美术
|
|
||||||
|
|
||||||
- 主类型:2D坦克区域争夺
|
|
||||||
- 融合类型:无
|
|
||||||
- 视觉类型:风格化俯视2D
|
|
||||||
- 关键词:轮廓清晰、几何掩体、弹道高亮、原创装甲
|
|
||||||
- 色彩氛围:冷青灰战场衬托橙蓝阵营高亮;节点被占领时产生清晰的环形脉冲,命中、受击和得分使用短促高对比反馈。
|
|
||||||
- MVP 美术边界:MVP 使用可复用的几何占位资产:一张俯视战场、两种原创装甲外形、节点与掩体模块;先保证阵营、弹道、占领状态在桌面和移动视口均清楚。
|
|
||||||
|
|
||||||
## 游戏支柱
|
|
||||||
|
|
||||||
### 移动夺势
|
|
||||||
|
|
||||||
- 玩家感受:始终知道下一处冲突在哪里,移动本身就是争夺优势而非赶路。
|
|
||||||
- 机制:节点位置与活跃状态持续改变,玩家必须在占领、转移、驻守和反攻之间做出即时选择。
|
|
||||||
- 决定状态:confirmed
|
|
||||||
|
|
||||||
### 掩体交火
|
|
||||||
|
|
||||||
- 玩家感受:每次探头、绕侧和开火都带来可读的风险回报。
|
|
||||||
- 机制:几何掩体阻挡弹道,玩家通过角度、射击窗口和绕行路线逼退对手,再进入节点控分。
|
|
||||||
- 决定状态:confirmed
|
|
||||||
|
|
||||||
### 清晰逆转
|
|
||||||
|
|
||||||
- 玩家感受:局势紧张但不迷惑,玩家理解自己为何领先或落后并愿意再开一局。
|
|
||||||
- 机制:目标分、活跃节点和控制状态持续可视化;落后方可通过夺回当前节点改变局势。
|
|
||||||
- 决定状态:confirmed
|
|
||||||
|
|
||||||
## 核心循环
|
|
||||||
|
|
||||||
1. 进入战场并观察当前活跃节点与敌方位置
|
|
||||||
2. 驾驶“棱虎机”在几何掩体间移动,瞄准并发射脉冲炮
|
|
||||||
3. 抵达活跃节点并在敌方干扰下完成占领或夺回
|
|
||||||
4. 控制节点持续积累“脉冲分”,节点轮换后转移路线
|
|
||||||
5. 先达到目标分的一方获胜,结算后可立即重开
|
|
||||||
|
|
||||||
## 目标用户
|
|
||||||
|
|
||||||
- 核心用户:偏好短局即时动作、方向操控、躲避射击和争夺空间的休闲玩家;可接受单人对抗基础AI。
|
|
||||||
- 偏好:喜欢规则一眼可懂、操作反馈直接、每局约十几分钟内完成,并能通过走位和时机而非复杂配装取胜。
|
|
||||||
- 单局时长:默认每局约10~20分钟;首个可玩闭环优先做到一局可完整开始、争夺、决胜和重开。
|
|
||||||
- 参考游戏:无
|
|
||||||
|
|
||||||
## Runtime 平台事实
|
|
||||||
|
|
||||||
- Runtime:self-contained-web
|
|
||||||
- 视口:desktop / mobile
|
|
||||||
- 输入:keyboard / touch
|
|
||||||
- 预览:local-http
|
|
||||||
|
|
||||||
## MVP 系统
|
|
||||||
|
|
||||||
### 坦克操控与射击
|
|
||||||
|
|
||||||
- 最小功能:提供八方向移动、旋转瞄准、单一脉冲炮射击、受击反馈与短暂失活重生,支持键盘和触控操作。
|
|
||||||
- 必要原因:直接构成坦克对战手感,也是区域争夺发生的主要冲突手段。
|
|
||||||
- 验证方式:试玩者能在一分钟内完成移动、瞄准、射击和躲入掩体,并能用射击驱离节点附近敌人。
|
|
||||||
- 决定状态:confirmed
|
|
||||||
|
|
||||||
### 轮换节点占领
|
|
||||||
|
|
||||||
- 最小功能:以少量节点组成单张战场,仅一个节点在任一时刻活跃;进入后按占优方推进占领,活跃节点轮换并提供清晰状态提示。
|
|
||||||
- 必要原因:落实用户确认的多节点轮换占领,并制造移动、停留和反攻决策。
|
|
||||||
- 验证方式:玩家无需额外说明即可找到活跃节点,读懂中立、己方和敌方控制状态,并在轮换后改变路线。
|
|
||||||
- 决定状态:confirmed
|
|
||||||
|
|
||||||
### 目标分胜负
|
|
||||||
|
|
||||||
- 最小功能:活跃节点由控制方持续获得脉冲分;任一方先达到目标分即胜,显示双方分数、当前节点和胜负结算。
|
|
||||||
- 必要原因:把占领行为闭合成清晰、可验证的单局目标。
|
|
||||||
- 验证方式:试玩者能预测哪方领先、理解如何逆转,并在达到目标分时明确知道对局结束。
|
|
||||||
- 决定状态:confirmed
|
|
||||||
|
|
||||||
### 俯视战场结构
|
|
||||||
|
|
||||||
- 最小功能:布置可绕行的几何掩体、节点路径与出生区域;掩体阻挡弹道并形成接近、驻守和侧袭路线。
|
|
||||||
- 必要原因:让位置博弈支撑区域争夺,避免节点规则沦为单纯站桩计分。
|
|
||||||
- 验证方式:观察玩家是否主动利用掩体接近节点或规避火力,而非只在开阔地互射。
|
|
||||||
- 决定状态:confirmed
|
|
||||||
|
|
||||||
### 基础对手AI
|
|
||||||
|
|
||||||
- 最小功能:提供一名基础AI对手:追踪活跃节点、靠近争夺、在射程内攻击并在失活后返回战场。
|
|
||||||
- 必要原因:在无多人条件下完成完整的对抗闭环并验证核心玩法。
|
|
||||||
- 验证方式:连续试玩中,AI应持续争夺节点并制造可理解的反攻机会,不出现长时间卡住或无目标游走。
|
|
||||||
- 决定状态:default\_pending
|
|
||||||
|
|
||||||
## 制作边界
|
|
||||||
|
|
||||||
- 多人联机与服务器
|
|
||||||
- 商城、赛季和复杂社交
|
|
||||||
- 开放世界与完整剧情
|
|
||||||
- 多地图、多武器树与复杂成长
|
|
||||||
- 可编辑关卡和排行榜
|
|
||||||
|
|
||||||
## 创作者提示
|
|
||||||
|
|
||||||
- 先做:先做单张紧凑俯视战场、玩家坦克、基础AI对手、移动瞄准射击、掩体碰撞、节点轮换、占领计分和胜负结算,确保一局可从开始玩到结束。
|
|
||||||
- 暂缓:暂缓多人联机、商城、服务器、开放世界、赛季、复杂社交、完整剧情、多武器树和多地图内容。
|
|
||||||
- 如何验证:用可操作原型观察玩家是否在首局主动驶向活跃节点、利用掩体交火、理解分数变化并完成一局;记录误读占领状态、无目标游走和胜负不明的情况。
|
|
||||||
- 何时扩展:仅当试玩者能无讲解理解活跃节点、占领状态和领先来源,并主动移动反攻时,再增加第二种坦克特性、第二张地图或轻量成长选择。
|
|
||||||
-59
@@ -1,59 +0,0 @@
|
|||||||
# 速览卡:《星露谷物语》金样项目
|
|
||||||
|
|
||||||
> 12 字段版本;渲染器照旧出卡走审批。字段来源见每节尾注(概念层/定调记录/台账投影)。概念层变更定稿后本卡必须同步更新(prompt 级纪律)。
|
|
||||||
|
|
||||||
## 1. 游戏名称
|
|
||||||
《星露谷物语》(金样项目沿用案例名;新项目由概念层第 1 节定名)←概念层§1
|
|
||||||
|
|
||||||
## 2. 一句话描述
|
|
||||||
继承一座荒废农场的乡村生活 RPG:安排每天的时间与体力,种田、探索、交朋友,把日子过成自己想要的样子。(←概念层§1 一句话概念,45~90 字)
|
|
||||||
|
|
||||||
## 3. 游戏分类
|
|
||||||
乡村生活模拟 RPG(经营+探索+社交;参照系牧场物语)←概念层§1
|
|
||||||
|
|
||||||
## 4. 美术风格(四件)←定调记录+概念层§4
|
|
||||||
- 视觉类型:手绘感像素风、俯视 45° 视角。
|
|
||||||
- 风格关键词:温暖、田园、四季分明、生活感。
|
|
||||||
- 色彩与氛围:暖土绿基底+季节信号色整体切换;治愈不压抑;无锐利科技感、无阴暗元素。
|
|
||||||
- MVP 美术边界:首期 3 区域 tileset、8 位 NPC(行走+立绘)、约 120 物品图标、玩家换装 5 层;不做 19 层全量换装与全区域。
|
|
||||||
|
|
||||||
## 5. 游戏支柱(3 条)←设计锚点提炼
|
|
||||||
| 支柱 | 玩家感受 | 实现机制 |
|
|
||||||
|---|---|---|
|
|
||||||
| 自己的节奏 | "今天想干嘛就干嘛,明天一切更顺手。" | 自由日程+时间体力预算;无失败结局 |
|
|
||||||
| 今天的选择让明天更从容 | "升级工具、攒钱扩建是有意义的。" | 长期投资线:工具升级/技能/设施 |
|
|
||||||
| 社区让独居变成归属 | "镇上的人在等我。" | NPC 关系/任务/社区修复目标 |
|
|
||||||
|
|
||||||
## 6. 核心循环(5 步)←锚点循环位展开
|
|
||||||
安排一天的时间与体力 → 农/采/钓/矿/战/社交任选组合 → 获得资源·金钱·经验·关系 → 投资工具·设施·种子·物品 → 解锁更高效或更丰富的活动。
|
|
||||||
|
|
||||||
## 7. 目标用户 ←概念层§5
|
|
||||||
牧场物语系慢节奏成长玩家+动森式"无压力日常"需求;单人、可反复、每次一至数个游戏日;不要求预先掌握复杂数值。
|
|
||||||
|
|
||||||
## 8. 平台事实 ←运行时注入,禁改
|
|
||||||
自包含 Web · 双视口(桌面/移动)· 键鼠/触屏双输入 · 本地 HTTP 预览(金样项目按 HTML 演示路线锁定)。
|
|
||||||
|
|
||||||
## 9. MVP 系统(5 个)←概念层"最小闭环粗清单"
|
|
||||||
| 系统 | 最小功能 | 为什么必须有 | 验证方法 |
|
|
||||||
|---|---|---|---|
|
|
||||||
| 时间与日程 | 时钟/日终结算/季节天气 | 全局节拍器 | 一个游戏日全流程可完成并结算 |
|
|
||||||
| 体力与状态 | 单池体力/昏倒惩罚 | 一切取舍的成本源 | 玩家主动在体力耗尽前收手 |
|
|
||||||
| 农场经营 | 锄种浇收+加工队列 | 核心产出与规划场 | "买种→收获→出售"闭环成立 |
|
|
||||||
| 物品与制作 | item_id/背包/配方解锁 | 资源身份与转化 | 拾取/堆叠/制作全链无回翻 GDD |
|
|
||||||
| 经济与商店 | 基准价+价差+出货箱 | 投资回报换算 | 第 4 日现金流回正(前五日验算) |
|
|
||||||
|
|
||||||
## 10. 制作边界 ←概念层"不是什么"表
|
|
||||||
不做:硬核生存(无饥饿/债务/死亡惩罚);效率至上的工厂经营;以战斗为核心的动作游戏;剧情驱动的任务链主线;多人竞争;无边界开放世界(区域小网络全步行可达)。
|
|
||||||
|
|
||||||
## 11. 创作者提示(先做与验证)←概念层"先做与验证"节
|
|
||||||
- 先做:第 1 日循环(买种→播种→浇灌→收获→出售→日终结算)+一个可进入的矿井遭遇。
|
|
||||||
- 暂不做:装备刷取、随机构筑、复杂剧情、节日全量、联机。
|
|
||||||
- 这样验证:测试者玩完第 1 日后是否主动说"再玩一天";能否说出"明天要先做什么"。
|
|
||||||
- 达标再扩展:玩家能自述明日计划后,才加社交深度与矿井分层。
|
|
||||||
|
|
||||||
## 12. 决定状态与原型验证项 ←台账投影(decision-log.md v3)
|
|
||||||
- 已确认(confirmed):定调 D-01 / 单人 D-02 / 战斗伴生 D-03 / 日目标自设 D-07 / 活动统一接口 D-11 / 战斗节奏判定 D-13。
|
|
||||||
- 技术代决(auto_decided,可一键翻案):D-04 时间片 / D-05 分区域切换 / D-06 28 日季 / D-09 营业条件 / D-10 出货箱日终 / D-12 工具占用 / D-16 矿井生成 P2 / D-17 换装 5 层 / D-18 品质三档(推翻 D-08 两档)。
|
|
||||||
- 等拍板(pending_user):D-14 体力战斗是否共享单池(暂按共享实现);D-15 背包格子/重量(暂按格子制,B 级阻断存档结构)。
|
|
||||||
- 待原型(prototype_pending):D-13b 战斗判定窗口手感(前摇帧数/450ms 无敌帧基准)。
|
|
||||||
- 默认兜底(default_pending):D-19 天气权重数值(默认已入表,带 designer_note)。
|
|
||||||
-200
@@ -1,200 +0,0 @@
|
|||||||
# 系统架构:《星露谷物语》
|
|
||||||
|
|
||||||
## 架构定位与目标
|
|
||||||
本阶段确定"哪些系统支撑一轮玩法",不展开单系统内部规则。
|
|
||||||
划分原则:将生活模拟 RPG 拆成职责清晰、可独立讨论的规则系统,同时保留少量跨系统入口,避免"每个功能都能互相调用"造成架构失控。系统划分服务于顶层循环:安排一天、执行活动、获得进展、投入成长、解锁新选择。
|
|
||||||
|
|
||||||
一句话架构:
|
|
||||||
> 玩家在有限的时间与体力下,通过农场、探索与社交三组活动系统产出资源与关系,经物品与经济系统转化为投资,由时间系统推进日终,把一天的成果变成下一天的选择。
|
|
||||||
|
|
||||||
变更记录:
|
|
||||||
- 2026-09-05:战斗与敌人系统定为伴生风险定位,深度刻意受限,不进入最小闭环核心链(依据:概念分析 D-03)。
|
|
||||||
|
|
||||||
## 系统地图
|
|
||||||
|
|
||||||
| 编号 | 系统 | 一句话职责 | 优先级 |
|
|
||||||
|---|---|---|---|
|
|
||||||
| S01 | 时间与日程 | 推进游戏时间、日期、季节、天气、营业时间、NPC 日程和日终结算 | P0 |
|
|
||||||
| S02 | 体力与状态 | 管理体力、负面状态、恢复、昏倒和行动成本 | P0 |
|
|
||||||
| S03 | 农场经营 | 管理土地、作物、畜牧、农场设施和生产状态 | P0 |
|
|
||||||
| S04 | 探索与地图 | 管理区域、出入口、可交互资源点、地图解锁和移动 | P0(基础) |
|
|
||||||
| S05 | 采集与钓鱼 | 管理野外采集、钓鱼活动、资源品质和获得物 | P1 |
|
|
||||||
| S06 | 战斗与敌人 | 管理矿区或危险区域中的战斗、伤害、敌人行为和战利品 | P1 |
|
|
||||||
| S07 | 物品、背包与制作 | 管理物品实例、堆叠、工具、装备、配方和制作队列 | P0 |
|
|
||||||
| S08 | 成长与技能 | 管理技能经验、等级、工具升级、职业选择和能力解锁 | P0(基础) |
|
|
||||||
| S09 | 经济与商店 | 管理货币、买卖、价格、商店库存、订单和资金流 | P0 |
|
|
||||||
| S10 | NPC 与关系 | 管理 NPC 日程、对话、好感度、礼物偏好和关系事件 | P1 |
|
|
||||||
| S11 | 任务与社区目标 | 管理任务状态、阶段目标、奖励、社区修复和区域解锁条件 | P1 |
|
|
||||||
| S12 | 事件与节日 | 管理季节事件、节日活动、条件触发和特殊奖励 | P1 |
|
|
||||||
|
|
||||||
支撑层(不拥有核心规则):
|
|
||||||
- 存档与进度系统:保存跨日、跨季节和跨阶段的持久状态。
|
|
||||||
- UI 与文本呈现层:展示状态、提供操作入口、呈现反馈与文本。
|
|
||||||
|
|
||||||
P0 段:
|
|
||||||
|
|
||||||
| 系统 | 目的 | 输入 | 输出 | P0 原因 |
|
|
||||||
|---|---|---|---|---|
|
|
||||||
| S01 时间与日程 | 全局时钟与日终 | 各系统行动完成信号、日终触发 | 日期/季节/天气变化、日终结算、跨天 tick | 没有"一天",规划与取舍失去标尺 |
|
|
||||||
| S02 体力与状态 | 全局行动成本 | 各系统行动请求、食物与休息 | 体力变化、昏倒、状态效果 | 没有它,"想做的事多于做得到的"不成立 |
|
|
||||||
| S03 农场经营 | 核心产出与规划场 | 时间 tick、种子与工具、体力 | 作物畜产品、设施生产状态 | 概念核心承诺的载体 |
|
|
||||||
| S04 探索与地图 | 活动场景与空间约束 | 移动指令、区域解锁条件 | 位置、区域状态、资源点入口 | 没有空间结构,农/矿/镇一体失去意义 |
|
|
||||||
| S07 物品与制作 | 资源身份与转化 | 各系统获得物、配方请求 | 物品实例、制作结果 | 所有系统产出的公共语言 |
|
|
||||||
| S08 成长与技能 | 长期回报层 | 各活动经验提交 | 等级、能力与配方解锁 | 长期动机的最小载体 |
|
|
||||||
| S09 经济与商店 | 投资与回报换算 | 物品、金钱 | 价格、交易、库存 | 没有它,"变现 vs 投资"张力无载体 |
|
|
||||||
|
|
||||||
## 系统职责
|
|
||||||
|
|
||||||
| 系统 | 主要职责 | 不负责 → 移交谁 |
|
|
||||||
|---|---|---|
|
|
||||||
| S01 时间与日程 | 时间推进、日期、季节、天气、营业与日终 | 直接决定某项活动的奖励 → 各活动系统 |
|
|
||||||
| S02 体力与状态 | 行动消耗、恢复、昏倒、状态效果 | 农作物或敌人的具体配置 → S03/S06 |
|
|
||||||
| S03 农场经营 | 土地、作物、畜牧、设施生产 | 商店买卖规则和角色技能 → S09/S08 |
|
|
||||||
| S04 探索与地图 | 区域连接、进入条件、资源点位置、移动 | 具体掉落概率和战斗公式 → S05/S06 |
|
|
||||||
| S05 采集与钓鱼 | 采集和钓鱼行为、成功条件、获得物 | 物品价格和任务奖励 → S09/S11 |
|
|
||||||
| S06 战斗与敌人 | 战斗流程、敌人状态、伤害与战利品请求 | 角色长期成长和商店价格 → S08/S09 |
|
|
||||||
| S07 物品与制作 | 背包、物品、配方、制作与工具装备 | 物品最终经济价值的平衡目标 → S09 |
|
|
||||||
| S08 成长与技能 | 经验、等级、技能分支、能力解锁 | 单次行动的基础奖励 → 各活动系统 |
|
|
||||||
| S09 经济与商店 | 货币、交易、库存、订单、价格 | 任务剧情与 NPC 情感变化 → S10/S11 |
|
|
||||||
| S10 NPC 与关系 | 日程、互动、好感、关系事件 | 全局季节推进和商店库存 → S01/S09 |
|
|
||||||
| S11 任务与社区 | 目标、前置、奖励、社区进度和解锁 | NPC 的日常行为表现 → S10 |
|
|
||||||
| S12 事件与节日 | 周期事件、特殊流程和限定内容 | 常规日常行动的基础规则 → 各活动系统 |
|
|
||||||
|
|
||||||
职责说明:
|
|
||||||
|
|
||||||
### S01 时间与日程系统
|
|
||||||
负责一天制的节奏规则:什么时候推进日期、哪些系统收到跨天 tick、日终结算何时发生。它不负责奖励结算,也不负责作物成长规则——只负责"什么时候"和"谁被通知"。
|
|
||||||
|
|
||||||
### S06 战斗与敌人系统
|
|
||||||
负责战斗内状态、敌人行为与战利品请求。它不直接修改商店价格或 NPC 好感,不负责角色长期成长;战利品只提交请求,由 S07 物品系统入账。定位是矿井探索的风险与节奏变化,不是成长主轴(D-03)。
|
|
||||||
|
|
||||||
### S07 物品、背包与制作系统
|
|
||||||
负责物品身份、容器、堆叠与配方队列。它是全项目的公共语言层——任何系统的产出都以 `item_id` 入账;它不负责物品的经济价值平衡,价格只由 S09 维护。
|
|
||||||
|
|
||||||
## 依赖与数据流
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
flowchart TD
|
|
||||||
S1[S01 时间与日程] --> S2[S02 体力与状态]
|
|
||||||
S1 --> S3[S03 农场经营]
|
|
||||||
S1 --> S4[S04 探索与地图]
|
|
||||||
S1 --> S10[S10 NPC 与关系]
|
|
||||||
S1 --> S12[S12 事件与节日]
|
|
||||||
S3 --> S7[S07 物品与制作]
|
|
||||||
S4 --> S5[S05 采集与钓鱼]
|
|
||||||
S4 --> S6[S06 战斗与敌人]
|
|
||||||
S5 --> S7
|
|
||||||
S6 --> S7
|
|
||||||
S7 --> S9[S09 经济与商店]
|
|
||||||
S7 --> S8[S08 成长与技能]
|
|
||||||
S8 --> S7
|
|
||||||
S10 --> S11[S11 任务与社区]
|
|
||||||
S12 -.读取日期季节.-> S1
|
|
||||||
UI[UI 与文本呈现] -.读取状态.-> S1
|
|
||||||
UI -.读取状态.-> S3
|
|
||||||
UI -.读取状态.-> S7
|
|
||||||
SAVE[存档与进度] -.订阅持久状态.-> S1
|
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
flowchart LR
|
|
||||||
T[时间/体力] --> ACT[玩家行动]
|
|
||||||
ACT --> GAIN[物品·金钱·经验·关系·任务进度]
|
|
||||||
GAIN --> INV[制作·交易·升级·解锁]
|
|
||||||
INV --> NEW[新的行动选择]
|
|
||||||
NEW --> ACT
|
|
||||||
```
|
|
||||||
|
|
||||||
主要状态:
|
|
||||||
- 全局状态:日期、季节、天气、当前时间、已解锁区域、社区进度。
|
|
||||||
- 玩家状态:位置、体力、生命、技能等级、工具、装备、背包和金钱。
|
|
||||||
- 场景状态:土地、作物成长、设施生产、资源点、敌人和宝箱。
|
|
||||||
- 社会状态:NPC 位置、关系值、已触发事件、任务阶段和节日参与状态。
|
|
||||||
|
|
||||||
主数据归属规则:
|
|
||||||
- 规则文档描述"如何计算"和"何时发生";数据表描述"有哪些对象"和"每个对象的配置"。
|
|
||||||
- 系统之间通过稳定 ID 关联(物品 ID、NPC ID、区域 ID、任务 ID、配方 ID)。
|
|
||||||
- 任何系统都不复制另一系统的主数据;任务只引用物品 ID,不重新定义物品价格。
|
|
||||||
|
|
||||||
## 核心循环覆盖检查
|
|
||||||
|
|
||||||
| 顶层循环环节 | 认领系统 |
|
|
||||||
|---|---|
|
|
||||||
| 查看天气、日程与目标 | S01、S11、S12、UI |
|
|
||||||
| 选择活动并移动 | S04、S02 |
|
|
||||||
| 农务与生产 | S03、S07、S02 |
|
|
||||||
| 采集、钓鱼与战斗 | S04、S05、S06、S07 |
|
|
||||||
| 出售、购买与投资 | S09、S07、S03 |
|
|
||||||
| 社交与委托 | S10、S11、S07 |
|
|
||||||
| 日终结算与保存 | S01、S12、存档、UI |
|
|
||||||
|
|
||||||
## 目录映射
|
|
||||||
|
|
||||||
| 目录 | 本阶段定位 |
|
|
||||||
|---|---|
|
|
||||||
| 03_systems/S01_time_schedule/ | 时间推进、日期季节天气、营业时段、日终结算 |
|
|
||||||
| 03_systems/S02_stamina_status/ | 体力、状态效果、昏倒与恢复 |
|
|
||||||
| 03_systems/S03_farm_management/ | 土地、作物、畜牧、设施生产 |
|
|
||||||
| 03_systems/S04_exploration_map/ | 区域、连接、资源点、解锁与移动 |
|
|
||||||
| 03_systems/S05_foraging_fishing/ | 采集、钓鱼、品质与获得物 |
|
|
||||||
| 03_systems/S06_combat_enemies/ | 战斗、敌人行为、伤害与战利品请求 |
|
|
||||||
| 03_systems/S07_items_inventory_crafting/ | 物品、背包、配方与制作队列 |
|
|
||||||
| 03_systems/S08_progression_skills/ | 技能经验、等级、工具升级、能力解锁 |
|
|
||||||
| 03_systems/S09_economy_shop/ | 货币、买卖、价格、库存与订单 |
|
|
||||||
| 03_systems/S10_npc_relationship/ | NPC 日程、对话、好感与关系事件 |
|
|
||||||
| 03_systems/S11_quests_community/ | 任务、社区目标、奖励与解锁条件 |
|
|
||||||
| 03_systems/S12_events_festivals/ | 季节事件、节日、条件触发 |
|
|
||||||
| 支撑层不单开系统文档 | 存档与 UI 随实现层组织,规则不独立成文 |
|
|
||||||
|
|
||||||
## MVP 最小闭环
|
|
||||||
1. 玩家在一个游戏日内完成开垦、播种、浇灌,并看到成长状态反馈。
|
|
||||||
2. 在时间与体力约束下选择当日主目标(农场劳动或外出)。
|
|
||||||
3. 外出采集(或矿井轻度战斗)带回资源。
|
|
||||||
4. 通过出售或加工获得金钱,投资种子或工具。
|
|
||||||
5. 日终结算展示当日变化并保存。
|
|
||||||
6. 次日作物状态变化,玩家据此形成新计划。
|
|
||||||
7. 数个游戏日内出现第一次技能提升与配方解锁。
|
|
||||||
|
|
||||||
如果这条闭环不成立,不应继续增加钓鱼深度、节日、社区目标或更多区域。
|
|
||||||
|
|
||||||
## 统一数值基准
|
|
||||||
本案例采用"宽松治愈型"数值风格。全局单位:时间片、游戏日、货币、体力、经验;所有数值字段必须注明单位。
|
|
||||||
- 时间节奏基准:单次常规行动控制在短时间片内;玩家一天应能完成农务、一个主要外出目标和少量顺路活动;早期玩家不应因一次路线失误失去整天进度。
|
|
||||||
- 货币量级基准:主要货币只有一种;初期基础种子可用少量日常产出购买;一次普通收获不应立刻买下最高阶升级;任务奖励以补足短期资金为主,不替代生产交易。
|
|
||||||
- 成长回报基准:前几级在正常尝试一种活动的数个游戏日内出现;升级奖励优先采用节省时间体力、扩大选择和解锁配方,而非单纯提高伤害售价;专长分支宽松可恢复。
|
|
||||||
- 体力与风险基准:体力是规划提示不是严苛倒计时;普通农务与移动成本低,战斗、钓鱼和重型工具才产生明显取舍;失败成本采用时间、少量金钱或位置变化,不损毁进度。
|
|
||||||
|
|
||||||
(具体换算数值与前五日验算由技术文档层·数值策划承接。)
|
|
||||||
|
|
||||||
## 系统边界
|
|
||||||
- 农场经营只管理农场内的生产状态,不负责所有资源的通用背包逻辑。
|
|
||||||
- 探索与地图只管理"在哪里"和"能否进入",不管理每种活动的具体奖励。
|
|
||||||
- 战斗只管理战斗内状态和战利品请求,不直接修改商店价格或 NPC 好感。
|
|
||||||
- NPC 与关系负责互动和关系变化;任务与社区负责可验证目标,二者通过事件和条件连接。
|
|
||||||
- UI、文本和表现不反向承载核心规则;所有关键变化必须由规则系统确认。
|
|
||||||
- 本案例不拆出独立多人、拍卖、复杂天气模拟、动态市场或高复杂度叙事工具系统。
|
|
||||||
|
|
||||||
## 优先级与范围
|
|
||||||
- P0(最小可玩闭环):时间与日程、体力、农场、物品背包、经济、基础地图、基础成长和日终结算。
|
|
||||||
- P1(形成完整案例):采集、钓鱼、轻度战斗、NPC 关系、任务、社区目标、制作、商店、季节和节日。
|
|
||||||
- P2(扩展内容):更多区域、敌人、作物、配方、关系事件、节日小游戏和终局后的自由活动。
|
|
||||||
|
|
||||||
拆分系统不等于所有系统都要在最小版本同时实现;系统独立性是为了便于协作和后续裁剪。
|
|
||||||
|
|
||||||
## 风险与校验
|
|
||||||
|
|
||||||
| 风险 | 校验方式 |
|
|
||||||
|---|---|
|
|
||||||
| 农场变成例行公事,失去规划感 | 玩家是否在目标选择阶段出现真实取舍与计划调整 |
|
|
||||||
| 矿井战斗反客为主 | 战斗收益是否仍以"农场难以产出的材料"为主,而非直接金钱 |
|
|
||||||
| 时间压力变成打卡义务 | 休闲型玩家能否自由调低日程重量而不被惩罚 |
|
|
||||||
| 经济成长过快,后期失去决策 | 升级价格是否持续制造"效率 vs 规模"的选择 |
|
|
||||||
| UI 泄题,探索失去意义 | 关键信息是否保留为探索发现而非全量直读 |
|
|
||||||
| 系统间主数据重复维护 | 交叉检查:同一事实是否只有一个系统拥有写权 |
|
|
||||||
|
|
||||||
## 开放的结构问题
|
|
||||||
- 体力与生命是否保持为两个状态,还是在轻度战斗中共享一套风险资源?
|
|
||||||
- NPC 日程、任务条件和节日事件之间采用统一条件格式还是各自维护?
|
|
||||||
- 农场设施生产是否由农场系统统一管理,还是交给通用制作队列?
|
|
||||||
- 采集、钓鱼和战斗是否共享统一的"活动结果"接口?
|
|
||||||
- 哪些系统需要独立数据表,哪些小型配置应合并为一张内容表?
|
|
||||||
-63
@@ -1,63 +0,0 @@
|
|||||||
# 概念设计:《星露谷物语》
|
|
||||||
|
|
||||||
## 一句话概念
|
|
||||||
《星露谷物语》是一款以经营农场为基础、融合探索、采集、制作、轻度战斗、角色成长与社区叙事的乡村生活模拟 RPG;玩家通过安排每日时间与体力,把荒废农场逐步建设成理想家园,并与周围居民建立关系。
|
|
||||||
|
|
||||||
## 定调与设计锚点
|
|
||||||
|
|
||||||
### 定调记录
|
|
||||||
- 参照选择:以牧场物语系为主(无压力日常方面学动物森友会);不参考任何高难动作与生存类游戏。
|
|
||||||
- 调性滑杆:压力感 低 / 战斗比重 低 / 管理深度 中 / 叙事比重 中低 / 节奏 慢。
|
|
||||||
- 调性锚:
|
|
||||||
T1 轻松治愈、自己的节奏(目标体验);T2 不劝退、无唯一最优解(体验门槛);T3 战斗轻度、非高难动作(非目标);T4 以"游戏日"为单位、可反复的单人体验(情境);T5 时间体力有限但休闲不打卡(跑偏风险);T6 小团队可维护的规模(关键约束);T7 日常叙事而非宏大主线,隐藏信息不迫使玩家查攻略(非目标/跑偏风险)。
|
|
||||||
|
|
||||||
### 设计锚点
|
|
||||||
- 核心幻想:离开令人疲惫的城市生活,继承一片荒废土地,在自己的节奏中经营、探索、成长,并成为社区的一员。
|
|
||||||
玩家念头:"再玩一天就好——今天做完想做的事,明天的一切都会更顺手。"
|
|
||||||
- 目标体验:治愈、自由规划、持续成长、发现秘密,以及"今天的选择会让未来更轻松"的掌控感。
|
|
||||||
- 玩家动机:改善农场与生活条件;发现新区域和资源;完成社区目标;提升技能;与 NPC 建立关系;按照自己的偏好塑造生活方式。
|
|
||||||
- 核心循环:安排一天的时间与体力 → 进行农业、采集、钓鱼、采矿、战斗或社交 → 获得资源、金钱、经验与关系进展 → 投资工具、设施、种子和物品 → 解锁更高效或更丰富的活动。
|
|
||||||
- 跑偏风险:系统过多导致目标分散;时间与体力限制把休闲体验变成每日打卡;隐藏信息迫使玩家依赖外部攻略;经济成长过快使后期失去决策。
|
|
||||||
- 非目标:不做多人竞争、高难度动作战斗、唯一最优效率经营、主线剧情取代日常(详见《不是什么》)。
|
|
||||||
|
|
||||||
## 玩家身份与基调
|
|
||||||
- 玩家身份:一名辞职逃离城市、继承祖父荒废农场的归乡人——不是拯救世界的英雄,是重新学会生活的人。季节与节日构成一年的节拍,日落结算构成每天的呼吸。
|
|
||||||
- 情绪基调:温暖治愈,慢而踏实。可以有忙碌与轻度压力(时间、体力),不做生存焦虑(饥饿、债务倒计时)与黑暗题材;孤独感只作为被社区逐渐治愈的起点,不成为基调本身。
|
|
||||||
|
|
||||||
## 风格与世界观
|
|
||||||
复古像素风的温暖乡村世界。玩家来到一个正在现代化与传统生活之间摇摆的小镇,农场、商店、社区设施、自然区域和矿井共同构成可步行抵达的生活网络。世界观服务于生活模拟而非复杂设定解释:季节、天气、节日、居民日程和区域变化,让同一张地图随着时间产生生活感。叙事主要通过 NPC 日常对话、关系事件、任务和社区目标逐步展开。
|
|
||||||
|
|
||||||
## 目标玩家与情境
|
|
||||||
- 目标玩家:与牧场物语系受众高度重合——喜欢种田与小人际的慢节奏成长玩家;同时吸收动物森友会式"无压力日常整理"的需求(自定义、装饰、按自己的节奏玩)。但它不能变成纯装饰沙盒,因为农场经营的时间、体力与季节取舍,以及社区修复目标必须始终存在。
|
|
||||||
- 适合情境:单人、可反复游玩、每次一个游戏日或几个游戏日;可以高效规划,也可以把时间用于装饰、社交或探索。
|
|
||||||
- 体验门槛:需要理解基础资源转换和时间安排,不应要求预先掌握复杂数值或寻找唯一正确答案。
|
|
||||||
|
|
||||||
## 不是什么
|
|
||||||
| 不是 | 因为 |
|
|
||||||
|---|---|
|
|
||||||
| 硬核生存农场模拟 | 没有饥饿、债务、死亡惩罚;压力止于温和的时间与体力 |
|
|
||||||
| 效率至上的工厂经营 | 不要求唯一最优解,装饰与闲逛是合法玩法而非浪费 |
|
|
||||||
| 以战斗为核心的动作游戏 | 战斗只是采矿与探索的伴生风险,深度刻意受限 |
|
|
||||||
| 剧情驱动的叙事游戏 | 社区叙事是日常的背景与情感回报,不是任务链主线 |
|
|
||||||
| 多人社交平台 | 单人体验为前提,人际关系由 NPC 关系承载 |
|
|
||||||
| 无边界开放世界 | 地图是功能明确的小区域网络,全部可步行抵达 |
|
|
||||||
|
|
||||||
## 核心张力
|
|
||||||
- 时间与体力有限,但想做的事情很多:玩家必须决定今天的优先级。
|
|
||||||
- 立即变现与长期投资:出售资源能快速获得资金,制作设备和升级工具则能提高未来效率。
|
|
||||||
- 稳定经营与未知探索:农场提供可预测收益,矿井、钓鱼和新区域提供风险与发现。
|
|
||||||
- 个人效率与社区关系:把时间用于赚钱会挤压社交,但关系又会带来配方、剧情和新的情感目标。
|
|
||||||
- 自由生活与阶段目标:玩家可以自由安排日常,同时受到季节、节日、任务和社区修复目标的轻度牵引。
|
|
||||||
|
|
||||||
## 边界与约束
|
|
||||||
- 概念层只定义核心幻想、目标用户、体验基调与排除方向;具体战斗公式、作物成长天数、礼物偏好、掉落率、系统清单和 MVP 内容,留给顶层及以后决定。
|
|
||||||
- 设计规模以单人或小团队可理解、可维护为前提;地图采用多个功能明确的区域,而非无边界开放世界。
|
|
||||||
- 所有系统都必须回流到"安排一天并获得长期改善"的核心循环;独立小游戏或装饰功能不能成为主要范围扩张来源。
|
|
||||||
- 案例声明:本文以《星露谷物语》为案例展示设计的组织方式,不复制其具体角色、文本、美术、地图或数值。
|
|
||||||
|
|
||||||
## 概念定稿
|
|
||||||
《星露谷物语》的核心不是"种田赚钱",而是:
|
|
||||||
> 在自己的节奏里经营一片土地与一段生活——今天的选择让明天更从容,而社区让独居变成归属。
|
|
||||||
|
|
||||||
交给下一层的约束:时间与体力必须构成温和而非焦虑的取舍;战斗、采矿、社交等支线必须回流农场生活循环;成长权重要允许玩家自定义(效率型与休闲型玩家都成立)。
|
|
||||||
(调性已在第 2 节定死;顶层及以下一切开放问题先回定调记录的 T1~T7 级联。)
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user