Control NPC count per room

This commit is contained in:
Christian Semmler 2026-03-07 14:58:27 -08:00
parent ff0593fd60
commit 853e8981fa
No known key found for this signature in database
GPG Key ID: 086DAA1360BEEE5C
4 changed files with 27 additions and 5 deletions

View File

@ -199,6 +199,8 @@ class LegoAnimationManager : public MxCore {
LEGO1_EXPORT static void configureLegoAnimationManager(MxS32 p_legoAnimationManagerConfig); LEGO1_EXPORT static void configureLegoAnimationManager(MxS32 p_legoAnimationManagerConfig);
void SetMaxAllowedExtras(MxU32 p_maxAllowedExtras) { m_maxAllowedExtras = p_maxAllowedExtras; }
// SYNTHETIC: LEGO1 0x1005ed10 // SYNTHETIC: LEGO1 0x1005ed10
// LegoAnimationManager::`scalar deleting destructor' // LegoAnimationManager::`scalar deleting destructor'

View File

@ -2,6 +2,7 @@
#include "extensions/multiplayer/charactercloner.h" #include "extensions/multiplayer/charactercloner.h"
#include "extensions/multiplayer/charactercustomizer.h" #include "extensions/multiplayer/charactercustomizer.h"
#include "legoanimationmanager.h"
#include "legogamestate.h" #include "legogamestate.h"
#include "legomain.h" #include "legomain.h"
#include "legopathactor.h" #include "legopathactor.h"
@ -341,6 +342,15 @@ void NetworkManager::ProcessIncomingPackets()
m_localPeerId = assignedId; m_localPeerId = assignedId;
m_worldSync.SetLocalPeerId(assignedId); m_worldSync.SetLocalPeerId(assignedId);
} }
if (length >= 6) {
uint8_t maxActors = data[5];
if (maxActors >= 5 && maxActors <= 40) {
LegoAnimationManager::configureLegoAnimationManager(maxActors);
if (AnimationManager()) {
AnimationManager()->SetMaxAllowedExtras(maxActors);
}
}
}
break; break;
} }
case MSG_HOST_ASSIGN: { case MSG_HOST_ASSIGN: {

View File

@ -25,6 +25,7 @@ export class GameRoom implements DurableObject {
private nextPeerId = 1; private nextPeerId = 1;
private hostPeerId = 0; private hostPeerId = 0;
private maxPlayers = 5; private maxPlayers = 5;
private maxActors = 5;
constructor( constructor(
private state: DurableObjectState, private state: DurableObjectState,
@ -53,7 +54,7 @@ export class GameRoom implements DurableObject {
server.accept(); server.accept();
this.connections.set(peerId, server); this.connections.set(peerId, server);
server.send(createAssignIdMsg(peerId)); server.send(createAssignIdMsg(peerId, this.maxActors));
this.assignHostIfNeeded(peerId, server); this.assignHostIfNeeded(peerId, server);
server.addEventListener("message", (event) => server.addEventListener("message", (event) =>
@ -80,6 +81,7 @@ export class GameRoom implements DurableObject {
try { try {
const body = (await request.json()) as { const body = (await request.json()) as {
maxPlayers?: number; maxPlayers?: number;
maxActors?: number;
}; };
const ceiling = this.env.MAX_PLAYERS_CEILING const ceiling = this.env.MAX_PLAYERS_CEILING
? Number(this.env.MAX_PLAYERS_CEILING) ? Number(this.env.MAX_PLAYERS_CEILING)
@ -90,11 +92,17 @@ export class GameRoom implements DurableObject {
Math.min(body.maxPlayers, ceiling) Math.min(body.maxPlayers, ceiling)
); );
} }
if (body.maxActors !== undefined) {
this.maxActors = Math.max(
5,
Math.min(body.maxActors, 40)
);
}
} catch { } catch {
// Ignore parse errors, keep defaults // Ignore parse errors, keep defaults
} }
return new Response( return new Response(
JSON.stringify({ maxPlayers: this.maxPlayers }), JSON.stringify({ maxPlayers: this.maxPlayers, maxActors: this.maxActors }),
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@ -109,6 +117,7 @@ export class GameRoom implements DurableObject {
JSON.stringify({ JSON.stringify({
players: this.connections.size, players: this.connections.size,
maxPlayers: this.maxPlayers, maxPlayers: this.maxPlayers,
maxActors: this.maxActors,
}), }),
{ {
headers: { headers: {

View File

@ -15,8 +15,8 @@ export const MSG_WORLD_EVENT_REQUEST = 8;
export const MSG_CUSTOMIZE = 10; export const MSG_CUSTOMIZE = 10;
export const MSG_ASSIGN_ID = 0xff; export const MSG_ASSIGN_ID = 0xff;
// AssignIdMsg: compact server-only message — type(1) + peerId(4) // AssignIdMsg: compact server-only message — type(1) + peerId(4) + maxActors(1)
const ASSIGN_ID_SIZE = 1 + 4; const ASSIGN_ID_SIZE = 1 + 4 + 1;
// HostAssignMsg: header(9) + hostPeerId(4) // HostAssignMsg: header(9) + hostPeerId(4)
const HOST_ASSIGN_SIZE = HEADER_SIZE + 4; const HOST_ASSIGN_SIZE = HEADER_SIZE + 4;
@ -25,11 +25,12 @@ const HOST_ASSIGN_SIZE = HEADER_SIZE + 4;
export const SNAPSHOT_TARGET_OFFSET = HEADER_SIZE; export const SNAPSHOT_TARGET_OFFSET = HEADER_SIZE;
export const SNAPSHOT_MIN_SIZE = HEADER_SIZE + 4 + 2; export const SNAPSHOT_MIN_SIZE = HEADER_SIZE + 4 + 2;
export function createAssignIdMsg(peerId: number): ArrayBuffer { export function createAssignIdMsg(peerId: number, maxActors: number): ArrayBuffer {
const buf = new ArrayBuffer(ASSIGN_ID_SIZE); const buf = new ArrayBuffer(ASSIGN_ID_SIZE);
const view = new DataView(buf); const view = new DataView(buf);
view.setUint8(0, MSG_ASSIGN_ID); view.setUint8(0, MSG_ASSIGN_ID);
view.setUint32(1, peerId, true); view.setUint32(1, peerId, true);
view.setUint8(5, maxActors);
return buf; return buf;
} }