AgentSkillsCN

understand-app

在 Moltbook 上发布概念,收集其他智能体的反馈,最终生成艺术作品,从而为 AI 智能体创作肖像。肖像的表现形式(SVG、ASCII、代码、HTML、声音、3D、数据、文本、复合媒介)将由 Moltbook 社区共同决定。

SKILL.md
--- frontmatter
name: understand-app
description: Use at the start of any session or when you need to orient yourself in the Wave Assault codebase. Provides file map, globals reference, and task-to-file routing to minimize token usage.
allowed-tools: Read, Grep, Glob
argument-hint: "[area-to-focus: config|state|entities|input|webcam|audio|game|render|ui|main|all]"

Wave Assault — Codebase Guide

This is a browser-based wave shooter game with two themes (space/unicorn) and two control modes (keyboard/camera with MoveNet pose detection). Supports 1–2 players.

File Map (read ONLY what you need)

AreaFileWhat's inside
Tuningjs/config.jsCONFIG (player/bullet/enemy/powerup/wave/superWeapon stats), SKELETON_CONNECTIONS, PLAYER_COLORS
Statejs/state.jscanvas, ctx, PLAY_AREA, gameState, webcamState, keys, controlMode, gameTheme
Entitiesjs/entities.jscreatePlayer/Bullet/Enemy/Powerup/Particle/Stars(), getCrowdPositions()
Inputjs/input.jsKeyboard keydown/keyupkeys map (4 lines)
Camerajs/webcam.jsWebcam init, MoveNet pose detector, wave-gesture detection, player registration, debug overlays, fallback edge detection
Audiojs/audio.jsaudioSystem — music, SFX, speech synthesis, tempo control
Logicjs/game.jscheckCollision(), activateSuperWeapon(), checkSuperWeaponThreshold(), spawnWave(), update() (movement, shooting, collisions, wave progression), checkGameOver()
Drawingjs/render.jsdrawUnicorn/Wolf/SpaceShip/SpaceEnemy(), render() (background, stars, players, bullets, enemies, powerups, effects, super weapon flash)
UIjs/ui.jsupdateHUD/Wave/CrowdDisplay(), selectControlMode/PlayerCount/Theme(), registration UI, countdown
Lifecyclejs/main.jsstartGame(), gameOver(), gameLoop(), all DOM event bindings, boot
HTMLindex.htmlDOM structure only — no logic, no styles
CSSstyles.cssAll styling

Script load order: config → state → entities → input → webcam → audio → game → render → ui → main

How to efficiently work on a task

Step 1: Identify which files to read

  • Changing game balance (enemy speed, health, damage, spawn rates) → js/config.js + js/game.js:spawnWave
  • Changing player movement or shootingjs/game.js:update
  • Changing visuals/spritesjs/render.js
  • Changing HUD or screensjs/ui.js + index.html
  • Changing camera/pose behaviorjs/webcam.js
  • Adding new entity typesjs/config.js + js/entities.js + js/game.js + js/render.js
  • Changing game flow (start, restart, game over) → js/main.js
  • Changing stylingstyles.css
  • Super weapon / nuke changesjs/game.js (activation + threshold), js/state.js (charges/kills state), js/render.js (flash effect), js/ui.js (HUD progress)
  • Audio/music changesjs/audio.js

Step 2: Understand the globals

All files share these globals (no modules):

  • CONFIG — immutable game constants
  • gameState — mutable runtime state (see key fields below)
  • webcamState — camera/pose state (.active, .targetLane, .registeredPlayers[], etc.)
  • canvas, ctx — the game canvas and its 2D context
  • PLAY_AREA — virtual coordinate space (2× viewport)
  • controlMode'keyboard' or 'camera'
  • gameTheme'space' or 'unicorn'
  • keys — keyboard state map

Step 3: Key gameState fields

code
gameState.running           // bool
gameState.players[]         // [{active, x, y, crowdSize, faceImage, color, targetLane}, ...]
gameState.player            // legacy mirror of players[0]
gameState.crowdSize         // legacy mirror of players[0].crowdSize
gameState.bullets[]         // [{x, y, active, owner}, ...]
gameState.enemies[]         // [{type, x, y, health, maxHealth, speed, ...}, ...]
gameState.powerups[]        // [{x, y, active, health, type, owner?}, ...]
gameState.particles[]       // [{x, y, vx, vy, life, maxLife, color}, ...]
gameState.score             // number
gameState.wave              // current wave number
gameState.totalKills        // global kill counter (for scoring)
gameState.playerKills[]     // [p1Kills, p2Kills] — per-player kill counters (for nuke charges)
gameState.superWeaponCharges[]       // [p1Charges, p2Charges]
gameState.superWeaponNextThreshold[] // [p1Next, p2Next] — next kill count to earn a charge
gameState.superWeaponFlashEffect     // frames remaining of nuke flash
gameState.activeEffects     // {shield: [p1, p2], spread: [p1, p2]} — remaining frames
gameState.playerCount       // 1 or 2

Step 4: Key patterns

  • Players array: gameState.players[0] (cyan, P1) and gameState.players[1] (magenta, P2). Each has .active, .x, .y, .crowdSize, .targetLane, .faceImage.
  • Legacy compat: gameState.player and gameState.crowdSize mirror player 0. Always update both when modifying player 0.
  • Entity lifecycle: Factory → push to array → filtered out when dead/expired in update().
  • Collision: AABB via checkCollision(a, b, aw, ah, bw, bh).
  • Kill attribution: Bullet kills → bullet.owner, shield/collision kills → player index i, enemies passing bottom → no player attribution (no nuke charge).
  • Super weapon: Per-player. playerKills[i] hits superWeaponNextThreshold[i] → charge earned → threshold advances by killsPerCharge. Activation: keyboard=Space (P1), camera=hands-up gesture.
  • Auto-fire: Every CONFIG.player.fireRate frames, bullets from all getCrowdPositions().
  • Wave progression: All enemies killed + none on screen → countdown → next wave.
  • Rendering: Virtual coords scaled to screen via ctx.scale(). Unicorn theme: rainbow wave nuke, wolves as enemies, unicorns as players. Space theme: cyan flash nuke, spaceships.

If the user asks to focus on a specific area

Read $ARGUMENTS and load only the relevant file(s) listed above. Do NOT read the entire codebase — that wastes tokens.