Managing Global User State
This guide explains how to manage user state in Agent8. Use user state to store and update individual profiles, preferences, and other personal data that persists across sessions.
Understanding User State
Each user in Agent8 has a persistent state that can be accessed and modified using the $global.getMyState() and $global.updateMyState() functions. By default, every user state includes an account field containing the user’s unique identifier, and this state persists between requests.
By default, every user state includes an account field containing
the user’s unique identifier.
Server API
$sender.account: string: The account of the user who sent the request.$global.getUserState(account: string): Promise<Object>: Retrieves a specific user’s state.$global.updateUserState(account: string, state: Object): Promise<Object>: Updates a specific user’s state.$global.getMyState(): Promise<Object>: Equivalent to$global.getUserState($sender.account).$global.updateMyState(state: Object): Promise<Object>: Equivalent to$global.updateUserState($sender.account, state).
class Server {
getMyAccount() {
return $sender.account;
}
async getUserState(account) {
return await $global.getUserState(account);
}
async updateUserState(account, state) {
return await $global.updateUserState(account, state);
}
async getMyState() {
return await $global.getMyState();
}
async updateMyState(state) {
return await $global.updateMyState(state);
}
}Client API
subscriptions
server.subscribeGlobalMyState((state: any) => {}): UnsubscribeFunctionserver.subscribeGlobalUserState(account: string, (state: any) => {}): UnsubscribeFunction
hooks
const myState = useGlobalMyState()const userState = useGlobalUserState(account: string)
Subscribe to Global User State Updates
import { useGameServer } from "@agent8/gameserver";
import { useEffect } from "react";
function UserStateComponent() {
const { connected, server } = useGameServer();
useEffect(() => {
if (!connected) return;
// Subscribe to my state
const unsubscribeMyState = server.subscribeGlobalMyState((state) => {
console.log("My state updated:", state);
});
// Subscribe to another user's state
const account = "other-user-account";
const unsubscribeUserState = server.subscribeGlobalUserState(
account,
(state) => {
console.log(`User ${account} state updated:`, state);
}
);
// Cleanup subscriptions
return () => {
unsubscribeMyState();
unsubscribeUserState();
};
}, [connected, server]);
return <div>User State Component</div>;
}Sync User State
To synchronize the user state in real-time using hooks:
import { useGlobalMyState, useGlobalUserState } from "@agent8/gameserver";
function UserStateDisplay() {
const myState = useGlobalMyState();
const userState = useGlobalUserState("other-user-account");
return (
<div>
<h2>My State</h2>
<pre>{JSON.stringify(myState, null, 2)}</pre>
<h2>User State for {account}</h2>
<pre>{JSON.stringify(userState, null, 2)}</pre>
</div>
);
}Example 1: Transfer Money
In this example, you transfer money to a specific user. When you transfer money, the specified amount is deducted from your balance and added to the recipient’s balance.
class Server {
async transferMoney(targetAccount, amount) {
const myState = await $global.getMyState();
const currentBalance = myState.balance || 0;
// Deduct the transfer amount from sender's balance
const newSenderBalance = currentBalance - amount;
// Get the target user's state and calculate new balance
const targetState = await $global.getUserState(targetAccount);
const targetBalance = targetState.balance || 0;
const newTargetBalance = targetBalance + amount;
await $global.updateMyState({ balance: newSenderBalance });
await $global.updateUserState(targetAccount, { balance: newTargetBalance });
return {
targetAccount,
transferred: amount,
newSenderBalance,
newTargetBalance,
};
}
}
import { useGameServer, useGlobalMyState, useGlobalUserState } from "@agent8/gameserver";
import { useEffect } from "react";
export default function TransferMoney() {
const { connected, server } = useGameServer();
const myState = useGlobalMyState();
const targetAccount = "target-user-account";
const yourState = useGlobalUserState(targetAccount);
const transferAmount = 10;
useEffect(() => {
if (!connected) return;
// Optional: Perform additional setup with subscriptions
const unsubscribeMyState = server.subscribeGlobalMyState((state) => {
// Do something with state updates
});
return () => unsubscribeMyState();
}, [connected, server]);
const handleTransfer = async () => {
const result = await server.remoteFunction("transferMoney", [
targetAccount,
transferAmount,
]);
console.log("Transfer result:", result);
};
if (!connected) return <p>Loading...</p>;
return (
<div>
<p>My balance: {myState.balance || 0}</p>
<p>Your balance: {yourState.balance || 0}</p>
<button onClick={handleTransfer}>Transfer $10 to {targetAccount}</button>
</div>
);
}