feat(sdk): define single-game public contracts
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
import type { GameModule } from './game-module.ts';
|
||||
|
||||
/** The one compile-time game identity and module factory for an app. */
|
||||
export interface GameEntry {
|
||||
readonly key: string;
|
||||
readonly gameId: string | number;
|
||||
readonly route: string;
|
||||
resolveSeatCount(roomtype: readonly unknown[]): number;
|
||||
createModule(): GameModule;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { GameSeatMapper } from './game-seat-mapper.ts';
|
||||
import type { PlatformGameSnapshot } from './snapshots.ts';
|
||||
|
||||
export type GameHostCommand =
|
||||
| { readonly type: 'room.prepare' }
|
||||
| { readonly type: 'room.exit' };
|
||||
|
||||
/** The only platform capability surface available to a game module. */
|
||||
export interface GameHost {
|
||||
readonly seat: GameSeatMapper;
|
||||
getSnapshot(): PlatformGameSnapshot;
|
||||
subscribe(listener: (snapshot: PlatformGameSnapshot) => void): () => void;
|
||||
sendGameMessage(rpc: string, data: unknown): void;
|
||||
execute(command: GameHostCommand): void;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import type { GameHost } from './game-host.ts';
|
||||
import type { GameServerMessage, PlatformToGameEvent } from './platform-events.ts';
|
||||
|
||||
/** Per-room game implementation with an explicit lifecycle. */
|
||||
export interface GameModule {
|
||||
attach(host: GameHost): void;
|
||||
handlePlatformEvent(event: PlatformToGameEvent): void;
|
||||
handleGameMessage(message: GameServerMessage): void;
|
||||
restore(deskinfo: unknown): void;
|
||||
dispose(): void;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/** Maps server seat numbers to the current game's view-seat numbers. */
|
||||
export interface GameSeatMapper {
|
||||
toView(serverSeat: number): number;
|
||||
toServer(viewSeat: number): number;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export * from './game-entry.ts';
|
||||
export * from './game-host.ts';
|
||||
export * from './game-module.ts';
|
||||
export * from './game-seat-mapper.ts';
|
||||
export * from './platform-events.ts';
|
||||
export * from './snapshots.ts';
|
||||
@@ -0,0 +1,15 @@
|
||||
/** Platform lifecycle events delivered to the current game module. */
|
||||
export type PlatformToGameEvent =
|
||||
| { readonly type: 'room.entered'; readonly roomtype: readonly unknown[] }
|
||||
| { readonly type: 'room.player-joined'; readonly seat: number }
|
||||
| { readonly type: 'room.player-left'; readonly seat: number }
|
||||
| { readonly type: 'room.player-ready'; readonly seat: number }
|
||||
| { readonly type: 'room.player-offline'; readonly seat: number }
|
||||
| { readonly type: 'room.player-online'; readonly seat: number }
|
||||
| { readonly type: 'room.dissolved' };
|
||||
|
||||
/** Opaque game-route server message; only the game interprets its data. */
|
||||
export interface GameServerMessage {
|
||||
readonly rpc: string;
|
||||
readonly data: unknown;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/** Public connection phases available to a game. */
|
||||
export type PlatformGameConnectionPhase =
|
||||
| 'connected'
|
||||
| 'logged-in'
|
||||
| 'reconnecting'
|
||||
| 'slow'
|
||||
| 'kicked';
|
||||
|
||||
/** Plain public connection projection. */
|
||||
export interface PlatformGameAppSnapshot {
|
||||
readonly phase: PlatformGameConnectionPhase;
|
||||
}
|
||||
|
||||
/** Plain public identity projection for the local player. */
|
||||
export interface PlatformGameSelfSnapshot {
|
||||
readonly playerId: number;
|
||||
readonly seat: number;
|
||||
}
|
||||
|
||||
/** Plain public room projection. `roomtype` remains opaque server data. */
|
||||
export interface PlatformGameRoomSnapshot {
|
||||
readonly roomcode: string;
|
||||
readonly roomtype: readonly unknown[];
|
||||
readonly stage: number;
|
||||
readonly needprepare: number;
|
||||
readonly infinite: number;
|
||||
}
|
||||
|
||||
/** Plain public player projection for one occupied game seat. */
|
||||
export interface GameSeatSnapshot {
|
||||
readonly seat: number;
|
||||
readonly playerId: number;
|
||||
readonly nickname: string;
|
||||
readonly avatar: string;
|
||||
readonly online: boolean;
|
||||
readonly ready: boolean;
|
||||
}
|
||||
|
||||
/** Immutable platform data exposed to a game module. */
|
||||
export interface PlatformGameSnapshot {
|
||||
readonly connection: PlatformGameAppSnapshot;
|
||||
readonly self: PlatformGameSelfSnapshot;
|
||||
readonly room: PlatformGameRoomSnapshot;
|
||||
readonly seats: readonly GameSeatSnapshot[];
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
export * from './contracts/index.ts';
|
||||
|
||||
import type { EventBus } from '../core/events.ts';
|
||||
import type { ReadonlyReactive } from '../core/reactive.ts';
|
||||
import type { ReadonlyPlayerStore } from '../platform/readonly.ts';
|
||||
@@ -26,6 +28,8 @@ export interface GameSeat {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated migration-only. Use GameHost from sdk/contracts instead.
|
||||
*
|
||||
* GameContext:子游戏调用框架能力的唯一入口。
|
||||
*
|
||||
* 只暴露只读 Store + 受限 net.send + 座位工具 + 事件总线。
|
||||
@@ -47,6 +51,8 @@ export interface GameContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated migration-only. Use GameModule from sdk/contracts instead.
|
||||
*
|
||||
* IGameModule:子游戏实现,被框架调用(框架 spec §4)。
|
||||
*
|
||||
* 子游戏实现这个接口并注册自己;框架 Router 据 route 分发对局包。
|
||||
@@ -92,4 +98,4 @@ export interface IGameModule {
|
||||
onDissolve?(): void;
|
||||
/** 玩家离线/上线(在线由 onPlayerJoin 重复触发,离线由本钩子)。 */
|
||||
onOffline?(seat: number): void;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user