feat: integrate room framework and isolated subgame bundles

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.
This commit is contained in:
2026-09-09 03:13:18 +08:00
parent a7ec8aa6a7
commit 35216f75e7
1028 changed files with 835556 additions and 21415 deletions
@@ -68,6 +68,25 @@ const envelope: OutboundEnvelope = {
data: { gameid: 101 },
};
test('debug packet logs preserve transmitted text and precede business dispatch',async(t)=>{
const logs:unknown[][]=[];
t.mock.method(console,'log',(...args:unknown[])=>logs.push(args));
const {client,transports}=makeHarness();client.start();await transports[0]!.flush();
const login:OutboundEnvelope={app:'youle',route:'agent',rpc:'player_login',data:{test:true}};
client.send(login);
assert.ok(logs.some(row=>row[0]==='[收发包] 发送'&&row[2]===transports[0]!.sent[0]));
const heartbeats=['{"com":"@serverheartbeat"}',JSON.stringify('{"com":"@serverheartbeat"}')];
for(const heartbeat of heartbeats)transports[0]!.serverPush(heartbeat);
await transports[0]!.flush();
assert.equal(logs.some(row=>row[0]==='[收发包] 接收'&&heartbeats.includes(row[2] as string)),false);
const raw='{"app":"youle","route":"agent","rpc":"player_login","data":{"roomtype":[0,1,0]}}';
let dispatched=false;
client.subscribe(event=>{if(event.type==='message'){
assert.ok(logs.some(row=>row[0]==='[收发包] 接收'&&row[2]===raw));dispatched=true;
}});
transports[0]!.serverPush(raw);await transports[0]!.flush();assert.ok(dispatched);client.stop();
});
test('start emits the opened server and never sends login automatically', async () => {
const { client, transports } = makeHarness();
const events: WireEvent[] = [];