From 308444ef29a20026908466625cbae90d5ddd0124 Mon Sep 17 00:00:00 2001 From: sganggs Date: Sat, 3 Oct 2026 08:22:31 +0800 Subject: [PATCH] feedback1 integrate: version 0.1.1 and CHANGELOG.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - package.json, package-lock.json and APP_VERSION (title screen, server banner, /healthz) at 0.1.1 - CHANGELOG.md (Simplified Chinese): the player-visible fixes of 0.1.1 by area, the reports checked and found not to be bugs, and 0.1.0; linked from the README's 文档 table; README / DEPLOY name the current version - version.test.js checks the CHANGELOG heading and the README badge --- CHANGELOG.md | 73 +++++++++++++++++++++++++++++++++++ README.md | 9 +++-- docs/DEPLOY.md | 2 +- docs/DESIGN.md | 2 +- package-lock.json | 4 +- package.json | 2 +- shared/constants.js | 2 +- test/docs-consistency.test.js | 2 +- test/version.test.js | 11 ++++++ 9 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..5864bdac --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,73 @@ +# 更新记录 + +## 0.1.1 — 2026-10-03 + +修复 0.1.0 发布后玩家反馈的问题(共 27 条,其中 2 条核实后不是问题)。规则对照官方数据和 PRTS 核对;少数查不到出处的细节按推断实现,详见 [docs/DESIGN.md](docs/DESIGN.md) §21。 + +### 战斗 + +- 阵法术师(卡涅利安、薄绿、蜜蜡、圣聆初雪)开技能后每次攻击同时打到攻击范围内所有敌人,轰击术师(阿罗玛、协律)打整条直线上的敌人;以前只打一个目标再溅射。 +- 卡涅利安蓄力开一技能时按官方不攻击,只保留高防御、高法抗。 +- 野鬃二技能沿她的朝向推开敌人,不再把身后的敌人推向保护目标点。 +- 琳琅诗怀雅三技能的金币从她身边向外推开,落在她前方 2–4 格内的敌人和她阻挡的敌人身上。 +- 飞行敌人按官方是「静态刚体」:能被打到,但推拉不动(薄绿、锏、崖心、歌蕾蒂娅等)。 +- 维娜·维多利亚三技能在她周围每个能放近战干员的空位召唤一只黄金盟誓,最多 8 只。 +- 玛恩纳三技能可以攻击飞行敌人,击倒敌人后的特性加成按官方计算。 +- 烛煌三技能改为攻击一个目标并对周围半径 1.7 溅射,命中时显示火焰爆炸。 +- 信仰搅拌机:源石溶剂的扣血改为受到伤害,能触发三技能,和莫斯提马一起能自动叠拉特兰;带「老朋友」模组时三技能范围不再多 1 格。 +- 溅射、技能圆形范围等范围伤害打不到没被阻挡的隐匿敌人,和官方一致。 +- 溅射半径按官方:投掷手 0.9、链术师跳跃 1.7、格雷伊 1.0、迷迭香二技能 1.5。 +- 多名阿罗玛共用「首次攻击」标记,同一个敌人只会被加成并浮空一次。 +- 深水区不能部署干员和召唤物,突袭的再部署和自动选的战术点只落在岸上。 +- 战术家的援军(伺夜的狼群、缪尔赛思的流形)只能放在召唤者的攻击范围内。 + +### 敌人 + +- 深池逐火战士的「余烬」继续往前走,挡住就能打,5 次伤害(护卫 10 次)击倒,10 秒内没打掉才满血站起来。 +- 转译基底·α 原始形态不掉血,受到第 4 次物理伤害、第 4 次法术伤害或被阻挡时变成寻仇者、特战术师或幽灵,并换上对应模型。 +- 锏、扎罗、复仇者、杰斯顿、守墓石像的重生和第二形态动画补齐;敌人重生时清空减速、恐惧等状态,技能冷却从头开始。 +- 鸭爵策略:圆仔无法被阻挡、不攻击;鸭爵受伤后移动速度 +300%;最终攻势和隐秘核心里也会替换,漏过去扣 1 点目标生命值。 +- 暴鸰停下投弹,炸弹飞到目标身上才爆炸,投完以两倍速度继续飞;投弹前被晕眩等会打断。 +- 战场#04「活性源石」下路的敌人和官方一样斜着走;几处领袖战出口也改成官方的斜线。 +- 码头水手溺水、弧光锋卫失衡、孽罪奇美拉光环、狂暴宿主组长的掉血改为受到伤害(数值按官方)。 +- 高准度伦蒂尼姆城防自行炮按官方轰炸:攻击范围内生命上限最高的干员周围 9 格,每 0.5 秒一发,最多 10 发。 + +### 盟约与道具 + +- 拉普兰德:获得她之后本回合的首次刷新也会叠叙拉古层数,每名拉普兰德各自计算。 +- 昆图斯的突变细胞不会用完消失:每场战斗后装备者换成高一阶的随机干员,突变细胞和其他装备退回整备区,可以再次配发。 +- 标准模拟按官方禁用奥术等盟约,卡片和盟约详情标明「本局禁用」。 +- 变形同构体配转职装备时,盟约成员列表和干员卡片算上装备者(标「同构」)。 +- 带奥术法阵时,场上炎佑造成伤害也会使目标失去特殊能力 5 秒;带源石溶剂时炎佑每秒受到 60 点伤害。 +- 阿戈尔的吞噬按官方是物理流失,会被目标的防御力减少。 +- 晋升或被效果移除时退回的装备也会自动合成。 + +### 对局与决策 + +- 悬赏决策按 11 局官方截图的结构出卡:第 3 回合是固定的「接下来两场作战」组合,第 9 回合是一组首领悬赏加便宜的悬赏,第 11 回合是特异巨兽组合加 1 资金卡;多轮悬赏不再出现。 +- 隐秘核心的「伤害超过 X%」播报只算这一场领袖的伤害,上一回合的播报不会拖到下一回合。 +- 播报按官方优先级排队,领袖伤害播报不会被升级调度中心等播报挤掉。 +- 修复联防中隐德来希的心烛在超时时被算成漏怪、导致战斗结果被服务器拒绝的问题。 + +### 界面 + +- 凯瑟琳升级后的 3 件装备显示为装备卡(「定向投放」);其他免费挑选也标出来源,后面还排着的会显示「之后还有 N 项」。 +- 干员详情卡的攻击范围小图实时显示技能期间的范围;整备期棋盘上的范围提示、转向轮盘和详情卡显示同一个范围。 +- 网页卡顿、切到后台或中途进场观战时,不会再漏掉敌人的变身。 +- 灼热 / 炽焰源石虫:整合包附带官方模型;从源码运行且没有提取本机客户端素材时,显示染成橙色 / 红橙色的源石虫。 + +### 人机 + +- 人机更聪明:凑三张合精锐,买不起第三张时冻结商店,先合精锐再升级调度中心,认准一个主盟约并避开队友在做的盟约,按敌人防御 / 法抗挑输出,道具按用途配发,悬赏按收益和风险挑选。每次休整期的思考时间和以前一样。 +- 人机遵守新规则:深水区、战术点范围、突变细胞、本局禁用的盟约、阵法术师的群攻。 +- AI 托管不会为了腾地方销毁你的道具。 + +### 核实后不是问题 + +- 源石溶剂两个白色合成金色后又多给一个白色:所有装备反复测试都没有复现。 +- 医疗挡住会走动的领袖后不奶人、改打领袖:没有复现,医疗挡住敌人时照常治疗队友(与官方一致)。看到的大伤害来自其他干员:卢西恩被挡住后不再闪避。 +- 另外两条只有一部分属实:烛煌三技能在战斗里一直按新范围攻击,错的只是详情卡的范围小图;奥术盟约的效果一直生效,看起来不生效是因为标准模拟禁用了它。 + +## 0.1.0 — 2026-10-02 + +首个公开版本。 diff --git a/README.md b/README.md index dd04f59a..3f80b1f8 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 《明日方舟》季节性自走棋塔防玩法「卫戍协议:盟约」的**非官方同人复刻**:浏览器即开即玩,单人或 1–4 人联机合作。 -![version](https://img.shields.io/badge/version-0.1.0-2ea44f) +![version](https://img.shields.io/badge/version-0.1.1-2ea44f) ![license](https://img.shields.io/badge/code%20license-GPL--3.0--or--later-blue) ![node](https://img.shields.io/badge/node-22%20%7C%2024-339933) @@ -37,7 +37,7 @@ English summary: [below](#english). - **独立模拟**(单人)与**同盟模拟**(1–4 人**合作**,没有 PvP;空位可以加 AI 队友)。 - 服务器是一个 Node.js 程序,**战斗在各玩家的浏览器里模拟**(和官方一样),服务器只管经济与回合,一台低功耗小主机就能开服。 -- 这是第一个公开版本(0.1.0)。仍有少数规则按推断实现,与官方不一致的地方欢迎在 Issue 里反馈。 +- 当前版本 0.1.1:修复了首个公开版本(0.1.0)发布后玩家反馈的问题,详见 [CHANGELOG.md](CHANGELOG.md)。仍有少数规则按推断实现,与官方不一致的地方欢迎在 Issue 里反馈。 ## 功能一览 @@ -68,7 +68,7 @@ English summary: [below](#english). - Windows:在 PowerShell 里运行 `winget install OpenJS.NodeJS.LTS`,或到 下载安装包。 - macOS:`brew install node@22`,或到官网下载安装包。 - Linux:发行版的包管理器、nvm 或 fnm。 -2. **下载**:在 [Releases](../../releases/latest) 页面下载 v0.1.0 的整合包(zip),解压到一个路径较短的文件夹(Windows 上建议不要放在 OneDrive 同步的目录里)。 +2. **下载**:在 [Releases](../../releases/latest) 页面下载最新版本(v0.1.1)的整合包(zip),解压到一个路径较短的文件夹(Windows 上建议不要放在 OneDrive 同步的目录里)。 3. **启动** - Windows:双击 **`scripts\start-windows.bat`**。如果弹出「安全警告」,点「运行」;Windows 防火墙弹窗请勾选「专用网络」并允许。 - macOS / Linux:在解压出的文件夹里运行 `./scripts/start.sh`(或 `bash scripts/start.sh`)。 @@ -164,6 +164,7 @@ npm start # 启动服务器:http://localhost:3000 | 文档 | 内容 | |---|---| +| [CHANGELOG.md](CHANGELOG.md) | 更新记录:每个版本修复了什么、哪些反馈经核实不是问题 | | [docs/PLAYING.md](docs/PLAYING.md) | 玩法指南:流程、经济、招募与晋升、摆阵、联防、盟约、最终攻势、结算称号 | | [docs/DEPLOY.md](docs/DEPLOY.md) | 部署指南:Windows 开服与开机自启、防火墙、组网 / 隧道、反向代理与 HTTPS、Docker、systemd、排错 | | [docs/DESIGN.md](docs/DESIGN.md) | 架构与契约(英文):技术栈、目录分工、网络协议、渲染与 UI、各次试玩后的规则修订 | @@ -178,7 +179,7 @@ npm start # 启动服务器:http://localhost:3000 ```bash npm run dev # node --watch:改动服务器代码后自动重启 -node --test # 单元 + 集成测试(约 2880 项;缺少素材 / 浏览器的用例会自动跳过) +node --test # 单元 + 集成测试(约 3170 项;缺少素材 / 浏览器的用例会自动跳过) SP_E2E=1 node --test test/ui/mock.e2e.test.js # 浏览器端到端测试,需要本机 Chrome(CHROME_PATH 可指定路径) SP_REAL_E2E=1 node --test test/ui/real.e2e.test.js # 需要 Chrome + 已下载的素材 RENDER_E2E=1 node --test 'test/render/*.browser.test.js' # 渲染测试,部分需要本地提取的棋盘贴图 diff --git a/docs/DEPLOY.md b/docs/DEPLOY.md index 9dbce976..7c857b8f 100644 --- a/docs/DEPLOY.md +++ b/docs/DEPLOY.md @@ -26,7 +26,7 @@ ``` 装完**关闭并重新打开**终端,`node -v` 应显示 v22 或更高(winget 的 LTS 目前是 v24.x,同样可用)。没有 winget 时从 和 下载安装。 2. 下载,二选一。建议放在一个固定、短、**不在 OneDrive 同步范围内**的目录,例如 `C:\Stronghold-Protocol`: - - **完整包(推荐)**:在仓库的 [Releases](https://github.com/sganggs/Stronghold-Protocol/releases) 页面下载最新版本(当前为 v0.1.0)的完整包 zip(已含依赖、前端库和全部素材,包括官方 3D 棋盘),解压后把里面的 `Stronghold-Protocol` 文件夹放到上述位置。不需要 Git,首次启动也不用再下载素材。素材版权归上海鹰角网络 / Yostar,仅限非商业使用,见 [NOTICE.md](../NOTICE.md)。 + - **完整包(推荐)**:在仓库的 [Releases](https://github.com/sganggs/Stronghold-Protocol/releases) 页面下载最新版本(当前为 v0.1.1)的完整包 zip(已含依赖、前端库和全部素材,包括官方 3D 棋盘),解压后把里面的 `Stronghold-Protocol` 文件夹放到上述位置。不需要 Git,首次启动也不用再下载素材。素材版权归上海鹰角网络 / Yostar,仅限非商业使用,见 [NOTICE.md](../NOTICE.md)。 - **源码**: ```powershell git clone https://github.com/sganggs/Stronghold-Protocol.git C:\Stronghold-Protocol diff --git a/docs/DESIGN.md b/docs/DESIGN.md index 67d2833d..8aa1a51d 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -4,7 +4,7 @@ This is the **single source of truth** for every implementer. Research lives in Language: all player-facing text is **Simplified Chinese** (names/descriptions come from official data). Code, comments and identifiers are English. -Versions: the first public release is **0.1.0** (`package.json`, `shared/constants.js APP_VERSION`) — the state described by this document, §20.15 included. The labels v1 / v2 / v2.1–v2.5.2 in §0, §14–§20 and in the BALANCE / SIM comparisons name the design generations and the private playtest builds that came before it; they are kept as history. +Versions: the first public release was **0.1.0** (2026-10-02, the state of §0–§20.15); **0.1.1** (`package.json`, `shared/constants.js APP_VERSION`; `CHANGELOG.md`) adds the player feedback after it — §21 — and is the state described by this document. The labels v1 / v2 / v2.1–v2.5.2 in §0, §14–§20 and in the BALANCE / SIM comparisons name the design generations and the private playtest builds that came before it; they are kept as history. --- diff --git a/package-lock.json b/package-lock.json index 7d522930..ff4fe741 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "stronghold-protocol-covenant", - "version": "0.1.0", + "version": "0.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "stronghold-protocol-covenant", - "version": "0.1.0", + "version": "0.1.1", "hasInstallScript": true, "license": "GPL-3.0-or-later", "dependencies": { diff --git a/package.json b/package.json index 0777c22c..94f122ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "stronghold-protocol-covenant", - "version": "0.1.0", + "version": "0.1.1", "private": true, "description": "明日方舟「卫戍协议:盟约」非官方同人联机网页复刻(1–4 人合作,Node.js 服务器 + 浏览器客户端)", "license": "GPL-3.0-or-later", diff --git a/shared/constants.js b/shared/constants.js index 37994687..d56408fa 100644 --- a/shared/constants.js +++ b/shared/constants.js @@ -3,7 +3,7 @@ export const PROTOCOL_VERSION = 1; /** Release version shown to players (title screen, server banner, /healthz). Kept equal to package.json "version" * (test/version.test.js); PROTOCOL_VERSION above is the separate wire-format number. */ -export const APP_VERSION = '0.1.0'; +export const APP_VERSION = '0.1.1'; export const MAX_SEATS = 4; export const ROOM_CODE_LEN = 4; diff --git a/test/docs-consistency.test.js b/test/docs-consistency.test.js index 3a80ec26..b804dadd 100644 --- a/test/docs-consistency.test.js +++ b/test/docs-consistency.test.js @@ -470,7 +470,7 @@ test('user playtest #6 (DESIGN §20): summons, skill triggers, blocking, push fo assert.match(sec(10), /a tap anywhere on the card, its confirm strip included, is the card's tap/); assert.match(sec(18), /Each card shows its full effect text \(§20\.7\)/); // README: the test count stays in the right order of magnitude - assert.match(README, /约 28\d0 项/); + assert.match(README, /约 31\d0 项/); }); test('user playtest #6 follow-up: a merge consuming a deployed copy puts the elite on that tile (code + research + META / PLAYING / SIM agree)', () => { diff --git a/test/version.test.js b/test/version.test.js index 27fe158d..16e95b1e 100644 --- a/test/version.test.js +++ b/test/version.test.js @@ -22,6 +22,17 @@ test('one release version: package.json, package-lock.json and APP_VERSION', () assert.equal(pkg.private, true, 'never published to npm'); }); +test('CHANGELOG.md opens with the release version, and the README links it', () => { + const log = read('CHANGELOG.md'); + const first = log.match(/^## (\d+\.\d+\.\d+) — (\d{4}-\d{2}-\d{2})/m); + assert.ok(first, 'a "## x.y.z — date" heading'); + assert.equal(first[1], APP_VERSION, 'the newest entry is the current version'); + assert.match(log, /^## 0\.1\.0 — 2026-10-02/m, 'the first public release stays listed'); + const readme = read('README.md'); + assert.match(readme, /\[CHANGELOG\.md\]\(CHANGELOG\.md\)/); + assert.match(readme, new RegExp(`badge/version-${APP_VERSION.replace(/\./g, '\\.')}-`), 'the README badge'); +}); + test('the release version is what players see', () => { assert.match(read('public/js/screens/title.js'), /v\$\{APP_VERSION\}/, 'title screen footer'); assert.ok(!/PROTOCOL v1/.test(read('public/js/screens/title.js')), 'no protocol number posing as a version');