@rydr/game-sdk 5.0.0 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -18
- package/dist/client/PlatformClient.d.ts +11 -10
- package/dist/client/PlatformClient.d.ts.map +1 -1
- package/dist/client/PlatformClient.js +46 -21
- package/dist/client/PlatformClient.js.map +1 -1
- package/dist/host/PlatformHost.d.ts +16 -7
- package/dist/host/PlatformHost.d.ts.map +1 -1
- package/dist/host/PlatformHost.js +3 -0
- package/dist/host/PlatformHost.js.map +1 -1
- package/dist/protocol/buttons.d.ts +62 -31
- package/dist/protocol/buttons.d.ts.map +1 -1
- package/dist/protocol/buttons.js +42 -25
- package/dist/protocol/buttons.js.map +1 -1
- package/dist/protocol/capabilities.d.ts +1 -1
- package/dist/protocol/messages.d.ts +22 -5
- package/dist/protocol/messages.d.ts.map +1 -1
- package/dist/protocol/perf.d.ts +37 -0
- package/dist/protocol/perf.d.ts.map +1 -0
- package/dist/protocol/perf.js +17 -0
- package/dist/protocol/perf.js.map +1 -0
- package/dist/protocol/version.d.ts +2 -2
- package/dist/protocol/version.d.ts.map +1 -1
- package/dist/protocol/version.js +31 -2
- package/dist/protocol/version.js.map +1 -1
- package/dist/three/perf-marks.d.ts +2 -21
- package/dist/three/perf-marks.d.ts.map +1 -1
- package/dist/three/perf-marks.js.map +1 -1
- package/dist/ui/README.md +3 -0
- package/dist/ui/heat-vignette.d.ts +75 -0
- package/dist/ui/heat-vignette.d.ts.map +1 -0
- package/dist/ui/heat-vignette.js +126 -0
- package/dist/ui/heat-vignette.js.map +1 -0
- package/dist/ui/index.d.ts +7 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +7 -0
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/overheat-glitch.d.ts +56 -0
- package/dist/ui/overheat-glitch.d.ts.map +1 -0
- package/dist/ui/overheat-glitch.js +177 -0
- package/dist/ui/overheat-glitch.js.map +1 -0
- package/dist/ui/overheat-hud-bar.d.ts +79 -0
- package/dist/ui/overheat-hud-bar.d.ts.map +1 -0
- package/dist/ui/overheat-hud-bar.js +302 -0
- package/dist/ui/overheat-hud-bar.js.map +1 -0
- package/dist/ui/showcase/index.js +2 -2
- package/dist/ui/showcase/index.js.map +1 -1
- package/package.json +1 -1
package/dist/protocol/version.js
CHANGED
|
@@ -131,8 +131,37 @@
|
|
|
131
131
|
// whatever went back on `DIAMOND_LEFT` must now go back on `DIAMOND_RIGHT`. Doing only the first step
|
|
132
132
|
// compiles and runs while keeping the old, wrong ergonomics. Finally, replace every hardcoded button
|
|
133
133
|
// letter in on-screen text with `session.buttonLabel(…)`.
|
|
134
|
-
|
|
134
|
+
// Bumped 26 → 27: REMOVES the trigger axes `LT`/`RT` from the `input.axis` `name` vocabulary
|
|
135
|
+
// (BREAKING for the `AxisName` type — it narrows to the four stick axes `LX`/`LY`/`RX`/`RY`). The
|
|
136
|
+
// shoulder triggers are plain CLICKS on the hardware — there is no analog trigger travel — so
|
|
137
|
+
// `axis("LT"|"RT")` promised a reading that could never exist. The digital `LT`/`RT` ButtonNames are
|
|
138
|
+
// untouched. Wire-wise this is a no-op: no shell ever emitted a trigger axis (protocol-22 shells only
|
|
139
|
+
// ever sent stick axes), and the SDK's keyboard emulation was the sole feeder (`a`/`e` snapping 0/1),
|
|
140
|
+
// now removed. Migrate: `session.axis("LT"|"RT")` → `session.isDown("LT"|"RT")` (the on/off click).
|
|
141
|
+
// Bumped 27 → 28: adds `OPTIONS` to the `input.button` `name` vocabulary — a single extra button,
|
|
142
|
+
// distinct from the platform's own overlay menu (`M`/phone `MENU`/gamepad Start, which never reaches
|
|
143
|
+
// a game). It's the GAME's own menu/options button. Keyboard `o`, a standard gamepad's Select/Back
|
|
144
|
+
// button, and a new phone icon all send it; not every device has it, so never gate a required flow
|
|
145
|
+
// behind it alone. Additive: no existing shape or name changed, and an older game's `onButton` has no
|
|
146
|
+
// branch for `OPTIONS`, so it's inert there — no old-guest shield needed. (Unrelated to the wire
|
|
147
|
+
// vocabulary: the right stick and both stick-click buttons also moved off `i`/`j`/`k`/`l`/`f`/`o` onto
|
|
148
|
+
// the numeric keypad in this same release, but that's purely which PHYSICAL KEY the SDK's own keyboard
|
|
149
|
+
// emulation listens for — the `ButtonName`s it produces are unchanged, so it carries no protocol bump.)
|
|
150
|
+
// Bumped 28 → 29: adds `rydr/rider.adjustFtp` (`{ direction: 1 | -1 }`, game→platform) — the fourth
|
|
151
|
+
// shell-owned rider-key relay, joining `audio.adjustMaster` (T/G), `trainer.adjustResistance` (W/X)
|
|
152
|
+
// and `menu.toggle` (M). The keys are − and + and they step the rider's PLAYING FTP: a memory-only
|
|
153
|
+
// session override the shell layers on the profile FTP, so a rider can make every game harder or
|
|
154
|
+
// easier mid-ride without editing their profile (it resets to the profile number on reload). Like
|
|
155
|
+
// its three siblings it exists only because a focused game iframe swallows the keystroke before the
|
|
156
|
+
// shell window can see it. There is no reply message — the shell pushes the resulting FTP to every
|
|
157
|
+
// game as a fresh `rydr/identity.update`, so a game reads it exactly where it already reads FTP
|
|
158
|
+
// (`session.identity.ftp` / `onIdentityChange`). Ungated (no capability), like the other three.
|
|
159
|
+
// Additive: an older shell has no `onAdjustFtp` handler, so the message is a silent no-op there
|
|
160
|
+
// (−/+ keeps working only while the shell holds focus) and nothing existing changed. No game code
|
|
161
|
+
// required — but a game that snapshots `identity.ftp` at init instead of subscribing to
|
|
162
|
+
// `onIdentityChange` won't see mid-ride changes, which was already true for a profile edit.
|
|
163
|
+
export const RYDR_PROTOCOL_VERSION = 29;
|
|
135
164
|
/** Semver of this SDK build. Sent in the handshake for telemetry/debugging.
|
|
136
165
|
* (Bumped to 2.0.0 by `npm version major` on release — see CHANGELOG [Unreleased].) */
|
|
137
|
-
export const RYDR_SDK_VERSION = "
|
|
166
|
+
export const RYDR_SDK_VERSION = "6.1.0";
|
|
138
167
|
//# sourceMappingURL=version.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/protocol/version.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,8FAA8F;AAC9F,yDAAyD;AACzD,4FAA4F;AAC5F,oGAAoG;AACpG,kGAAkG;AAClG,6EAA6E;AAC7E,kGAAkG;AAClG,uGAAuG;AACvG,wFAAwF;AACxF,oGAAoG;AACpG,gGAAgG;AAChG,yFAAyF;AACzF,kHAAkH;AAClH,oGAAoG;AACpG,qGAAqG;AACrG,kGAAkG;AAClG,mGAAmG;AACnG,oGAAoG;AACpG,6FAA6F;AAC7F,gGAAgG;AAChG,uGAAuG;AACvG,mGAAmG;AACnG,kGAAkG;AAClG,+FAA+F;AAC/F,kGAAkG;AAClG,iGAAiG;AACjG,iGAAiG;AACjG,+FAA+F;AAC/F,qGAAqG;AACrG,uGAAuG;AACvG,+FAA+F;AAC/F,qGAAqG;AACrG,kGAAkG;AAClG,2BAA2B;AAC3B,mGAAmG;AACnG,mGAAmG;AACnG,gGAAgG;AAChG,iGAAiG;AACjG,oFAAoF;AACpF,oGAAoG;AACpG,kGAAkG;AAClG,oGAAoG;AACpG,iGAAiG;AACjG,sGAAsG;AACtG,wGAAwG;AACxG,qGAAqG;AACrG,uGAAuG;AACvG,sGAAsG;AACtG,wGAAwG;AACxG,qGAAqG;AACrG,uGAAuG;AACvG,uGAAuG;AACvG,mGAAmG;AACnG,kFAAkF;AAClF,yGAAyG;AACzG,oGAAoG;AACpG,uGAAuG;AACvG,0GAA0G;AAC1G,yGAAyG;AACzG,yBAAyB;AACzB,sGAAsG;AACtG,sGAAsG;AACtG,qGAAqG;AACrG,wGAAwG;AACxG,uGAAuG;AACvG,6FAA6F;AAC7F,iGAAiG;AACjG,iGAAiG;AACjG,+FAA+F;AAC/F,mGAAmG;AACnG,iGAAiG;AACjG,oGAAoG;AACpG,qCAAqC;AACrC,kGAAkG;AAClG,yGAAyG;AACzG,4GAA4G;AAC5G,sGAAsG;AACtG,oGAAoG;AACpG,oGAAoG;AACpG,qGAAqG;AACrG,mGAAmG;AACnG,mGAAmG;AACnG,gGAAgG;AAChG,+FAA+F;AAC/F,iGAAiG;AACjG,oGAAoG;AACpG,kEAAkE;AAClE,qGAAqG;AACrG,wGAAwG;AACxG,sGAAsG;AACtG,0GAA0G;AAC1G,2GAA2G;AAC3G,yGAAyG;AACzG,oGAAoG;AACpG,iFAAiF;AACjF,wGAAwG;AACxG,4GAA4G;AAC5G,0GAA0G;AAC1G,uGAAuG;AACvG,2GAA2G;AAC3G,0GAA0G;AAC1G,wGAAwG;AACxG,mGAAmG;AACnG,4GAA4G;AAC5G,0GAA0G;AAC1G,2GAA2G;AAC3G,qFAAqF;AACrF,kGAAkG;AAClG,qGAAqG;AACrG,uGAAuG;AACvG,mGAAmG;AACnG,0FAA0F;AAC1F,qGAAqG;AACrG,kGAAkG;AAClG,uGAAuG;AACvG,+EAA+E;AAC/E,uGAAuG;AACvG,uGAAuG;AACvG,gEAAgE;AAChE,2FAA2F;AAC3F,iGAAiG;AACjG,qGAAqG;AACrG,sGAAsG;AACtG,qGAAqG;AACrG,0DAA0D;AAC1D,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAW,CAAC;AAEjD;wFACwF;AACxF,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC"}
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/protocol/version.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,27 +17,8 @@
|
|
|
17
17
|
* Browser-only (uses `performance.now()` + `window`). Part of the optional
|
|
18
18
|
* `@rydr/game-sdk/three` entry point.
|
|
19
19
|
*/
|
|
20
|
-
|
|
21
|
-
export
|
|
22
|
-
avg: number;
|
|
23
|
-
max: number;
|
|
24
|
-
n: number;
|
|
25
|
-
}
|
|
26
|
-
/** Snapshot of every recorded label. */
|
|
27
|
-
export type PerfReport = Record<string, PerfReportEntry>;
|
|
28
|
-
declare global {
|
|
29
|
-
interface Window {
|
|
30
|
-
__PERF__?: boolean;
|
|
31
|
-
__perfReport?: () => PerfReport | null;
|
|
32
|
-
}
|
|
33
|
-
interface WindowEventMap {
|
|
34
|
-
/** Fired by the SDK when the built-in secret button code toggles the perf overlay.
|
|
35
|
-
* `detail.on` is the new visibility state. See `connectToPlatform`. */
|
|
36
|
-
"rydr:perf-toggle": CustomEvent<{
|
|
37
|
-
on: boolean;
|
|
38
|
-
}>;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
20
|
+
import type { PerfReport, PerfReportEntry } from "../protocol/perf.js";
|
|
21
|
+
export type { PerfReport, PerfReportEntry };
|
|
41
22
|
/** Start a timing region under `label`. No-op unless `window.__PERF__` is set. */
|
|
42
23
|
export declare function perfMark(label: string): void;
|
|
43
24
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"perf-marks.d.ts","sourceRoot":"","sources":["../../src/three/perf-marks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAMH,
|
|
1
|
+
{"version":3,"file":"perf-marks.d.ts","sourceRoot":"","sources":["../../src/three/perf-marks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC;AAU5C,kFAAkF;AAClF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAG5C;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAY/C;AAED,iFAAiF;AACjF,wBAAgB,UAAU,IAAI,UAAU,GAAG,IAAI,CAU9C;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI7C;AAED,uEAAuE;AACvE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI9C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"perf-marks.js","sourceRoot":"","sources":["../../src/three/perf-marks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;
|
|
1
|
+
{"version":3,"file":"perf-marks.js","sourceRoot":"","sources":["../../src/three/perf-marks.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/README.md
CHANGED
|
@@ -48,6 +48,9 @@ feed its `{x, y, onScreen}` into `setScreenPos`/`setVisible` — don't compute p
|
|
|
48
48
|
| `mountChoiceCard(host, opts)` | fn | A player choice menu: prompt + highlighted option list (▲▼ move, A confirm). |
|
|
49
49
|
| `mountRarityCard(host, opts)` / `buildRarityCard(opts)` | fn | A generic rarity-tinted item/creature card. |
|
|
50
50
|
| `createPowerRace(opts)` | fn | A timed **power-vs-deadline race** overlay — the "push NOW or lose it" beat. A charge bar (∫power dt) races a clock; first to 100% wins. `start()` then `setPower(w)`+`tick(dt)` per frame; `won`/`lost` via `onResolve`. Recolour with `theme`, relabel with `text`. |
|
|
51
|
+
| `mountHeatVignette(host, opts)` | fn | **Screen-edge heat vignette alone** — the peripheral amber→orange→red glow that escalates with heat. Take this when your game draws its own heat bar. `setHeat(heat01, locked)` per frame. |
|
|
52
|
+
| `mountOverheatGlitch(host, opts)` | fn | **Lockout glitch overlay alone** — one-shot RGB chromatic burst on entry, then scanlines + red noise for the lockout. `setLocked(bool)` per frame. |
|
|
53
|
+
| `mountOverheatHudBar(host, opts)` | fn | **The whole overheat package**: centred inferno bar + label + COOLING DOWN countdown, composing the vignette and glitch above. One `update(heat01, locked, lockoutRemaining)` per frame. |
|
|
51
54
|
| `injectCss()` | fn | Force the `.rydr-ui-*` CSS into `<head>` early (components call it for you). |
|
|
52
55
|
|
|
53
56
|
Types: `DiamondButton` (`"DIAMOND_UP"\|"DIAMOND_DOWN"\|"DIAMOND_LEFT"\|"DIAMOND_RIGHT"`), `DirButton`, `KeycapVariant` (`"full"\|"solo"`),
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mountHeatVignette` — the **screen-edge heat vignette**, on its own.
|
|
3
|
+
*
|
|
4
|
+
* A peripheral "you are cooking" cue: a coloured glow bleeding in from the edges of the play area
|
|
5
|
+
* that escalates amber → orange → red as heat rises, pulsing faster at each stage. It reads in
|
|
6
|
+
* peripheral vision while the player's eyes are on the road, which is exactly what a heat mechanic
|
|
7
|
+
* needs — the player should feel the danger without looking at a bar.
|
|
8
|
+
*
|
|
9
|
+
* This is the vignette **alone**, deliberately separable: a game that draws its own heat bar (e.g.
|
|
10
|
+
* the racing game's in-canvas gauge) still wants the peripheral cue. Pair it with
|
|
11
|
+
* {@link mountOverheatGlitch} for the lockout flash, or take the whole pre-assembled package —
|
|
12
|
+
* bar + vignette + glitch — from {@link mountOverheatHudBar}.
|
|
13
|
+
*
|
|
14
|
+
* Self-contained DOM/CSS like the rest of `@rydr/game-sdk/ui`: it injects its own scoped
|
|
15
|
+
* `.rydr-heat-vignette*` stylesheet once into `<head>`, needs no global styles, no CSS variables and
|
|
16
|
+
* no three.js. It takes a **0..1 heat value**, not a `session` — the game owns its heat model and
|
|
17
|
+
* feeds the ratio in.
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* const vignette = mountHeatVignette(hudHost);
|
|
21
|
+
* // every frame:
|
|
22
|
+
* vignette.setHeat(heat.fillRatio, heat.isLocked);
|
|
23
|
+
* // on teardown:
|
|
24
|
+
* vignette.dispose();
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* **Host contract:** the vignette is `position: absolute; inset: 0` and sits at `z-index: 19`, so
|
|
28
|
+
* `host` must be positioned (and ideally `isolation: isolate`, so the z-index doesn't leak past it).
|
|
29
|
+
* A full-viewport `position: fixed; inset: 0; pointer-events: none; isolation: isolate` div over the
|
|
30
|
+
* game canvas is the intended host.
|
|
31
|
+
*/
|
|
32
|
+
/** Discrete escalation stage of a heat cue. Drives the vignette colour + pulse rate. */
|
|
33
|
+
export type HeatStage = "idle" | "warn" | "crit" | "danger";
|
|
34
|
+
/**
|
|
35
|
+
* Default heat levels (0..1) at which each stage kicks in. `heat ∈ [warn, crit)` is a slow amber
|
|
36
|
+
* pulse, `[crit, danger)` a faster orange one, `[danger, 1]` the red panic pulse. Override per-mount
|
|
37
|
+
* with {@link HeatVignetteOptions.thresholds} when a game's own bar escalates on a different curve —
|
|
38
|
+
* keep the two in sync so the peripheral cue and the bar tell the same story.
|
|
39
|
+
*/
|
|
40
|
+
export declare const HEAT_STAGE_THRESHOLDS: Readonly<Record<Exclude<HeatStage, "idle">, number>>;
|
|
41
|
+
/** Classify a 0..1 heat value into a {@link HeatStage} using `thresholds` (default {@link HEAT_STAGE_THRESHOLDS}). */
|
|
42
|
+
export declare function heatStageFor(heat01: number, thresholds?: Readonly<Record<Exclude<HeatStage, "idle">, number>>): HeatStage;
|
|
43
|
+
/** Options for {@link mountHeatVignette}. */
|
|
44
|
+
export interface HeatVignetteOptions {
|
|
45
|
+
/** Stage cut-offs (0..1). Default {@link HEAT_STAGE_THRESHOLDS}. */
|
|
46
|
+
thresholds?: Readonly<Record<Exclude<HeatStage, "idle">, number>>;
|
|
47
|
+
/**
|
|
48
|
+
* Stacking order inside the host. Default `19` — under {@link mountOverheatHudBar}'s bar (20) and
|
|
49
|
+
* glitch overlay (21), so the three compose in the intended order when used together.
|
|
50
|
+
*/
|
|
51
|
+
zIndex?: number;
|
|
52
|
+
}
|
|
53
|
+
/** Live handle to a mounted heat vignette. Returned by {@link mountHeatVignette}. */
|
|
54
|
+
export interface HeatVignette {
|
|
55
|
+
/** The vignette element (already appended to the host). */
|
|
56
|
+
readonly root: HTMLDivElement;
|
|
57
|
+
/**
|
|
58
|
+
* Drive the vignette for one frame.
|
|
59
|
+
*
|
|
60
|
+
* @param heat01 Heat as a 0..1 ratio; classified into a stage via the mount's thresholds.
|
|
61
|
+
* @param locked True while the game is in its overheat lockout — forces the `danger` stage for the
|
|
62
|
+
* whole window, so the peripheral cue stays bright even as heat drains during a forced cooldown.
|
|
63
|
+
*/
|
|
64
|
+
setHeat(heat01: number, locked?: boolean): void;
|
|
65
|
+
/** Force a stage directly, bypassing the heat→stage mapping (for scripted moments/cutscenes). */
|
|
66
|
+
setStage(stage: HeatStage): void;
|
|
67
|
+
/** Remove the vignette from the host. Idempotent. */
|
|
68
|
+
dispose(): void;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Mount a heat vignette into `host`. See the module header for the host contract; drive it every
|
|
72
|
+
* frame with {@link HeatVignette.setHeat}.
|
|
73
|
+
*/
|
|
74
|
+
export declare function mountHeatVignette(host: HTMLElement, opts?: HeatVignetteOptions): HeatVignette;
|
|
75
|
+
//# sourceMappingURL=heat-vignette.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heat-vignette.d.ts","sourceRoot":"","sources":["../../src/ui/heat-vignette.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,wFAAwF;AACxF,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5D;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAChC,CAAC;AAExD,sHAAsH;AACtH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAyB,GACvF,SAAS,CAKX;AAED,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qFAAqF;AACrF,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAChD,iGAAiG;IACjG,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACjC,qDAAqD;IACrD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,WAAW,EACjB,IAAI,GAAE,mBAAwB,GAC7B,YAAY,CA8Bd"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mountHeatVignette` — the **screen-edge heat vignette**, on its own.
|
|
3
|
+
*
|
|
4
|
+
* A peripheral "you are cooking" cue: a coloured glow bleeding in from the edges of the play area
|
|
5
|
+
* that escalates amber → orange → red as heat rises, pulsing faster at each stage. It reads in
|
|
6
|
+
* peripheral vision while the player's eyes are on the road, which is exactly what a heat mechanic
|
|
7
|
+
* needs — the player should feel the danger without looking at a bar.
|
|
8
|
+
*
|
|
9
|
+
* This is the vignette **alone**, deliberately separable: a game that draws its own heat bar (e.g.
|
|
10
|
+
* the racing game's in-canvas gauge) still wants the peripheral cue. Pair it with
|
|
11
|
+
* {@link mountOverheatGlitch} for the lockout flash, or take the whole pre-assembled package —
|
|
12
|
+
* bar + vignette + glitch — from {@link mountOverheatHudBar}.
|
|
13
|
+
*
|
|
14
|
+
* Self-contained DOM/CSS like the rest of `@rydr/game-sdk/ui`: it injects its own scoped
|
|
15
|
+
* `.rydr-heat-vignette*` stylesheet once into `<head>`, needs no global styles, no CSS variables and
|
|
16
|
+
* no three.js. It takes a **0..1 heat value**, not a `session` — the game owns its heat model and
|
|
17
|
+
* feeds the ratio in.
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* const vignette = mountHeatVignette(hudHost);
|
|
21
|
+
* // every frame:
|
|
22
|
+
* vignette.setHeat(heat.fillRatio, heat.isLocked);
|
|
23
|
+
* // on teardown:
|
|
24
|
+
* vignette.dispose();
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* **Host contract:** the vignette is `position: absolute; inset: 0` and sits at `z-index: 19`, so
|
|
28
|
+
* `host` must be positioned (and ideally `isolation: isolate`, so the z-index doesn't leak past it).
|
|
29
|
+
* A full-viewport `position: fixed; inset: 0; pointer-events: none; isolation: isolate` div over the
|
|
30
|
+
* game canvas is the intended host.
|
|
31
|
+
*/
|
|
32
|
+
const STYLE_ID = "rydr-heat-vignette-css";
|
|
33
|
+
/**
|
|
34
|
+
* Default heat levels (0..1) at which each stage kicks in. `heat ∈ [warn, crit)` is a slow amber
|
|
35
|
+
* pulse, `[crit, danger)` a faster orange one, `[danger, 1]` the red panic pulse. Override per-mount
|
|
36
|
+
* with {@link HeatVignetteOptions.thresholds} when a game's own bar escalates on a different curve —
|
|
37
|
+
* keep the two in sync so the peripheral cue and the bar tell the same story.
|
|
38
|
+
*/
|
|
39
|
+
export const HEAT_STAGE_THRESHOLDS = Object.freeze({ warn: 0.5, crit: 0.65, danger: 0.8 });
|
|
40
|
+
/** Classify a 0..1 heat value into a {@link HeatStage} using `thresholds` (default {@link HEAT_STAGE_THRESHOLDS}). */
|
|
41
|
+
export function heatStageFor(heat01, thresholds = HEAT_STAGE_THRESHOLDS) {
|
|
42
|
+
if (heat01 >= thresholds.danger)
|
|
43
|
+
return "danger";
|
|
44
|
+
if (heat01 >= thresholds.crit)
|
|
45
|
+
return "crit";
|
|
46
|
+
if (heat01 >= thresholds.warn)
|
|
47
|
+
return "warn";
|
|
48
|
+
return "idle";
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Mount a heat vignette into `host`. See the module header for the host contract; drive it every
|
|
52
|
+
* frame with {@link HeatVignette.setHeat}.
|
|
53
|
+
*/
|
|
54
|
+
export function mountHeatVignette(host, opts = {}) {
|
|
55
|
+
injectCss();
|
|
56
|
+
const thresholds = opts.thresholds ?? HEAT_STAGE_THRESHOLDS;
|
|
57
|
+
const root = document.createElement("div");
|
|
58
|
+
root.className = "rydr-heat-vignette";
|
|
59
|
+
if (opts.zIndex !== undefined)
|
|
60
|
+
root.style.zIndex = String(opts.zIndex);
|
|
61
|
+
host.appendChild(root);
|
|
62
|
+
// Cache the applied stage so we only touch classList on a transition, not every frame.
|
|
63
|
+
let lastStage = "idle";
|
|
64
|
+
const setStage = (stage) => {
|
|
65
|
+
if (stage === lastStage)
|
|
66
|
+
return;
|
|
67
|
+
root.classList.remove("stage-warn", "stage-crit", "stage-danger");
|
|
68
|
+
if (stage !== "idle")
|
|
69
|
+
root.classList.add(`stage-${stage}`);
|
|
70
|
+
lastStage = stage;
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
root,
|
|
74
|
+
setStage,
|
|
75
|
+
setHeat(heat01, locked = false) {
|
|
76
|
+
const clamped = Math.max(0, Math.min(1, heat01 || 0));
|
|
77
|
+
setStage(locked ? "danger" : heatStageFor(clamped, thresholds));
|
|
78
|
+
},
|
|
79
|
+
dispose() {
|
|
80
|
+
root.remove();
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
let cssInjected = false;
|
|
85
|
+
/** Inject the scoped vignette CSS once per document. */
|
|
86
|
+
function injectCss() {
|
|
87
|
+
if (cssInjected || document.getElementById(STYLE_ID)) {
|
|
88
|
+
cssInjected = true;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const style = document.createElement("style");
|
|
92
|
+
style.id = STYLE_ID;
|
|
93
|
+
style.textContent = CSS;
|
|
94
|
+
document.head.appendChild(style);
|
|
95
|
+
cssInjected = true;
|
|
96
|
+
}
|
|
97
|
+
const CSS = `
|
|
98
|
+
.rydr-heat-vignette {
|
|
99
|
+
position: absolute;
|
|
100
|
+
inset: 0;
|
|
101
|
+
pointer-events: none;
|
|
102
|
+
z-index: 19;
|
|
103
|
+
opacity: 0;
|
|
104
|
+
transition: opacity 0.2s;
|
|
105
|
+
box-shadow: inset 0 0 0 0 transparent;
|
|
106
|
+
}
|
|
107
|
+
.rydr-heat-vignette.stage-warn {
|
|
108
|
+
opacity: 1;
|
|
109
|
+
box-shadow: inset 0 0 80px rgba(251, 191, 36, 0.35);
|
|
110
|
+
}
|
|
111
|
+
.rydr-heat-vignette.stage-crit {
|
|
112
|
+
opacity: 1;
|
|
113
|
+
box-shadow: inset 0 0 120px rgba(249, 115, 22, 0.55);
|
|
114
|
+
animation: rydr-heat-vignette-pulse 0.7s ease-in-out infinite;
|
|
115
|
+
}
|
|
116
|
+
.rydr-heat-vignette.stage-danger {
|
|
117
|
+
opacity: 1;
|
|
118
|
+
box-shadow: inset 0 0 180px rgba(239, 68, 68, 0.85);
|
|
119
|
+
animation: rydr-heat-vignette-pulse 0.3s ease-in-out infinite;
|
|
120
|
+
}
|
|
121
|
+
@keyframes rydr-heat-vignette-pulse {
|
|
122
|
+
0%, 100% { filter: brightness(0.7); }
|
|
123
|
+
50% { filter: brightness(1.25); }
|
|
124
|
+
}
|
|
125
|
+
`;
|
|
126
|
+
//# sourceMappingURL=heat-vignette.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heat-vignette.js","sourceRoot":"","sources":["../../src/ui/heat-vignette.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,MAAM,QAAQ,GAAG,wBAAwB,CAAC;AAK1C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAChC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;AAExD,sHAAsH;AACtH,MAAM,UAAU,YAAY,CAC1B,MAAc,EACd,aAAmE,qBAAqB;IAExF,IAAI,MAAM,IAAI,UAAU,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAC;IACjD,IAAI,MAAM,IAAI,UAAU,CAAC,IAAI;QAAE,OAAO,MAAM,CAAC;IAC7C,IAAI,MAAM,IAAI,UAAU,CAAC,IAAI;QAAE,OAAO,MAAM,CAAC;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC;AA+BD;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAiB,EACjB,OAA4B,EAAE;IAE9B,SAAS,EAAE,CAAC;IACZ,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,qBAAqB,CAAC;IAE5D,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC3C,IAAI,CAAC,SAAS,GAAG,oBAAoB,CAAC;IACtC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAEvB,uFAAuF;IACvF,IAAI,SAAS,GAAc,MAAM,CAAC;IAElC,MAAM,QAAQ,GAAG,CAAC,KAAgB,EAAQ,EAAE;QAC1C,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO;QAChC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;QAClE,IAAI,KAAK,KAAK,MAAM;YAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC;QAC3D,SAAS,GAAG,KAAK,CAAC;IACpB,CAAC,CAAC;IAEF,OAAO;QACL,IAAI;QACJ,QAAQ;QACR,OAAO,CAAC,MAAc,EAAE,MAAM,GAAG,KAAK;YACpC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;YACtD,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;QAClE,CAAC;QACD,OAAO;YACL,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB,wDAAwD;AACxD,SAAS,SAAS;IAChB,IAAI,WAAW,IAAI,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrD,WAAW,GAAG,IAAI,CAAC;QACnB,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC;IACpB,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACjC,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BX,CAAC"}
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
* choice menu, a labeled diamond, a solo labeled diamond, and a generic rarity card). Games use it to show "which button to
|
|
6
6
|
* press" in one consistent visual language across the library.
|
|
7
7
|
*
|
|
8
|
+
* It also carries the **overheat HUD family** — the screen-edge heat vignette, the lockout glitch
|
|
9
|
+
* overlay, and the pre-assembled bar that composes both — so every game with a heat mechanic shares
|
|
10
|
+
* one look and can take just the pieces it needs (a game drawing its own bar takes only the cues).
|
|
11
|
+
*
|
|
8
12
|
* Self-contained, like `@rydr/game-sdk/three`'s perf-overlay: it injects its own scoped `.rydr-ui-*`
|
|
9
13
|
* CSS once into `<head>`, depends on no global styles or CSS variables, and pulls in no three.js — so
|
|
10
14
|
* a game gets the look just by constructing a component. Wire any keycap to real input by passing the
|
|
@@ -33,4 +37,7 @@ export * from "./solo-labeled-diamond.js";
|
|
|
33
37
|
export * from "./rarity-card.js";
|
|
34
38
|
export * from "./power-race.js";
|
|
35
39
|
export * from "./admin-nav.js";
|
|
40
|
+
export * from "./heat-vignette.js";
|
|
41
|
+
export * from "./overheat-glitch.js";
|
|
42
|
+
export * from "./overheat-hud-bar.js";
|
|
36
43
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/ui/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
package/dist/ui/index.js
CHANGED
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
* choice menu, a labeled diamond, a solo labeled diamond, and a generic rarity card). Games use it to show "which button to
|
|
6
6
|
* press" in one consistent visual language across the library.
|
|
7
7
|
*
|
|
8
|
+
* It also carries the **overheat HUD family** — the screen-edge heat vignette, the lockout glitch
|
|
9
|
+
* overlay, and the pre-assembled bar that composes both — so every game with a heat mechanic shares
|
|
10
|
+
* one look and can take just the pieces it needs (a game drawing its own bar takes only the cues).
|
|
11
|
+
*
|
|
8
12
|
* Self-contained, like `@rydr/game-sdk/three`'s perf-overlay: it injects its own scoped `.rydr-ui-*`
|
|
9
13
|
* CSS once into `<head>`, depends on no global styles or CSS variables, and pulls in no three.js — so
|
|
10
14
|
* a game gets the look just by constructing a component. Wire any keycap to real input by passing the
|
|
@@ -33,4 +37,7 @@ export * from "./solo-labeled-diamond.js";
|
|
|
33
37
|
export * from "./rarity-card.js";
|
|
34
38
|
export * from "./power-race.js";
|
|
35
39
|
export * from "./admin-nav.js";
|
|
40
|
+
export * from "./heat-vignette.js";
|
|
41
|
+
export * from "./overheat-glitch.js";
|
|
42
|
+
export * from "./overheat-hud-bar.js";
|
|
36
43
|
//# sourceMappingURL=index.js.map
|
package/dist/ui/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mountOverheatGlitch` — the **overheat lockout glitch overlay**, on its own.
|
|
3
|
+
*
|
|
4
|
+
* The "your engine just blew" screen dressing: a one-shot RGB chromatic-aberration burst on the
|
|
5
|
+
* frame the lockout begins (cyan slides left, red slides right, white pops in the middle, ~160 ms),
|
|
6
|
+
* then sustained scanlines + a red noise wash for as long as the lockout lasts. It makes a forced
|
|
7
|
+
* cooldown feel like a hardware failure rather than a stat change.
|
|
8
|
+
*
|
|
9
|
+
* This is the glitch **alone**, deliberately separable: a game that draws its own heat bar (e.g. the
|
|
10
|
+
* racing game's in-canvas gauge) still wants the lockout drama. Pair it with
|
|
11
|
+
* {@link mountHeatVignette} for the peripheral heat cue, or take the whole pre-assembled package —
|
|
12
|
+
* bar + vignette + glitch — from {@link mountOverheatHudBar}.
|
|
13
|
+
*
|
|
14
|
+
* Self-contained DOM/CSS like the rest of `@rydr/game-sdk/ui`: it injects its own scoped
|
|
15
|
+
* `.rydr-heat-glitch*` stylesheet once into `<head>`, needs no global styles, no CSS variables and no
|
|
16
|
+
* three.js. It is driven by a single boolean — the game owns the lockout state.
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* const glitch = mountOverheatGlitch(hudHost);
|
|
20
|
+
* // every frame (edge-detected internally — cheap to call unconditionally):
|
|
21
|
+
* glitch.setLocked(heat.isLocked);
|
|
22
|
+
* // on teardown:
|
|
23
|
+
* glitch.dispose();
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* **Host contract:** the overlay is `position: absolute; inset: 0` at `z-index: 21`, so `host` must
|
|
27
|
+
* be positioned (and ideally `isolation: isolate`, so the z-index doesn't leak past it). A
|
|
28
|
+
* full-viewport `position: fixed; inset: 0; pointer-events: none; isolation: isolate` div over the
|
|
29
|
+
* game canvas is the intended host.
|
|
30
|
+
*/
|
|
31
|
+
/** Options for {@link mountOverheatGlitch}. */
|
|
32
|
+
export interface OverheatGlitchOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Stacking order inside the host. Default `21` — above {@link mountHeatVignette} (19) and
|
|
35
|
+
* {@link mountOverheatHudBar}'s bar (20), so the three compose in the intended order.
|
|
36
|
+
*/
|
|
37
|
+
zIndex?: number;
|
|
38
|
+
}
|
|
39
|
+
/** Live handle to a mounted glitch overlay. Returned by {@link mountOverheatGlitch}. */
|
|
40
|
+
export interface OverheatGlitch {
|
|
41
|
+
/** The overlay element (already appended to the host). */
|
|
42
|
+
readonly root: HTMLDivElement;
|
|
43
|
+
/**
|
|
44
|
+
* Set the lockout state. Safe to call every frame — the entry burst fires only on the
|
|
45
|
+
* `false → true` edge, and the sustained dressing follows the flag.
|
|
46
|
+
*/
|
|
47
|
+
setLocked(locked: boolean): void;
|
|
48
|
+
/** Remove the overlay from the host and cancel any pending entry beat. Idempotent. */
|
|
49
|
+
dispose(): void;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Mount an overheat glitch overlay into `host`. See the module header for the host contract; drive
|
|
53
|
+
* it with {@link OverheatGlitch.setLocked}.
|
|
54
|
+
*/
|
|
55
|
+
export declare function mountOverheatGlitch(host: HTMLElement, opts?: OverheatGlitchOptions): OverheatGlitch;
|
|
56
|
+
//# sourceMappingURL=overheat-glitch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overheat-glitch.d.ts","sourceRoot":"","sources":["../../src/ui/overheat-glitch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAOH,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wFAAwF;AACxF,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,sFAAsF;IACtF,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,WAAW,EACjB,IAAI,GAAE,qBAA0B,GAC/B,cAAc,CAqChB"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mountOverheatGlitch` — the **overheat lockout glitch overlay**, on its own.
|
|
3
|
+
*
|
|
4
|
+
* The "your engine just blew" screen dressing: a one-shot RGB chromatic-aberration burst on the
|
|
5
|
+
* frame the lockout begins (cyan slides left, red slides right, white pops in the middle, ~160 ms),
|
|
6
|
+
* then sustained scanlines + a red noise wash for as long as the lockout lasts. It makes a forced
|
|
7
|
+
* cooldown feel like a hardware failure rather than a stat change.
|
|
8
|
+
*
|
|
9
|
+
* This is the glitch **alone**, deliberately separable: a game that draws its own heat bar (e.g. the
|
|
10
|
+
* racing game's in-canvas gauge) still wants the lockout drama. Pair it with
|
|
11
|
+
* {@link mountHeatVignette} for the peripheral heat cue, or take the whole pre-assembled package —
|
|
12
|
+
* bar + vignette + glitch — from {@link mountOverheatHudBar}.
|
|
13
|
+
*
|
|
14
|
+
* Self-contained DOM/CSS like the rest of `@rydr/game-sdk/ui`: it injects its own scoped
|
|
15
|
+
* `.rydr-heat-glitch*` stylesheet once into `<head>`, needs no global styles, no CSS variables and no
|
|
16
|
+
* three.js. It is driven by a single boolean — the game owns the lockout state.
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* const glitch = mountOverheatGlitch(hudHost);
|
|
20
|
+
* // every frame (edge-detected internally — cheap to call unconditionally):
|
|
21
|
+
* glitch.setLocked(heat.isLocked);
|
|
22
|
+
* // on teardown:
|
|
23
|
+
* glitch.dispose();
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* **Host contract:** the overlay is `position: absolute; inset: 0` at `z-index: 21`, so `host` must
|
|
27
|
+
* be positioned (and ideally `isolation: isolate`, so the z-index doesn't leak past it). A
|
|
28
|
+
* full-viewport `position: fixed; inset: 0; pointer-events: none; isolation: isolate` div over the
|
|
29
|
+
* game canvas is the intended host.
|
|
30
|
+
*/
|
|
31
|
+
const STYLE_ID = "rydr-heat-glitch-css";
|
|
32
|
+
/** How long the one-shot entry burst is allowed to run before its marker class is cleared (ms). */
|
|
33
|
+
const ENTRY_BEAT_MS = 500;
|
|
34
|
+
/**
|
|
35
|
+
* Mount an overheat glitch overlay into `host`. See the module header for the host contract; drive
|
|
36
|
+
* it with {@link OverheatGlitch.setLocked}.
|
|
37
|
+
*/
|
|
38
|
+
export function mountOverheatGlitch(host, opts = {}) {
|
|
39
|
+
injectCss();
|
|
40
|
+
const root = document.createElement("div");
|
|
41
|
+
root.className = "rydr-heat-glitch";
|
|
42
|
+
if (opts.zIndex !== undefined)
|
|
43
|
+
root.style.zIndex = String(opts.zIndex);
|
|
44
|
+
root.innerHTML = `
|
|
45
|
+
<div class="rydr-heat-glitch-scanlines"></div>
|
|
46
|
+
<div class="rydr-heat-glitch-noise"></div>
|
|
47
|
+
<div class="rydr-heat-glitch-flash">
|
|
48
|
+
<div class="flash-cyan"></div>
|
|
49
|
+
<div class="flash-red"></div>
|
|
50
|
+
<div class="flash-white"></div>
|
|
51
|
+
</div>
|
|
52
|
+
`;
|
|
53
|
+
host.appendChild(root);
|
|
54
|
+
let lastLocked = false;
|
|
55
|
+
/** Timer clearing the one-shot `.entry` marker after the entry burst. */
|
|
56
|
+
let entryTimer = 0;
|
|
57
|
+
return {
|
|
58
|
+
root,
|
|
59
|
+
setLocked(locked) {
|
|
60
|
+
if (locked === lastLocked)
|
|
61
|
+
return;
|
|
62
|
+
lastLocked = locked;
|
|
63
|
+
root.classList.toggle("locked", locked);
|
|
64
|
+
if (!locked)
|
|
65
|
+
return;
|
|
66
|
+
root.classList.add("entry");
|
|
67
|
+
clearTimeout(entryTimer);
|
|
68
|
+
entryTimer = window.setTimeout(() => root.classList.remove("entry"), ENTRY_BEAT_MS);
|
|
69
|
+
},
|
|
70
|
+
dispose() {
|
|
71
|
+
clearTimeout(entryTimer);
|
|
72
|
+
root.remove();
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
let cssInjected = false;
|
|
77
|
+
/** Inject the scoped glitch CSS once per document. */
|
|
78
|
+
function injectCss() {
|
|
79
|
+
if (cssInjected || document.getElementById(STYLE_ID)) {
|
|
80
|
+
cssInjected = true;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const style = document.createElement("style");
|
|
84
|
+
style.id = STYLE_ID;
|
|
85
|
+
style.textContent = CSS;
|
|
86
|
+
document.head.appendChild(style);
|
|
87
|
+
cssInjected = true;
|
|
88
|
+
}
|
|
89
|
+
const CSS = `
|
|
90
|
+
.rydr-heat-glitch {
|
|
91
|
+
position: absolute;
|
|
92
|
+
inset: 0;
|
|
93
|
+
pointer-events: none;
|
|
94
|
+
z-index: 21;
|
|
95
|
+
opacity: 0;
|
|
96
|
+
transition: opacity 0.2s;
|
|
97
|
+
}
|
|
98
|
+
.rydr-heat-glitch.locked { opacity: 1; }
|
|
99
|
+
|
|
100
|
+
/* ─── SUSTAINED DRESSING ──────────────────────────────────────── */
|
|
101
|
+
.rydr-heat-glitch-scanlines {
|
|
102
|
+
position: absolute;
|
|
103
|
+
inset: 0;
|
|
104
|
+
background: repeating-linear-gradient(
|
|
105
|
+
0deg,
|
|
106
|
+
rgba(0,0,0,0.18) 0 2px,
|
|
107
|
+
transparent 2px 4px
|
|
108
|
+
);
|
|
109
|
+
animation: rydr-heat-glitch-scan 0.7s linear infinite;
|
|
110
|
+
}
|
|
111
|
+
@keyframes rydr-heat-glitch-scan {
|
|
112
|
+
from { background-position: 0 0; }
|
|
113
|
+
to { background-position: 0 8px; }
|
|
114
|
+
}
|
|
115
|
+
.rydr-heat-glitch-noise {
|
|
116
|
+
position: absolute;
|
|
117
|
+
inset: 0;
|
|
118
|
+
background:
|
|
119
|
+
radial-gradient(at 20% 30%, rgba(239,68,68,0.12), transparent 60%),
|
|
120
|
+
radial-gradient(at 80% 70%, rgba(239,68,68,0.10), transparent 55%),
|
|
121
|
+
radial-gradient(at 50% 90%, rgba(220,38,38,0.08), transparent 50%);
|
|
122
|
+
mix-blend-mode: screen;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* ─── ENTRY BEAT — RGB FLASH ──────────────────────────────────────
|
|
126
|
+
Full-screen chromatic-aberration burst when the lockout begins. Cyan
|
|
127
|
+
layer slides left, red slides right, white pops in the middle. ~160 ms. */
|
|
128
|
+
.rydr-heat-glitch-flash {
|
|
129
|
+
position: absolute;
|
|
130
|
+
inset: 0;
|
|
131
|
+
opacity: 0;
|
|
132
|
+
pointer-events: none;
|
|
133
|
+
}
|
|
134
|
+
.rydr-heat-glitch-flash .flash-cyan,
|
|
135
|
+
.rydr-heat-glitch-flash .flash-red,
|
|
136
|
+
.rydr-heat-glitch-flash .flash-white {
|
|
137
|
+
position: absolute;
|
|
138
|
+
inset: 0;
|
|
139
|
+
mix-blend-mode: screen;
|
|
140
|
+
}
|
|
141
|
+
.rydr-heat-glitch-flash .flash-cyan { background: rgba(0, 220, 255, 0.40); }
|
|
142
|
+
.rydr-heat-glitch-flash .flash-red { background: rgba(255, 0, 80, 0.40); }
|
|
143
|
+
.rydr-heat-glitch-flash .flash-white { background: rgba(255, 255, 255, 0.35); }
|
|
144
|
+
|
|
145
|
+
.rydr-heat-glitch.entry .rydr-heat-glitch-flash {
|
|
146
|
+
animation: rydr-heat-glitch-flash-shell 0.16s ease-out forwards;
|
|
147
|
+
}
|
|
148
|
+
.rydr-heat-glitch.entry .rydr-heat-glitch-flash .flash-cyan {
|
|
149
|
+
animation: rydr-heat-glitch-shift-left 0.16s ease-out forwards;
|
|
150
|
+
}
|
|
151
|
+
.rydr-heat-glitch.entry .rydr-heat-glitch-flash .flash-red {
|
|
152
|
+
animation: rydr-heat-glitch-shift-right 0.16s ease-out forwards;
|
|
153
|
+
}
|
|
154
|
+
.rydr-heat-glitch.entry .rydr-heat-glitch-flash .flash-white {
|
|
155
|
+
animation: rydr-heat-glitch-pop 0.16s ease-out forwards;
|
|
156
|
+
}
|
|
157
|
+
@keyframes rydr-heat-glitch-flash-shell {
|
|
158
|
+
0% { opacity: 0; }
|
|
159
|
+
35% { opacity: 1; }
|
|
160
|
+
100% { opacity: 0; }
|
|
161
|
+
}
|
|
162
|
+
@keyframes rydr-heat-glitch-shift-left {
|
|
163
|
+
0% { transform: translateX(0); }
|
|
164
|
+
35% { transform: translateX(-14px); }
|
|
165
|
+
100% { transform: translateX(0); }
|
|
166
|
+
}
|
|
167
|
+
@keyframes rydr-heat-glitch-shift-right {
|
|
168
|
+
0% { transform: translateX(0); }
|
|
169
|
+
35% { transform: translateX(14px); }
|
|
170
|
+
100% { transform: translateX(0); }
|
|
171
|
+
}
|
|
172
|
+
@keyframes rydr-heat-glitch-pop {
|
|
173
|
+
0%, 100% { opacity: 0; }
|
|
174
|
+
35% { opacity: 1; }
|
|
175
|
+
}
|
|
176
|
+
`;
|
|
177
|
+
//# sourceMappingURL=overheat-glitch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overheat-glitch.js","sourceRoot":"","sources":["../../src/ui/overheat-glitch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,QAAQ,GAAG,sBAAsB,CAAC;AAExC,mGAAmG;AACnG,MAAM,aAAa,GAAG,GAAG,CAAC;AAwB1B;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAiB,EACjB,OAA8B,EAAE;IAEhC,SAAS,EAAE,CAAC;IAEZ,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC3C,IAAI,CAAC,SAAS,GAAG,kBAAkB,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvE,IAAI,CAAC,SAAS,GAAG;;;;;;;;GAQhB,CAAC;IACF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAEvB,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,yEAAyE;IACzE,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,OAAO;QACL,IAAI;QACJ,SAAS,CAAC,MAAe;YACvB,IAAI,MAAM,KAAK,UAAU;gBAAE,OAAO;YAClC,UAAU,GAAG,MAAM,CAAC;YACpB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACxC,IAAI,CAAC,MAAM;gBAAE,OAAO;YACpB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC5B,YAAY,CAAC,UAAU,CAAC,CAAC;YACzB,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,CAAC;QACtF,CAAC;QACD,OAAO;YACL,YAAY,CAAC,UAAU,CAAC,CAAC;YACzB,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB,sDAAsD;AACtD,SAAS,SAAS;IAChB,IAAI,WAAW,IAAI,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrD,WAAW,GAAG,IAAI,CAAC;QACnB,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC;IACpB,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACjC,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuFX,CAAC"}
|