@idosgames/module-sdk 0.11.0 → 0.13.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/dist/index.cjs +1 -1
- package/dist/index.d.cts +113 -2
- package/dist/index.d.ts +113 -2
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var x=/^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9-]*@[1-9]\d*$/;function S(e){return typeof e=="string"&&x.test(e)}function M(e){let t=e.indexOf(":");return t<0?"":e.slice(0,t)}var c=/^(string|number|boolean)(\[\])?(\?)?$/;function u(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e,t){return e==="number"?typeof t=="number"&&Number.isFinite(t):typeof t===e}function f(e,t,
|
|
1
|
+
'use strict';var x=/^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9-]*@[1-9]\d*$/;function S(e){return typeof e=="string"&&x.test(e)}function M(e){let t=e.indexOf(":");return t<0?"":e.slice(0,t)}var c=/^(string|number|boolean)(\[\])?(\?)?$/;function u(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e,t){return e==="number"?typeof t=="number"&&Number.isFinite(t):typeof t===e}function f(e,t,o){if(!u(t))return `${o||"payload"} must be an object`;for(let[r,n]of Object.entries(e)){let i=o?`${o}.${r}`:r,a=t[r];if(typeof n!="string"){let p=f(n,a,i);if(p)return p;continue}let d=c.exec(n);if(!d)return `${i}: invalid descriptor "${n}"`;let[,s="",g,m]=d;if(a===void 0){if(m)continue;return `${i} is missing`}if(g){if(!Array.isArray(a))return `${i} must be ${s}[]`;if(!a.every(p=>l(s,p)))return `${i} must contain only ${s} values`;continue}if(!l(s,a))return `${i} must be a ${s}`}return null}function y(e,t){for(let[o,r]of Object.entries(e)){let n=t?`${t}.${o}`:o;if(typeof r=="string"){if(!c.test(r))throw new Error(`shape(): field "${n}" has invalid type "${r}" \u2014 use "string" | "number" | "boolean", optionally with "[]" and/or a trailing "?"`)}else if(u(r))y(r,n);else throw new Error(`shape(): field "${n}" must be a type string or an object`)}}function h(e){return y(e,""),{descriptor:e,check:t=>f(e,t,"")}}function v(e,t){if(!S(e))throw new Error(`defineTopic(): "${e}" is not a valid topic name \u2014 expected "<module-id>:<event>@<major>", e.g. "idle-rpg:character-upgraded@1"`);return {name:e,shape:t}}var T={modeChanged:v("host:mode-changed@1",h({from:"string?",to:"string"}))};var b=["currency-bar","wallet","status","account","menu","modes"];function R(e){return typeof e=="string"&&b.includes(e)}function D(e){return e}exports.SHARED_UI_ROLES=b;exports.TOPIC_NAME_RE=x;exports.defineModule=D;exports.defineTopic=v;exports.hostTopics=T;exports.isSharedUiRole=R;exports.isTopicName=S;exports.shape=h;exports.topicNamespace=M;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RealtimeSession, IDosGamesClient } from '@idosgames/core';
|
|
1
|
+
import { RealtimeSession, VoiceController, IDosGamesClient } from '@idosgames/core';
|
|
2
2
|
export { IDosGamesClient, SdkEvents } from '@idosgames/core';
|
|
3
3
|
import { ComponentType } from 'react';
|
|
4
4
|
|
|
@@ -232,6 +232,13 @@ interface FeatureDefinition {
|
|
|
232
232
|
primary?: boolean;
|
|
233
233
|
/** The screen. Rendered by the presenter, inside the kit provider and the client provider. */
|
|
234
234
|
Screen: ComponentType<FeatureScreenProps>;
|
|
235
|
+
/**
|
|
236
|
+
* The screen paints edge to edge (its own background, a stage like the Heroes screen): the lobby
|
|
237
|
+
* gives it the whole area between its top row and the menu — no side padding, no width limit — and
|
|
238
|
+
* stretches it to that height. Default `false`: a page on the lobby's background, padded and kept
|
|
239
|
+
* to a readable width on a wide window.
|
|
240
|
+
*/
|
|
241
|
+
fullBleed?: boolean;
|
|
235
242
|
/**
|
|
236
243
|
* Whether the title has something for this screen yet. Default `true`. A screen that depends on
|
|
237
244
|
* title data (a shop without offers is an empty tab) registers with `false` and calls
|
|
@@ -345,6 +352,13 @@ interface MultiplayerRoom {
|
|
|
345
352
|
readonly lateJoin: boolean;
|
|
346
353
|
/** Leave the room for good: closes the session and the rooms screen forgets it. */
|
|
347
354
|
leave(): Promise<void>;
|
|
355
|
+
/**
|
|
356
|
+
* The room's voice chat, or `null` when the room has none. The rooms system owns it and draws its
|
|
357
|
+
* controls (the mic button over the game included); a game reads it for its own touches — who is
|
|
358
|
+
* speaking (`isSpeaking`, `on("change")`), a talking player's marker, proximity volume
|
|
359
|
+
* (`setPeerVolume` by distance).
|
|
360
|
+
*/
|
|
361
|
+
readonly voice: VoiceController | null;
|
|
348
362
|
}
|
|
349
363
|
/** What `ctx.features.open("multiplayer", args)` understands. */
|
|
350
364
|
interface MultiplayerScreenArgs {
|
|
@@ -525,6 +539,76 @@ interface AppNotifications {
|
|
|
525
539
|
dismiss(id: string): void;
|
|
526
540
|
}
|
|
527
541
|
|
|
542
|
+
/** The room's voices, as the recording takes them (the multiplayer system provides this). */
|
|
543
|
+
interface RecordingVoiceSource {
|
|
544
|
+
/** This player's microphone track (silent while not transmitting); null — mic off. */
|
|
545
|
+
mic(): MediaStreamTrack | null;
|
|
546
|
+
/** Other players' voice tracks. */
|
|
547
|
+
others(): MediaStreamTrack[];
|
|
548
|
+
/** The publisher allows other players' voices in videos (`Multiplayer.RecordVoices`). */
|
|
549
|
+
recordOthers(): boolean;
|
|
550
|
+
/** Called when tracks come or go (a player joined, the mic went on). */
|
|
551
|
+
subscribe(listener: () => void): () => void;
|
|
552
|
+
}
|
|
553
|
+
/** `ctx.clips`. */
|
|
554
|
+
interface ClipsRegistry {
|
|
555
|
+
/**
|
|
556
|
+
* A bright moment right now. `weight` 1–10 (default 5): how much it is worth showing — a boss
|
|
557
|
+
* kill 8, a level-up 4. Close marks merge into one clip (their weights add up).
|
|
558
|
+
*/
|
|
559
|
+
mark(name: string, weight?: number): void;
|
|
560
|
+
/** The multiplayer system registers the room's voices here; `null` when the room is gone. */
|
|
561
|
+
setVoiceSource(source: RecordingVoiceSource | null): void;
|
|
562
|
+
/** This player is making a long recording right now. */
|
|
563
|
+
isRecording(): boolean;
|
|
564
|
+
/** Called when `isRecording` changes. */
|
|
565
|
+
subscribe(listener: () => void): () => void;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/** The hero to draw, as the engine's Character system describes it. */
|
|
569
|
+
interface CharacterArtSubject {
|
|
570
|
+
/** The character's id (`CharacterID` of its definition). */
|
|
571
|
+
characterId: string;
|
|
572
|
+
/** Its class (`Classification.ClassID`), if any. */
|
|
573
|
+
classId?: string | null;
|
|
574
|
+
/** What it wears: equipment slot id → the worn item's `ItemID`. */
|
|
575
|
+
equipment: Readonly<Record<string, string>>;
|
|
576
|
+
/** The worn skin (`WornSkinID`), if any. */
|
|
577
|
+
skinId?: string | null;
|
|
578
|
+
/** Not the player's yet (shown dimmed by the screen) — the art may draw it in a calmer pose. */
|
|
579
|
+
locked?: boolean;
|
|
580
|
+
}
|
|
581
|
+
interface CharacterArtOptions {
|
|
582
|
+
/**
|
|
583
|
+
* "live" — the figure moving (breathing, blinking), for a big view; "still" — one frame, for a list
|
|
584
|
+
* of many heroes. Default "live".
|
|
585
|
+
*/
|
|
586
|
+
mode?: "live" | "still";
|
|
587
|
+
}
|
|
588
|
+
/** One mounted figure. */
|
|
589
|
+
interface CharacterArtView {
|
|
590
|
+
/** The hero changed (equipped, switched): redraw it. A changed weapon may play a short move. */
|
|
591
|
+
update(subject: CharacterArtSubject): void;
|
|
592
|
+
/** Stop drawing and free what was made (the screen unmounts). */
|
|
593
|
+
destroy(): void;
|
|
594
|
+
}
|
|
595
|
+
interface CharacterArt {
|
|
596
|
+
/**
|
|
597
|
+
* Draw the hero into `host` — an element the screen sizes and positions; fill it, the figure
|
|
598
|
+
* standing on its bottom edge and centred. The returned view is updated and destroyed by the screen.
|
|
599
|
+
*/
|
|
600
|
+
mount(host: HTMLElement, subject: CharacterArtSubject, options?: CharacterArtOptions): CharacterArtView;
|
|
601
|
+
}
|
|
602
|
+
/** `ctx.characterArt` — the game's character art, shared by every module of the session. */
|
|
603
|
+
interface CharacterArtRegistry {
|
|
604
|
+
/** Make this the art every screen draws heroes with. Returns the unregister function. */
|
|
605
|
+
set(art: CharacterArt): () => void;
|
|
606
|
+
/** The art now, or null — no game set one (the screen draws its own picture). */
|
|
607
|
+
get(): CharacterArt | null;
|
|
608
|
+
/** Called when the art is set or removed (a screen remounts its figures). */
|
|
609
|
+
subscribe(listener: () => void): () => void;
|
|
610
|
+
}
|
|
611
|
+
|
|
528
612
|
/** What a module is, for catalog/UI purposes. Not every module is a game. */
|
|
529
613
|
type ModuleType = "game" | "app" | "ai-app";
|
|
530
614
|
/**
|
|
@@ -719,6 +803,12 @@ interface ModuleContext {
|
|
|
719
803
|
* `LobbyHeroDefinition`.
|
|
720
804
|
*/
|
|
721
805
|
lobby: LobbyRegistry;
|
|
806
|
+
/**
|
|
807
|
+
* The game's character art (see `CharacterArt`): a game sets how its hero is drawn (`set`), a
|
|
808
|
+
* screen of another module (the Heroes screen) draws the hero with it (`get()?.mount(...)`) — or its
|
|
809
|
+
* own picture when no game set one.
|
|
810
|
+
*/
|
|
811
|
+
characterArt: CharacterArtRegistry;
|
|
722
812
|
/**
|
|
723
813
|
* Switch the host to another mode (a route id registered by any module) — e.g. the lobby starts a
|
|
724
814
|
* game, the Workshop opens a world and hands the screen to the game. Unknown ids are ignored. Called
|
|
@@ -750,6 +840,12 @@ interface ModuleContext {
|
|
|
750
840
|
* one look, one queue, one sound for the whole app. The module's own id is the default `source`.
|
|
751
841
|
*/
|
|
752
842
|
notifications: AppNotifications;
|
|
843
|
+
/**
|
|
844
|
+
* The platform's video recording (see `ClipsRegistry`): a game marks bright moments
|
|
845
|
+
* (`ctx.clips.mark("boss_down", 8)`) — they become the player's "Best moments" clips on
|
|
846
|
+
* idosgames.com. A no-op anywhere else.
|
|
847
|
+
*/
|
|
848
|
+
clips: ClipsRegistry;
|
|
753
849
|
}
|
|
754
850
|
/**
|
|
755
851
|
* A module's debug surface for the agent: read its state, drive it with named actions.
|
|
@@ -842,6 +938,21 @@ interface EngineScene {
|
|
|
842
938
|
* host falls back to reading the canvas itself, which is correct for 2D canvases.
|
|
843
939
|
*/
|
|
844
940
|
capture?(): Promise<Blob | null>;
|
|
941
|
+
/**
|
|
942
|
+
* Where the action is right now, 0–1 on both axes of the canvas (the player, the explosion) — for
|
|
943
|
+
* the platform's video recording: a vertical (TikTok) cut of a landscape game follows this point
|
|
944
|
+
* instead of cutting the middle. Called a few times a second; keep it cheap. Omit — the centre.
|
|
945
|
+
*/
|
|
946
|
+
focus?(): {
|
|
947
|
+
x: number;
|
|
948
|
+
y: number;
|
|
949
|
+
} | null;
|
|
950
|
+
/**
|
|
951
|
+
* The game's own sound as a MediaStream, for the platform's video recording — e.g. a
|
|
952
|
+
* `MediaStreamAudioDestinationNode` your audio graph also feeds (Three.js: `listener.context`).
|
|
953
|
+
* Omit — videos carry the voices but not the game's sound.
|
|
954
|
+
*/
|
|
955
|
+
audio?(): MediaStream | null;
|
|
845
956
|
/** Permanent teardown — dispose GPU resources, remove listeners. */
|
|
846
957
|
destroy(): void;
|
|
847
958
|
}
|
|
@@ -930,4 +1041,4 @@ interface SharedEventBus<Events extends Record<string, unknown> = Record<string,
|
|
|
930
1041
|
/** Identity helper that pins a module literal to the `Module` type for editor help and errors. */
|
|
931
1042
|
declare function defineModule(module: Module): Module;
|
|
932
1043
|
|
|
933
|
-
export { type AppNotifications, type CapturedContent, type ContentFileData, type ContentRegistry, type ContentTypeHandler, type DownloadedContent, type EngineScene, type FeatureDefinition, type FeatureEntry, type FeatureGroup, type FeaturePresenter, type FeatureRegistry, type FeatureScreenProps, type InferShape, type LoadingReporter, type LoadingTask, type LobbyHeroAction, type LobbyHeroDefinition, type LobbyHeroStage, type LobbyHeroView, type LobbyRegistry, type LocalContentItem, type ModeEntry, type ModeRegistry, type Module, type ModuleAgentApi, type ModuleAuthor, type ModuleContext, type ModuleEngine, type ModuleEventEmit, type ModuleEventListen, type ModuleEvents, type ModuleEventsManifest, type ModuleManifest, type ModuleMedia, type ModuleMeta, type ModuleSharedUi, type ModuleType, type MultiplayerGame, type MultiplayerRegistry, type MultiplayerRoom, type MultiplayerScreenArgs, type MultiplayerSetting, type NotificationAction, type NotificationInput, type NotificationLevel, type PanelSlot, type RouteEntry, SHARED_UI_ROLES, type SceneMountContext, type Shape, type ShapeDescriptor, type ShapeLeaf, type ShapeLeafSpec, type SharedEventBus, type SharedUiContext, type SharedUiRole, type SurfaceAllocator, type SurfaceHandle, type SurfaceKind, TOPIC_NAME_RE, type Topic, type TopicName, type TopicPayload, type UiPanel, defineModule, defineTopic, hostTopics, isSharedUiRole, isTopicName, shape, topicNamespace };
|
|
1044
|
+
export { type AppNotifications, type CapturedContent, type CharacterArt, type CharacterArtOptions, type CharacterArtRegistry, type CharacterArtSubject, type CharacterArtView, type ClipsRegistry, type ContentFileData, type ContentRegistry, type ContentTypeHandler, type DownloadedContent, type EngineScene, type FeatureDefinition, type FeatureEntry, type FeatureGroup, type FeaturePresenter, type FeatureRegistry, type FeatureScreenProps, type InferShape, type LoadingReporter, type LoadingTask, type LobbyHeroAction, type LobbyHeroDefinition, type LobbyHeroStage, type LobbyHeroView, type LobbyRegistry, type LocalContentItem, type ModeEntry, type ModeRegistry, type Module, type ModuleAgentApi, type ModuleAuthor, type ModuleContext, type ModuleEngine, type ModuleEventEmit, type ModuleEventListen, type ModuleEvents, type ModuleEventsManifest, type ModuleManifest, type ModuleMedia, type ModuleMeta, type ModuleSharedUi, type ModuleType, type MultiplayerGame, type MultiplayerRegistry, type MultiplayerRoom, type MultiplayerScreenArgs, type MultiplayerSetting, type NotificationAction, type NotificationInput, type NotificationLevel, type PanelSlot, type RecordingVoiceSource, type RouteEntry, SHARED_UI_ROLES, type SceneMountContext, type Shape, type ShapeDescriptor, type ShapeLeaf, type ShapeLeafSpec, type SharedEventBus, type SharedUiContext, type SharedUiRole, type SurfaceAllocator, type SurfaceHandle, type SurfaceKind, TOPIC_NAME_RE, type Topic, type TopicName, type TopicPayload, type UiPanel, defineModule, defineTopic, hostTopics, isSharedUiRole, isTopicName, shape, topicNamespace };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RealtimeSession, IDosGamesClient } from '@idosgames/core';
|
|
1
|
+
import { RealtimeSession, VoiceController, IDosGamesClient } from '@idosgames/core';
|
|
2
2
|
export { IDosGamesClient, SdkEvents } from '@idosgames/core';
|
|
3
3
|
import { ComponentType } from 'react';
|
|
4
4
|
|
|
@@ -232,6 +232,13 @@ interface FeatureDefinition {
|
|
|
232
232
|
primary?: boolean;
|
|
233
233
|
/** The screen. Rendered by the presenter, inside the kit provider and the client provider. */
|
|
234
234
|
Screen: ComponentType<FeatureScreenProps>;
|
|
235
|
+
/**
|
|
236
|
+
* The screen paints edge to edge (its own background, a stage like the Heroes screen): the lobby
|
|
237
|
+
* gives it the whole area between its top row and the menu — no side padding, no width limit — and
|
|
238
|
+
* stretches it to that height. Default `false`: a page on the lobby's background, padded and kept
|
|
239
|
+
* to a readable width on a wide window.
|
|
240
|
+
*/
|
|
241
|
+
fullBleed?: boolean;
|
|
235
242
|
/**
|
|
236
243
|
* Whether the title has something for this screen yet. Default `true`. A screen that depends on
|
|
237
244
|
* title data (a shop without offers is an empty tab) registers with `false` and calls
|
|
@@ -345,6 +352,13 @@ interface MultiplayerRoom {
|
|
|
345
352
|
readonly lateJoin: boolean;
|
|
346
353
|
/** Leave the room for good: closes the session and the rooms screen forgets it. */
|
|
347
354
|
leave(): Promise<void>;
|
|
355
|
+
/**
|
|
356
|
+
* The room's voice chat, or `null` when the room has none. The rooms system owns it and draws its
|
|
357
|
+
* controls (the mic button over the game included); a game reads it for its own touches — who is
|
|
358
|
+
* speaking (`isSpeaking`, `on("change")`), a talking player's marker, proximity volume
|
|
359
|
+
* (`setPeerVolume` by distance).
|
|
360
|
+
*/
|
|
361
|
+
readonly voice: VoiceController | null;
|
|
348
362
|
}
|
|
349
363
|
/** What `ctx.features.open("multiplayer", args)` understands. */
|
|
350
364
|
interface MultiplayerScreenArgs {
|
|
@@ -525,6 +539,76 @@ interface AppNotifications {
|
|
|
525
539
|
dismiss(id: string): void;
|
|
526
540
|
}
|
|
527
541
|
|
|
542
|
+
/** The room's voices, as the recording takes them (the multiplayer system provides this). */
|
|
543
|
+
interface RecordingVoiceSource {
|
|
544
|
+
/** This player's microphone track (silent while not transmitting); null — mic off. */
|
|
545
|
+
mic(): MediaStreamTrack | null;
|
|
546
|
+
/** Other players' voice tracks. */
|
|
547
|
+
others(): MediaStreamTrack[];
|
|
548
|
+
/** The publisher allows other players' voices in videos (`Multiplayer.RecordVoices`). */
|
|
549
|
+
recordOthers(): boolean;
|
|
550
|
+
/** Called when tracks come or go (a player joined, the mic went on). */
|
|
551
|
+
subscribe(listener: () => void): () => void;
|
|
552
|
+
}
|
|
553
|
+
/** `ctx.clips`. */
|
|
554
|
+
interface ClipsRegistry {
|
|
555
|
+
/**
|
|
556
|
+
* A bright moment right now. `weight` 1–10 (default 5): how much it is worth showing — a boss
|
|
557
|
+
* kill 8, a level-up 4. Close marks merge into one clip (their weights add up).
|
|
558
|
+
*/
|
|
559
|
+
mark(name: string, weight?: number): void;
|
|
560
|
+
/** The multiplayer system registers the room's voices here; `null` when the room is gone. */
|
|
561
|
+
setVoiceSource(source: RecordingVoiceSource | null): void;
|
|
562
|
+
/** This player is making a long recording right now. */
|
|
563
|
+
isRecording(): boolean;
|
|
564
|
+
/** Called when `isRecording` changes. */
|
|
565
|
+
subscribe(listener: () => void): () => void;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/** The hero to draw, as the engine's Character system describes it. */
|
|
569
|
+
interface CharacterArtSubject {
|
|
570
|
+
/** The character's id (`CharacterID` of its definition). */
|
|
571
|
+
characterId: string;
|
|
572
|
+
/** Its class (`Classification.ClassID`), if any. */
|
|
573
|
+
classId?: string | null;
|
|
574
|
+
/** What it wears: equipment slot id → the worn item's `ItemID`. */
|
|
575
|
+
equipment: Readonly<Record<string, string>>;
|
|
576
|
+
/** The worn skin (`WornSkinID`), if any. */
|
|
577
|
+
skinId?: string | null;
|
|
578
|
+
/** Not the player's yet (shown dimmed by the screen) — the art may draw it in a calmer pose. */
|
|
579
|
+
locked?: boolean;
|
|
580
|
+
}
|
|
581
|
+
interface CharacterArtOptions {
|
|
582
|
+
/**
|
|
583
|
+
* "live" — the figure moving (breathing, blinking), for a big view; "still" — one frame, for a list
|
|
584
|
+
* of many heroes. Default "live".
|
|
585
|
+
*/
|
|
586
|
+
mode?: "live" | "still";
|
|
587
|
+
}
|
|
588
|
+
/** One mounted figure. */
|
|
589
|
+
interface CharacterArtView {
|
|
590
|
+
/** The hero changed (equipped, switched): redraw it. A changed weapon may play a short move. */
|
|
591
|
+
update(subject: CharacterArtSubject): void;
|
|
592
|
+
/** Stop drawing and free what was made (the screen unmounts). */
|
|
593
|
+
destroy(): void;
|
|
594
|
+
}
|
|
595
|
+
interface CharacterArt {
|
|
596
|
+
/**
|
|
597
|
+
* Draw the hero into `host` — an element the screen sizes and positions; fill it, the figure
|
|
598
|
+
* standing on its bottom edge and centred. The returned view is updated and destroyed by the screen.
|
|
599
|
+
*/
|
|
600
|
+
mount(host: HTMLElement, subject: CharacterArtSubject, options?: CharacterArtOptions): CharacterArtView;
|
|
601
|
+
}
|
|
602
|
+
/** `ctx.characterArt` — the game's character art, shared by every module of the session. */
|
|
603
|
+
interface CharacterArtRegistry {
|
|
604
|
+
/** Make this the art every screen draws heroes with. Returns the unregister function. */
|
|
605
|
+
set(art: CharacterArt): () => void;
|
|
606
|
+
/** The art now, or null — no game set one (the screen draws its own picture). */
|
|
607
|
+
get(): CharacterArt | null;
|
|
608
|
+
/** Called when the art is set or removed (a screen remounts its figures). */
|
|
609
|
+
subscribe(listener: () => void): () => void;
|
|
610
|
+
}
|
|
611
|
+
|
|
528
612
|
/** What a module is, for catalog/UI purposes. Not every module is a game. */
|
|
529
613
|
type ModuleType = "game" | "app" | "ai-app";
|
|
530
614
|
/**
|
|
@@ -719,6 +803,12 @@ interface ModuleContext {
|
|
|
719
803
|
* `LobbyHeroDefinition`.
|
|
720
804
|
*/
|
|
721
805
|
lobby: LobbyRegistry;
|
|
806
|
+
/**
|
|
807
|
+
* The game's character art (see `CharacterArt`): a game sets how its hero is drawn (`set`), a
|
|
808
|
+
* screen of another module (the Heroes screen) draws the hero with it (`get()?.mount(...)`) — or its
|
|
809
|
+
* own picture when no game set one.
|
|
810
|
+
*/
|
|
811
|
+
characterArt: CharacterArtRegistry;
|
|
722
812
|
/**
|
|
723
813
|
* Switch the host to another mode (a route id registered by any module) — e.g. the lobby starts a
|
|
724
814
|
* game, the Workshop opens a world and hands the screen to the game. Unknown ids are ignored. Called
|
|
@@ -750,6 +840,12 @@ interface ModuleContext {
|
|
|
750
840
|
* one look, one queue, one sound for the whole app. The module's own id is the default `source`.
|
|
751
841
|
*/
|
|
752
842
|
notifications: AppNotifications;
|
|
843
|
+
/**
|
|
844
|
+
* The platform's video recording (see `ClipsRegistry`): a game marks bright moments
|
|
845
|
+
* (`ctx.clips.mark("boss_down", 8)`) — they become the player's "Best moments" clips on
|
|
846
|
+
* idosgames.com. A no-op anywhere else.
|
|
847
|
+
*/
|
|
848
|
+
clips: ClipsRegistry;
|
|
753
849
|
}
|
|
754
850
|
/**
|
|
755
851
|
* A module's debug surface for the agent: read its state, drive it with named actions.
|
|
@@ -842,6 +938,21 @@ interface EngineScene {
|
|
|
842
938
|
* host falls back to reading the canvas itself, which is correct for 2D canvases.
|
|
843
939
|
*/
|
|
844
940
|
capture?(): Promise<Blob | null>;
|
|
941
|
+
/**
|
|
942
|
+
* Where the action is right now, 0–1 on both axes of the canvas (the player, the explosion) — for
|
|
943
|
+
* the platform's video recording: a vertical (TikTok) cut of a landscape game follows this point
|
|
944
|
+
* instead of cutting the middle. Called a few times a second; keep it cheap. Omit — the centre.
|
|
945
|
+
*/
|
|
946
|
+
focus?(): {
|
|
947
|
+
x: number;
|
|
948
|
+
y: number;
|
|
949
|
+
} | null;
|
|
950
|
+
/**
|
|
951
|
+
* The game's own sound as a MediaStream, for the platform's video recording — e.g. a
|
|
952
|
+
* `MediaStreamAudioDestinationNode` your audio graph also feeds (Three.js: `listener.context`).
|
|
953
|
+
* Omit — videos carry the voices but not the game's sound.
|
|
954
|
+
*/
|
|
955
|
+
audio?(): MediaStream | null;
|
|
845
956
|
/** Permanent teardown — dispose GPU resources, remove listeners. */
|
|
846
957
|
destroy(): void;
|
|
847
958
|
}
|
|
@@ -930,4 +1041,4 @@ interface SharedEventBus<Events extends Record<string, unknown> = Record<string,
|
|
|
930
1041
|
/** Identity helper that pins a module literal to the `Module` type for editor help and errors. */
|
|
931
1042
|
declare function defineModule(module: Module): Module;
|
|
932
1043
|
|
|
933
|
-
export { type AppNotifications, type CapturedContent, type ContentFileData, type ContentRegistry, type ContentTypeHandler, type DownloadedContent, type EngineScene, type FeatureDefinition, type FeatureEntry, type FeatureGroup, type FeaturePresenter, type FeatureRegistry, type FeatureScreenProps, type InferShape, type LoadingReporter, type LoadingTask, type LobbyHeroAction, type LobbyHeroDefinition, type LobbyHeroStage, type LobbyHeroView, type LobbyRegistry, type LocalContentItem, type ModeEntry, type ModeRegistry, type Module, type ModuleAgentApi, type ModuleAuthor, type ModuleContext, type ModuleEngine, type ModuleEventEmit, type ModuleEventListen, type ModuleEvents, type ModuleEventsManifest, type ModuleManifest, type ModuleMedia, type ModuleMeta, type ModuleSharedUi, type ModuleType, type MultiplayerGame, type MultiplayerRegistry, type MultiplayerRoom, type MultiplayerScreenArgs, type MultiplayerSetting, type NotificationAction, type NotificationInput, type NotificationLevel, type PanelSlot, type RouteEntry, SHARED_UI_ROLES, type SceneMountContext, type Shape, type ShapeDescriptor, type ShapeLeaf, type ShapeLeafSpec, type SharedEventBus, type SharedUiContext, type SharedUiRole, type SurfaceAllocator, type SurfaceHandle, type SurfaceKind, TOPIC_NAME_RE, type Topic, type TopicName, type TopicPayload, type UiPanel, defineModule, defineTopic, hostTopics, isSharedUiRole, isTopicName, shape, topicNamespace };
|
|
1044
|
+
export { type AppNotifications, type CapturedContent, type CharacterArt, type CharacterArtOptions, type CharacterArtRegistry, type CharacterArtSubject, type CharacterArtView, type ClipsRegistry, type ContentFileData, type ContentRegistry, type ContentTypeHandler, type DownloadedContent, type EngineScene, type FeatureDefinition, type FeatureEntry, type FeatureGroup, type FeaturePresenter, type FeatureRegistry, type FeatureScreenProps, type InferShape, type LoadingReporter, type LoadingTask, type LobbyHeroAction, type LobbyHeroDefinition, type LobbyHeroStage, type LobbyHeroView, type LobbyRegistry, type LocalContentItem, type ModeEntry, type ModeRegistry, type Module, type ModuleAgentApi, type ModuleAuthor, type ModuleContext, type ModuleEngine, type ModuleEventEmit, type ModuleEventListen, type ModuleEvents, type ModuleEventsManifest, type ModuleManifest, type ModuleMedia, type ModuleMeta, type ModuleSharedUi, type ModuleType, type MultiplayerGame, type MultiplayerRegistry, type MultiplayerRoom, type MultiplayerScreenArgs, type MultiplayerSetting, type NotificationAction, type NotificationInput, type NotificationLevel, type PanelSlot, type RecordingVoiceSource, type RouteEntry, SHARED_UI_ROLES, type SceneMountContext, type Shape, type ShapeDescriptor, type ShapeLeaf, type ShapeLeafSpec, type SharedEventBus, type SharedUiContext, type SharedUiRole, type SurfaceAllocator, type SurfaceHandle, type SurfaceKind, TOPIC_NAME_RE, type Topic, type TopicName, type TopicPayload, type UiPanel, defineModule, defineTopic, hostTopics, isSharedUiRole, isTopicName, shape, topicNamespace };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var x=/^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9-]*@[1-9]\d*$/;function S(e){return typeof e=="string"&&x.test(e)}function M(e){let t=e.indexOf(":");return t<0?"":e.slice(0,t)}var c=/^(string|number|boolean)(\[\])?(\?)?$/;function u(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e,t){return e==="number"?typeof t=="number"&&Number.isFinite(t):typeof t===e}function f(e,t,
|
|
1
|
+
var x=/^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9-]*@[1-9]\d*$/;function S(e){return typeof e=="string"&&x.test(e)}function M(e){let t=e.indexOf(":");return t<0?"":e.slice(0,t)}var c=/^(string|number|boolean)(\[\])?(\?)?$/;function u(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e,t){return e==="number"?typeof t=="number"&&Number.isFinite(t):typeof t===e}function f(e,t,o){if(!u(t))return `${o||"payload"} must be an object`;for(let[r,n]of Object.entries(e)){let i=o?`${o}.${r}`:r,a=t[r];if(typeof n!="string"){let p=f(n,a,i);if(p)return p;continue}let d=c.exec(n);if(!d)return `${i}: invalid descriptor "${n}"`;let[,s="",g,m]=d;if(a===void 0){if(m)continue;return `${i} is missing`}if(g){if(!Array.isArray(a))return `${i} must be ${s}[]`;if(!a.every(p=>l(s,p)))return `${i} must contain only ${s} values`;continue}if(!l(s,a))return `${i} must be a ${s}`}return null}function y(e,t){for(let[o,r]of Object.entries(e)){let n=t?`${t}.${o}`:o;if(typeof r=="string"){if(!c.test(r))throw new Error(`shape(): field "${n}" has invalid type "${r}" \u2014 use "string" | "number" | "boolean", optionally with "[]" and/or a trailing "?"`)}else if(u(r))y(r,n);else throw new Error(`shape(): field "${n}" must be a type string or an object`)}}function h(e){return y(e,""),{descriptor:e,check:t=>f(e,t,"")}}function v(e,t){if(!S(e))throw new Error(`defineTopic(): "${e}" is not a valid topic name \u2014 expected "<module-id>:<event>@<major>", e.g. "idle-rpg:character-upgraded@1"`);return {name:e,shape:t}}var T={modeChanged:v("host:mode-changed@1",h({from:"string?",to:"string"}))};var b=["currency-bar","wallet","status","account","menu","modes"];function R(e){return typeof e=="string"&&b.includes(e)}function D(e){return e}export{b as SHARED_UI_ROLES,x as TOPIC_NAME_RE,D as defineModule,v as defineTopic,T as hostTopics,R as isSharedUiRole,S as isTopicName,h as shape,M as topicNamespace};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idosgames/module-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "The composable-module contract for the iDosGames host shell: Module / ModuleContext types plus tiny authoring helpers. Framework-neutral at runtime — a module can be a game (Three/Phaser), a plain app, or an AI app.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
},
|
|
47
47
|
"//": "@idosgames/core is a real range, not '*': a published contract must name the version of core whose IDosGamesClient/SdkEvents shapes it references. Bump in step with core (see RELEASING.md). react is an OPTIONAL peer — the contract references React's ComponentType type only (a UI panel is a React component), which is erased at build, so a runtime-only module needs no React.",
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@idosgames/core": "^0.
|
|
49
|
+
"@idosgames/core": "^0.23.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"react": "^18.3.1 || ^19.0.0"
|