Makelore 2.0 initial clean snapshot
This commit is contained in:
169
.opencode/skills/nianxxgame-skill/SKILL.md
Normal file
169
.opencode/skills/nianxxgame-skill/SKILL.md
Normal file
@@ -0,0 +1,169 @@
|
||||
---
|
||||
name: nianxxgame-skill
|
||||
description: nianXXgame skill designs, builds, debugs, playtests, polishes, and ships practical 2D or 3D web games through a lightweight, evidence-driven workflow that joins game design, project delivery, and engineering. Use Phaser 3.90 for the default 2D path or Three.js with TypeScript for an explicitly chosen 3D path.
|
||||
---
|
||||
|
||||
# nianXXgame skill
|
||||
|
||||
Turn an informal game idea or an existing 2D/3D web game project into one verified playable result at a time. Keep design intent, delivery state, and runtime behavior aligned without creating process for its own sake.
|
||||
|
||||
## Apply the three pillars
|
||||
|
||||
Treat these pillars as equally important across the game lifecycle:
|
||||
|
||||
1. **Design:** define the intended player experience, rules, choices, feedback, and testable risks.
|
||||
2. **Delivery:** constrain scope, select one player-visible result, and keep project state recoverable.
|
||||
3. **Engineering:** implement safely in the selected engine, verify in a real browser, and preserve project conventions.
|
||||
|
||||
Apply only the depth relevant to the request: design-only work still needs scope and testable outcomes, while runtime work needs all three pillars. Do not let technical completion substitute for a coherent experience. When implementation is in scope, do not let design documentation substitute for a playable build.
|
||||
|
||||
## Coordinate the game asset workflow
|
||||
|
||||
In the current NianCode game template, `game-art` is the only role that directly uses the project-owned `game-assets` Skill and its Meowa adapter. Other roles should make the workflow useful through shared artifacts:
|
||||
|
||||
- `game-design` records the visual intent, player-facing purpose, priority, and acceptance context in `GDD.md` and `TASKS.md` when a new asset gap appears.
|
||||
- `game-art` checks Works Square/open-source sources first, then uses `game-assets` for a clear gap, records the generated run and license state in `ASSET_PLAN.md`, and submits candidates for review.
|
||||
- `game-development` integrates only assets whose project-local review state is `approved`; without one, use a reversible placeholder and keep the gap visible.
|
||||
- `game-test-release` verifies the approved asset's real path, metadata, readability, and runtime behavior, then sends defects back to `game-art`.
|
||||
|
||||
No role should call Meowa directly, expose a Key, bypass the local quota, or treat a candidate as a formal asset. The product-operations role only describes assets that are already real, approved, and evidenced; it does not enter this generation handoff.
|
||||
|
||||
## Select the rendering path
|
||||
|
||||
- Keep 2D as the default: use Phaser 3.90.0 and read `references/phaser3-standards.md`.
|
||||
- Support 3D when the user explicitly chooses or insists on it: record `Rendering Mode: 3D` and an exact pinned Three.js version in `TECH_STACK.md`, use TypeScript, and read `references/web3d-standards.md`.
|
||||
- Do not silently force a 3D request into 2D, and do not silently migrate an existing 2D game to 3D. If the mode changes, update `GDD.md`, `TECH_STACK.md`, `TASKS.md`, and the relevant asset plan before implementation.
|
||||
- Meowa `game-assets` currently generates 2D pixel/HD raster assets only. A 3D path may still use Meowa for reviewed 2D textures or UI, but models must come from user-provided, open-source, or otherwise authorized project-local sources recorded in `ASSET_PLAN.md`.
|
||||
|
||||
## Route bundled resources
|
||||
|
||||
Load only the resources required by the work:
|
||||
|
||||
- Read [the game-design standards](references/game-design-standards.md) before ideation, GDD work, mechanic or economy design, progression, balancing, controls, game feel, UI/feedback, accessibility, playtest planning, or design review.
|
||||
- Read [the Phaser 3 standards](references/phaser3-standards.md) before creating or changing the 2D Phaser architecture, scenes, game objects, state, input, physics, camera, animation, audio, asset loading, lifecycle behavior, scaling, persistence, performance, tests, or build configuration. Also read it when diagnosing a 2D runtime defect.
|
||||
- Read [the Web 3D standards](references/web3d-standards.md) before creating or changing the 3D Three.js renderer, scene graph, camera, controls, model loading, materials, animation, disposal, resize behavior, performance, tests, or build configuration. Also read it when diagnosing a 3D runtime defect.
|
||||
- Read the selected engine reference together with the design standards when a playable result combines design decisions and implementation.
|
||||
- For a new game or an engine/mode change, create or update `TECH_STACK.md` with the selected rendering mode, exact engine version, browser target, asset formats, and verification plan before implementation.
|
||||
- Copy and adapt [the GDD template](assets/GDD.template.md) for a new game, a design deliverable, or ongoing development that lacks an equivalent design document. For an isolated fix with clear intent, use a concise defect note instead of creating a full GDD.
|
||||
- Copy and adapt [the task template](assets/TASKS.template.md) when ongoing implementation, release, or handoff work needs an active queue and the project lacks an equivalent tracker. Do not create it for a standalone design deliverable or isolated fix when no continuation state is useful.
|
||||
|
||||
Preserve an established equivalent document instead of creating duplicates. Draft the needed content for the user; do not hand a beginner a blank template as a questionnaire. Never edit the bundled templates while working on a game.
|
||||
|
||||
When present, use the project's GDD and task tracker as the canonical project memory. Do not create parallel planning, findings, progress, devlog, or handoff files unless the user, repository, or host environment explicitly requires them. When such files are mandatory, keep them brief and point back to the canonical document instead of duplicating design decisions, acceptance checks, or status.
|
||||
|
||||
## Detect the working mode
|
||||
|
||||
Inspect the request and project before proposing work. Confirm the rendering mode and engine from `GDD.md`, `TECH_STACK.md`, dependency metadata, imports, or runtime code. Use Phaser 3.90.0 for 2D and Three.js for an explicitly selected 3D path; do not silently migrate another engine or major version.
|
||||
|
||||
Choose the dominant mode:
|
||||
|
||||
- **Concept/new:** start from an idea, an empty directory, or no runnable game.
|
||||
- **Existing/build:** extend, change, refactor, balance, or polish a runnable Phaser 3 or Three.js project.
|
||||
- **Bug:** reproduce and repair behavior that conflicts with the intended or established design.
|
||||
- **Resume:** continue from an active task, partial implementation, handoff, or interrupted session.
|
||||
|
||||
State the detected mode and current stage briefly. If evidence conflicts, resolve it by inspecting the project before asking the user.
|
||||
|
||||
Ask at most three high-impact questions in one decision round. Include a recommended default when useful. Infer reversible details from context and record the assumption; pause only when alternatives would materially change the game, scope, or existing user work. Translate game-development jargon into concrete player outcomes for non-expert users.
|
||||
|
||||
## Use four adaptive stages
|
||||
|
||||
Treat stages as risk lenses, not approval gates. Enter the stage that matches the current goal; do not force an existing feature or isolated bug through earlier stages.
|
||||
|
||||
### Concept
|
||||
|
||||
Define the smallest coherent game promise. Establish the player fantasy, audience and platform, session shape, design pillars, player verbs, core loop, win/loss or outcome flow, scope boundary, and riskiest unproven assumption. Seed the GDD only as far as needed to make the next prototype falsifiable.
|
||||
|
||||
Exit with one explicit prototype question and a playable acceptance target.
|
||||
|
||||
### Prototype
|
||||
|
||||
Build the cheapest playable test of the highest design or technical risk. Prefer placeholder assets, exposed tuning values, and a complete micro-loop over production architecture or content volume. Test whether the intended choice, challenge, control, or feedback is legible and satisfying.
|
||||
|
||||
Exit by deciding to keep, revise, or discard the tested assumption, and update the GDD with evidence.
|
||||
|
||||
### Build
|
||||
|
||||
Deliver vertical slices that cross input, rules, state, feedback, and outcome. Keep the game runnable after each slice. Add only the architecture and content needed by the current result, while preserving extension points supported by near-term evidence.
|
||||
|
||||
Exit each slice with verified acceptance checks, synchronized applicable documents, and exactly one recommended next result.
|
||||
|
||||
### Ship
|
||||
|
||||
Stabilize the complete intended loop. Prioritize blockers, clarity, feel, accessibility, performance, device/browser behavior, asset and save integrity, release configuration, and regression coverage. Freeze optional scope before adding polish.
|
||||
|
||||
Exit only with a reproducible production build and recorded playthrough evidence.
|
||||
|
||||
## Use the shared project workspace
|
||||
|
||||
Treat the project directory as the durable context shared by every Agent. At the start of work, inspect relevant existing design, task, asset, code, test, release, knowledge, and status artifacts. At the end, leave concrete progress, assumptions, evidence, risks, and recommended next work in the artifacts owned by the current Agent's system prompt.
|
||||
|
||||
This Skill does not assign role ownership or mandate filenames. The Agent system prompt is the sole authority for which artifacts the Agent reads and maintains. Do not create duplicate process documents when the project already has an equivalent source of truth.
|
||||
|
||||
Chat summaries and cross-session messages are not substitutes for project files. Do not depend on automatic dispatch. A downstream Agent should be able to reconstruct the current state by reading the project workspace.
|
||||
|
||||
Missing upstream artifacts are not approval gates. Inspect the project facts, proceed with the smallest safe and reversible assumption when possible, and record that assumption in the current Agent's owned artifact. Ask the user only when the missing decision would materially change the result or overwrite existing work.
|
||||
|
||||
## Keep version context synchronized
|
||||
|
||||
When the project has `VERSION.md` and `TASKS.md`, read both before working. Treat `VERSION.md` as the authoritative current project version and `TASKS.md` as the shared current-version work index maintained by every Agent.
|
||||
|
||||
Update only tasks related to the current work: owner, status, observable acceptance, evidence summary, blockers, source artifact, and next action. Keep specialized design, asset, engineering, test, and release facts in the Agent-owned artifacts named by its system prompt; link or summarize them from `TASKS.md` instead of duplicating them.
|
||||
|
||||
When updating a role-owned Markdown artifact, synchronize its `Project Version`, increment its `Document Revision` for a material edit, and set `Last Updated By` to the current stable Agent id. Do not change the project version unless the Agent system prompt or the user grants version-owner authority. Otherwise record a PATCH, MINOR, or MAJOR proposal in `TASKS.md` with reason and affected artifacts.
|
||||
|
||||
Keep root artifacts focused on the current version. Historical versions belong in incremental `docs/versions/<version>/` snapshots with `VERSION_SUMMARY.md`; do not copy unchanged artifacts merely to make an archive look complete. Archived artifacts are read-only except for explicit errata.
|
||||
|
||||
## Check design readiness
|
||||
|
||||
Before editing runtime code, confirm that the current result answers:
|
||||
|
||||
1. What should the player perceive, decide, or accomplish?
|
||||
2. What inputs, states, rules, outcomes, and feedback produce that experience?
|
||||
3. What observable evidence will show that the result works and feels understandable?
|
||||
|
||||
For a small defect, use a reproducible failure, expected behavior, and regression check instead of expanding a full system specification. If a missing design decision would change implementation materially, resolve it in the current Agent's owned project artifact first. Otherwise proceed with the smallest reversible assumption and record it.
|
||||
|
||||
## Honor the requested depth
|
||||
|
||||
Stop at design when the user asks only for ideation, GDD work, system design, balancing analysis, playtest planning, or design review. Do not scaffold or change runtime code merely because implementation could follow.
|
||||
|
||||
Complete design-only work when the affected design artifact is coherent, contradictions and assumptions are explicit, the next risky question is testable, and any proposed implementation has observable acceptance checks. Recommend one next step without starting it. Enter the playable-result loop only when the user requests implementation, repair, runtime verification, or release work.
|
||||
|
||||
## Execute one playable-result loop
|
||||
|
||||
Repeat this loop for only the current result:
|
||||
|
||||
1. **Inspect:** read project instructions, dependency metadata, structure, existing design/task documents, relevant code, available checks, and current uncommitted work. Preserve established patterns and unrelated changes.
|
||||
2. **Frame:** state the player-visible result, linked design intent, one to three acceptance checks, primary risk, and smallest vertical slice.
|
||||
3. **Prepare context:** update only the current Agent's role-owned artifact needed to remove ambiguity and preserve the result for other Agents.
|
||||
4. **Implement:** make the smallest coherent change that completes the slice. Keep tunable design values discoverable and avoid speculative frameworks.
|
||||
5. **Check mechanically:** run the project's applicable static checks, tests, and production build. Fix new failures caused by the change.
|
||||
6. **Play in a real browser:** launch the actual game and exercise the affected path. Do not infer playability from compilation, unit tests, or screenshots alone.
|
||||
7. **Observe:** inspect visible behavior, controls, scene/state transitions, feedback timing, layout and scaling, console errors, and relevant edge cases. Capture concrete evidence.
|
||||
8. **Iterate:** repair the highest-impact gap and repeat implementation and verification until acceptance checks pass or a genuine blocker remains.
|
||||
9. **Reconcile:** update the current Agent's owned project artifacts with confirmed changes and findings; close or rescope tracked work when one exists; leave one recommended next playable result.
|
||||
|
||||
For the core loop, verify an appropriate version of **start -> act -> receive feedback -> reach an outcome -> restart or continue**. For a defect, reproduce before the fix when practical and prove the same path after it.
|
||||
|
||||
Never claim a result is complete when browser playtesting was unavailable. Record it as implemented but unverified, state why, and provide exact manual verification steps.
|
||||
|
||||
## Require completion evidence
|
||||
|
||||
Mark a playable result complete only when all applicable evidence exists:
|
||||
|
||||
- each acceptance check has an observed pass;
|
||||
- the affected gameplay path has been exercised in an actual browser;
|
||||
- applicable automated checks and the production build pass;
|
||||
- no new relevant runtime or console errors remain;
|
||||
- affected input, resize, pause/resume, restart, and scene transitions behave correctly;
|
||||
- applicable role-owned project artifacts match the implemented behavior;
|
||||
- known limitations and unverified environments are explicit.
|
||||
|
||||
Report completion with: the playable result, material design decisions, changed areas, verification evidence, remaining risks, and one recommended next result. Distinguish observed facts from assumptions.
|
||||
|
||||
## Recover interrupted work
|
||||
|
||||
When resuming, inspect the relevant role-owned artifacts plus project status, uncommitted changes, recent verification output, and runnable behavior before editing. Reconstruct the last confirmed checkpoint and continue from the first unmet acceptance check. Do not repeat completed work, overwrite unexplained changes, or trust stale status over runtime evidence.
|
||||
|
||||
If code and project artifacts disagree, preserve user work, establish what currently runs, identify the smallest discrepancy, and reconcile the current Agent's owned artifacts as part of the next verified result. If safe continuation is impossible, stop with the concrete blocker, evidence already gathered, and the smallest decision needed from the user.
|
||||
197
.opencode/skills/nianxxgame-skill/assets/GDD.template.md
Normal file
197
.opencode/skills/nianxxgame-skill/assets/GDD.template.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# [Game Title] — Living GDD
|
||||
|
||||
Project Version: v0.1.0
|
||||
Document Revision: 1
|
||||
Last Updated By: game-design
|
||||
|
||||
> Keep this document current and testable. The agent drafts it from the user's brief; do not ask the user to fill blanks. For a first concept pass, complete Status, the core prompts in Sections 1–4, the `Must`/`Not in this release` boundary in Section 6, and the top risk/current experiment in Section 7. Delete unused placeholder rows. Add active system specifications in Section 5 and evidence records in Section 8 only as the next prototype needs them, then replace hypotheses with evidence.
|
||||
|
||||
## Status
|
||||
|
||||
- **Stage:** Concept / Prototype / Build / Ship
|
||||
- **Current build:** [path, URL, tag, or commit]
|
||||
- **Last updated:** YYYY-MM-DD
|
||||
- **Largest current risk:** [one testable question]
|
||||
- **Decision labels:** Hypothesis / Tested / Committed
|
||||
|
||||
## 1. Game promise
|
||||
|
||||
- **One-sentence game:** [Player + core action + pressure/goal + distinctive result]
|
||||
- **Player fantasy:** [Who the player feels like and what feeling to protect]
|
||||
- **Target player:** [Relevant experience, interests, and accessibility needs]
|
||||
- **Platform and input:** [Browser/device plus keyboard, pointer, touch, or gamepad]
|
||||
- **Rendering mode:** [2D by default / 3D only when the user explicitly chooses it]
|
||||
- **Engine:** [Phaser 3.90.0 for 2D / Three.js + TypeScript for 3D, with exact dependency version in TECH_STACK.md]
|
||||
- **Typical session:** [Duration and natural stopping point]
|
||||
- **Desired feeling arc:** [Start → tension/growth → result]
|
||||
- **Hard constraints:** [Schedule, team, technology, content, or release limits]
|
||||
|
||||
## 2. Pillars and boundaries
|
||||
|
||||
| Pillar | Observable player promise | Trade-off it wins |
|
||||
|---|---|---|
|
||||
| [Pillar 1] | [What the player perceives or does] | [What to prefer when ideas conflict] |
|
||||
| [Pillar 2] | [What the player perceives or does] | [What to prefer when ideas conflict] |
|
||||
| [Optional pillar 3] | [Promise] | [Trade-off] |
|
||||
|
||||
### Non-goals for this release
|
||||
|
||||
- [Explicitly excluded feature, audience, mode, or production burden]
|
||||
- [Second exclusion]
|
||||
- [Optional third exclusion]
|
||||
|
||||
## 3. Experience chain and core loop
|
||||
|
||||
| Fantasy | Player verbs | Mechanics | Rules/pressure | Feedback | Reason to repeat |
|
||||
|---|---|---|---|---|---|
|
||||
| [Experience] | [3–6 verbs] | [Systems] | [Limits and consequences] | [How results are perceived] | [Mastery, variation, reward, or new goal] |
|
||||
|
||||
### Core loop
|
||||
|
||||
1. [Receive or choose a goal.]
|
||||
2. [Read the situation and decide.]
|
||||
3. [Perform the core verb.]
|
||||
4. [Receive a clear consequence.]
|
||||
5. [Retry, advance, or choose the next goal.]
|
||||
|
||||
### State flow
|
||||
|
||||
`Launch → Start → Play → Pause/Resume → Outcome → Retry/Continue`
|
||||
|
||||
- **Start condition:** [How play begins]
|
||||
- **Success/outcome condition:** [Observable rule]
|
||||
- **Failure/end condition:** [Observable rule]
|
||||
- **Retry/continue:** [What resets, what persists, and retry friction]
|
||||
|
||||
## 4. Player model
|
||||
|
||||
### Controls and feedback
|
||||
|
||||
| Input/context | Verb | Availability | Immediate response | Accessible alternative |
|
||||
|---|---|---|---|---|
|
||||
| [Input] | [Action] | [When legal] | [Control/visual/audio response] | [Remap, toggle, assist, or N/A with reason] |
|
||||
|
||||
### Rules the player must understand
|
||||
|
||||
1. [Rule or invariant in player language]
|
||||
2. [Rule or invariant in player language]
|
||||
3. [Rule or invariant in player language]
|
||||
|
||||
### Essential information
|
||||
|
||||
| Player question | How the game answers | Fallback cue |
|
||||
|---|---|---|
|
||||
| What is my goal? | [World/UI/audio cue] | [Persistent or repeatable cue] |
|
||||
| What can I act on? | [Affordance and state cue] | [Redundant cue] |
|
||||
| What changed and why? | [Cause/effect feedback] | [Result/failure explanation] |
|
||||
| What can I do next? | [Prompt, layout, or state] | [Recovery route] |
|
||||
|
||||
### Presentation baseline
|
||||
|
||||
- **Camera:** [Fixed/following; framing, bounds, movement, shake, and comfort limits]
|
||||
- **3D presentation when applicable:** [Scene, world-up, units, model format, lighting, camera controls, loading fallback, and performance target]
|
||||
- **UI:** [Persistent information, overlays, safe areas, and hierarchy]
|
||||
- **Feel and feedback:** [Timing, motion, audio, effects, and restraint]
|
||||
- **Accessibility:** [Remapping, alternatives, reduced motion, contrast, text, and audio controls]
|
||||
|
||||
## 5. Active system specifications
|
||||
|
||||
> Copy this block only when a system enters active work. Keep its stable `SYS-###` ID. Tracked tasks must reference the ID or exact heading.
|
||||
|
||||
### SYS-001 — [System name]
|
||||
|
||||
- **Status:** Hypothesis / Tested / Committed
|
||||
- **Player purpose and pillar:** [Why it exists]
|
||||
- **Decision or expression:** [Meaningful choice or skill]
|
||||
- **Inputs and preconditions:** [Trigger and legal context]
|
||||
- **Owned/read state:** [State and source of truth]
|
||||
- **Outputs/events:** [State changes and external signals]
|
||||
- **Dependencies:** [Systems, assets, content, or platform assumptions]
|
||||
|
||||
#### Rules and transitions
|
||||
|
||||
1. [Availability/start rule]
|
||||
2. [Active behavior, priority, or formula]
|
||||
3. [Resolve, interrupt, and recovery rule]
|
||||
|
||||
`available → started → active → resolved/interrupted → recovered`
|
||||
|
||||
#### Feedback and fairness
|
||||
|
||||
| Event/state | Immediate confirmation | Consequence | Recovery/next action | Redundant cue |
|
||||
|---|---|---|---|---|
|
||||
| [Event] | [Response] | [Visible result] | [What follows] | [Non-audio/non-color cue] |
|
||||
|
||||
#### Tunables
|
||||
|
||||
| Name | Unit | Default hypothesis | Safe test range | Intended player effect |
|
||||
|---|---|---:|---:|---|
|
||||
| [Meaningful name] | [s, px/s, count, %] | [value] | [low–high] | [Effect] |
|
||||
|
||||
#### Edge cases
|
||||
|
||||
- [Repeated/simultaneous input]
|
||||
- [Interrupt, scene/state change, or limit]
|
||||
- [Cleanup and player recovery]
|
||||
|
||||
#### Delivery contract
|
||||
|
||||
- **Acceptance criteria — maximum 3:**
|
||||
- [ ] [Observable player-facing condition]
|
||||
- [ ] [Critical rule or edge condition]
|
||||
- [ ] [Feedback/recovery condition]
|
||||
- **Non-goals — maximum 3:** [Excluded behavior for this version]
|
||||
- **Primary playtest question:** [One uncertainty this implementation must answer]
|
||||
|
||||
## 6. MVP and release boundary
|
||||
|
||||
### Must
|
||||
|
||||
- [Complete start → play → result → retry/continue loop]
|
||||
- [Core system/content requirement]
|
||||
- [Required feedback, UX, accessibility, or delivery condition]
|
||||
|
||||
### Later, after evidence
|
||||
|
||||
- [Extension and the evidence that would justify it]
|
||||
- [Extension and trigger]
|
||||
|
||||
### Not in this release
|
||||
|
||||
- [Explicit exclusion]
|
||||
- [Explicit exclusion]
|
||||
|
||||
### Quality boundary
|
||||
|
||||
- **Target environment:** [Device/browser/display/input]
|
||||
- **Performance target:** [Frame rate, load time, or supported floor]
|
||||
- **Save/data expectation:** [Persistence and compatibility]
|
||||
|
||||
## 7. Risks and playtests
|
||||
|
||||
| Priority | Risk as a question | Cheapest valid test | Pass/change signal | Status/evidence |
|
||||
|---:|---|---|---|---|
|
||||
| 1 | [Largest uncertainty] | [Prototype/playtest] | [Observed behavior] | [Planned/Keep/Change/Inconclusive + link] |
|
||||
| 2 | [Next uncertainty] | [Test] | [Signal] | [Status] |
|
||||
|
||||
### Current experiment
|
||||
|
||||
- **Question:** [One question]
|
||||
- **Build:** [Included and deliberately omitted]
|
||||
- **Observe:** [Behavior/result, not only opinion]
|
||||
- **Decision:** Keep / Change / Inconclusive
|
||||
- **Next action:** [One concrete follow-up]
|
||||
|
||||
## 8. Evidence and decisions
|
||||
|
||||
### Tuning
|
||||
|
||||
| Variable | System | Current value | Target effect | Last evidence | Next test |
|
||||
|---|---|---:|---|---|---|
|
||||
| [Name] | [SYS-###] | [Value + unit] | [Player outcome] | [Build/test/date] | [Change/control] |
|
||||
|
||||
### Playtests and design changes
|
||||
|
||||
| Date/build | Question or trigger | Observed evidence | Decision | Affected sections/tasks |
|
||||
|---|---|---|---|---|
|
||||
| [Date/build] | [Question, constraint, defect] | [What happened] | [Keep/change and why] | [Headings, SYS IDs, TASK IDs] |
|
||||
67
.opencode/skills/nianxxgame-skill/assets/TASKS.template.md
Normal file
67
.opencode/skills/nianxxgame-skill/assets/TASKS.template.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# [Game Title] — Tasks
|
||||
|
||||
Project Version: v0.1.0
|
||||
Document Revision: 1
|
||||
Last Updated By: <stable-agent-id>
|
||||
|
||||
> Every Agent reads and maintains this current-version task context. Keep specialized facts in role-owned artifacts and link them here. Record owner, status, acceptance, evidence, blockers, version proposals, and next action.
|
||||
|
||||
## Now
|
||||
|
||||
### TASK-001 — [Player-visible outcome]
|
||||
|
||||
- **Design source:** [§ exact GDD heading, SYS-###, or concise defect note]
|
||||
- **Why now:** [Risk reduced, loop completed, or evidence needed]
|
||||
- **Playable slice:** [Start condition → player action → feedback/result → retry/continue]
|
||||
|
||||
#### Acceptance criteria — 1 to 3
|
||||
|
||||
- [ ] [Observable behavior in the target play environment]
|
||||
- [ ] [Critical rule, failure, or edge case]
|
||||
- [ ] [Feedback, recovery, or complete-loop condition]
|
||||
|
||||
#### Non-goals — maximum 3
|
||||
|
||||
- [Behavior, content, or polish explicitly outside this task]
|
||||
- [Optional exclusion]
|
||||
- [Optional exclusion]
|
||||
|
||||
#### Completion evidence — 1 to 3
|
||||
|
||||
- [ ] [Build/test command and result]
|
||||
- [ ] [Playtest path and observed result]
|
||||
- [ ] [Optional screenshot, recording, log, or URL]
|
||||
|
||||
## Next — maximum 3
|
||||
|
||||
1. **TASK-002 — [Player-visible outcome]** — Design: [§ heading/SYS-###/defect note] — [Why it follows]
|
||||
2. **TASK-003 — [Player-visible outcome]** — Design: [§ heading/SYS-###/defect note] — [Why it follows]
|
||||
3. **TASK-004 — [Player-visible outcome]** — Design: [§ heading/SYS-###/defect note] — [Why it follows]
|
||||
|
||||
## Blocked
|
||||
|
||||
| Task | Design reference | Blocker | Evidence already gathered | Unblock condition/owner |
|
||||
|---|---|---|---|---|
|
||||
| [TASK-### — outcome] | [§ heading/SYS-###] | [Specific missing input or dependency] | [Link/result] | [Concrete condition and responsible person if known] |
|
||||
|
||||
## Version Proposals
|
||||
|
||||
| Proposed version | Level | Proposed by | Reason | Affected artifacts | Status |
|
||||
|---|---|---|---|---|---|
|
||||
| [v0.2.0] | [PATCH/MINOR/MAJOR] | [stable-agent-id] | [Why a new version is needed] | [Files/areas] | proposed |
|
||||
|
||||
## Last verified
|
||||
|
||||
- **Date/build:** [YYYY-MM-DD + URL/tag/commit]
|
||||
- **Environment:** [Device, browser/runtime, display, and input]
|
||||
- **Verified path:** [Start → core action → result → retry/continue]
|
||||
- **Checks passed:** [Build/runtime/console/playtest results]
|
||||
- **Known issue:** [Most important remaining issue, or “None known”]
|
||||
|
||||
## Promotion rule
|
||||
|
||||
When `Now` is complete:
|
||||
|
||||
1. Record up to three pieces of completion evidence and update `Last verified`.
|
||||
2. Propagate any design discovery to the applicable GDD section or defect note before closing the task.
|
||||
3. Promote at most one `Next` task that attacks the largest current risk or closes the most important playable loop. If none is justified, leave `Now` explicitly empty.
|
||||
@@ -0,0 +1,278 @@
|
||||
# Practical Game Design Standards
|
||||
|
||||
Use this reference to turn a game idea into decisions that can be implemented and tested. Treat the GDD as a living agreement about player experience, not as a pitch deck or a complete prediction of the final game.
|
||||
|
||||
## Contents
|
||||
|
||||
1. [Build a traceable design chain](#1-build-a-traceable-design-chain)
|
||||
2. [Set pillars and non-goals](#2-set-pillars-and-non-goals)
|
||||
3. [Specify systems before building them](#3-specify-systems-before-building-them)
|
||||
4. [Protect feel, readability, and fairness](#4-protect-feel-readability-and-fairness)
|
||||
5. [Balance with explicit targets](#5-balance-with-explicit-targets)
|
||||
6. [Plan progression and content](#6-plan-progression-and-content)
|
||||
7. [Design UX and accessibility with the game](#7-design-ux-and-accessibility-with-the-game)
|
||||
8. [Control scope, risk, and playtesting](#8-control-scope-risk-and-playtesting)
|
||||
9. [Review designs and propagate changes](#9-review-designs-and-propagate-changes)
|
||||
|
||||
## 1. Build a traceable design chain
|
||||
|
||||
Connect every important feature through this chain:
|
||||
|
||||
**Fantasy → Verbs → Mechanics → Rules → Feedback → Loop**
|
||||
|
||||
| Link | Question to answer | Useful output |
|
||||
|---|---|---|
|
||||
| Fantasy | Who is the player, and what should it feel like to be them? | One concrete experience statement |
|
||||
| Verbs | What meaningful actions express that fantasy? | A short list of player verbs |
|
||||
| Mechanics | What systems make those actions possible? | State, interactions, resources, and relationships |
|
||||
| Rules | What creates decisions, limits, risk, and consequences? | Preconditions, transitions, formulas, and invariants |
|
||||
| Feedback | How does the player perceive action, state, and consequence? | Visual, audio, motion, UI, and control response |
|
||||
| Loop | Why does the player repeat the actions with new decisions? | A closed sequence from goal to result to next goal |
|
||||
|
||||
Write the chain in player language before implementation language. For example:
|
||||
|
||||
> Feel like a nimble rooftop courier → run, jump, route, recover → momentum and traversal systems → speed trades off against safe landings → immediate motion and landing feedback → choose route, traverse, deliver, improve, retry.
|
||||
|
||||
Check traceability in both directions:
|
||||
|
||||
- Remove or defer a mechanic that supports no intended verb or pillar.
|
||||
- Add rules or feedback when a promised verb has no meaningful decision or readable result.
|
||||
- Repair any loop that has no clear goal, result, or reason to repeat.
|
||||
- Distinguish a core loop from a list of activities. A loop changes state and creates the next decision.
|
||||
|
||||
Avoid starting with content volume, feature names, or technology. First prove that the smallest version of the chain is enjoyable and understandable.
|
||||
|
||||
## 2. Set pillars and non-goals
|
||||
|
||||
Define two to four design pillars. Make each pillar a decision rule, not a slogan.
|
||||
|
||||
A useful pillar contains:
|
||||
|
||||
- The experience to protect.
|
||||
- An observable implication for rules, presentation, or content.
|
||||
- A trade-off it wins when two good ideas conflict.
|
||||
|
||||
Weak: “Fast and fun.”
|
||||
|
||||
Stronger: “Keep decisions fast: the player can read the next threat and act without opening a menu.”
|
||||
|
||||
Write explicit non-goals beside the pillars. Non-goals prevent accidental expansion and make trade-offs honest. Examples include “no long-term crafting economy,” “no competitive balance,” or “no precision platforming on touch input.” Do not describe quality failures as non-goals.
|
||||
|
||||
Use the following filter for every proposed feature:
|
||||
|
||||
1. Name the pillar or required player outcome it supports.
|
||||
2. State what new decision or expression it creates.
|
||||
3. State its implementation, content, UX, and testing cost.
|
||||
4. Cut or defer it if the benefit cannot justify the cost inside the current milestone.
|
||||
|
||||
## 3. Specify systems before building them
|
||||
|
||||
Give each scheduled system a stable ID such as `SYS-001`. Keep the specification short enough to review, but precise enough that two implementers would produce the same player-facing behavior.
|
||||
|
||||
Include these fields:
|
||||
|
||||
| Field | Required decision |
|
||||
|---|---|
|
||||
| Purpose | Player need and pillar supported |
|
||||
| Player decision | Choice, skill, or expression created |
|
||||
| Inputs and preconditions | What starts the system and when it is legal |
|
||||
| State | Data the system owns or reads |
|
||||
| Rules and transitions | Ordered behavior, formulas, priority, and invariants |
|
||||
| Outputs | State changes and events visible to other systems |
|
||||
| Feedback | How success, failure, availability, and cause are communicated |
|
||||
| Tunables | Named values, units, defaults, safe ranges, and intended effect |
|
||||
| Edge cases | Interruptions, simultaneous events, limits, and recovery behavior |
|
||||
| Dependencies | Systems, content, assets, and platform assumptions |
|
||||
| Non-goals | Behavior explicitly outside this version |
|
||||
| Acceptance | Up to three observable conditions for completion |
|
||||
| Playtest question | The most uncertain player-facing assumption |
|
||||
|
||||
Prefer state transitions over vague prose. For any action, define at least:
|
||||
|
||||
`available → started → active → resolved or interrupted → recovered`
|
||||
|
||||
Specify conflict rules where events can overlap. Define which event wins, whether inputs buffer, which state owns cleanup, and how the player recovers. Avoid hidden special cases; if an exception is necessary, record why it exists.
|
||||
|
||||
Keep tunable values outside scattered behavior code where practical. Name values by their design meaning rather than by their current number.
|
||||
|
||||
A system is ready to build when its purpose, normal path, failure path, feedback, major edge cases, and acceptance conditions are known. Unknown numeric values are acceptable when they are marked as tuning hypotheses with test ranges.
|
||||
|
||||
## 4. Protect feel, readability, and fairness
|
||||
|
||||
### Game feel
|
||||
|
||||
Make the control response fit the promised fantasy. For each core verb, examine:
|
||||
|
||||
- Input recognition and input-to-visible-response delay.
|
||||
- Start, active, contact, recovery, and cancellation phases.
|
||||
- Acceleration, deceleration, momentum, hit-stop, shake, animation, and sound.
|
||||
- Input buffering, forgiveness windows, aim assistance, or snapping where appropriate.
|
||||
- Whether feedback reinforces the true rule instead of disguising it.
|
||||
|
||||
Layer feedback by purpose:
|
||||
|
||||
1. Confirm the input or state change immediately.
|
||||
2. Show the world consequence at the point of interaction.
|
||||
3. Reinforce importance with secondary motion, audio, particles, or UI.
|
||||
|
||||
Do not let animation delay a supposedly immediate action unless anticipation is itself part of the challenge. Add intensity only after the action is mechanically legible.
|
||||
|
||||
### Readability
|
||||
|
||||
Ensure the player can answer these questions during play:
|
||||
|
||||
- What can I act on now?
|
||||
- What is dangerous, helpful, or unavailable?
|
||||
- What changed, and what caused it?
|
||||
- What is my current goal and progress?
|
||||
- What can I do after a failure?
|
||||
|
||||
Use hierarchy, contrast, shape, timing, position, motion, and sound consistently. Never rely on color, sound, small text, or brief animation alone for critical information. Test the game at the actual play size and under the busiest expected state, not only in isolated scenes.
|
||||
|
||||
### Fairness
|
||||
|
||||
Make outcomes explainable even when the game is difficult:
|
||||
|
||||
- Telegraph threats early enough for the intended skill level and input method.
|
||||
- Keep cause and effect consistent across similar situations.
|
||||
- Avoid unavoidable damage, hidden rule changes, and punishment from unreadable off-screen events.
|
||||
- Provide recovery, mitigation, or a deliberate commitment trade-off.
|
||||
- Distinguish execution difficulty from missing information.
|
||||
- On failure, communicate the cause and make retry friction proportional to the lesson.
|
||||
|
||||
Fair does not mean easy. It means the player can form a correct model, make a meaningful choice, and understand the result.
|
||||
|
||||
## 5. Balance with explicit targets
|
||||
|
||||
Define the experience target before changing numbers. Examples include desired encounter duration, number of mistakes allowed, time between meaningful choices, resource pressure, or frequency of a signature action.
|
||||
|
||||
For every important tuning value, record:
|
||||
|
||||
- Name, unit, default, and allowed range.
|
||||
- Player-facing purpose.
|
||||
- Systems and content affected.
|
||||
- Evidence for the current value.
|
||||
|
||||
Balance in controlled passes:
|
||||
|
||||
1. Establish a simple baseline case.
|
||||
2. Test low, expected, and high-skill or high-power cases.
|
||||
3. Change one variable or one tightly coupled group at a time.
|
||||
4. Record the observed effect, not only the new value.
|
||||
5. Retest earlier cases after changing shared values.
|
||||
|
||||
Watch for dominant strategies, dead choices, positive feedback that removes recovery, resource sources without meaningful sinks, and upgrades that erase core decisions. Prefer trade-offs and new options over upgrades that only increase every number.
|
||||
|
||||
Use formulas as inspectable models, not as proof of fun. Validate them through play. If a value has no plausible range or target effect, the design question is still unresolved.
|
||||
|
||||
## 6. Plan progression and content
|
||||
|
||||
Make progression change what the player understands, chooses, or can express. Numerical growth may support progression, but should not be its only form.
|
||||
|
||||
Introduce mechanics with this sequence when practical:
|
||||
|
||||
**Teach → Test → Twist → Combine → Master**
|
||||
|
||||
- Teach one idea in a low-cost situation.
|
||||
- Test whether the player can use it intentionally.
|
||||
- Twist one assumption without changing all rules at once.
|
||||
- Combine it with a previously understood idea.
|
||||
- Offer mastery through efficiency, risk, expression, or optional challenge.
|
||||
|
||||
Plan content as a matrix of reusable variables rather than a list of isolated levels. Useful axes include space, timing, enemy role, objective, constraint, reward, and modifier. Recombine proven elements before creating new systems.
|
||||
|
||||
For economies, list every source, sink, cap, conversion, and reset. State why the resource exists and what decision scarcity creates. Avoid currencies that merely add steps between the player and an obvious purchase.
|
||||
|
||||
Set explicit content budgets for the current milestone: number of stages, enemy roles, upgrades, tutorials, audiovisual sets, and supported modes. Do not produce full content before the core loop, authoring pipeline, and representative content slice are validated.
|
||||
|
||||
## 7. Design UX and accessibility with the game
|
||||
|
||||
Treat menus, onboarding, pause, failure, restart, and settings as part of the playable loop.
|
||||
|
||||
Define the complete state path:
|
||||
|
||||
`launch → start → learn → play → pause/resume → result → retry or continue`
|
||||
|
||||
Keep the current goal and available actions clear. Teach through a safe action and immediate consequence where possible; use text to clarify, not to replace interaction. Do not require the player to remember information that can remain visible or be reviewed.
|
||||
|
||||
Establish an accessibility baseline at the start:
|
||||
|
||||
- Support the target input methods and make essential controls remappable where feasible.
|
||||
- Provide alternatives for hold, rapid repeat, precise timing, and simultaneous inputs when those are not core challenges.
|
||||
- Keep text readable at the target display size and allow scaling when the interface needs it.
|
||||
- Do not encode critical state with color or audio alone; support captions or visual equivalents.
|
||||
- Offer control over music, effects, motion, shake, flashes, and other intense presentation as relevant.
|
||||
- Preserve settings and avoid erasing progress without confirmation.
|
||||
- Make focus, selection, disabled state, and navigation order unambiguous.
|
||||
|
||||
Test accessibility options in real play. An option that breaks feedback, layout, timing, or progression is not complete.
|
||||
|
||||
## 8. Control scope, risk, and playtesting
|
||||
|
||||
### Scope around a closed loop
|
||||
|
||||
Build the smallest slice that lets a player start, perform the core verbs, receive a meaningful result, and retry or continue. A slice is not complete when it contains many systems but no full player journey.
|
||||
|
||||
Separate scope into:
|
||||
|
||||
- **Must:** required to test the current design claim.
|
||||
- **Later:** valuable after the claim is validated.
|
||||
- **Not now:** explicitly excluded from the milestone.
|
||||
|
||||
Count content and polish work, not only code. Every mechanic creates costs in UI, feedback, audio, content, onboarding, accessibility, balance, testing, and maintenance.
|
||||
|
||||
### Attack the largest uncertainty
|
||||
|
||||
Track risks as testable questions. Consider:
|
||||
|
||||
- Desirability: is the loop appealing enough to repeat?
|
||||
- Comprehension: can the player form the intended model?
|
||||
- Usability: can the player perform the verbs reliably?
|
||||
- Feasibility: can the system meet technical and production constraints?
|
||||
- Content: can enough varied play be produced at an affordable rate?
|
||||
- Balance: do intended choices remain viable across progression?
|
||||
|
||||
Prioritize high-uncertainty, high-impact risks. Build a prototype to answer one major question, not to resemble a finished game. Use disposable presentation when polished assets would not change the answer.
|
||||
|
||||
### Run evidence-seeking playtests
|
||||
|
||||
For each test:
|
||||
|
||||
1. Write one primary question and the behavior that would answer it.
|
||||
2. Use a build that isolates the relevant decision when possible.
|
||||
3. Let the player act without coaching; record where intervention became necessary.
|
||||
4. Capture behavior, outcome, confusion, and recovery before asking for opinions.
|
||||
5. Separate observation from interpretation.
|
||||
6. Decide `keep`, `change`, or `inconclusive`, then name the next test.
|
||||
|
||||
Do not ask only “Was it fun?” Ask what the player thought the goal was, why they made a choice, what they expected, and what caused a result. Prefer repeated behavioral evidence over a single stated preference.
|
||||
|
||||
## 9. Review designs and propagate changes
|
||||
|
||||
Review a proposed system in this order:
|
||||
|
||||
1. Trace it to fantasy, verbs, pillars, and the core loop.
|
||||
2. Check that it creates a meaningful player decision or expression.
|
||||
3. Walk through normal, failure, interrupted, and repeated use.
|
||||
4. Check feedback, readability, fairness, and accessibility.
|
||||
5. Check tuning surfaces, content burden, dependencies, and scope.
|
||||
6. Confirm acceptance conditions and the playtest question.
|
||||
|
||||
Classify discrepancies before editing:
|
||||
|
||||
- **Implementation defect:** the build disagrees with the current GDD.
|
||||
- **Design change:** evidence suggests the intended behavior should change.
|
||||
- **Documentation drift:** the build and intended design agree, but the GDD is stale.
|
||||
|
||||
For a design change, update the source GDD section first or in the same change. Then inspect and update every affected layer:
|
||||
|
||||
`core loop → system rules → shared state → controls/camera → feedback/UI/audio → onboarding/accessibility → tuning/content → acceptance tests/tasks`
|
||||
|
||||
Record consequential decisions with date, evidence, decision, and affected sections. Do not preserve a bad decision merely because it was previously documented; preserve the reason for changing it.
|
||||
|
||||
Call a design increment complete only when:
|
||||
|
||||
- The build demonstrates the intended player-facing behavior.
|
||||
- Its acceptance conditions pass in the target play environment.
|
||||
- The main uncertainty has evidence from a playtest or an explicit reason it could not yet be tested.
|
||||
- The GDD, task board, and implemented behavior agree.
|
||||
@@ -0,0 +1,306 @@
|
||||
# Phaser 3 Engineering Standards
|
||||
|
||||
Use this reference when creating, extending, or reviewing a Phaser 3 game. It defines a small, reliable default and the conditions under which that default should grow.
|
||||
|
||||
## Rule levels
|
||||
|
||||
- **Required** rules apply to all new work. In an existing project, preserve a sound established convention when changing it would be unrelated or risky; record the exception.
|
||||
- **Conditional** guidance applies only when its stated condition is true. Do not add its machinery in anticipation of possible future needs.
|
||||
|
||||
## Contents
|
||||
|
||||
- [Compatibility baseline](#compatibility-baseline)
|
||||
- [Grow-on-demand structure](#grow-on-demand-structure)
|
||||
- [Scenes and lifecycle](#scenes-and-lifecycle)
|
||||
- [Assets and loading](#assets-and-loading)
|
||||
- [Input actions](#input-actions)
|
||||
- [Physics choice and rules](#physics-choice-and-rules)
|
||||
- [Scale and responsive layout](#scale-and-responsive-layout)
|
||||
- [State ownership](#state-ownership)
|
||||
- [Time, delta, and determinism](#time-delta-and-determinism)
|
||||
- [Tuning and configuration](#tuning-and-configuration)
|
||||
- [Verification and completion](#verification-and-completion)
|
||||
- [Common failure patterns](#common-failure-patterns)
|
||||
- [Official references](#official-references)
|
||||
|
||||
## Compatibility baseline
|
||||
|
||||
### Required
|
||||
|
||||
- For a new project, declare the exact dependency `"phaser": "3.90.0"` and commit the package-manager lockfile. Do not use `latest`, `^3.90.0`, `~3.90.0`, or an unversioned install command. `latest` now resolves to Phaser 4 and can silently change the API surface.
|
||||
- Start new projects with Vite, the `vanilla-ts` template, strict TypeScript, and no UI framework. Set `compilerOptions.strict` to `true`; fix type errors instead of broadly disabling checks or spreading `any`.
|
||||
- Use ES modules and keep one obvious browser entry point that creates exactly one `Phaser.Game` instance.
|
||||
- Use the Phaser 3.90 API documentation as the authority. Official examples may target an earlier Phaser 3 release, so verify copied APIs against 3.90 and reject Phaser 2 or 4 code.
|
||||
- Keep the dependency surface small. A library must solve a present, demonstrated need and must not duplicate a Phaser facility already sufficient for the game.
|
||||
|
||||
### Conditional
|
||||
|
||||
- In an existing project, keep its working bundler, language, package manager, and framework unless migration is explicitly in scope.
|
||||
- Add React, Vue, Svelte, or another UI framework only when Phaser is embedded in an application whose non-game UI already needs it. Keep the Phaser game boundary explicit.
|
||||
- Upgrade Phaser only as a deliberate compatibility task with release-note review and a complete browser regression pass.
|
||||
|
||||
## Grow-on-demand structure
|
||||
|
||||
### Required
|
||||
|
||||
Begin with the smallest structure that gives the current game clear ownership:
|
||||
|
||||
```text
|
||||
index.html
|
||||
src/
|
||||
main.ts
|
||||
game/
|
||||
config.ts
|
||||
scenes/
|
||||
GameScene.ts
|
||||
public/
|
||||
assets/
|
||||
```
|
||||
|
||||
- `main.ts` owns game startup only; `config.ts` owns `Phaser.Types.Core.GameConfig`; Scenes own presentation and orchestration.
|
||||
- Keep a one-scene prototype in one scene file until a real boundary appears.
|
||||
- Organize new files by cohesive gameplay system or responsibility, not by generic class type alone.
|
||||
- Delete abandoned experiments and unused assets once a direction is chosen. Do not leave two active implementations of the same rule.
|
||||
- Avoid speculative architecture: no service container, event bus, ECS, repository layer, global state library, or plugin framework without a present need.
|
||||
|
||||
### Conditional
|
||||
|
||||
- Add `BootScene` when startup configuration or a tiny boot asset set must load before the main preload.
|
||||
- Add `PreloadScene` when load time is visible enough to need progress, error, or retry UI.
|
||||
- Add `MenuScene`, `ResultScene`, or overlay Scenes when they have distinct lifecycle, input, or rendering needs—not merely to shorten a file.
|
||||
- Extract `gameplay/`, `ui/`, `audio/`, `data/`, or `shared/` only after each has more than one cohesive consumer.
|
||||
- Introduce a pure domain module when rules such as scoring, progression, spawning, or combat can be expressed without Phaser objects; this is also the preferred unit-test boundary.
|
||||
|
||||
## Scenes and lifecycle
|
||||
|
||||
Phaser starts a Scene through `init` → `preload` → `create`, then calls `update(time, delta)` while it is running. A stopped Scene instance can start again; its constructor is not a per-run reset hook.
|
||||
|
||||
### Required
|
||||
|
||||
- Give every Scene one stable, unique key. Keep its constructor limited to `super(...)` and values that truly live for the entire Scene instance.
|
||||
- Reset every run-specific flag, counter, collection, and reference in `init` or `create`. A restart must behave like a fresh run.
|
||||
- Load required assets in `preload` before using them in `create`. Keep gameplay setup out of `preload`.
|
||||
- Create input handlers, colliders, timers, tweens, and subscriptions from one visible setup path. Prevent a second registration on restart.
|
||||
- Treat `shutdown` as the cleanup boundary. Remove anything not owned and cleaned by the Scene systems: `window` or `document` listeners, game/registry/external-emitter listeners, observers, intervals, network subscriptions, and retained callbacks.
|
||||
- Use `destroy` only for final Scene removal. Do not rely on it for ordinary stop, start, or restart cleanup.
|
||||
- Guard terminal transitions so collisions or consecutive update frames cannot start, stop, or restart a Scene twice.
|
||||
- Pass small typed data objects between Scenes. Never pass live Game Objects, physics bodies, cameras, or Scene plugins as shared state.
|
||||
- Make `this.scene.restart()` safe to run repeatedly. Smoke-test at least two complete restarts.
|
||||
- Guard global animation creation with `this.anims.exists(key)` or create global animations once in a dedicated startup path.
|
||||
|
||||
### Conditional
|
||||
|
||||
- When using `sleep`/`wake`, handle their events explicitly: sleep does not run shutdown, and wake does not rerun `create`.
|
||||
- When using `pause`/`resume`, decide which timers, physics, input, audio, and overlay Scenes should pause; verify the decision rather than assuming all systems share one clock.
|
||||
- Run a separate UI Scene above gameplay only when UI must retain an independent lifecycle. Define which Scene owns shared data and transition authority.
|
||||
- Stream assets during play only when level size requires it; specify loading, cancellation, cache, and failure behavior first.
|
||||
|
||||
## Assets and loading
|
||||
|
||||
### Required
|
||||
|
||||
- Give every texture, atlas, animation, audio clip, tilemap, and data file a stable semantic key. Centralize keys as typed constants; do not scatter raw string keys through gameplay code.
|
||||
- Use namespaced keys such as `player.body`, `player.run`, and `audio.hit` to avoid collisions and clarify asset type and ownership.
|
||||
- Keep filenames lowercase and portable; avoid spaces, case-only distinctions, and platform-specific path separators.
|
||||
- For Vite assets placed under `public/assets`, derive the loader base from `import.meta.env.BASE_URL`. Do not assume the game is always hosted at domain root `/`.
|
||||
- Surface load failures. A missing required asset must produce a clear error or retry state, not a silent blank canvas.
|
||||
- Load each shared asset once and reuse Phaser's global caches. Do not reload the same level-independent asset in every Scene.
|
||||
- Keep source art separate from runtime exports. Commit only optimized runtime formats and sizes the game actually uses.
|
||||
- Match spritesheet frame dimensions exactly. Verify atlas frame names, animation ranges, texture filtering, and origins in the browser.
|
||||
|
||||
### Conditional
|
||||
|
||||
- Use a texture atlas when many small sprites are displayed together or a production art pipeline already emits one.
|
||||
- Enable `pixelArt` and disable smoothing only for intentional pixel art; render at integer-friendly scales and inspect movement for shimmer.
|
||||
- Preload alternate audio formats when the supported browser matrix requires them. Start or resume audio only after a user gesture and preserve the user's mute setting.
|
||||
- Add asset manifests, generated key types, compression, or lazy loading only when asset volume makes manual management error-prone or initial load materially slow.
|
||||
|
||||
## Input actions
|
||||
|
||||
### Required
|
||||
|
||||
- Translate devices into semantic actions such as `moveLeft`, `jump`, `confirm`, `pause`, and `restart`. Gameplay rules consume actions, not scattered key codes or pointer events.
|
||||
- Distinguish held actions from edge-triggered actions. Poll `isDown` for continuous movement; use `Phaser.Input.Keyboard.JustDown`, `JustUp`, or explicit event edges for one-shot actions.
|
||||
- Keep input registration and teardown with the owning Scene. Clear latched actions on shutdown, pause, focus loss, and device disconnection.
|
||||
- Prevent browser defaults for gameplay keys such as arrows or Space when scrolling would interfere with play.
|
||||
- Convert pointer screen coordinates through the relevant camera before using them as world coordinates.
|
||||
- Ensure one physical gesture produces at most one gameplay command, even when keyboard, pointer, and UI handlers overlap.
|
||||
- Keep restart, pause, and debug controls separate from the core movement state so they cannot remain stuck.
|
||||
|
||||
### Conditional
|
||||
|
||||
- When touch is supported, provide visible touch controls or direct gestures; test multi-touch, finger occlusion, cancellation, and both target orientations.
|
||||
- When gamepads are supported, handle connect/disconnect at runtime, dead zones, axis normalization, and a keyboard fallback.
|
||||
- Add rebinding and persisted mappings when the brief or accessibility requirements call for them. Store semantic action mappings, not engine objects.
|
||||
- Use input buffering or coyote time only when the design calls for forgiving timing; keep its duration in tuning configuration.
|
||||
|
||||
## Physics choice and rules
|
||||
|
||||
Choose the least complex model that can express the game:
|
||||
|
||||
| Need | Choice |
|
||||
| --- | --- |
|
||||
| No collision or only simple range checks | Manual movement and geometry checks |
|
||||
| Fast axis-aligned or circular collision, platformer, top-down movement | Arcade Physics |
|
||||
| Rotated/compound bodies, joints, torque, stacking, physical simulation | Matter Physics |
|
||||
|
||||
### Required
|
||||
|
||||
- Default to Arcade Physics for ordinary arcade gameplay. Use Matter only when a documented mechanic needs its capabilities.
|
||||
- Use one physics system for interacting objects. Arcade and Matter bodies do not collide with each other; never attach the same Game Object to both.
|
||||
- Specify units for velocity, acceleration, gravity, dimensions, and cooldowns. Treat Arcade velocity as pixels per second; do not multiply a velocity passed to Arcade by frame delta.
|
||||
- Match physics bodies to the intended collision silhouette, not blindly to transparent texture bounds. Recheck offsets after changing scale or origin.
|
||||
- Separate collision (`collider`, with resolution) from trigger detection (`overlap`, without resolution) intentionally.
|
||||
- Make collision callbacks idempotent or guard them; physics can report contact across multiple steps.
|
||||
- Define world bounds and out-of-bounds behavior explicitly. Do not let important objects disappear forever without a recovery or terminal rule.
|
||||
- Keep physics debug rendering development-only and disable it in production builds.
|
||||
|
||||
### Conditional
|
||||
|
||||
- After moving or scaling an Arcade static body, call `refreshBody()` so its body matches its visual transform.
|
||||
- Use Arcade collision categories, body masks, immovable/pushable settings, and custom process callbacks when layers have distinct interaction rules.
|
||||
- For Matter, define body shapes, friction, restitution, mass/density, collision categories, and sleeping deliberately; test unstable stacks and high-speed tunneling.
|
||||
- Use a fixed simulation strategy or seeded replay only when determinism is a product requirement. Isolate rendering interpolation from authoritative simulation state.
|
||||
|
||||
## Scale and responsive layout
|
||||
|
||||
### Required
|
||||
|
||||
- Choose one logical game resolution and design gameplay in those world units.
|
||||
- For new fixed-composition games, default to `Phaser.Scale.FIT` with `Phaser.Scale.CENTER_BOTH`. Let CSS size the canvas container; do not derive simulation coordinates from CSS pixels.
|
||||
- Give the parent element an explicit usable size. Remove unintended page margins and prevent page scrolling around the game canvas.
|
||||
- Anchor HUD and menus to camera/viewport bounds, not world objects, unless the UI is intentionally diegetic.
|
||||
- Test the minimum and maximum supported aspect ratios. Critical play space, text, and controls must remain visible and usable.
|
||||
- Recompute responsive layout from current dimensions; do not incrementally nudge old positions on every resize event.
|
||||
- Keep camera bounds, physics bounds, and visible world bounds conceptually separate and configure each intentionally.
|
||||
|
||||
### Conditional
|
||||
|
||||
- Use `RESIZE` instead of `FIT` only when the design should reveal more or less world as the viewport changes. Listen for resize and relayout cameras, UI, and hit areas.
|
||||
- For mobile targets, account for orientation changes, browser chrome, display cutouts, and CSS safe-area insets. Do not place essential controls at unsafe edges.
|
||||
- Raise render resolution for high-density displays only after profiling fill rate and texture memory; cap it on lower-powered mobile devices.
|
||||
- Letterbox intentionally when preserving composition matters more than filling every pixel. Give the surrounding page a designed background.
|
||||
|
||||
## State ownership
|
||||
|
||||
Use the narrowest owner that matches the state's lifetime:
|
||||
|
||||
| State lifetime | Preferred owner |
|
||||
| --- | --- |
|
||||
| One Game Object | That object or its focused controller |
|
||||
| One Scene run | The Scene or a Scene-owned system |
|
||||
| One play session across Scenes | A typed plain-data session store |
|
||||
| Across browser sessions | A versioned persistence adapter |
|
||||
| Static balance values | Read-only tuning/configuration modules |
|
||||
|
||||
### Required
|
||||
|
||||
- Assign one authoritative writer for each piece of state. Other systems receive snapshots, queries, or explicit commands.
|
||||
- Keep rules state as plain serializable data where practical. Keep Phaser Game Objects, bodies, sounds, and timers out of saves and cross-Scene stores.
|
||||
- Separate definition data, current runtime state, and rendered view. Do not mutate imported configuration to represent a run.
|
||||
- Use the Phaser registry only behind named, typed accessors for genuinely game-global values. Do not turn it into an unstructured dumping ground.
|
||||
- Make transitions explicit: title → playing → paused → result → restart. Reject commands invalid for the current state.
|
||||
- Avoid mutable globals and values attached to `window`. Destroy the `Phaser.Game` instance if the host page unmounts or recreates it.
|
||||
- Version persistent save data, validate it on load, and provide a safe fallback for corrupt or old data.
|
||||
|
||||
### Conditional
|
||||
|
||||
- Use events for discrete notifications with multiple legitimate listeners. Use direct calls or returned values for single-owner commands and queries.
|
||||
- Introduce a finite-state machine when booleans allow impossible combinations or transition guards are being duplicated.
|
||||
- Add immutable updates, snapshots, or replay logs only when undo, deterministic replay, networking, or difficult state debugging requires them.
|
||||
|
||||
## Time, delta, and determinism
|
||||
|
||||
### Required
|
||||
|
||||
- Remember that `update(time, delta)` receives `delta` in milliseconds. Convert once with `const dt = delta / 1000` for manual velocities expressed per second.
|
||||
- Make manual movement, meters, cooldowns, spawning, and animation-independent rules frame-rate independent. Never express gameplay duration as a count of render frames.
|
||||
- Do not multiply Arcade Physics velocity by `delta`; the physics world already integrates it.
|
||||
- Prefer Scene-owned `this.time` events and tweens to raw `setTimeout` or `setInterval` so lifecycle and pausing remain coherent.
|
||||
- Decide what happens on tab blur or a long frame. Pause, or clamp the delta used by manual integration to prevent a large teleport or instant timer drain.
|
||||
- Remove or invalidate delayed callbacks when their owner shuts down. A callback from a previous run must never mutate the next run.
|
||||
- Store durations with unit-bearing names such as `spawnIntervalMs` or `invulnerabilitySeconds`.
|
||||
|
||||
### Conditional
|
||||
|
||||
- Use wall-clock time only for mechanics that must advance while the game is closed; validate clock jumps and persist a reference timestamp.
|
||||
- Use `Phaser.Math.RandomDataGenerator` with an explicit seed when reproducing a run, testing procedural output, or synchronizing simulations matters.
|
||||
- Use a custom fixed-step loop only when the design or networking model requires it. Define accumulation, maximum catch-up steps, interpolation, and overload behavior.
|
||||
|
||||
## Tuning and configuration
|
||||
|
||||
### Required
|
||||
|
||||
- Put player-facing balance values in small typed, read-only configuration objects grouped by system. Keep engine boot configuration separate from gameplay tuning.
|
||||
- Name values by meaning and unit; include a short rationale or valid range when a number is not self-evident.
|
||||
- Avoid repeated magic numbers in Scenes and callbacks. One mechanic must read from one source of truth.
|
||||
- Keep tunable values traceable to the relevant game-design rule and acceptance criteria. When tuning changes the designed behavior, update both.
|
||||
- Clamp user- or data-supplied values at system boundaries. Reject invalid level or content data with a useful message.
|
||||
- Keep secrets and privileged rules off the client. Everything shipped to a browser can be inspected or modified.
|
||||
|
||||
### Conditional
|
||||
|
||||
- Load level/content JSON when non-programmers need to edit repeated content or when many levels share one schema. Validate it before constructing gameplay objects.
|
||||
- Add a development-only tuning panel when iteration speed justifies it. Ensure its state and debug commands cannot leak into production behavior.
|
||||
- Introduce schema generation, migrations, or remote configuration only when content volume or live operations creates a current need.
|
||||
|
||||
## Verification and completion
|
||||
|
||||
### Required automated checks
|
||||
|
||||
- Install from the committed lockfile in a clean environment.
|
||||
- Run strict type checking and every existing lint or automated test command.
|
||||
- Run the production build. A development server compiling successfully is not a substitute.
|
||||
- Keep rules such as score calculation, spawn selection, damage, progression, and save migration pure where possible, and add focused tests when they are nontrivial or regression-prone.
|
||||
|
||||
### Required browser smoke check
|
||||
|
||||
Run the built game in a real browser, preferably from the production preview, and verify:
|
||||
|
||||
1. The page loads into the intended first interactive state.
|
||||
2. The primary input performs the core action and visible/audio feedback occurs.
|
||||
3. The player can reach the success or failure result through the intended loop.
|
||||
4. Restart returns to a clean initial run; complete and restart the loop at least twice.
|
||||
5. There are no new console errors, unhandled promise rejections, failed required asset requests, or duplicate-event symptoms.
|
||||
6. Pause/focus loss and return do not cause stuck input, a time jump, or resumed sounds that should remain paused.
|
||||
7. The supported minimum and maximum viewport sizes remain playable.
|
||||
|
||||
### Conditional checks
|
||||
|
||||
- Test each declared input family—keyboard, pointer, touch, and gamepad—on representative hardware.
|
||||
- Add browser automation for stable critical flows such as boot, start, result, restart, save/load, and resize when manual regression becomes costly.
|
||||
- Profile frame time, draw calls, memory, asset size, and mobile thermal behavior when measured performance misses its target. Optimize measured bottlenecks, not guesses.
|
||||
- Test offline, slow network, load failure, localization, accessibility, and persistence recovery when the product claims those capabilities.
|
||||
|
||||
## Common failure patterns
|
||||
|
||||
| Symptom | Likely cause | Required response |
|
||||
| --- | --- | --- |
|
||||
| Phaser 4 types or APIs appear in a Phaser 3 game | Installed `latest` or a version range resolved unexpectedly | Pin `phaser` to exactly `3.90.0`, recreate the lockfile deliberately, and use the versioned API docs |
|
||||
| Blank canvas with no visible error | Wrong parent size, Scene not registered, or required asset failed | Inspect console/network, verify parent dimensions and Scene order, and surface loader errors |
|
||||
| Input fires twice after restart | Listener registered on every `create` without cleanup | Register once per run and unsubscribe on shutdown |
|
||||
| Result Scene starts repeatedly | Transition is triggered from repeated overlap/update callbacks | Add a terminal-state guard before changing Scenes |
|
||||
| Score, health, or flags survive restart | State initialized only in the constructor | Reset all run state in `init` or `create` |
|
||||
| Movement speed changes with frame rate | Per-frame movement or wrong delta units | Express speed per second and use `delta / 1000` for manual integration |
|
||||
| Object teleports after tab return | A large delta was integrated after suspension | Pause on blur or clamp manual-integration delta |
|
||||
| Pointer aim is offset when camera moves or canvas scales | Screen coordinates used as world coordinates | Convert through the active camera |
|
||||
| Sprite and collision do not line up | Body size/offset was not updated after origin or scale changes | Configure and visually debug the body after final transform |
|
||||
| Static collider remains at its old position | Arcade static body changed without refresh | Call `refreshBody()` after the transform |
|
||||
| Assets work locally but 404 under a subpath | Root-relative URL ignored Vite base path | Derive loader URLs from `import.meta.env.BASE_URL` |
|
||||
| Audio is silent on mobile | Playback started before a user gesture | Unlock/resume audio from an explicit interaction and expose mute state |
|
||||
| Pixel art is blurred or shimmers | Filtering or fractional scaling/positioning | Enable pixel-art settings and use integer-friendly scales and positions |
|
||||
| Game exists twice after navigation | Host recreated the game without destroying the old instance | Keep one owner and call `game.destroy(true)` during host teardown |
|
||||
|
||||
## Official references
|
||||
|
||||
- [Phaser 3.90.0 release](https://github.com/phaserjs/phaser/releases/tag/v3.90.0)
|
||||
- [Phaser 3.90.0 API documentation](https://docs.phaser.io/api-documentation/3.90.0/api-documentation)
|
||||
- [Scenes and lifecycle](https://docs.phaser.io/phaser/concepts/scenes)
|
||||
- [Loader](https://docs.phaser.io/phaser/concepts/loader)
|
||||
- [Input](https://docs.phaser.io/phaser/concepts/input)
|
||||
- [Arcade Physics](https://docs.phaser.io/phaser/concepts/physics/arcade)
|
||||
- [Matter Physics](https://docs.phaser.io/phaser/concepts/physics/matter)
|
||||
- [Scale Manager](https://docs.phaser.io/phaser/concepts/scale-manager)
|
||||
- [Time and Clock](https://docs.phaser.io/phaser/concepts/time)
|
||||
- [Vite getting started](https://vite.dev/guide/)
|
||||
- [TypeScript strict mode](https://www.typescriptlang.org/tsconfig/strict.html)
|
||||
@@ -0,0 +1,58 @@
|
||||
# Web 3D Engineering Standards
|
||||
|
||||
Use this reference when a game explicitly chooses the 3D path. The default web 3D engine is Three.js with TypeScript; this path is opt-in and does not silently convert an existing 2D Phaser game.
|
||||
|
||||
## Choose and pin the runtime
|
||||
|
||||
- Record `Rendering Mode: 3D` and the exact `three` version in `TECH_STACK.md` before implementation.
|
||||
- Install Three.js through the project's package manager. Do not depend on a CDN-only runtime, an unpinned `latest` tag, or a copied dependency whose version is not recorded in the lockfile.
|
||||
- Keep the browser game boundary explicit: the renderer owns scene presentation, while rules, scoring, progression, and content state stay in plain TypeScript modules where practical.
|
||||
- Use `WebGLRenderer` as the compatibility baseline unless the project has a separately verified WebGPU plan. Do not claim WebGPU support from a local-only experiment.
|
||||
|
||||
## Keep a small 3D architecture
|
||||
|
||||
- Keep one obvious browser entry point that creates one renderer, one scene root, and one active camera graph for the current game view.
|
||||
- Separate responsibilities into `main.ts`/bootstrap, renderer setup, scene or world composition, input mapping, domain state, and asset loading. Do not put all behavior in one animation loop.
|
||||
- Use a typed camera contract and explicit coordinate/unit conventions. Record world-up, player height, movement units, near/far planes, and collision assumptions in `TECH_STACK.md` or the relevant role artifact.
|
||||
- Prefer a small vertical slice: one camera, one controllable object, one interaction, one feedback path, and one restart/continue outcome before adding a large world.
|
||||
- Keep animation and gameplay timing based on elapsed time, not frame count. Make pause, resume, restart, and visibility changes explicit.
|
||||
|
||||
## Load and own 3D assets
|
||||
|
||||
- Prefer GLB/glTF for runtime models. Load them through `GLTFLoader` or the project's verified loader boundary, and keep model paths project-relative.
|
||||
- Use a loading state with progress or a clear fallback. A missing model, texture, environment map, or decoder must produce an actionable error instead of an empty canvas.
|
||||
- Keep source models, runtime copies, previews, and license metadata distinct. `ASSET_PLAN.md` is the source-of-truth handoff; only approved project-local paths enter the runtime.
|
||||
- When removing a model or scene, dispose geometries, materials, textures, render targets, and other GPU-owned resources that are no longer used. Do not assume JavaScript garbage collection releases GPU memory.
|
||||
- Keep texture dimensions, color space, normal-map conventions, compression, polygon budget, animation clips, and file size visible in `ART_GUIDE.md` or `ASSET_PLAN.md`.
|
||||
|
||||
## Camera, input, and responsive rendering
|
||||
|
||||
- Update the camera aspect/projection and renderer size from the actual drawing buffer when the viewport changes. Do not stretch a 3D scene by leaving a stale aspect ratio.
|
||||
- Cap device pixel ratio to the project's measured performance target. Prefer stable frame time and readable interaction over maximum resolution.
|
||||
- Make pointer lock, pointer/touch input, keyboard input, and camera movement explicit. Provide a non-pointer-lock fallback for the first playable result when the platform allows it.
|
||||
- Ensure the game remains understandable on the supported desktop and mobile viewports. Record unsupported controls or browser constraints in `TEST_REPORT.md`.
|
||||
|
||||
## Performance and visual correctness
|
||||
|
||||
- Measure frame time, draw calls, visible triangles, texture memory, model size, and load time before optimizing. Fix the measured bottleneck.
|
||||
- Frustum-cull or simplify content only when the scene needs it; do not add a scene graph or streaming framework without evidence.
|
||||
- Verify lighting, tone mapping, output color space, shadows, transparency, depth ordering, and animation transitions in the target browser. A model loading successfully is not visual acceptance.
|
||||
- Test resize, device-pixel-ratio changes, tab background/foreground, pause/resume, restart, and a missing-asset failure path.
|
||||
|
||||
## Completion evidence
|
||||
|
||||
For a 3D playable result, record:
|
||||
|
||||
- the exact `three` version and browser/runtime assumptions;
|
||||
- a real-browser path from load to interaction, feedback, outcome, and restart/continue;
|
||||
- desktop and mobile viewport behavior, camera/resize evidence, and console/network results;
|
||||
- model/texture paths, license metadata, approval state, and any placeholder or unsupported feature;
|
||||
- measured performance risks and the next smallest playable result.
|
||||
|
||||
Do not call a 3D game complete because the renderer compiled or a screenshot exists. The playable interaction and the relevant browser evidence must be observed.
|
||||
|
||||
## References
|
||||
|
||||
- [Three.js documentation](https://threejs.org/docs/)
|
||||
- [Three.js examples](https://threejs.org/examples/)
|
||||
- [glTF specification](https://www.khronos.org/gltf/)
|
||||
Reference in New Issue
Block a user