@@ -882,6 +882,7 @@ export class WeatherLayer {
882882 tint : Phaser . GameObjects . Rectangle | null ;
883883 /** @type {Drop[] } */
884884 drops : Drop [ ] ;
885+ _snow : boolean ;
885886 _heavy : boolean ;
886887 /** @type {AmbientMode } */
887888 ambientMode : AmbientMode ;
@@ -897,12 +898,20 @@ export class WeatherLayer {
897898 _ensureUpdateLoop ( ) : void ;
898899 /** @param {boolean } heavy */
899900 _startRain ( heavy : boolean ) : void ;
901+ /** @param {boolean } heavy */
902+ _startSnow ( heavy : boolean ) : void ;
900903 /**
901904 * @param {boolean } initial - if true, seed positions across the full
902905 * screen so rain doesn't pop in from the top all at once.
903906 * @returns {Drop }
904907 */
905908 _makeDrop ( initial : boolean ) : Drop ;
909+ /**
910+ * @param {boolean } initial - seed flakes across the screen so snow is
911+ * already falling when the scene appears.
912+ * @returns {Drop }
913+ */
914+ _makeSnowflake ( initial : boolean ) : Drop ;
906915 _startLeaves ( ) : void ;
907916 /**
908917 * @param {boolean } initial - seed across the full screen on first build
@@ -923,7 +932,8 @@ export class WeatherLayer {
923932export type PrecipitationMode = "none" | "light-rain" | "heavy-rain" | "snow" | "heavy-snow" ;
924933export type AmbientMode = "none" | "falling-leaves" ;
925934/**
926- * One falling raindrop drawn as a line each frame.
935+ * One falling precipitation particle drawn each frame.
936+ * Rain uses short slanted lines; snow uses small soft dots.
927937 */
928938export type Drop = {
929939 x : number ;
@@ -932,6 +942,10 @@ export type Drop = {
932942 vy : number ;
933943 length : number ;
934944 alpha : number ;
945+ radius ?: number ;
946+ wobbleAmp ?: number ;
947+ wobbleFreq ?: number ;
948+ wobblePhase ?: number ;
935949} ;
936950/**
937951 * One falling leaf sprite, sway + spin animated per-frame.
@@ -1603,7 +1617,33 @@ export type WanderHost = Walker & {
16031617 despawn : ( ) => void ;
16041618 isSpawned : ( ) => boolean ;
16051619} ;
1606- declare class WanderBehavior {
1620+ /**
1621+ * @typedef {object } WanderOptions
1622+ * @property {boolean } [startPresent] - force the initial present/absent roll.
1623+ * @property {{x: number, y: number} | null } [startPos] - when present-on-entry
1624+ * (not from an exit), stand here instead of a random walkable point.
1625+ * @property {number } [presentChance] - chance of being present on attach. Default 1 (always present).
1626+ * @property {[number, number] | null } [walksRange] - wanders before leaving the scene. `null` = perpetual (never leaves).
1627+ * @property {[number, number] } [wanderDelayRange] - ms paused between wanders. Default [3000, 6000].
1628+ * @property {number } [returnInterval] - ms between return-check rolls while absent. Default 18000.
1629+ * @property {number } [returnChance] - chance to return on each check. Default 0.33.
1630+ * @property {{x: number, y: number, w: number, h: number} } [area] - explicit roam bounds. When set, random
1631+ * destinations are picked inside this rect (no walkable snap) — use it when the character's roam zone differs
1632+ * from the player walkable polygon (e.g. a foreground shore strip). Defaults to the scene walkable.
1633+ * @property {boolean } [startAtExit] - spawn from a random scene exit. Default = can-leave.
1634+ * @property {boolean } [walkInOnSpawn] - walk to a random point immediately on spawn (vs pausing first). Default false.
1635+ * @property {string | null } [idleFrame] - texture shown while paused between wanders. Default = host still frame.
1636+ * @property {number } [interruptResumeMs] - ms before the routine resumes after a click greeting. Default 2600.
1637+ * @property {boolean } [autoStart] - run the state machine on construction. Default true.
1638+ */
1639+ /**
1640+ * The come-and-go wander machine, generalized out of the six controllers that
1641+ * each hand-rolled it. Drives a {@link import("./walker.js").WanderHost} through
1642+ * `wandering` → `leaving` → `absent`, picking random walkable points, and
1643+ * (optionally) leaving the scene after a few walks before checking back on a
1644+ * timer. Knows nothing about sprites except through the host.
1645+ */
1646+ export class WanderBehavior {
16071647 /**
16081648 * @param {import("./walker.js").WanderHost } host
16091649 * @param {WanderOptions } [opts]
@@ -3555,6 +3595,73 @@ export function buildCutsceneContext(scene: any, cs: Cutscene, present: Map<stri
35553595 * @return {number }
35563596 */
35573597export function randomInt ( ...args : number [ ] ) : number ;
3598+ /**
3599+ * Shared "renderable item" shape used across a game's item collections (props,
3600+ * equipment, scene-specific objects). Every collection extends this with its own
3601+ * positional / domain
3602+ * fields, but the visual fields are uniform: pick a frame, set a scale,
3603+ * optionally rotate.
3604+ *
3605+ * Pattern for a new collection — declare a typedef that intersects this
3606+ * with the scene-specific fields, e.g.:
3607+ * `import("./itemDef.js").RenderableItem & { x: number, y: number }`
3608+ */
3609+ export type RenderableItem = {
3610+ /**
3611+ * - registry key
3612+ */
3613+ id : string ;
3614+ /**
3615+ * - atlas frame name. Defaults to `id` if omitted.
3616+ */
3617+ frame ?: string ;
3618+ /**
3619+ * - display scale, default 1
3620+ */
3621+ scale ?: number ;
3622+ /**
3623+ * - rotation in DEGREES (Phaser setAngle), default 0
3624+ */
3625+ rotation ?: number ;
3626+ } ;
3627+ /**
3628+ * Shared "renderable item" shape used across a game's item collections (props,
3629+ * equipment, scene-specific objects). Every collection extends this with its own
3630+ * positional / domain
3631+ * fields, but the visual fields are uniform: pick a frame, set a scale,
3632+ * optionally rotate.
3633+ *
3634+ * Pattern for a new collection — declare a typedef that intersects this
3635+ * with the scene-specific fields, e.g.:
3636+ * `import("./itemDef.js").RenderableItem & { x: number, y: number }`
3637+ *
3638+ * @typedef {object } RenderableItem
3639+ * @property {string } id - registry key
3640+ * @property {string } [frame] - atlas frame name. Defaults to `id` if omitted.
3641+ * @property {number } [scale] - display scale, default 1
3642+ * @property {number } [rotation] - rotation in DEGREES (Phaser setAngle), default 0
3643+ */
3644+ /**
3645+ * A `RenderableItem` placed in a scene at a specific position. Add a list
3646+ * of these to `AdventureSceneConfig.propItems` and the base scene renders
3647+ * them automatically (no per-scene loop needed). Subclasses can grab the
3648+ * resulting sprite via `this.propSprites.get(id)` for later manipulation
3649+ * (destroy on pickup, toggle visibility, etc.).
3650+ *
3651+ * @typedef {RenderableItem & {
3652+ * atlas: string,
3653+ * x: number,
3654+ * y: number,
3655+ * depth?: number,
3656+ * flipX?: boolean,
3657+ * origin?: { x?: number, y?: number },
3658+ * shouldRender?: () => boolean,
3659+ * seasons?: string[],
3660+ * hideIfPickedUp?: boolean,
3661+ * }} PropItem
3662+ */
3663+ /** @type {RenderableItem } */
3664+ export const RenderableItem : RenderableItem ;
35583665/**
35593666 * Engine — content registry (ADR 0005).
35603667 *
0 commit comments