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);
void SetMaxAllowedExtras(MxU32 p_maxAllowedExtras) { m_maxAllowedExtras = p_maxAllowedExtras; }
// SYNTHETIC: LEGO1 0x1005ed10
// LegoAnimationManager::`scalar deleting destructor'

View File

@ -2,6 +2,7 @@
#include "extensions/multiplayer/charactercloner.h"
#include "extensions/multiplayer/charactercustomizer.h"
#include "legoanimationmanager.h"
#include "legogamestate.h"
#include "legomain.h"
#include "legopathactor.h"
@ -341,6 +342,15 @@ void NetworkManager::ProcessIncomingPackets()
m_localPeerId = 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;
}
case MSG_HOST_ASSIGN: {

View File

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

View File

@ -15,8 +15,8 @@ export const MSG_WORLD_EVENT_REQUEST = 8;
export const MSG_CUSTOMIZE = 10;
export const MSG_ASSIGN_ID = 0xff;
// AssignIdMsg: compact server-only message — type(1) + peerId(4)
const ASSIGN_ID_SIZE = 1 + 4;
// AssignIdMsg: compact server-only message — type(1) + peerId(4) + maxActors(1)
const ASSIGN_ID_SIZE = 1 + 4 + 1;
// HostAssignMsg: header(9) + hostPeerId(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_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 view = new DataView(buf);
view.setUint8(0, MSG_ASSIGN_ID);
view.setUint32(1, peerId, true);
view.setUint8(5, maxActors);
return buf;
}