@66rpg/lumimaker 0.1.50 → 0.1.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,141 +1,143 @@
1
- # LumiMakerSdk 接口规范细则
2
-
3
- 全局对象为 **`window.LumiMakerSdk`**。发布到幻光文游社区后,在社区播放页的 iframe(或官方 App 打开的受信壳)里运行时,平台注入该对象。脚本版本见 `version`,作品不要写死这个数字。
4
-
5
- 失败时抛出的错误对象名为 **`LumiMakerError`**,带 `code` 字符串。
6
-
7
- 作品不要自己 `postMessage`,不要读 token,不要带 Cookie 调社区接口。
8
-
9
- ---
10
-
11
- ## 1. 生命周期与上下文
12
-
13
- | 方法 / 属性 | 返回类型 | 说明 |
14
- |---|---|---|
15
- | `version` | string | 脚本版本。作品不要依赖具体数字。 |
16
- | `ready()` | `Promise<{ ready: boolean; context: LumiMakerContext \| null; error?: string }>` | 与播放页握手。约 5 秒超时。**超时不 throw**,返回 `ready: false`。受信壳超时 `error` 为「等待主站数据超时」(本地预览正常)。未受信容器立刻失败,`error` 为「请在幻光社区或官方 App 中打开」,并跳到社区作品帖。 |
17
- | `isReady()` | boolean | 是否已拿到 context。 |
18
- | `getError()` | string | 最近一次握手失败文案;无失败时为空字符串。不是所有通道错误都会写入。 |
19
- | `getContext()` | LumiMakerContext \| null | 公开上下文。无 token、无 api 地址。 |
20
- | `getGameId()` | string | 便捷读取;未握手为空字符串。 |
21
- | `getUser()` | LumiMakerUser \| null | 便捷读取当前用户。 |
22
- | `isLoggedIn()` | boolean | 等价于是否已有 `getUser()`。 |
23
- | `onChange(fn)` | `() => void` | context / 登录变化。`fn` 可能收到 `null`。必须用返回值取消监听。语言仅在宿主推语言消息时变;**现网播放页尚未推这条**。 |
24
- | `isMuted()` | boolean | 播放页静音开关,默认 `false`。不进 `getContext()`。脚本加载后已自动听宿主并静音本页媒体,**不必调用**。 |
25
- | `onMuteChange(fn)` | `() => void` | 宿主静音状态变化时回调。必须用返回值取消监听。 |
26
-
27
- ### 1.1 `getContext()` 字段
28
-
29
- | 字段 | 类型 | 说明 |
30
- |---|---|---|
31
- | `gameId` | string | 当前作品对外 id。 |
32
- | `lang` | string | 握手时播放页语言。 |
33
- | `user` | object \| null | `{ username, nickname, avatar }`;未登录为 `null`。`username` 来自社区用户 id。 |
34
- | `variant` | number | `1` 正式 · `2` 试玩(demo) · `3` 衍生。 |
35
- | `parentOrigin` | string | 仅供 SDK 校验消息来源,作品业务不要用。 |
36
-
37
- ---
38
-
39
- ## 2. 登录
40
-
41
- | 方法 | 返回类型 | 说明 |
42
- |---|---|---|
43
- | `requireLogin()` | `Promise<void>` | 已登录立刻成功。否则请播放页弹出社区登录。用户取消 → `LOGIN_CANCELLED`。未受信壳会先抛 `UNTRUSTED_SHELL`。 |
44
-
45
- 未登录时试玩 iframe 仍可玩离线内容。无 token 时 `queryGame()` / `queryUser()` 得到 `NOT_LOGGED_IN`。
46
-
47
- ---
48
-
49
- ## 3. 查询(须已登录)
50
-
51
- 游戏自己发 HTTP,`credentials: 'omit'`,只打平台 `/v1/game-sdk/*`。`game_id` 由 token 绑定,不要自己拼查询参数。
52
-
53
- | 方法 | 返回类型 | 说明 |
54
- |---|---|---|
55
- | `queryGame()` | `Promise<LumiMakerGameInfo>` | 当前作品货架与权限。SDK 原样返回服务端对象,不做字段校验。 |
56
- | `queryUser()` | `Promise<LumiMakerUser>` | `username`、`nickname`、`avatar`。 |
57
-
58
- ### `queryGame()` 字段
59
-
60
- | 字段 | 类型 | 说明 |
61
- |---|---|---|
62
- | `game_id` | string | 作品 id。不要把原始 id 念给玩家。 |
63
- | `owner` | string | 作者用户名。 |
64
- | `name` | string | 平台显示名。 |
65
- | `summary` | string | 简介。 |
66
- | `cover_url` | string | 封面地址。 |
67
- | `variant` | number | `1` 正式 · `2` 试玩 · `3` 衍生。 |
68
- | `parent_game_id` | string | 试玩 / 衍生关联的正式版 id;没有则为空字符串。 |
69
- | `price_flower` / `price_cny` / `price_usd` | number | 标价。作品内不要用它们复刻社区购买墙。 |
70
- | `latest_version_no` | number | 平台最新版本序号。不要把版本 ID 念给玩家。 |
71
- | `play_url` | string | 托管播放地址。**严禁用此 URL 跳转**;也不要念给玩家。 |
72
- | `post_id` | string | 关联主帖 id;demo 与正式版共用;无则为空字符串。不要念给玩家。 |
73
- | `status` | number | 货架 `1` 启用 / `2` 禁用。 |
74
- | `purchased` | boolean | 对该可售主体是否有已支付订单;作者未下单为 `false`。 |
75
- | `can_play` | boolean | 能拿到 token 时为 `true`。用来画自制章节锁。 |
76
- | `ai_model` / `engine` / `languages` / `orientations` / `play_duration` | 可选 | 可能缺省。 |
77
-
78
- 自制 UI 读 `can_play` / `purchased`。正式版未获权时播放页不会加载 iframe。
79
-
80
- ---
81
-
82
- ## 4. 安全跳转与全屏
83
-
84
- 只允许下列无参方法。不要操作 `window.top.location`,不要传入自定义 URL。公开 API **没有** `toggleFullscreen()`(协议里宿主可认全屏 `toggle`,游戏不要调)。
85
-
86
- | 方法 | 返回类型 | 说明 |
87
- |---|---|---|
88
- | `navigateHome()` | void | 播放页回社区首页。 |
89
- | `navigateAuthorPage()` | void | 打开作者页。 |
90
- | `navigateBack()` | void | 有历史则后退,否则回作品帖。 |
91
- | `openPlayHtml(html)` | `Promise<void>` | 换到 **包根** 另一个玩法 HTML,只传文件名(如 `staff.html`)。不要传目录、不要把查询串写进这个参数给签名接口。社区 iframe 会自动拦 `<a>` / `assign` / `replace`(Chromium 还能拦 `location.href =`),已发布入口一般不必调。查出非法文件名 → `FAILED`。官方 App 直开无宿主时会失败。 |
92
- | `openPlayWindow(html, options?)` | `Promise<void>` | 另开包根玩法页。`options.target` 省略时是新窗口;自定义名字会加上平台前缀,同一名字复用同一个窗口。不要传 `_self`、`_parent`、`_top`。`options.features` 只保留宽、高和位置(`width` / `height` / `left` / `top` / `screenX` / `screenY`)。返回值里没有窗口对象。非法文件名 → `FAILED`。 |
93
- | `requestFullscreen()` | `Promise<void>` | 全屏**播放器外壳**,不是游戏改 `top`。须在真实点击等手势里调用。 |
94
- | `exitFullscreen()` | `Promise<void>` | 退出播放器全屏。 |
95
-
96
- 浏览器拒绝全屏 → `FULLSCREEN_DENIED`。
97
-
98
- ### 4.1 包内 HTML 跳转(注入脚本自动拦)
99
-
100
- 社区播放页 iframe 里,脚本会在真正跳走前拦住包根 `.html`,请播放页另签后再换页。作者一般继续写相对链接即可,不必自己调 `openPlayHtml`。
101
-
102
- 查询(`?` 起)和锚点(`#` 起)**各自最长 2048 个字符**,超出的部分会被截掉。查询里**不能**使用 `auth_key`、`signature`、`expires`、`OSSAccessKeyId` 这些签名参数名(大小写不限);写进去会被当成平台已签名地址,业务查询可能补不回。
103
-
104
- | 写法 | 播放页里 |
105
- |---|---|
106
- | 包根 `staff.html`、`search.html?q=`、`snapshot.html#u=…` | 能打开。查询串和 `#` 在新页补回,不要指望它们出现在签名请求里。查询和 `#` **各自最长 2048 个字符**,超出截掉。查询里不要用 `auth_key`、`signature`、`expires`、`OSSAccessKeyId`(大小写不限),这些是平台签名参数名。再次打开同一页时,业务查询和 `#` 按这次链接整段替换 |
107
- | 左键 `target="_blank"`、自定义窗口名,或 Ctrl / ⌘ | 当前页不换。播放页另开可刷新的社区窗口。含 `<base target="_blank">`。页面已 `preventDefault` 则不打开 |
108
- | `target="_parent"` / `_top` | 不要写。不换当前页,也不跳出作品框 |
109
- | 当前页 `#id` | 只滚动,不换页 |
110
- | `./#id`、`/#id`、`.`、`/`、`jubenba/` | **不要写**。会当成打开目录,请求失败;脚本会拦住,但也不会改成该目录的 `index.html` |
111
- | 子目录 `jubenba/search.html` | 打不开。玩法 HTML 放在 `dist/` 根目录 |
112
- | 链接上已 `preventDefault` | 脚本不再换页,让页面自己的点击处理先完成 |
113
-
114
- 带平台签名参数的地址不要改路径。Firefox 里若仍用 `location.href =`,可能拦不住。右键「在新标签页中打开」和中键不经过脚本。社区 iframe 里对包根页调用 `window.open`:`_self` 换当前页,其它窗口名走上面的新窗口;`_parent` / `_top`、子目录和外链不会替你打开。官方 App 直开入口、没有社区播放页时,这套拦截不装。
115
-
116
- 本地 `npm run dev` 没有这套拦截,相对链接按普通静态站工作。
117
-
118
- ---
119
-
120
- ## 5. 错误码
121
-
122
- | `code` | 何时 | 处理 |
123
- |---|---|---|
124
- | `NOT_LOGGED_IN` | 无 token,或查询鉴权失败 | 需要登录时再 `requireLogin()`;试玩可继续离线。 |
125
- | `LOGIN_CANCELLED` | 用户关掉登录 | 非致命,留在当前界面。 |
126
- | `TIMEOUT` | 握手或桥接超时。**`ready()` 超时只返回 `ready: false`,不 throw 本码** | 本地预览按未连接处理。 |
127
- | `FULLSCREEN_DENIED` | 浏览器拒绝全屏 | 只在用户点击里请求全屏。 |
128
- | `UNTRUSTED_SHELL` | 不在社区播放页 iframe / 官方 App | 提示在幻光社区或官方 App 打开。 |
129
- | `FAILED` | 其它业务或通信失败 | 通用重试提示;不要把内部报文念给玩家。 |
130
-
131
- ---
132
-
133
- ## 6. 容器(作者需要知道的行为)
134
-
135
- | 环境 | 行为 |
136
- |---|---|
137
- | 社区播放页 iframe | 正常握手。 |
138
- | 官方 App(本窗有官方桥) | 不跳走。没有播放页 Host 时 `ready()` 仍超时,离线可玩。 |
139
- | 浏览器地址栏直开托管页,或第三方站点嵌套 | 跳到社区作品帖;拿不到帖则空白页。 |
140
-
141
- 不要把「直开托管地址」当成正规玩法入口。本地预览请继续 `npm run dev`,或嵌在社区播放页 / 官方 App。
1
+ # LumiMakerSdk 接口规范细则
2
+
3
+ 全局对象为 **`window.LumiMakerSdk`**。发布到幻光文游社区后,在社区播放页的 iframe(或官方 App 打开的受信壳)里运行时,平台注入该对象。脚本版本见 `version`,作品不要写死这个数字。
4
+
5
+ 失败时抛出的错误对象名为 **`LumiMakerError`**,带 `code` 字符串。
6
+
7
+ 作品不要自己 `postMessage`,不要读 token,不要带 Cookie 调社区接口。
8
+
9
+ ---
10
+
11
+ ## 1. 生命周期与上下文
12
+
13
+ | 方法 / 属性 | 返回类型 | 说明 |
14
+ |---|---|---|
15
+ | `version` | string | 脚本版本。作品不要依赖具体数字。 |
16
+ | `ready()` | `Promise<{ ready: boolean; context: LumiMakerContext \| null; error?: string }>` | 与播放页握手。约 5 秒超时。**超时不 throw**,返回 `ready: false`。受信壳超时 `error` 为「等待主站数据超时」(本地预览正常)。未受信容器立刻失败,`error` 为「请在幻光社区或官方 App 中打开」,并跳到社区作品帖。 |
17
+ | `isReady()` | boolean | 是否已拿到 context。 |
18
+ | `getError()` | string | 最近一次握手失败文案;无失败时为空字符串。不是所有通道错误都会写入。 |
19
+ | `getContext()` | LumiMakerContext \| null | 公开上下文。无 token、无 api 地址。 |
20
+ | `getGameId()` | string | 便捷读取;未握手为空字符串。 |
21
+ | `getUser()` | LumiMakerUser \| null | 便捷读取当前用户。 |
22
+ | `isLoggedIn()` | boolean | 等价于是否已有 `getUser()`。 |
23
+ | `onChange(fn)` | `() => void` | 登录变化。`fn` 可能收到 `null`。必须用返回值取消监听。 |
24
+
25
+ ### 1.1 `getContext()` 字段
26
+
27
+ | 字段 | 类型 | 说明 |
28
+ |---|---|---|
29
+ | `gameId` | string | 当前作品对外 id。 |
30
+ | `lang` | string | 握手时播放页语言。 |
31
+ | `user` | object \| null | `{ username, nickname, avatar }`;未登录为 `null`。`username` 来自社区用户 id。 |
32
+ | `variant` | number | `1` 正式 · `2` 试玩(demo) · `3` 衍生。 |
33
+ | `parentOrigin` | string | 仅供 SDK 校验消息来源,作品业务不要用。 |
34
+
35
+ ---
36
+
37
+ ## 2. 登录
38
+
39
+ | 方法 | 返回类型 | 说明 |
40
+ |---|---|---|
41
+ | `requireLogin()` | `Promise<void>` | 已登录立刻成功。否则请播放页弹出社区登录。用户取消 → `LOGIN_CANCELLED`。未受信壳会先抛 `UNTRUSTED_SHELL`。 |
42
+
43
+ 未登录时试玩 iframe 仍可玩离线内容。无 token 时 `queryGame()` / `queryUser()` 得到 `NOT_LOGGED_IN`。
44
+
45
+ ---
46
+
47
+ ## 3. 查询(须已登录)
48
+
49
+ 游戏自己发 HTTP,`credentials: 'omit'`,只打平台 `/v1/game-sdk/*`。`game_id` 由 token 绑定,不要自己拼查询参数。
50
+
51
+ | 方法 | 返回类型 | 说明 |
52
+ |---|---|---|
53
+ | `queryGame()` | `Promise<LumiMakerGameInfo>` | 当前作品货架与权限。SDK 原样返回服务端对象,不做字段校验。 |
54
+ | `queryUser()` | `Promise<LumiMakerUser>` | `username`、`nickname`、`avatar`。 |
55
+
56
+ ### `queryGame()` 字段
57
+
58
+ | 字段 | 类型 | 说明 |
59
+ |---|---|---|
60
+ | `game_id` | string | 作品 id。不要把原始 id 念给玩家。 |
61
+ | `owner` | string | 作者用户名。 |
62
+ | `name` | string | 平台显示名。 |
63
+ | `summary` | string | 简介。 |
64
+ | `cover_url` | string | 封面地址。 |
65
+ | `variant` | number | `1` 正式 · `2` 试玩 · `3` 衍生。 |
66
+ | `parent_game_id` | string | 试玩 / 衍生关联的正式版 id;没有则为空字符串。 |
67
+ | `price_flower` / `price_cny` / `price_usd` | number | 标价。作品内不要用它们复刻社区购买墙。 |
68
+ | `latest_version_no` | number | 平台最新版本序号。不要把版本 ID 念给玩家。 |
69
+ | `play_url` | string | 托管播放地址。**严禁用此 URL 跳转**;也不要念给玩家。 |
70
+ | `post_id` | string | 关联主帖 id;demo 与正式版共用;无则为空字符串。不要念给玩家。 |
71
+ | `status` | number | 货架 `1` 启用 / `2` 禁用。 |
72
+ | `purchased` | boolean | 对该可售主体是否有已支付订单;作者未下单为 `false`。 |
73
+ | `can_play` | boolean | 能拿到 token 时为 `true`。用来画自制章节锁。 |
74
+ | `ai_model` / `engine` / `languages` / `orientations` / `play_duration` / `mouse_only` | 可选 | 可能缺省。`mouse_only` 为游戏上存的值:明确开启才是 `true`。 |
75
+ | `orig_price_flower` / `orig_price_cny` / `orig_price_usd` | 可选 | 仅当前价为活动覆盖价时下发。 |
76
+
77
+ 自制 UI 读 `can_play` / `purchased`。正式版未获权时播放页不会加载 iframe。
78
+
79
+ ---
80
+
81
+ ## 4. 安全跳转与全屏
82
+
83
+ 只允许下列无参方法。不要操作 `window.top.location`,不要传入自定义 URL。公开 API **没有** `toggleFullscreen()`(协议里宿主可认全屏 `toggle`,游戏不要调)。
84
+
85
+ | 方法 | 返回类型 | 说明 |
86
+ |---|---|---|
87
+ | `navigateHome()` | void | 播放页回社区首页。 |
88
+ | `navigateAuthorPage()` | void | 打开作者页。 |
89
+ | `navigateBack()` | void | 有历史则后退,否则回作品帖。 |
90
+ | `openPlayHtml(html)` | `Promise<void>` | 换到包内另一个玩法 HTML,传包内路径(如 `staff.html`、`assets/index.html`)。反斜杠会改成斜杠,开头的 `/` 和 `./` 会去掉。按包内路径算,不跟着当前子目录再相对一次。不要传目录地址,不要把查询串写进路径。`..`、路径里的空白不会签名。社区 iframe 会自动拦 `<a>` / `assign` / `replace`(Chromium 还能拦 `location.href =`),已发布入口一般不必调。查出非法路径 → `FAILED`。官方 App 直开无宿主时会失败。 |
91
+ | `openPlayWindow(html, options?)` | `Promise<void>` | 另开包内玩法页,路径规则与 `openPlayHtml` 相同。`options.target` 省略时是新窗口。窗口名用字母开头,后面可以是字母、数字、`-`、`_`,最长 64;同一名字回到同一个窗口。不要传 `_self`、`_parent`、`_top`。`options.features` 只保留宽、高和位置(`width` / `height` / `left` / `top` / `screenX` / `screenY`)。返回值里没有窗口对象。非法路径 → `FAILED`。 |
92
+ | `signPlayHtml(html, done?)` | `Promise<string>` | 只要这个包内文件的地址,例如 `staff.html` 或 `assets/index.html`。当前页保持不动,也不开新窗口。按包内路径算,不跟着当前子目录再相对一次。`./assets/index.html` 当成 `assets/index.html`。路径后可以带查询和 `#`,签好后这两段留在返回的地址上。`await`、`.then` 或回调 `(error, url)` 都能拿到。地址给程序自己用:不要显示给玩家,不要改路径,不要套到另一个文件上。外链、已经带签名的地址、`..`、路径中的空白直接失败。非法路径或签名失败 → `FAILED`。官方 App 直开、没有播放页时会失败。 |
93
+ | `requestFullscreen()` | `Promise<void>` | 全屏**播放器外壳**,不是游戏改 `top`。须在真实点击等手势里调用。 |
94
+ | `exitFullscreen()` | `Promise<void>` | 退出播放器全屏。 |
95
+
96
+ 浏览器拒绝全屏 → `FULLSCREEN_DENIED`。
97
+
98
+ ### 4.1 多页怎么写
99
+
100
+ 在社区播放页里,下一页写普通链接即可,不必再调 `openPlayHtml`。
101
+
102
+ 查询(`?` 起)和锚点(`#` 起)**各自最长 2048 个字符**,超出的部分会被截掉。查询里**不能**使用 `auth_key`、`signature`、`expires`、`OSSAccessKeyId` 这些签名参数名(大小写不限);写进去会被当成平台已签名地址,业务查询可能补不回。
103
+
104
+ | 写法 | 播放页里 |
105
+ |---|---|
106
+ | 包内 `staff.html`、`assets/index.html`、`search.html?q=`、`snapshot.html#u=…` | 能打开。查询串和 `#` 在新页补回,不要指望它们出现在签名请求里。查询和 `#` **各自最长 2048 个字符**,超出截掉。查询里不要用 `auth_key`、`signature`、`expires`、`OSSAccessKeyId`(大小写不限),这些是平台签名参数名。再次打开同一页时,业务查询和 `#` 按这次链接整段替换。根目录 `index.html` 和 `assets/index.html` 是两页 |
107
+ | 左键 `target="_blank"`、自定义窗口名,或 Ctrl / ⌘ | 当前页不换。播放页另开可刷新的社区窗口。含 `<base target="_blank">`。页面已 `preventDefault` 则不打开 |
108
+ | `target="_parent"` / `_top` | 不要写。不换当前页,也不跳出作品框 |
109
+ | 当前页 `#id` | 只滚动,不换页 |
110
+ | `./#id`、`/#id`、`.`、`/`、`jubenba/` | **不要写**。会当成打开目录,请求失败;脚本会拦住,但也不会改成该目录的 `index.html` |
111
+ | 子目录 `assets/index.html`、`jubenba/search.html` | 能打开。这是包内路径,不是目录地址 |
112
+ | 链接上已 `preventDefault` | 脚本不再换页,让页面自己的点击处理先完成 |
113
+
114
+ 要某个包内页面的地址、又要留在当前页:`signPlayHtml('staff.html')`,也可以写成 `assets/index.html?q=关键词#intro`。返回的地址给程序自己用,不要显示给玩家,不要改路径,不要套到另一个文件上。`openPlayHtml`、`signPlayHtml`、`openPlayWindow` 按包内路径算;普通链接、`assign`、`window.open` 仍按浏览器相对地址算。
115
+
116
+ 右键「在新标签页中打开」和中键打不开。官方 App 直接打开作品、没有播放页时,换页、另开窗口和 `signPlayHtml` 都不会成功。
117
+
118
+ 本地 `npm run dev` 没有这套拦截,相对链接按普通静态站工作。
119
+
120
+ ---
121
+
122
+ ## 5. 错误码
123
+
124
+ | `code` | 何时 | 处理 |
125
+ |---|---|---|
126
+ | `NOT_LOGGED_IN` | 无 token,或查询鉴权失败 | 需要登录时再 `requireLogin()`;试玩可继续离线。 |
127
+ | `LOGIN_CANCELLED` | 用户关掉登录 | 非致命,留在当前界面。 |
128
+ | `TIMEOUT` | 握手或桥接超时。**`ready()` 超时只返回 `ready: false`,不 throw 本码** | 本地预览按未连接处理。 |
129
+ | `FULLSCREEN_DENIED` | 浏览器拒绝全屏 | 只在用户点击里请求全屏。 |
130
+ | `UNTRUSTED_SHELL` | 不在社区播放页 iframe / 官方 App | 提示在幻光社区或官方 App 打开。 |
131
+ | `FAILED` | 其它业务或通信失败 | 通用重试提示;不要把内部报文念给玩家。 |
132
+
133
+ ---
134
+
135
+ ## 6. 容器(作者需要知道的行为)
136
+
137
+ | 环境 | 行为 |
138
+ |---|---|
139
+ | 社区播放页 iframe | 正常握手。 |
140
+ | 官方 App(本窗有官方桥) | 不跳走。没有播放页 Host 时 `ready()` 仍超时,离线可玩。 |
141
+ | 浏览器地址栏直开托管页,或第三方站点嵌套 | 跳到社区作品帖;拿不到帖则空白页。 |
142
+
143
+ 不要把「直开托管地址」当成正规玩法入口。本地预览请继续 `npm run dev`,或嵌在社区播放页 / 官方 App。
@@ -38,7 +38,7 @@ npx lumimaker validate-template
38
38
 
39
39
  - 涉及文件或目录缺失:对照协议第 1 节(目录结构)补齐必要项。
40
40
  - 涉及配置或脚本问题:对照协议第 2 节(package.json)核对字段格式与脚本要求。
41
- - 涉及构建输出问题:对照协议第 3 节(构建产物)检查产物目录与入口。社区播放页能打开的玩法 HTML 须在 `dist/` 根目录,见该节第 5 条。
41
+ - 涉及构建输出问题:对照协议第 3 节(构建产物)检查产物目录与入口。社区播放页能打开包内 `.html` 路径(含子目录文件),目录地址打不开,见该节第 5 条。
42
42
 
43
43
  > **原则**:仅针对报错项和协议明确约定的内容做修改;协议未约定的文件和配置保持原样,切勿随意变动。
44
44
 
@@ -103,7 +103,7 @@
103
103
  2. **入口文件**:`dist/` 根目录下**必须**产出 `index.html` 入口文件。可以仅产出纯 `index.html`,无需任何其他静态资源文件。
104
104
  3. **静态资源(建议)**:若构建产物包含 JavaScript、CSS、图片等静态资源,建议放置于与 `index.html` 同级的 `dist/assets/` 目录下。
105
105
  4. **其他产物**:除 `dist/index.html` 外,产物目录内的其他文件组织形式本协议不作强制限制。
106
- 5. **社区播放页能打开的玩法 HTML**:须与 `index.html` 同在 `dist/` 根目录。子目录里的 `.html`、目录地址(如 `jubenba/`)在播放页打不开,也不会自动改成该目录的 `index.html`。页内锚点写 `#id`,不要写 `./#id`。链接写法见 `lumimaker-play-sdk`。
106
+ 5. **社区播放页能打开的玩法 HTML**:写包内 `.html` 路径,例如 `staff.html` 或 `assets/index.html`。目录地址(如 `jubenba/`)打不开,也不会自动改成该目录的 `index.html`。页内锚点写 `#id`,不要写 `./#id`。链接写法见 `lumimaker-play-sdk`。
107
107
 
108
108
  ---
109
109
 
@@ -113,3 +113,4 @@
113
113
  |---|---|---|
114
114
  | 1.0 | 2026-09-22 | 初始版本。明确工程目录结构、`package.json` 配置字段与脚本规范,以及 `dist/` 构建产物约定(assets 为可选,支持纯 index.html)。 |
115
115
  | 1.1 | 2026-10-05 | 补充:社区播放页只签 `dist/` 根目录的玩法 HTML;目录地址不会回落为该目录的 `index.html`。 |
116
+ | 1.2 | 2026-10-09 | 播放页改为签包内 `.html` 路径,子目录里的页面可以打开;目录地址仍然不会变成该目录的 `index.html`。 |