Complete room UI and protocol integration, move game definitions and resources behind bundle entries, publish authoritative version XML, and document single-game builds. Include all current resource changes and experiment artifacts.
20 lines
1.1 KiB
TypeScript
20 lines
1.1 KiB
TypeScript
import type {GameDefinition} from '../../framework/sdk/contracts/game-definition.ts';
|
|
|
|
export interface SubgameEntry {readonly definition:GameDefinition;}
|
|
export function gameBundleName(key:string):string {
|
|
if(!/^[A-Za-z0-9_-]+$/.test(key))throw Error('Invalid gameKey: '+key);
|
|
return 'game-'+key;
|
|
}
|
|
/** Resolve only after the selected bundle has registered its entry class. */
|
|
export function getGameDefinition(key:string,findEntry:(name:string)=>SubgameEntry|null):GameDefinition {
|
|
gameBundleName(key);
|
|
const entry=findEntry('GameEntry_'+key);
|
|
if(!entry?.definition)throw Error('Missing subgame entry: '+key);
|
|
if(entry.definition.key!==key)throw Error('Subgame entry key mismatch: '+key);
|
|
return entry.definition;
|
|
}
|
|
export function gameResourcePath(root:string,resource:string):string {
|
|
if(!/^games\/[A-Za-z0-9_-]+$/.test(root)||!resource.startsWith(root+'/')||!resource.endsWith('.prefab')||resource.split('/').some(part=>!part||part==='.'||part==='..')||resource.includes('\\'))throw Error('Invalid private game resource: '+resource);
|
|
return resource.slice(root.length+1,-'.prefab'.length);
|
|
}
|