Managing Room State
This guide explains how to manage room state in Agent8. Use room state to store and update room-specific configurations—such as room status, maintenance settings, counters, and other values that affect only users within a room.
Every room state automatically includes default values: { roomId: string, $users: string[] }.
For example: { roomId: "roomA", $users: ["account1", "account2"] }.
The $users field is automatically updated when users join or leave the room.
Understanding Room State
Room state in Agent8 is shared among all users in a specific room and can be accessed using the functions $room.getRoomState() and $room.updateRoomState(). Because the state persists between requests, it is ideal for managing configurations and statuses that are unique to each room.
Remember: Room state is shared by all users in the room, so it is best used for room announcements, status updates, and settings that need to stay consistent among all participants.
Server API
$sender.roomId: string: The ID of the room the sender is in.$room.getRoomState(): Promise<Object>: Retrieves the current room state.$room.updateRoomState(state: Object): Promise<Object>: Updates the room state with new values.
class Server {
async getRoomState() {
return await $room.getRoomState(); // { roomId: string, $users: string[] }
}
async updateRoomState(state) {
return await $room.updateRoomState(state);
}
}Client API
subscriptions
server.subscribeRoomState(roomId: string, (state: any) => {}): UnsubscribeFunction- roomId is required.
hooks
const roomState = useRoomState();- The hook always gets the current room. No room ID is required.
Subscribe to Room State Updates
import { useGameServer } from "@agent8/gameserver";
import { useEffect } from "react";
function RoomStateComponent({ roomId }) {
const { connected, server } = useGameServer();
useEffect(() => {
if (!connected) return;
const unsubscribe = server.subscribeRoomState(roomId, (state) => {
// Handle room state updates here
console.log("Room state updated:", state);
});
// Cleanup subscription when component unmounts
return () => unsubscribe();
}, [connected, server]);
return <div>Room State Component</div>;
}Sync Room State with React Hooks
For real-time room state synchronization in React components:
import { useRoomState } from "@agent8/gameserver";
function RoomStateDisplay() {
const roomState = useRoomState();
return (
<div>
<h2>Room State</h2>
<p>Room ID: {roomState.roomId}</p>
<p>Users in room: {roomState.$users?.length || 0}</p>
<pre>{JSON.stringify(roomState, null, 2)}</pre>
</div>
);
}The useRoomState hook automatically handles subscriptions and
unsubscriptions, making it the recommended approach for React applications.
Example 1: Room Counter
This example demonstrates a persistent counter that increments within a room. The server updates the counter in the room state, while the clients display and trigger the update in real-time.
class Server {
async countup() {
const currentState = await $room.getRoomState();
const newCount = (currentState.count || 0) + 1;
await $room.updateRoomState({ count: newCount });
return { ...currentState, count: newCount };
}
}import { useGameServer, useRoomState } from "@agent8/gameserver";
import { useEffect } from "react";
const roomId = "room1";
export default function CountUp() {
const { connected, server } = useGameServer();
const roomState = useRoomState();
useEffect(() => {
if (!connected) return;
server.remoteFunction("joinRoom", roomId);
// Optional: Perform additional setup with the room state subscription
const unsubscribe = server.subscribeRoomState(roomId, (state) => {
// Additional handling if needed beyond useRoomState
console.log("Room state updated:", state);
});
return () => unsubscribe();
}, [connected, server]);
if (!connected) return <p>Loading...</p>;
const handleIncrement = async () => {
await server.remoteFunction("countup");
};
return (
<div>
<p>Count: {roomState.count || 0}</p>
<button onClick={handleIncrement}>Increase Count</button>
</div>
);
}