@edv4h/usketch-plugin-character 0.2.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +84 -0
  3. package/dist/character-camera.d.ts +33 -0
  4. package/dist/character-camera.d.ts.map +1 -0
  5. package/dist/character-camera.js +45 -0
  6. package/dist/character-camera.js.map +1 -0
  7. package/dist/character-input.d.ts +18 -0
  8. package/dist/character-input.d.ts.map +1 -0
  9. package/dist/character-input.js +89 -0
  10. package/dist/character-input.js.map +1 -0
  11. package/dist/character-layer.d.ts +7 -0
  12. package/dist/character-layer.d.ts.map +1 -0
  13. package/dist/character-layer.js +53 -0
  14. package/dist/character-layer.js.map +1 -0
  15. package/dist/character-physics.d.ts +55 -0
  16. package/dist/character-physics.d.ts.map +1 -0
  17. package/dist/character-physics.js +97 -0
  18. package/dist/character-physics.js.map +1 -0
  19. package/dist/character-runtime.d.ts +30 -0
  20. package/dist/character-runtime.d.ts.map +1 -0
  21. package/dist/character-runtime.js +229 -0
  22. package/dist/character-runtime.js.map +1 -0
  23. package/dist/character-service.d.ts +47 -0
  24. package/dist/character-service.d.ts.map +1 -0
  25. package/dist/character-service.js +36 -0
  26. package/dist/character-service.js.map +1 -0
  27. package/dist/character-store.d.ts +55 -0
  28. package/dist/character-store.d.ts.map +1 -0
  29. package/dist/character-store.js +100 -0
  30. package/dist/character-store.js.map +1 -0
  31. package/dist/character-sync.d.ts +42 -0
  32. package/dist/character-sync.d.ts.map +1 -0
  33. package/dist/character-sync.js +117 -0
  34. package/dist/character-sync.js.map +1 -0
  35. package/dist/character-types.d.ts +52 -0
  36. package/dist/character-types.d.ts.map +1 -0
  37. package/dist/character-types.js +7 -0
  38. package/dist/character-types.js.map +1 -0
  39. package/dist/index.d.ts +8 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +8 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/plugin.d.ts +36 -0
  44. package/dist/plugin.d.ts.map +1 -0
  45. package/dist/plugin.js +38 -0
  46. package/dist/plugin.js.map +1 -0
  47. package/dist/register-character-hud.d.ts +4 -0
  48. package/dist/register-character-hud.d.ts.map +1 -0
  49. package/dist/register-character-hud.js +122 -0
  50. package/dist/register-character-hud.js.map +1 -0
  51. package/package.json +48 -0
@@ -0,0 +1,117 @@
1
+ // Multiplayer via Yjs awareness (same model as the avatar plugin): each client
2
+ // publishes its own character under the `character` field; everyone reads the
3
+ // others' fields. Awareness is ephemeral — a client's character disappears when it
4
+ // disconnects — which is exactly the "coexisting live characters" semantics.
5
+ // Typed structurally so the plugin doesn't depend on @edv4h/usketch-sync.
6
+ import { wrapDeg } from "@edv4h/usketch-shared";
7
+ export const AWARENESS_FIELD = "character";
8
+ /** Validate an untrusted awareness payload (other clients can send anything). */
9
+ export function parseWireState(v) {
10
+ if (!v || typeof v !== "object")
11
+ return null;
12
+ const o = v;
13
+ const num = (k) => typeof o[k] === "number" && Number.isFinite(o[k]) ? o[k] : null;
14
+ const x = num("x");
15
+ const y = num("y");
16
+ const heading = num("heading");
17
+ if (x === null || y === null || heading === null)
18
+ return null;
19
+ const appearance = o.appearance && typeof o.appearance === "object" && !Array.isArray(o.appearance)
20
+ ? o.appearance
21
+ : {};
22
+ return {
23
+ x,
24
+ y,
25
+ heading: wrapDeg(heading),
26
+ speed: num("speed") ?? 0,
27
+ moving: o.moving === true,
28
+ appearance,
29
+ name: typeof o.name === "string" ? o.name : undefined,
30
+ };
31
+ }
32
+ /** Minimum interval between broadcasts (≈20 Hz) — remote views interpolate between. */
33
+ export const BROADCAST_INTERVAL_MS = 50;
34
+ export function createCharacterSync(awareness, store, onTargetsChanged, now = () => Date.now()) {
35
+ let lastSent = Number.NEGATIVE_INFINITY;
36
+ let lastPayload = null;
37
+ let targets = new Map();
38
+ const publish = (force = false) => {
39
+ const s = store.getState();
40
+ const t = now();
41
+ if (!force && t - lastSent < BROADCAST_INTERVAL_MS)
42
+ return;
43
+ const wire = s.enabled
44
+ ? {
45
+ x: s.pose.x,
46
+ y: s.pose.y,
47
+ heading: s.pose.heading,
48
+ speed: s.pose.speed,
49
+ moving: s.pose.moving,
50
+ appearance: s.appearance,
51
+ name: s.name,
52
+ }
53
+ : null;
54
+ const payload = JSON.stringify(wire);
55
+ if (payload === lastPayload)
56
+ return; // idle: don't spam awareness
57
+ lastPayload = payload;
58
+ lastSent = t;
59
+ awareness.setLocalStateField(AWARENESS_FIELD, wire);
60
+ };
61
+ const read = () => {
62
+ const next = new Map();
63
+ for (const [clientId, st] of awareness.getStates()) {
64
+ if (clientId === awareness.clientID)
65
+ continue;
66
+ const w = parseWireState(st?.[AWARENESS_FIELD]);
67
+ if (!w)
68
+ continue;
69
+ const id = String(clientId);
70
+ next.set(id, { id, ...w });
71
+ }
72
+ targets = next;
73
+ onTargetsChanged();
74
+ };
75
+ awareness.on("change", read);
76
+ read();
77
+ return {
78
+ publish,
79
+ targets: () => targets,
80
+ dispose() {
81
+ awareness.off("change", read);
82
+ // Withdraw our character so it vanishes for others right away.
83
+ awareness.setLocalStateField(AWARENESS_FIELD, null);
84
+ },
85
+ };
86
+ }
87
+ /**
88
+ * Ease displayed remote poses toward their latest targets (hides the ~20 Hz
89
+ * update steps). Returns the next display map and whether anything is still moving.
90
+ */
91
+ export function easeRemotes(display, targets, alpha) {
92
+ const next = new Map();
93
+ let settling = false;
94
+ for (const [id, t] of targets) {
95
+ const d = display.get(id);
96
+ if (!d) {
97
+ next.set(id, t);
98
+ continue;
99
+ }
100
+ const dx = t.x - d.x;
101
+ const dy = t.y - d.y;
102
+ const dh = wrapDeg(t.heading - d.heading);
103
+ if (Math.abs(dx) < 0.05 && Math.abs(dy) < 0.05 && Math.abs(dh) < 0.05) {
104
+ next.set(id, t);
105
+ continue;
106
+ }
107
+ settling = true;
108
+ next.set(id, {
109
+ ...t,
110
+ x: d.x + dx * alpha,
111
+ y: d.y + dy * alpha,
112
+ heading: wrapDeg(d.heading + dh * alpha),
113
+ });
114
+ }
115
+ return { next, settling };
116
+ }
117
+ //# sourceMappingURL=character-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"character-sync.js","sourceRoot":"","sources":["../src/character-sync.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,8EAA8E;AAC9E,mFAAmF;AACnF,6EAA6E;AAC7E,0EAA0E;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAahD,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAC;AAa3C,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,CAAU;IACxC,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC7C,MAAM,CAAC,GAAG,CAA4B,CAAC;IACvC,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CACzB,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAY,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7E,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;IAC/B,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC9D,MAAM,UAAU,GACf,CAAC,CAAC,UAAU,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;QAC/E,CAAC,CAAE,CAAC,CAAC,UAAkC;QACvC,CAAC,CAAC,EAAE,CAAC;IACP,OAAO;QACN,CAAC;QACD,CAAC;QACD,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;QACzB,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;QACxB,MAAM,EAAE,CAAC,CAAC,MAAM,KAAK,IAAI;QACzB,UAAU;QACV,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;KACrD,CAAC;AACH,CAAC;AAED,uFAAuF;AACvF,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAUxC,MAAM,UAAU,mBAAmB,CAClC,SAA6B,EAC7B,KAAqB,EACrB,gBAA4B,EAC5B,GAAG,GAAiB,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;IAEpC,IAAI,QAAQ,GAAG,MAAM,CAAC,iBAAiB,CAAC;IACxC,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,IAAI,OAAO,GAAyC,IAAI,GAAG,EAAE,CAAC;IAE9D,MAAM,OAAO,GAAG,CAAC,KAAK,GAAG,KAAK,EAAQ,EAAE;QACvC,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG,QAAQ,GAAG,qBAAqB;YAAE,OAAO;QAC3D,MAAM,IAAI,GAA8B,CAAC,CAAC,OAAO;YAChD,CAAC,CAAC;gBACA,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;gBACX,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;gBACX,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO;gBACvB,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK;gBACnB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM;gBACrB,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,IAAI,EAAE,CAAC,CAAC,IAAI;aACZ;YACF,CAAC,CAAC,IAAI,CAAC;QACR,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,OAAO,KAAK,WAAW;YAAE,OAAO,CAAC,6BAA6B;QAClE,WAAW,GAAG,OAAO,CAAC;QACtB,QAAQ,GAAG,CAAC,CAAC;QACb,SAAS,CAAC,kBAAkB,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IACrD,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,GAAS,EAAE;QACvB,MAAM,IAAI,GAAG,IAAI,GAAG,EAA2B,CAAC;QAChD,KAAK,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC,SAAS,EAAE,EAAE,CAAC;YACpD,IAAI,QAAQ,KAAK,SAAS,CAAC,QAAQ;gBAAE,SAAS;YAC9C,MAAM,CAAC,GAAG,cAAc,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;YAChD,IAAI,CAAC,CAAC;gBAAE,SAAS;YACjB,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;QACf,gBAAgB,EAAE,CAAC;IACpB,CAAC,CAAC;IAEF,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC;IAEP,OAAO;QACN,OAAO;QACP,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO;QACtB,OAAO;YACN,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAC9B,+DAA+D;YAC/D,SAAS,CAAC,kBAAkB,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC;KACD,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAC1B,OAA6C,EAC7C,OAA6C,EAC7C,KAAa;IAEb,MAAM,IAAI,GAAG,IAAI,GAAG,EAA2B,CAAC;IAChD,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1B,IAAI,CAAC,CAAC,EAAE,CAAC;YACR,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAChB,SAAS;QACV,CAAC;QACD,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC;YACvE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAChB,SAAS;QACV,CAAC;QACD,QAAQ,GAAG,IAAI,CAAC;QAChB,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE;YACZ,GAAG,CAAC;YACJ,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK;YACnB,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK;YACnB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,GAAG,KAAK,CAAC;SACxC,CAAC,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,52 @@
1
+ import type { ReactNode } from "react";
2
+ /** JSON-serializable look data, broadcast so other clients can draw you the same way. */
3
+ export type CharacterAppearance = Record<string, unknown>;
4
+ /** Everything a renderer needs to draw one character at its (already placed) spot. */
5
+ export interface CharacterRenderProps {
6
+ /** `"self"` for the local character, otherwise the remote client's id. */
7
+ id: string;
8
+ isSelf: boolean;
9
+ /** Facing in the world, degrees (0 = up / -y, clockwise). */
10
+ heading: number;
11
+ /**
12
+ * Apparent facing ON SCREEN = `heading + viewport.rotation`. Rotate a top-down
13
+ * sprite by this (`transform: rotate(${screenHeading}deg)`); a side-view sprite
14
+ * might instead flip on its sign.
15
+ */
16
+ screenHeading: number;
17
+ /** Whether the character is moving right now (drive walk cycles etc.). */
18
+ moving: boolean;
19
+ /** Signed speed along the heading, world units / s. */
20
+ speed: number;
21
+ /** Current viewport zoom (scale the sprite with the world, or not). */
22
+ zoom: number;
23
+ /** The owner's broadcast appearance. */
24
+ appearance: CharacterAppearance;
25
+ /** The owner's display name, if any. */
26
+ name?: string;
27
+ }
28
+ /**
29
+ * Draws one character. The plugin places the returned node centered on the
30
+ * character's screen position (a zero-size, pointer-transparent wrapper).
31
+ */
32
+ export type CharacterRenderer = (props: CharacterRenderProps) => ReactNode;
33
+ /** A remote client's character as last received (plus the smoothed display pose). */
34
+ export interface RemoteCharacter {
35
+ id: string;
36
+ x: number;
37
+ y: number;
38
+ heading: number;
39
+ speed: number;
40
+ moving: boolean;
41
+ appearance: CharacterAppearance;
42
+ name?: string;
43
+ }
44
+ /** Customizable key bindings: `KeyboardEvent.code` values per direction. */
45
+ export interface CharacterKeys {
46
+ up: string[];
47
+ down: string[];
48
+ left: string[];
49
+ right: string[];
50
+ }
51
+ export declare const DEFAULT_KEYS: CharacterKeys;
52
+ //# sourceMappingURL=character-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"character-types.d.ts","sourceRoot":"","sources":["../src/character-types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,yFAAyF;AACzF,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1D,sFAAsF;AACtF,MAAM,WAAW,oBAAoB;IACpC,0EAA0E;IAC1E,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;IAChB,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,MAAM,EAAE,OAAO,CAAC;IAChB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,UAAU,EAAE,mBAAmB,CAAC;IAChC,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,oBAAoB,KAAK,SAAS,CAAC;AAE3E,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,mBAAmB,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC7B,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,eAAO,MAAM,YAAY,EAAE,aAK1B,CAAC"}
@@ -0,0 +1,7 @@
1
+ export const DEFAULT_KEYS = {
2
+ up: ["KeyW"],
3
+ down: ["KeyS"],
4
+ left: ["KeyA"],
5
+ right: ["KeyD"],
6
+ };
7
+ //# sourceMappingURL=character-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"character-types.js","sourceRoot":"","sources":["../src/character-types.ts"],"names":[],"mappings":"AA0DA,MAAM,CAAC,MAAM,YAAY,GAAkB;IAC1C,EAAE,EAAE,CAAC,MAAM,CAAC;IACZ,IAAI,EAAE,CAAC,MAAM,CAAC;IACd,IAAI,EAAE,CAAC,MAAM,CAAC;IACd,KAAK,EAAE,CAAC,MAAM,CAAC;CACf,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { anchorPx, type CameraFocus, type CameraMode, easeFocus, followViewport, smoothingAlpha, targetRotation, } from "./character-camera.js";
2
+ export { type CharacterPose, type ControlScheme, DEFAULT_MOTION, headingVector, type MotionParams, type MoveInput, stepCharacter, turnToward, vectorHeading, } from "./character-physics.js";
3
+ export { CHARACTER_LAYER_ID, CHARACTER_VIEWPORT_PRIORITY } from "./character-runtime.js";
4
+ export { type CharacterApi, characterService, getCharacterApi, } from "./character-service.js";
5
+ export { AWARENESS_FIELD, type CharacterAwareness, type CharacterWireState, parseWireState, } from "./character-sync.js";
6
+ export { type CharacterAppearance, type CharacterKeys, type CharacterRenderer, type CharacterRenderProps, DEFAULT_KEYS, type RemoteCharacter, } from "./character-types.js";
7
+ export { type CharacterPluginOptions, createCharacterPlugin } from "./plugin.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,QAAQ,EACR,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,SAAS,EACT,cAAc,EACd,cAAc,EACd,cAAc,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,cAAc,EACd,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,aAAa,EACb,UAAU,EACV,aAAa,GACb,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EACN,KAAK,YAAY,EACjB,gBAAgB,EAChB,eAAe,GACf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,eAAe,EACf,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,cAAc,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,YAAY,EACZ,KAAK,eAAe,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export { anchorPx, easeFocus, followViewport, smoothingAlpha, targetRotation, } from "./character-camera.js";
2
+ export { DEFAULT_MOTION, headingVector, stepCharacter, turnToward, vectorHeading, } from "./character-physics.js";
3
+ export { CHARACTER_LAYER_ID, CHARACTER_VIEWPORT_PRIORITY } from "./character-runtime.js";
4
+ export { characterService, getCharacterApi, } from "./character-service.js";
5
+ export { AWARENESS_FIELD, parseWireState, } from "./character-sync.js";
6
+ export { DEFAULT_KEYS, } from "./character-types.js";
7
+ export { createCharacterPlugin } from "./plugin.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,QAAQ,EAGR,SAAS,EACT,cAAc,EACd,cAAc,EACd,cAAc,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGN,cAAc,EACd,aAAa,EAGb,aAAa,EACb,UAAU,EACV,aAAa,GACb,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAEN,gBAAgB,EAChB,eAAe,GACf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,eAAe,EAGf,cAAc,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAKN,YAAY,GAEZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAA+B,qBAAqB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { UsketchPlugin } from "@edv4h/usketch-shared";
2
+ import type { CameraMode } from "./character-camera.js";
3
+ import type { ControlScheme, MotionParams } from "./character-physics.js";
4
+ import type { CharacterAwareness } from "./character-sync.js";
5
+ import { type CharacterAppearance, type CharacterKeys, type CharacterRenderer } from "./character-types.js";
6
+ export interface CharacterPluginOptions {
7
+ /** Draws a character (self and others). Omitted = headless (nothing drawn). */
8
+ renderCharacter?: CharacterRenderer;
9
+ /** Broadcast look data for your character (e.g. `{ color: "#e44" }`). */
10
+ appearance?: CharacterAppearance;
11
+ /** Multiplayer: share characters through this provider's awareness. Omitted = solo. */
12
+ wsProvider?: {
13
+ awareness: CharacterAwareness;
14
+ };
15
+ /** Display name sent with your character. */
16
+ userName?: string;
17
+ /** Movement keys as `KeyboardEvent.code` lists (default WASD). */
18
+ keys?: Partial<CharacterKeys>;
19
+ /** Start with the character on (default `false`). */
20
+ enabledInitially?: boolean;
21
+ /** Default `"fixed"`. */
22
+ cameraMode?: CameraMode;
23
+ /** Default `"directional"`. */
24
+ controlScheme?: ControlScheme;
25
+ /** Speed / turning / vehicle tuning. */
26
+ motion?: Partial<MotionParams>;
27
+ /** Where the character sits on screen, as canvas fractions (default center). */
28
+ screenAnchor?: {
29
+ x?: number;
30
+ y?: number;
31
+ };
32
+ /** Follow-camera lag: 0 = rigid (default) … 0.99 = heavy. */
33
+ followSmoothing?: number;
34
+ }
35
+ export declare function createCharacterPlugin(options?: CharacterPluginOptions): UsketchPlugin;
36
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAiB,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAI1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAEtB,MAAM,sBAAsB,CAAC;AAG9B,MAAM,WAAW,sBAAsB;IACtC,+EAA+E;IAC/E,eAAe,CAAC,EAAE,iBAAiB,CAAC;IACpC,yEAAyE;IACzE,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,uFAAuF;IACvF,UAAU,CAAC,EAAE;QAAE,SAAS,EAAE,kBAAkB,CAAA;KAAE,CAAC;IAC/C,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9B,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yBAAyB;IACzB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,+BAA+B;IAC/B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wCAAwC;IACxC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,gFAAgF;IAChF,YAAY,CAAC,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,aAAa,CAgCzF"}
package/dist/plugin.js ADDED
@@ -0,0 +1,38 @@
1
+ import { setupCharacterRuntime } from "./character-runtime.js";
2
+ import { characterService, createCharacterApi } from "./character-service.js";
3
+ import { createCharacterStore } from "./character-store.js";
4
+ import { DEFAULT_KEYS, } from "./character-types.js";
5
+ import { registerCharacterHud } from "./register-character-hud.js";
6
+ export function createCharacterPlugin(options = {}) {
7
+ return {
8
+ id: "usketch-plugin-character",
9
+ name: "キャラクター",
10
+ setup(ctx) {
11
+ const store = createCharacterStore({
12
+ enabled: options.enabledInitially,
13
+ cameraMode: options.cameraMode,
14
+ controlScheme: options.controlScheme,
15
+ motion: options.motion,
16
+ anchor: options.screenAnchor,
17
+ followSmoothing: options.followSmoothing,
18
+ appearance: options.appearance,
19
+ name: options.userName,
20
+ renderer: options.renderCharacter,
21
+ });
22
+ const runtime = setupCharacterRuntime(ctx, store, {
23
+ keys: { ...DEFAULT_KEYS, ...options.keys },
24
+ awareness: options.wsProvider?.awareness,
25
+ });
26
+ const api = createCharacterApi(store, runtime);
27
+ const stopHud = registerCharacterHud(ctx, api);
28
+ // Provide the service LAST so a failed earlier step can't leak it.
29
+ const unprovide = characterService.provide(ctx.services, api);
30
+ return () => {
31
+ unprovide();
32
+ stopHud();
33
+ runtime.dispose();
34
+ };
35
+ },
36
+ };
37
+ }
38
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,EAIN,YAAY,GACZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AA2BnE,MAAM,UAAU,qBAAqB,CAAC,OAAO,GAA2B,EAAE;IACzE,OAAO;QACN,EAAE,EAAE,0BAA0B;QAC9B,IAAI,EAAE,QAAQ;QACd,KAAK,CAAC,GAAkB;YACvB,MAAM,KAAK,GAAG,oBAAoB,CAAC;gBAClC,OAAO,EAAE,OAAO,CAAC,gBAAgB;gBACjC,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,MAAM,EAAE,OAAO,CAAC,YAAY;gBAC5B,eAAe,EAAE,OAAO,CAAC,eAAe;gBACxC,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,IAAI,EAAE,OAAO,CAAC,QAAQ;gBACtB,QAAQ,EAAE,OAAO,CAAC,eAAe;aACjC,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,qBAAqB,CAAC,GAAG,EAAE,KAAK,EAAE;gBACjD,IAAI,EAAE,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE;gBAC1C,SAAS,EAAE,OAAO,CAAC,UAAU,EAAE,SAAS;aACxC,CAAC,CAAC;YACH,MAAM,GAAG,GAAG,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAC/C,MAAM,OAAO,GAAG,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC/C,mEAAmE;YACnE,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YAE9D,OAAO,GAAG,EAAE;gBACX,SAAS,EAAE,CAAC;gBACZ,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,OAAO,EAAE,CAAC;YACnB,CAAC,CAAC;QACH,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { PluginContext } from "@edv4h/usketch-shared";
2
+ import type { CharacterApi } from "./character-service.js";
3
+ export declare function registerCharacterHud(ctx: PluginContext, api: CharacterApi): () => void;
4
+ //# sourceMappingURL=register-character-hud.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-character-hud.d.ts","sourceRoot":"","sources":["../src/register-character-hud.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAO3D,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,GAAG,MAAM,IAAI,CAmHtF"}
@@ -0,0 +1,122 @@
1
+ const CAMERA_MODES = ["fixed", "rotate", "free"];
2
+ const SCHEMES = ["directional", "vehicle"];
3
+ const truthy = (v) => v === true || v === "true";
4
+ export function registerCharacterHud(ctx, api) {
5
+ const offSettings = ctx.hud.registerSettings({
6
+ id: "usketch-plugin-character:settings",
7
+ label: "キャラクター",
8
+ order: 15,
9
+ fields: [
10
+ { name: "enabled", label: "操作キャラ", type: "boolean" },
11
+ {
12
+ name: "cameraMode",
13
+ label: "カメラ",
14
+ type: "enum",
15
+ options: [
16
+ { value: "fixed", label: "追従(固定)" },
17
+ { value: "rotate", label: "追従(向きで回転)" },
18
+ { value: "free", label: "追従しない" },
19
+ ],
20
+ },
21
+ {
22
+ name: "controlScheme",
23
+ label: "操作方式",
24
+ type: "enum",
25
+ options: [
26
+ { value: "directional", label: "方向移動" },
27
+ { value: "vehicle", label: "車(前進+旋回)" },
28
+ ],
29
+ },
30
+ { name: "moveSpeed", label: "速度", type: "number", min: 50, max: 3000, step: 50 },
31
+ { name: "turnRate", label: "旋回(°/秒)", type: "number", min: 30, max: 1080, step: 30 },
32
+ { name: "anchorX", label: "画面位置 横(%)", type: "number", min: 0, max: 100, step: 5 },
33
+ { name: "anchorY", label: "画面位置 縦(%)", type: "number", min: 0, max: 100, step: 5 },
34
+ { name: "smoothing", label: "カメラ遅れ(%)", type: "number", min: 0, max: 95, step: 5 },
35
+ ],
36
+ get(name) {
37
+ const motion = api.getMotion();
38
+ const anchor = api.getAnchor();
39
+ switch (name) {
40
+ case "enabled":
41
+ return api.isEnabled();
42
+ case "cameraMode":
43
+ return api.getCameraMode();
44
+ case "controlScheme":
45
+ return api.getControlScheme();
46
+ case "moveSpeed":
47
+ return motion.moveSpeed;
48
+ case "turnRate":
49
+ return motion.turnRate;
50
+ case "anchorX":
51
+ return Math.round(anchor.x * 100);
52
+ case "anchorY":
53
+ return Math.round(anchor.y * 100);
54
+ case "smoothing":
55
+ return Math.round(api.getFollowSmoothing() * 100);
56
+ default:
57
+ return undefined;
58
+ }
59
+ },
60
+ set(name, value) {
61
+ switch (name) {
62
+ case "enabled":
63
+ if (truthy(value))
64
+ api.enable();
65
+ else
66
+ api.disable();
67
+ return;
68
+ case "cameraMode":
69
+ if (CAMERA_MODES.includes(value))
70
+ api.setCameraMode(value);
71
+ return;
72
+ case "controlScheme":
73
+ if (SCHEMES.includes(value))
74
+ api.setControlScheme(value);
75
+ return;
76
+ }
77
+ const n = Number(value);
78
+ if (!Number.isFinite(n))
79
+ return;
80
+ switch (name) {
81
+ case "moveSpeed":
82
+ api.setMotion({ moveSpeed: n });
83
+ break;
84
+ case "turnRate":
85
+ api.setMotion({ turnRate: n });
86
+ break;
87
+ case "anchorX":
88
+ api.setAnchor({ x: n / 100 });
89
+ break;
90
+ case "anchorY":
91
+ api.setAnchor({ y: n / 100 });
92
+ break;
93
+ case "smoothing":
94
+ api.setFollowSmoothing(n / 100);
95
+ break;
96
+ }
97
+ },
98
+ subscribe: (listener) => api.onChange(listener),
99
+ });
100
+ const offToggle = ctx.actions.register({
101
+ id: "character:toggle",
102
+ label: "操作キャラ ON/OFF",
103
+ group: "キャラクター",
104
+ order: 1,
105
+ run: () => api.toggle(),
106
+ isActive: () => api.isEnabled(),
107
+ });
108
+ const offPlace = ctx.actions.register({
109
+ id: "character:place-at-anchor",
110
+ label: "キャラを画面位置に配置",
111
+ group: "キャラクター",
112
+ order: 2,
113
+ run: () => api.placeAtAnchor(),
114
+ isEnabled: () => api.isEnabled(),
115
+ });
116
+ return () => {
117
+ offPlace();
118
+ offToggle();
119
+ offSettings();
120
+ };
121
+ }
122
+ //# sourceMappingURL=register-character-hud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-character-hud.js","sourceRoot":"","sources":["../src/register-character-hud.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@edv4h/usketch-plugin-character",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "source": "./src/index.ts",
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "dependencies": {
15
+ "@edv4h/usketch-shared": "4.14.0"
16
+ },
17
+ "peerDependencies": {
18
+ "react": ">=19"
19
+ },
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "README.md"
26
+ ],
27
+ "license": "MIT",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/EdV4H/usketch.git",
31
+ "directory": "plugins/usketch-plugin-character"
32
+ },
33
+ "homepage": "https://github.com/EdV4H/usketch#readme",
34
+ "bugs": {
35
+ "url": "https://github.com/EdV4H/usketch/issues"
36
+ },
37
+ "devDependencies": {
38
+ "@types/react": "19.2.18",
39
+ "typescript": "7.0.2",
40
+ "vitest": "4.1.11"
41
+ },
42
+ "scripts": {
43
+ "build": "tsc -p tsconfig.json",
44
+ "typecheck": "tsc --noEmit",
45
+ "test": "vitest run --passWithNoTests",
46
+ "clean": "rm -rf dist"
47
+ }
48
+ }