Commit Graph
9 Commits
Author SHA1 Message Date
sganggs 52b70434d0 0.2.5-dev: a restore-defaults loadout sync is never overwritten by an older in-flight sync (PR #540 by @Xinglan233, ported); importing a loadout with ops is refused before writing when the DIY data is missing (PR #538 by @Xinglan233, ported); the player package's package.json keeps only scripts whose files ship (#531) and its docs link unshipped files to the release tag on GitHub (#530); golden: unchanged 2026-10-12 14:45:01 +08:00
sganggs 9042125430 0.2.3: 重绘系列通用安装图标并记录功能审核决定(#413、#77/#408、#444、#407) 2026-10-10 02:11:23 +08:00
sganggs cefd1e7313 fb5-patch-pkg: every release zip carries MANIFEST.json (size + sha256 of each shipped non-art file, written after npm ci; the full, lite and update zips of a version list the same), and node tools/package.mjs --update --from <base>[,<base>…] builds Stronghold-Protocol-v<version>-update.zip — the full stage built as before, compared file by file with every base (an earlier full zip or its extracted folder; tools/package-update.mjs reads zips itself, zip64 included), shipping each file that is new or differs from at least one base plus MANIFEST.json and UPDATE.json (from, count, bytes, files, removed with each base's bytes); bases must be older, full (not lite or update) and distinct; the update stage gets the refusal and personal-info checks (sha256 values left out of the name scan); test/update-package.test.js (8), test/package.test.js expects MANIFEST.json in the zip 2026-10-07 11:23:55 +08:00
sganggs 25b2a87b26 feedback5 WAD: language packs are the first type of content packs — a language is a file in a language folder (public/i18n/<code>.json, optional data/i18n/<code>.json) or a pack folder (packs/<id>/pack.json); the server lists them live at /packs/index.json (server/packs.js), the menu shows every pack, strings fall back pack → base → declared fallback (English) → Chinese, broken placeholders are skipped, plurals follow Intl.PluralRules (English unchanged), English carries a _meta manifest like any pack; tools: i18n.mjs template / check <code>, packs.mjs list / index, build-i18n --lang ja|ko|zh-TW (the official JP / KR / TW clients); the release zip ships packs/ and a generated packs/index.json; golden unchanged 2026-10-07 02:38:22 +08:00
sganggs 575333137c feedback5 WX: the 39 summon models no web dump carries come from the local client (extract.py TOKEN_SPINES) and are drawn instead of the avatar diamond when data/local-assets.json lists them
- tools/local-extract/extract.py TOKEN_SPINES (`--only spine/token`): each token's battle prefab in the
  battle token packs (pkgrps/btl_pfb_tokens_*.ab; the Windows build has all 39, the iOS build lacks
  btl_pfb_tokens_0), the skeleton of its Front (or only) Spine renderer, written to
  public/assets/local/spine/token/<id>/ like the enemy models (sized pma atlas, premultiplied pages;
  the newer RGBA pages keep their own alpha). The enemy writer is shared (write_spine; the two enemy
  models re-extract byte for byte). The skinpack job of 乌尔比安's block is gone: it extracted
  nothing, and that token draws no model in the game (nor do 圣聆初雪's, 酒神's, 贝洛内's and
  予愿安洁莉娜's hidden tokens: no Spine renderer, no avatar in either install).
- tools/assets/local-token-spines.json (committed, `fetch-assets --local-spines`) → data/assets.json
  tokens[id].spineLocal for 35 自选 summons, 凯瑟琳's 爬行号·防护单元 and 凛御银灰's three 风雪之眼; the
  manifest is the same with or without the extraction (JSON diff: only the 39 spineLocal entries and
  the hash). spine.mjs LOCAL_SPINE_ROLES maps clips the resolver cannot read (电弧's 戴乌 C_Skill1_*,
  酒神's 本能的召唤 Loop / End, 白铁's platforms End, 战术锚点 on its Default pose) [ASSUMED where named].
- assets.js spineEntry: a token resolves its spineLocal like an enemy (no web model behind it: the
  diamond stays when it is not listed or fails to load). Scale as the web tokens (UNIT.modelScale).
- setup reports an extraction without the summon models; docs: ASSETS.md "Token models from the local
  client", DEPLOY.md §6, DESIGN §13 (design/client.md), README.
- Tests: test/local-token-models.test.js (new), test/local-extract.test.js (job table, prefab walk,
  alpha merge), test/assets.test.js (the local token models load like the client does),
  test/package.test.js (the full zip ships them), test/static-local-art.test.js. Golden unchanged.
2026-10-06 20:16:20 +08:00
sganggs 8ce6d280bd feedback5: merge W5W — DESIGN §25 catch-up (sleep port, board tap, packaging, the owner's 2026-10-06 answers, i18n phase 2, the 自选 voices, the summon-model gap) and the DESIGN split: docs/DESIGN.md is the index, current rules in docs/design/*.md, per-release history in docs/history/*.md, section numbers unchanged (the parts reassemble the old file byte for byte; test/docs-paths.test.js guards the index and every DESIGN §N citation); test/package.test.js builds its fake home path at run time 2026-10-06 19:22:14 +08:00
sganggs da1f5830ca feedback5 WW: split DESIGN.md into docs/design/ (the current rules) and docs/history/ (the per-release revisions), section numbers kept — a pure move: every ## N. block (heading, text, the --- after it) moves verbatim, each part file only gains a title line and a pointer to the index; docs/DESIGN.md keeps its header and becomes the index (a § → file table). design/overview.md §0 §1 §2 §11 §12, geometry-time.md §3 §4, engine.md §5 §7, match.md §6 §16, network.md §8 §14, client.md §9 §10 §13 §15; history/v2.2-playtest3.md §17, v2.3-playtest4.md §18, v2.4-playtest5.md §19, v2.5-playtest6.md §20, 0.1.1.md §21, 0.1.2.md §22, 0.1.3.md §23, 0.1.4.md §24, 0.2.0.md §25. Round trip: the index header plus the blocks in § order reproduce the pre-split DESIGN.md byte for byte (813 785 bytes, sha256 fe81884c…). Tests: test/helpers/designDocs.js designText() (the split script's splitBlocks / designText) reassembles the text in § order; docs-consistency and feedback1-gaps read it instead of docs/DESIGN.md (every pin unchanged); docs-paths guards the split (each § exactly once in docs/design/ or docs/history/, the index row of every file names its sections, every "DESIGN §N(.M)" cited in the repository is a heading — 779 in 327 files today); package.test keeps docs/design/ and docs/history/ out of the zips; golden unchanged 2026-10-06 19:08:44 +08:00
sganggs ec72abb0dd feedback5 WU: tools/package.mjs builds the runtime-only full zip and a lite zip without the art, with every check in --dry-run
npm run package / npm run package:lite (node tools/package.mjs [--lite] [--dry-run [--list]] [--out <dir>] [--force]
[--keep-stage] [--no-install] [--allow-dirty] [--root <dir>]) replaces the maintainer's copy-the-tree script:
Stronghold-Protocol-v<version>.zip and Stronghold-Protocol-v<version>-lite.zip, one Stronghold-Protocol/ folder each.

Ships (an allowlist over git ls-files): server/, shared/, data/, public/ but public/dev/, the start scripts, the tools a
player runs (setup, vendor, fetch-assets + tools/assets, doctor, and what setup starts: tools/local-extract,
crop-board-atlas), the four research tables the Node sim fallback and fetch-assets read (docs/research 03, 05-enemies,
05-maps, 07 JSON — the first cut left them out, so a lite zip's setup could not plan the art), package.json / lock,
LICENSE / NOTICE / THIRD-PARTY-NOTICES, README, CHANGELOG, docs/PLAYING.md, docs/DEPLOY.md; npm ci --omit=dev in the
stage adds node_modules and public/vendor. The full zip adds the files data/assets.json and data/local-assets.json list,
public/fonts and public/assets/local/ — not the rest of public/assets, so art the data dropped (焰狐龙梓兰's 15 files)
never ships. Left out: test/, maintainer tools, scripts/make-windows-bundle.mjs, the other docs and docs/img, research
notes, handoff/, .github/, types/, lint / editor / Docker files.

Checks (also in --dry-run, which writes nothing): 0.1.x's refusal list plus test, .github, AGENTS.md, public/dev,
node_modules/.cache, .env / .venv anywhere; relative and server-mount imports of shipped modules and the player npm
scripts resolve to shipped files; a full zip has every listed art file; no two paths differ only in case; no shipped
file (text or binary, art included) has a /Users/, C:\Users\ or /home/ path or this machine's account name (read from
the OS at run time, SP_PACKAGE_SCAN_USER=0 / SP_PACKAGE_SCAN_NAMES; node_modules for the name only); no shipped tracked
file has an uncommitted change. A build also checks that the stage holds exactly the plan before zipping, and refuses an
--out inside the repository.

Measured on this tree (version 0.1.3 until the bump): full zip 421,421,613 bytes (14,910 files, 589 MB unpacked), lite
zip 22,088,912 bytes (6,430 files, 85 MB); the 0.1.x layout of the same tree (every tracked file, all of public/assets)
zips to 429,644,767 bytes: 569 files and 25 MB unpacked less. Both stages started (npm start, /healthz, assets), setup
--check is green on the full one, and the lite one plans the art offline.

test/package.test.js (9 tests, about 1 s, no network, no npm install): the selection on sample paths and on the real
git ls-files (imports, npm entry points, research tables and spawned tools ship), the refusal list, a dry-run of a
temporary git checkout with fake art (full and lite lists), the scans and guards, and one --no-install build there.
2026-10-06 18:07:15 +08:00
sganggs b6c9918c46 feedback5 R6: add a player package tool with a lite dry-run
tools/package.mjs packs git-tracked runtime files and production dependencies. --lite leaves out local art, fonts and the local asset manifest. --dry-run lists the files and the uncompressed sizes and does not write a zip.
2026-10-05 16:23:47 +08:00