用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/mbianchidev/2dnd --skill phaser-scene-management命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | phaser-scene-management |
| description | Manage Phaser 4 scenes in 2D&D with correct state flow, cleanup, and transitions |
| license | MIT |
| File | Class | Scene key |
|---|---|---|
Boot.ts | BootScene | BootScene |
Overworld.ts | OverworldScene | OverworldScene |
Battle.ts | BattleScene | BattleScene |
Shop.ts | ShopScene | ShopScene |
Codex.ts | CodexScene | CodexScene |
Cutscene.ts | CutsceneScene | CutsceneScene |
Ending.ts | EndingScene | EndingScene |
Defeat.ts | DefeatScene | DefeatScene |
Register scenes in src/main.ts. The Phaser 4 configuration uses FIT scaling,
centered pixel art, and zoom 6.
import * as Phaser from "phaser";
export class ExampleScene extends Phaser.Scene {
constructor() {
super({ key: "ExampleScene" });
}
init(data: ExampleSceneData): void {
// Store and normalize scene input.
}
create(): void {
// Build display objects, input, audio, and scene-owned helpers.
}
}
Use explicit types and return values. Store Phaser objects that need later updates or cleanup as class properties.
src/systems/input.ts owns stable action/context contracts and pure state.
src/managers/input.ts is the single browser adapter for keyboard, pointer,
standard gamepads, and touch. Scenes must use the shared actions or existing
keyboard/pointer behavior reached by that adapter rather than adding independent
gamepad/mobile mappings. The adapter clears held input on scene changes, blur,
visibility loss, disconnect, and shutdown.
Touch controls use safe-area-aware responsive DOM buttons outside the canvas. Held D-pad directions use pointer capture; discrete buttons use click pulses so scene transitions cannot strand a press. Standard gamepads use left-stick/D-pad navigation and a visible right-stick cursor, clicked by pressing the stick, for pointer-first surfaces.
CodexScene keeps category, filter, sort, and search controls pointer-first so
touch and the gamepad cursor share the keyboard surface. Search uses
openMobileTextInput(). CodexDiscoveryManager owns non-interactive,
scene-local notices and must be cleared on shutdown; it never changes input
context or delays scene transitions.
AchievementOverlayManager owns the accessible Achievements/profile surface and
presentation-only title selection. AchievementNotificationManager reads
persisted pending IDs but displays them only in safe Overworld states; scene
shutdown clears visuals without acknowledging an interrupted notice. Both must
support keyboard, pointer, touch-menu access, gamepad cursor, text scaling,
high contrast, and reduced motion.
GatheringManager owns the in-place fishing/mining/foraging overlay, input,
timers, pointer controls, status record, and cleanup. Overworld resumes pending
gathering before World Events, blocks movement and other interactions while it
is open, and routes guarded rare finds through Battle with resolution hooks.
State-bearing transitions use createSharedSceneState() and preserve:
interface SharedSceneState {
player: PlayerState;
defeatedBosses: Set<string>;
codex: CodexData;
timeStep: number;
weatherState: WeatherState;
savedSpecialNpcs: SavedSpecialNpc[];
}
Scene-specific additions:
encounter: MonsterEncounter, biome, optional accessor-backed
partyCombatants, optional runtime-only battleHooks; Battle may return
transient questUpdates to Overworld after victorytownName, optional item IDs, city context, discount, and optional
stable shopSkillCheckIdCutsceneId, replay mode, return scene,
and optional runtime-only questUpdatesCutsceneIdPartyDefeatResultWhen a scene contract changes, update every scene.start() caller in the same
change.
player.party is persistent nested state and travels automatically with
player. Battle may additionally receive runtime-only accessor-backed
partyCombatants; never serialize those wrappers.
this.sceneTransitions.startWithFade(() => {
this.scene.start("OverworldScene", {
player: this.player,
defeatedBosses: this.defeatedBosses,
codex: this.codex,
timeStep: this.timeStep,
weatherState: this.weatherState,
savedSpecialNpcs: this.savedSpecialNpcs,
});
}, {
duration: 500,
label: "return to overworld",
});
Do not serialize Set<string> during scene transitions. Conversion to arrays
belongs in the save system.
SceneTransitionManager is the single owner of camera fades and queued scene
handoffs. Instantiate it once per scene, call prepare() at the start of
create(), and use its guarded start/restart methods instead of direct
fade-plus-timer pairs. Fade-complete events are primary; the duration-plus-grace
watchdog only recovers missing events. The manager must remove completed
listeners/timers, restore the outgoing camera before queueing the next scene,
and suppress duplicate handoffs during Phaser's one-update queue delay.
It resolves fade durations through the shared reduced-motion accessor and uses
an immediate guarded handoff when motion is disabled.
Call installSceneAccessibility(this) in every scene create(). The adapter
applies live text scale and high contrast, exposes preference state on the
canvas for browser assertions, and suppresses residual tweens in reduced-motion
mode. New scene animations must also branch through
isReducedMotionEnabled() or getMotionDuration().
Use ActorAnimationDirector for reusable actor poses and cleanup. Specialized
battle/world directors register sprites by stable actor ID, use explicit
ActorTextureFamily frame keys with fallback textures, and expose deterministic
debug state for browser synchronization. Kill owned tweens/timers on shutdown;
never wait for actor animation before an authoritative fade-complete handoff.
Overworld restarts use one shared payload that includes a fresh
savedSpecialNpcs snapshot. Block movement and other state-changing actions
while a handoff is pending.
Queue and save cutscene IDs before presentation. CutsceneScene and
EndingScene mark an ID seen and dequeue it only after completion or skip, then
chain the next pending ID. Reload resumes the first pending scene. Chronicle
replay never mutates progression. A skipped pre-boss scene still executes its
completion metadata and starts the selected fight. Add an input grace period
when a dialogue keypress can cross a scene boundary.
BootScene.preload() calls texture generation from
src/renderers/textures.ts. Add new procedural texture generation there and
invoke it through the existing aggregate generator. Do not load image, sprite,
or audio files.
Overworld delegates to renderers and managers. Instantiate these in init() so
a restarted scene receives fresh helpers, then load persisted data into them:
FogOfWarEncounterSystemMapRendererCityRendererPlayerRendererHUDRendererOverlayManagerQuestJournalManagerQuestFlowManagerChronicleManagerSkillCheckManagerDebugCommandSystemCompanionFollowerManagerPartyOverlayManagerBattle delegates companion manual/gambit turn UI to BattlePartyManager and
companion presentation to BattlePartyRenderer. Destroy their transient
containers on scene exit/restart.
Before replacing FogOfWar or EncounterSystem, preserve their debug toggle
state so Battle, Shop, and Codex round trips do not re-enable fog or encounters.
Phaser 4 geometry masks do not reliably clip the Battle log in this project. The Battle scene renders only messages that fit and changes the message offset on mouse-wheel input.
init().init().createHeroCombatant() so HP/effects stay backed by
PlayerState; companion wrappers use the same PartyCombatant contract.combatantId. Companion turns route through
onCompanionTurn, which receives all actors plus execution/log adapters and
must call completeTurn().executeValidatedBattleAction().battleActions.ts planner for gambit matching,
target validation, and action dispatch rather than scene-local rules.BattleActionEconomyState; reset it at the start of each hero turn.▶ selection marker for keyboard and
gamepad focus before targeting.SceneTransitionManager. Start Overworld or
DefeatScene from FADE_OUT_COMPLETE or the delayed recovery watchdog, and
restore the outgoing camera before Phaser queues the handoff.onBattleResolved; reward
adjustment happens before XP/gold are granted.DefeatScene, and never recalculate it there. Random and
boss encounters use the same recovery mechanics.Use debugLog(), debugPanelLog(), and debugPanelState(). Do not add
console.log. Invalid user actions should produce visible feedback and leave
the scene in a usable phase.
Overworld instead of OverworldSceneSet<string> is expectedinit phase.