1
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
# 世界底稿开局场景批生成解耦说明 2026-04-26
|
||||
|
||||
## 背景
|
||||
|
||||
当前第一版世界底稿生成链路里,`framework` 阶段同时要求模型输出 `camp.sceneTaskDescription`、`camp.actBackgroundPromptTexts` 和 `camp.actEventDescriptions`。这让“世界核心骨架”和“开局场景多幕内容”混在同一次世界生成任务里,后续普通场景批生成又要单独生成相同粒度的场景任务、三幕事件、三幕背景和幕 NPC 分配。
|
||||
|
||||
这与《AI 原生多幕场景创作与玩法流程 PRD》中“开局场景不是特殊系统,只是玩家开局所处的第一个场景”的约束不一致。开局场景应复用普通场景的批生成能力,而不是由世界骨架阶段提前生成一套缩水版内容。
|
||||
|
||||
## 落地边界
|
||||
|
||||
1. `framework` 阶段只负责世界顶层信息和轻量 `camp` 占位:
|
||||
- `name`
|
||||
- `description`
|
||||
2. 场景批生成阶段负责生成完整场景骨架:
|
||||
- 场景名与描述
|
||||
- 默认场景生图描述
|
||||
- `sceneTaskDescription`
|
||||
- `actBackgroundPromptTexts`
|
||||
- `actEventDescriptions`
|
||||
- `actNPCNames`
|
||||
- `connectedLandmarkNames`
|
||||
- `entryHook`
|
||||
3. 批生成场景结果的第一项固定视为开局场景:
|
||||
- 写回 `profile.camp`
|
||||
- `camp.id` 缺失时固定为 `camp-1`
|
||||
- `camp.kind` 固定为 `camp`
|
||||
4. 批生成场景结果的其余项写入 `profile.landmarks`。
|
||||
5. `sceneChapterBlueprints` 仍由统一场景蓝图编译函数生成:
|
||||
- 第 0 项来自 `camp`
|
||||
- 后续项来自 `landmarks`
|
||||
- 开局场景和普通场景共用三幕、NPC、任务、背景提示词规则
|
||||
|
||||
## 兼容策略
|
||||
|
||||
为了减少前端和存量链路改动,场景批生成 API 层仍沿用现有 `landmarks` JSON 字段名。字段名不再表示“只包含普通地标”,而表示“本批生成的场景条目”,其中第一项是 opening/camp 场景。
|
||||
|
||||
如果模型没有返回任何场景条目,则继续使用 `framework.camp` 的轻量占位构造兜底开局场景;这只是异常兜底,不是主生成路径。
|
||||
|
||||
## 验收点
|
||||
|
||||
1. 世界骨架 prompt 不再要求 `camp.sceneTaskDescription`、`camp.actBackgroundPromptTexts`、`camp.actEventDescriptions`。
|
||||
2. 场景批生成 prompt 明确要求第一项是开局场景。
|
||||
3. 生成后的 `profile.camp` 来自场景批生成第一项,而不是来自世界骨架阶段的开局多幕内容。
|
||||
4. `profile.landmarks[0]` 是第一个普通场景,不再重复包含开局场景。
|
||||
5. `sceneChapterBlueprints[0].sceneId === "camp-1"`,且仍包含 3 幕背景与事件描述。
|
||||
@@ -0,0 +1,38 @@
|
||||
# RPG 战斗确定性结束流程
|
||||
|
||||
更新时间:`2026-04-26`
|
||||
|
||||
## 背景
|
||||
|
||||
旧战斗单行为 PRD 允许在逃跑成功或战斗结束后再触发一次剧情推理。新的运行时规则改为:战斗过程与战斗结果都不再请求剧情推理,所有胜负出口都由确定性状态与固定选项驱动。
|
||||
|
||||
## 落地规则
|
||||
|
||||
1. 战斗中的 `battle_attack_basic / battle_use_skill / battle_recover_breath / inventory_use / battle_escape_breakout` 只结算数值、血量、冷却、物品与战斗状态,不再请求 `generateNextStep` 或 Rust `generate_action_story_payload` 的战斗推理。
|
||||
2. 玩家血量小于等于 0 时,先展示死亡动画;三秒后复活到当前世界的第一个场景第一幕。
|
||||
3. 复活状态必须清理战斗、遭遇、NPC 交互、战斗特效、当前 NPC 战斗结果,并把生命与灵力恢复到最大值。
|
||||
4. 战斗胜利或切磋结束时,弹出固定选项:
|
||||
- 若当前场景仍有下一幕:只显示“继续前进”,并把下一幕运行时状态与可用选项挂到 `deferredRuntimeState / deferredOptions`,点击后只揭开下一幕选项,不触发剧情推理。
|
||||
- 若当前场景已是最后一幕:显示可前往的其他场景选项,每个选项透传 `runtimePayload.targetSceneId`。
|
||||
5. “继续前进”和“前往其他场景”都是本地状态推进,不展示额外说明面板,不把规则描述写入 UI。
|
||||
|
||||
## 工程落点
|
||||
|
||||
1. `src/hooks/rpg-runtime-story/postBattleFlow.ts`
|
||||
- 生成死亡复活状态。
|
||||
- 生成战斗胜利后的固定 `StoryMoment`。
|
||||
- 解析下一幕或其他场景选项。
|
||||
2. `src/hooks/rpg-runtime-story/storyChoiceContinuation.ts`
|
||||
- 本地 fallback 胜利分支不再调用 `generateStoryForState(...)`。
|
||||
- 玩家死亡分支播放死亡态并延迟复活。
|
||||
3. `src/hooks/rpg-runtime-story/storyChoiceRuntime.ts`
|
||||
- 服务端 runtime action 回包若是战斗死亡或胜利,同样覆盖为固定流程。
|
||||
4. `server-rs/crates/api-server/src/runtime_story/compat/ai.rs`
|
||||
- 战斗 outcome 不再触发 reasoned story payload。
|
||||
|
||||
## 验收
|
||||
|
||||
1. 战斗中普通攻击、技能、恢复、物品、逃跑不会触发剧情推理。
|
||||
2. 玩家被打到 0 血时先播放死亡动画,约三秒后复活到第一个场景第一幕。
|
||||
3. 战斗胜利后只出现“继续前进”;最后一幕后出现其他场景入口。
|
||||
4. 服务端 runtime action 与本地 fallback 两条链表现一致。
|
||||
@@ -18,6 +18,8 @@
|
||||
3. `battle_use_skill` 的本地兜底结算必须尊重 `runtimePayload.skillId`,不能重新随机挑技能。
|
||||
4. `battle_recover_breath` 的本地兜底不能伪装成攻击动作;它只做恢复、冷却推进和后续敌方压力。
|
||||
5. 服务端战斗回包如果带 `presentation.battle`,前端先播放一次短动作和血量变化,再落 `hydratedSnapshot.gameState`,避免选项点击后血量直接跳变。
|
||||
6. 战斗中任一角色血量发生变化时,表现层根据前后血量差派生一次浮字:伤害使用红色负数,治疗使用绿色正数;该浮字只表达已经结算的血量差,不参与数值计算。
|
||||
7. 伤害浮字出现时,受击角色形象需要沿自身背向短距离后退再恢复;该后撤只作用在角色形象视觉容器,不改变 `playerX`、`sceneHostileNpcs.xMeters`、同伴站位或任何战斗结算字段。
|
||||
|
||||
## 验收点
|
||||
|
||||
@@ -25,3 +27,5 @@
|
||||
- 点击具体技能按钮时,播放与结算使用同一个 `skillId`。
|
||||
- 点击恢复时不会出现玩家同时释放攻击技能的错位表现。
|
||||
- 走服务端 runtime action 的战斗选项仍以 server-rs 返回快照为最终状态。
|
||||
- 受到伤害时,角色形象上方出现类似 `-9` 的红色浮字,并有短暂后撤回弹。
|
||||
- 获得治疗时,角色形象上方出现类似 `+1` 的绿色浮字,不触发受击后撤。
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# RPG 创作结果页新增实体同步修复 2026-04-26
|
||||
|
||||
## 问题
|
||||
|
||||
Agent 草稿结果页点击“新增可扮演角色”后,后端生成请求已完成,但前端提示:
|
||||
|
||||
`生成请求已完成,但结果页未收到新增内容,请返回创作页重新打开草稿后重试。`
|
||||
|
||||
触发点在结果页实体生成完成后的数量校验:前端会执行 `generate_characters`,等待操作完成后重新拉取 Agent session,再把 session 编译成结果页 `CustomWorldProfile`。如果新 profile 中对应实体数量没有增加,就显示该错误。
|
||||
|
||||
## 根因
|
||||
|
||||
当前链路已经约定 `session.draftProfile` 是 Agent 草稿与 RPG 运行时的真相源,但 `rpgCreationPreviewAdapter.buildPreviewFromSession()` 仍优先读取 `session.resultPreview.preview`。
|
||||
|
||||
当后端 action 已把新增角色写入 `draftProfile`,但 `resultPreview` 仍是旧快照时,结果页会继续消费旧预览,导致数量校验误判为“没有新增内容”。
|
||||
|
||||
## 修复
|
||||
|
||||
- `buildCustomWorldProfileFromAgentSession()` 改为优先归一化 `session.draftProfile`。
|
||||
- `resultPreview.preview` 只作为 `draftProfile` 缺失时的兼容 fallback。
|
||||
- 更新单测,覆盖“session 同时存在 draftProfile 与 resultPreview 时,结果页 profile 必须来自 draftProfile”。
|
||||
|
||||
## 后续约束
|
||||
|
||||
- Agent 草稿结果页新增、删除、进入世界都应以 `draftProfile` 为数据源。
|
||||
- `resultPreview` 继续承载发布质量、blocker、预览外壳信息,不再作为结果页实体列表的优先数据源。
|
||||
- 若新增实体字段在结果页缺失,应扩展 `draftProfile` 的归一化兼容,而不是把实体读取切回 `resultPreview.preview`。
|
||||
102
docs/technical/RPG_CREATION_HISTORY_ASSET_REUSE_2026-04-26.md
Normal file
102
docs/technical/RPG_CREATION_HISTORY_ASSET_REUSE_2026-04-26.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# RPG 创作编辑器历史素材复用设计
|
||||
|
||||
日期:`2026-04-26`
|
||||
|
||||
## 1. 本次目标
|
||||
|
||||
编辑场景角色与编辑场景图片时,玩家可以复用历史生成素材:
|
||||
|
||||
1. 场景角色形象区删除 `基于预设素材修改` 入口,以及它打开的预设拼装编辑下游。
|
||||
2. 场景角色形象区新增 `使用历史素材`,打开独立素材面板。
|
||||
3. 场景图片的幕背景配置新增 `使用历史素材`,打开独立素材面板。
|
||||
4. 历史素材面板需要展示所有账号过去生成过的对应类型素材,并明确标注素材归属账号。
|
||||
5. 选择素材后直接应用到当前角色或当前幕背景,不触发新一轮生成。
|
||||
|
||||
## 2. 数据真相
|
||||
|
||||
历史素材不从前端草稿 profile 扫描,也不从预设素材目录扫描。
|
||||
|
||||
历史素材统一来自 SpacetimeDB 的 `asset_object` 表:
|
||||
|
||||
| 使用位置 | `asset_kind` | 应用字段 |
|
||||
| --- | --- | --- |
|
||||
| 场景角色形象 | `character_visual` | `imageSrc`、`generatedVisualAssetId` |
|
||||
| 场景幕背景 | `scene_image` | `backgroundImageSrc`、`backgroundAssetId` |
|
||||
|
||||
`asset_object.owner_user_id` 是归属账号标注主源。为空时 UI 标注为 `未记录账号`,不能隐藏归属栏。
|
||||
|
||||
## 3. 后端接口
|
||||
|
||||
新增只读接口:
|
||||
|
||||
```text
|
||||
GET /api/assets/history?kind=character_visual
|
||||
GET /api/assets/history?kind=scene_image
|
||||
```
|
||||
|
||||
返回字段只包含前端选择所需脱敏信息:
|
||||
|
||||
1. `assetObjectId`
|
||||
2. `assetKind`
|
||||
3. `imageSrc`
|
||||
4. `ownerUserId`
|
||||
5. `ownerLabel`
|
||||
6. `profileId`
|
||||
7. `entityId`
|
||||
8. `createdAt`
|
||||
9. `updatedAt`
|
||||
|
||||
`asset_object` 仍保持 private table。读取历史列表必须通过 SpacetimeDB procedure + Axum facade,不能让前端直接订阅整表。
|
||||
|
||||
## 4. SpacetimeDB 设计
|
||||
|
||||
`module-assets` 新增:
|
||||
|
||||
1. `AssetHistoryListInput`
|
||||
2. `AssetHistoryEntrySnapshot`
|
||||
3. `AssetHistoryListResult`
|
||||
|
||||
`spacetime-module` 新增 procedure:
|
||||
|
||||
```rust
|
||||
list_asset_history_and_return(input: AssetHistoryListInput) -> AssetHistoryListResult
|
||||
```
|
||||
|
||||
实现规则:
|
||||
|
||||
1. 只允许 `character_visual`、`scene_image`。
|
||||
2. 按 `asset_kind` 过滤。
|
||||
3. 按 `created_at` 倒序返回。
|
||||
4. 默认最多返回 120 条,允许调用方传更小 limit。
|
||||
5. `image_src` 由 `object_key` 转为兼容代理路径:`/{object_key}`。
|
||||
|
||||
## 5. 前端交互
|
||||
|
||||
历史素材面板为独立弹层,不在当前面板下方展开。
|
||||
|
||||
角色历史素材卡片:
|
||||
|
||||
1. 展示素材图。
|
||||
2. 展示归属账号。
|
||||
3. 展示创建时间。
|
||||
4. 点击 `使用` 后写入当前草稿角色:
|
||||
- `imageSrc = imageSrc`
|
||||
- `generatedVisualAssetId = assetObjectId`
|
||||
- `generatedAnimationSetId = undefined`
|
||||
- `animationMap = undefined`
|
||||
|
||||
场景历史素材卡片:
|
||||
|
||||
1. 展示 16:9 预览。
|
||||
2. 展示归属账号。
|
||||
3. 展示创建时间。
|
||||
4. 点击 `使用` 后写入当前幕:
|
||||
- `backgroundImageSrc = imageSrc`
|
||||
- `backgroundAssetId = assetObjectId`
|
||||
|
||||
## 6. 非目标
|
||||
|
||||
1. 不新增图片生成模型能力。
|
||||
2. 不把历史素材复制成新 OSS 对象。
|
||||
3. 不修改旧预设素材目录。
|
||||
4. 不恢复 server-node 或 PostgreSQL 链路。
|
||||
@@ -0,0 +1,24 @@
|
||||
# RPG 创作场景幕资产一致性修复 2026-04-26
|
||||
|
||||
## 背景
|
||||
|
||||
当前世界草稿和场景编辑器存在三类一致性问题:
|
||||
|
||||
1. 世界草稿生成后,开局场景的三幕可能没有默认主角色。
|
||||
2. 开局场景列表层、幕卡片层、幕背景配置弹层可能显示不同图片。
|
||||
3. 幕背景智能生成弹层的默认提示词可能退回规则拼接文本,且预览图和外层当前幕不一致。
|
||||
|
||||
## 落地约束
|
||||
|
||||
1. 后端草稿生成必须为 `sceneChapterBlueprints[*].acts[*]` 写入稳定的幕级字段:`encounterNpcIds`、`primaryNpcId`、`oppositeNpcId`、`eventDescription`、`backgroundPromptText`。
|
||||
2. 开局场景 `camp` 在生成角色名单之前建立,但最终编译草稿时必须基于已生成的场景角色,为三幕自动补默认主角色,不允许把“开局关键角色”这类占位词留到可编辑草稿里。
|
||||
3. `backgroundPromptText` 必须优先来自模型生成的自然画面描述;缺失时才使用规则兜底,兜底也要基于真实主角色名。
|
||||
4. 前端场景编辑器展示某一幕时,列表卡、幕卡、配置弹层、智能生成弹层都应读取同一个幕级 `backgroundImageSrc`;只有旧草稿缺幕图时才展示场景主图作为视觉兜底,保存时不得把兜底图反写到所有幕。
|
||||
5. 智能生成幕背景时,默认提示词必须使用当前幕 `backgroundPromptText`,不再用标题、摘要、目标拼接替代。
|
||||
|
||||
## 验收点
|
||||
|
||||
1. 新生成的开局三幕每幕都有非空 `primaryNpcId`,并且第一位 `encounterNpcIds[0]` 与 `primaryNpcId` 一致。
|
||||
2. 普通场景与开局场景都能在幕背景生图 prompt 中写入真实主角色名。
|
||||
3. 开局场景第 2 幕在列表层、编辑卡片层、配置弹层、智能生成弹层中的预览图保持一致。
|
||||
4. 点击“跟随场景主图”只影响当前幕,不会把同一张图同步覆盖到三幕。
|
||||
@@ -0,0 +1,58 @@
|
||||
# RPG 创作世界角色维度信息编辑落地说明
|
||||
|
||||
更新时间:`2026-04-26`
|
||||
|
||||
## 1. 背景
|
||||
|
||||
统一角色属性系统把一个世界中“角色能力如何被理解”收口到 `CustomWorldProfile.attributeSchema.slots`。这六个 slot 是世界级设定,不是单个角色自己的六个字段。
|
||||
|
||||
当前结果页世界页可以展示角色维度,但编辑世界信息时只能修改世界名称、概述、基调、目标等文本,尚不能手动修订六个维度本身的信息。
|
||||
|
||||
## 2. 本次目标
|
||||
|
||||
在“编辑世界信息”独立面板中允许用户编辑六个角色维度的信息:
|
||||
|
||||
1. 修改 `attributeSchema.slots` 中每个维度的 `name`、`definition`、`positiveSignals`、`negativeSignals`、`combatUseText`、`socialUseText`、`explorationUseText`。
|
||||
2. 不在可扮演角色或场景角色编辑器中新增单角色六维数值编辑。
|
||||
3. 保存时同步更新 `profile.attributeSchema`。
|
||||
4. 若 `profile.ownedSettingLayers.ruleProfile.attributeSchema` 存在,同步写入同一份 schema,避免世界档案和设定层出现双源漂移。
|
||||
5. 前端只负责编辑结构化文本,不新增属性结算逻辑。
|
||||
|
||||
## 3. 交互设计
|
||||
|
||||
入口位置:
|
||||
|
||||
- 世界页点击“世界概述”里的编辑按钮
|
||||
- 打开现有“编辑世界信息”面板
|
||||
- 在基础世界文本字段下方增加“角色维度”区块
|
||||
|
||||
每个维度展示并允许编辑:
|
||||
|
||||
- 维度名称
|
||||
- 定义
|
||||
- 正向信号
|
||||
- 负向信号
|
||||
- 战斗体现
|
||||
- 社交体现
|
||||
- 探索体现
|
||||
|
||||
正向信号与负向信号使用逗号、中文逗号或换行拆分成数组。
|
||||
|
||||
## 4. 数据落点
|
||||
|
||||
保存路径:
|
||||
|
||||
- `profile.attributeSchema.slots[n]`
|
||||
- `profile.ownedSettingLayers.ruleProfile.attributeSchema.slots[n]`,仅当 `ownedSettingLayers` 已存在时同步
|
||||
|
||||
不修改:
|
||||
|
||||
- `profile.playableNpcs[n].attributeProfile`
|
||||
- `profile.storyNpcs[n].attributeProfile`
|
||||
|
||||
## 5. 验收
|
||||
|
||||
1. 世界信息面板能看到六个角色维度。
|
||||
2. 修改任一维度名称、定义、信号或三类用途说明后,保存到 `profile.attributeSchema.slots`。
|
||||
3. 编辑角色自身时不出现单角色六维数值输入区。
|
||||
4. UI 仍读取当前世界 schema,不回退写死旧四维文案。
|
||||
@@ -0,0 +1,19 @@
|
||||
# 世界档案 PC 布局扩展(2026-04-26)
|
||||
|
||||
## 背景
|
||||
|
||||
世界档案结果页和各实体编辑子面板在 PC 端仍沿用偏窄的弹窗与两列列表布局,宽屏下画布利用率不足。移动端现有单列滚动、底部弹层和触控布局已经稳定,本次不改变移动端结构。
|
||||
|
||||
## 落地规则
|
||||
|
||||
1. 世界档案主页面只在 `xl` 及以上断点扩展画布宽度与内部间距,移动端和 `sm/md/lg` 断点保持原有布局。
|
||||
2. 场景、可扮演角色、场景角色列表在 PC 端提高列数上限,让宽屏能显示更多卡片。
|
||||
3. 世界 Tab 在 PC 端由窄两列调整为更充分的三列信息布局,减少首屏纵向堆叠。
|
||||
4. 世界信息、基本设定、角色与场景编辑子面板在 PC 端使用更宽的 `max-width` 与更高可用高度;移动端仍保持 `h-[92vh]` 的底部弹层。
|
||||
5. 不新增说明类 UI 文案,不改写现有中文内容,不改变保存、删除、生成、发布等行为。
|
||||
|
||||
## 验收点
|
||||
|
||||
1. PC 端世界档案结果页内容区域能接近占满工作区宽度,列表在 2K 宽屏下可呈现更多列。
|
||||
2. PC 端打开世界、基本设定、角色、场景子面板时,弹窗宽度明显大于旧版 `sm:max-w-2xl` 默认宽度。
|
||||
3. 移动端仍为单列滚动列表,编辑子面板仍从底部弹出且宽度为全屏。
|
||||
@@ -29,6 +29,7 @@
|
||||
- 单轮变化限制在 `[-3, 3]`。
|
||||
5. `chatDirective.forceExitAfterTurn / closingMode=foreshadow_close` 时不生成建议,返回空数组,并在 `complete.chatDirective.forceExit` 中显式告知前端退出。
|
||||
6. LLM 未配置或失败时继续返回后端兜底 SSE,保证相遇和点击聊天链路不断。
|
||||
7. 在 Node 已完成平台账号鉴权并通过内部密钥转发到 Rust API 的链路中,`/api/runtime/chat/` 必须纳入 Rust 内部转发鉴权白名单;否则 NPC 主动开场会在进入 `runtime_chat` handler 前被 401 拒绝,前端只能收到“NPC 聊天续写失败”。
|
||||
|
||||
## 暂不落地
|
||||
|
||||
@@ -46,11 +47,14 @@
|
||||
- 优先 `LlmClient.stream_text(...)` 生成 `reply_delta`。
|
||||
- 再调用 `request_text(...)` 生成建议。
|
||||
- 计算 `affinityDelta / affinityText / chatDirective` 后输出 `complete`。
|
||||
3. 修改 `server-rs/crates/api-server/src/main.rs`
|
||||
3. 修改 `server-rs/crates/api-server/src/auth.rs`
|
||||
- `allows_internal_forwarded_auth(...)` 允许 `/api/runtime/chat/`,与 big-fish、puzzle 的内部转发鉴权策略保持一致。
|
||||
- 单测覆盖 `/api/runtime/chat/npc/turn/stream`,防止后续新增 runtime 路由时再次遗漏内部转发白名单。
|
||||
4. 修改 `server-rs/crates/api-server/src/main.rs`
|
||||
- 注册 `runtime_chat_prompt` 模块。
|
||||
|
||||
## 验收
|
||||
|
||||
1. `cargo fmt -p api-server`
|
||||
2. `cargo check -p api-server`
|
||||
3. `node scripts/check-encoding.mjs docs/technical/RUNTIME_NPC_CHAT_LLM_MIGRATION_2026-04-25.md server-rs/crates/api-server/src/runtime_chat.rs server-rs/crates/api-server/src/runtime_chat_prompt.rs server-rs/crates/api-server/src/main.rs`
|
||||
3. `node scripts/check-encoding.mjs docs/technical/RUNTIME_NPC_CHAT_LLM_MIGRATION_2026-04-25.md server-rs/crates/api-server/src/auth.rs server-rs/crates/api-server/src/runtime_chat.rs server-rs/crates/api-server/src/runtime_chat_prompt.rs server-rs/crates/api-server/src/main.rs`
|
||||
|
||||
@@ -8,19 +8,19 @@
|
||||
|
||||
Maincloud 发布不复用本地 `spacetime.local.json`,避免误把本地开发库名发布到云端。需要显式提供:
|
||||
|
||||
| 变量 | 用途 |
|
||||
| --- | --- |
|
||||
| `GENARRATIVE_SPACETIME_MAINCLOUD_DATABASE` | Maincloud 数据库名,发布脚本优先读取 |
|
||||
| 变量 | 用途 |
|
||||
| -------------------------------------------- | ------------------------------------------------------------ |
|
||||
| `GENARRATIVE_SPACETIME_MAINCLOUD_DATABASE` | Maincloud 数据库名,发布脚本优先读取 |
|
||||
| `GENARRATIVE_SPACETIME_MAINCLOUD_SERVER_URL` | Maincloud 服务地址,默认 `https://maincloud.spacetimedb.com` |
|
||||
| `GENARRATIVE_SPACETIME_MAINCLOUD_TOKEN` | `api-server` 连接 Maincloud 时使用的 token |
|
||||
| `GENARRATIVE_SPACETIME_MAINCLOUD_TOKEN` | `api-server` 连接 Maincloud 时使用的 token |
|
||||
|
||||
兼容 `api-server` 现有变量:
|
||||
|
||||
| 变量 | 用途 |
|
||||
| --- | --- |
|
||||
| `GENARRATIVE_SPACETIME_SERVER_URL` | `api-server` 实际连接地址 |
|
||||
| `GENARRATIVE_SPACETIME_DATABASE` | `api-server` 实际连接数据库 |
|
||||
| `GENARRATIVE_SPACETIME_TOKEN` | `api-server` 实际连接 token |
|
||||
| 变量 | 用途 |
|
||||
| ---------------------------------- | --------------------------- |
|
||||
| `GENARRATIVE_SPACETIME_SERVER_URL` | `api-server` 实际连接地址 |
|
||||
| `GENARRATIVE_SPACETIME_DATABASE` | `api-server` 实际连接数据库 |
|
||||
| `GENARRATIVE_SPACETIME_TOKEN` | `api-server` 实际连接 token |
|
||||
|
||||
## npm 命令
|
||||
|
||||
@@ -50,10 +50,12 @@ npm run api-server:maincloud
|
||||
|
||||
1. 从 `.env` 与 `.env.local` 读取默认环境。
|
||||
2. 将 `GENARRATIVE_SPACETIME_MAINCLOUD_*` 映射为 `api-server` 已支持的 `GENARRATIVE_SPACETIME_*`。
|
||||
3. 启动 `cargo run -p api-server --manifest-path server-rs/Cargo.toml`。
|
||||
3. 在 Windows 启动前检查 `server-rs/target/debug/api-server.exe` 对应的旧进程;如果旧进程仍在运行,先停止它,避免 Rust 编译阶段覆盖 exe 时出现 `failed to remove file ... 拒绝访问。 (os error 5)`。
|
||||
4. 启动 `cargo run -p api-server --manifest-path server-rs/Cargo.toml`。
|
||||
|
||||
## 设计约束
|
||||
|
||||
- Maincloud 数据库名必须显式配置,不能默认读取本地 `spacetime.local.json`。
|
||||
- 发布脚本只处理 SpacetimeDB 模块发布,不启动本地 SpacetimeDB。
|
||||
- `api-server` 继续通过 `SpacetimeClientConfig` 的 `server_url / database / token` 连接数据库,不在前端增加逻辑。
|
||||
- Windows 进程清理只能匹配本仓库 `server-rs/target/debug/api-server.exe` 的完整路径,不能按进程名泛化清理,避免影响其他 Rust 服务。
|
||||
|
||||
Reference in New Issue
Block a user