Skip to main content

Activate 'multi user' mode

3dverse applications can support real-time collaboration, allowing multiple users to join the same 3D scene simultaneously. This guide walks you through the core concepts and API hooks you’ll use to enable multi-user sessions, display client avatars, and manage a client list.

Overview

Multi-user mode in 3dverse works by connecting all participants to a shared session. Each client in a session receives live updates from other connected users, including their camera position and other interactive states.

To implement this, you’ll use a few key components from @3dverse/livelink-react:

  • Livelink — connects your app to a scene or session

  • Viewport — renders the scene from a given camera or client’s perspective

  • useClients() — gives access to all connected clients

  • DOM3DOverlay / DOMEntity — lets you display avatars directly inside the 3D viewport

Creating Sessions

Connecting multiple users under the same session is easy. In fact, it is the default behavior. When you initialize a Livelink component with a sceneId, the user will join an existing session for the provided sceneId if one exists, otherwise it will create a new session.

<Livelink
sceneId={scene_id}
token={token}
autoJoinExisting={true} // default
>
...
</Livelink>

This setup on its own, would ensures all clients always share the same collaborative space.

Setting autoJoinExisting={false} would always create a separate session instead.

Once the session is connected, the client application is able to retrieve the sessionId through the Livelink instance.

import { LivelinkContext } from "@3dverse/livelink-react";

const { instance } = useContext(LivelinkContext);

const sessionId = instance?.session.session_id;

Joining Specific Sessions

If you need more control or wish to have multiple sessions in parallel, you can specify which session to join by providing a sessionId.

import { Livelink } from "@3dverse/livelink-react";

<Livelink sessionId={sessionId} token={token}>
...
</Livelink>;

Listing Connected Clients

Once multiple users are in the same session, you can access the list of participants using the useClients() hook:

import { useClients } from "@3dverse/livelink-react";

const { clients } = useClients();

From here, you would be able to create a UI list of clients and more.

<ul>
{clients.map(client => (
<li>{client.id}</li>
))}
</ul>

Displaying Avatars in 3D

Each connected client can also be represented inside the 3D viewport, at the current location of their camera.

To do this, make an Avatar component which will fetch the camera entity associated with the provided client. The DOMEntity component is used to attach an HMTL avatar to its location:

import type { Client, Entity } from "@3dverse/livelink";
import { DOMEntity } from "@3dverse/livelink-react";

const Avatar = ({ client }: { client: Client }) => {

const [clientCameraEntity, setClientCameraEntity] = useState<Entity | null>(
null,
);

useEffect(() => {
client
.getCameraEntities()
.then(cameraEntities => setClientCameraEntity(cameraEntities[0]));
}, [client]);

if (!clientCameraEntity) {
return null;
}

return (
<DOMEntity
key={client.id}
scaleFactor={0.0025}
entity={clientCameraEntity}
>
<img src="/path/to/avatar.jpg" class="w-10 h-10 rounded-full object-cover" />
</DOMEntity>
);
};

Then, use the DOM3DOverlay component to render avatars for every client currently in the session.

<Viewport ...>
...
<DOM3DOverlay>
{clients.map(client => <Avatar client={client} /> )}
</DOM3DOverlay>
</Viewport>

Optional: Watching Other Clients’ Cameras

For spectating other users, you can even render a picture-in-picture viewport that displays another client’s camera feed. Take any client from the client list provided by useClients() as shown before and feed it into a new <Viewport />

<Livelink ...>
{/* Your own viewport */}
<Canvas className="w-full h-full">
<Viewport cameraEntity={cameraEntity} className="w-full h-full" />
</Canvas>

{/* Picture-in-picture viewport */}
{watchedClient && <Canvas className="absolute top-20 w-1/3 h-1/6 right-8>
<Viewport client={watchedClient} />
</Canvas>}
</Livelink>

Putting It All Together

When combined, these parts create a complete multi-user experience:

  • The first client creates a session

  • Others join using the shared session ID

  • Each client appears as an avatar in 3D space

  • A live client list and PiP camera view enhance collaboration