Install
openclaw skills install @hmily741963/war-skill红色警戒版《厨房战争》RTS 已完成并验证。 红警风 UI 重做:金属斜角描边 + 金红配色(金 #f0c84a / 红 #e23b3b),侧栏/雷达/菜单全套 chrome;建筑按钮带 emoji 缩略图、建造进度条、生产队列条;新增超级武器面板和维修/拆除区。 集结点(旗帜连线):选中生产建筑右键设集结点,新兵自动奔向集结点。 维修(扣食材回血)/ 拆除(返还 50% 造价)。
openclaw skills install @hmily741963/war-skillDeliver and iteratively improve a complete, single-file HTML5 RTS game that
mimics the Red Alert (红警) core loop with a kitchen-war theme. The game lives in
assets/index.html — one self-contained file (Canvas + a side HTML/CSS panel,
zero external dependencies). To give the user the game, copy assets/index.html
into their workspace and open it in the built-in preview via present_files.
This skill also encodes the hard-won quality bar: the game must be verified with a real browser end-to-end test that drives the actual game loop — not a transient/one-frame check — because multi-frame interaction bugs (e.g. the "moved a few steps then froze" deadlock) are invisible to instant tests.
assets/index.html to the user's workspace (e.g. 桌面 or current project).present_files so it opens in the live preview panel.The game is a faithful Red Alert-shape RTS. Confirm these exist after changes:
attackMove toward player buildings).? button) — explains goal, controls, hotkeys,
and tips. Dismissed once, accessible any time. Shown automatically on first load.localStorage.beep engine) —
build / produce / explode / promote / capture / superweapon / select / ach /
victory / defeat. Toggle with X or the toolbar button. Persisted.localStorage with toast + in-game panel
(🏆 成就): first win, speedrun (<5 min), low-HP survival, 10000 cash,
30 units produced, 10 buildings built, unit → vet-2, engineer capture,
superweapon kill, win on all 3 maps.📷 button or F) — exports the canvas as a PNG with
map / difficulty / cash / time watermark. Drop straight into a share.1-6 quick-select first 6 build items, Space / P pause,
H help, X SFX, M music, F screenshot, Esc cancel, plus the
legacy B / I / V tabs and S stop.dt) + pause (skip updates,
show "⏸ 已暂停" tag) — power-user and accessibility controls.A change is NOT done until scripts/verify_game.js runs green with 0 runtime
errors. This test drives the real game loop (not internal stubs):
pageerror / console.error throughout.The full 62-assertion real-browser e2e suite (the gate above plus the expanded regression + engagement-feature suites) must all pass with 0 console errors / warnings / pageerrors before declaring done:
| Suite | Asserts | Covers |
|---|---|---|
scripts/verify_game.js | 29 | start, all 6 buildings, 10 unit productions, tech gate, selection, move, superweapon, AI attack, fog, radar, stress, victory, defeat, zero errors |
_audit2.js (expanded) | 22 | all 3 maps boot+build+produce, sell, repair, engineer capture, double superweapon, power overdraw → lowPower, harvester economy, unreachable target, mass death, selected-unit death, zero errors |
_smoke_features.js | 11 | first-visit help, topBar, speed cycle 1→2→3→1, pause (button + Space), SFX toggle + persist, 10-achievement panel, hotkey 1 place, screenshot download, hotkey H help, post-feature NaN-free, zero errors |
Run command (managed Node + Playwright):
cd <skill>/scripts
export PLAYWRIGHT_BROWSERS_PATH="$LOCALAPPDATA/ms-playwright"
export NODE_PATH="C:/Users/www74/.workbuddy/binaries/node/workspace/node_modules"
"C:/Users/www74/.workbuddy/binaries/node/versions/22.22.2/node.exe" verify_game.js
The script auto-resolves the game at ../assets/index.html.
Instant Playwright clicks that land inside one frame pass even when the real
game is broken: the sidebar used to rebuild its buttons every frame, so a human's
cross-frame click never triggered onclick; and unit separation once exactly
cancelled per-frame movement, freezing units after a few steps. Only a test that
samples per-frame state across many frames catches these. See references/testing.md.
assets/index.html directly.u.speed / u.slowTimer (set by spawnUnit),
NOT u.def.speed. Units created anywhere must include these fields.applySeparation push is capped well below per-frame movement so units
never deadlock behind allies.updateCombatUnit must keep making progress (repath cooldown + seekDirect
fallback) so a findPath failure never leaves a unit permanently stopped.damage() when a yard is destroyed.x/y,
destX/destY, or mouse-derived coordinate becomes NaN (e.g. via a
clamp call, since clamp(NaN,a,b) returns NaN with the naive
v<a?v:a:v>b?b:v form), it spreads: tileBlocked(NaN,NaN) then does
G.map[ty][tx] → reads undefined → throws every frame, crashing the
whole game loop (symptom: "worked for a few moves then broke"). Guard rails
in place (do NOT remove): clamp coerces v!==v → a; clientToGame
guards r.width/r.height===0; tileBlocked/commandUnits/moveDirect/
moveAlongPath/seekDirect/ensureMove all early-return on non-finite
inputs. Keep them.clearBaseZone must preserve ALL T_RES tiles (not just those outside
the base's bbox). Each map deliberately places the starting resource patch
adjacent to the base (so the harvester mines immediately), and the patch
overlaps the base bounding box. The early form
if(T_RES && !insideFootprint) continue wiped the near-base resource, so
the harvester had to cross the entire map → first delivery ~30s instead of
~5s, devastating the early economy. Fixed: if(T_RES) continue;.updateUnits must also purge dead units from G.selUnits, not only
from sd.units. Otherwise a dead unit stays in the selection set, its
ghosts render, and stale references leak into the order/move pipeline.updateCombatUnit must drop a target whose side matches the attacker's
side (e.g. an engineer-captured building flips to player and the
remaining attackers must not keep "attacking" their own building). The
re-acquisition condition is
!u.target || u.target.hp<=0 || (u.target.side && u.target.side===u.side).assets/index.html — the game (deliverable).scripts/verify_game.js — mandatory real-browser e2e quality gate.references/testing.md — the verification methodology and known bug classes.