Hierarchy

  • IPlayersHelper

Methods

  • Live data for a player, or null when they are not present. Omit user for the local player. Matching is case-insensitive.

    Present means "identity is here" — a player whose profile has not replicated is still returned, with an empty name and nameResolved: false, but a usable userId and displayName. An entity carrying only avatar or wearable data and no identity is not a player and yields null.

    Parameters

    Returns null | GetPlayerDataRes

  • How many players are present. Deliberately not getPlayers().length: it reads the tracked size directly instead of building a payload per player, so it stays cheap for per-frame checks like capacity gates. Counts the local player on a client, same as getPlayers.

    Because of that it reflects the last settled tick, while getPlayers validates against live components — so for one frame after an entity disappears this can read one higher than getPlayers().length. Use getPlayers().length when you need the two to agree exactly.

    Returns number

  • Every player currently present, on the same "identity is here" threshold as getPlayer, and with the same element shape.

    On a client this includes the local player, whose identity is one of the tracked entities. Filter when you mean "everyone else": getPlayers().filter((p) => p.entity !== engine.PlayerEntity). A headless server has no local avatar, so there it is always just the remote peers.

    Returns GetPlayerDataRes[]

  • Called once per player when they arrive.

    By default this waits for the avatar profile component, so avatar is set. Pass { requireProfile: false } to be told as soon as the player's identity exists — see PlayerEventOptions for what each threshold guarantees about the name.

    By default this also fires once for each player who already satisfies the threshold — see replayPresent in PlayerEventOptions.

    Do not cache player.entity past the callback: the entity backing an address can be replaced without an event (see GetPlayerDataRes.entity).

    async handlers are supported; a rejection is logged and isolated, never left unhandled, and never stops the other handlers.

    Returns

    an unsubscribe function

    Example

    // rendering: wait for the profile, and render displayName (name may be unresolved)
    onEnterScene((player) => addNameplate(player.userId, player.displayName))

    // server presence: react as soon as the player exists
    onEnterScene(async (player) => {
    const profile = await store.load(player.userId)
    room.send('profile', profile, { to: [player.userId] })
    }, { requireProfile: false })

    Parameters

    Returns (() => void)

      • (): void
      • Called once per player when they arrive.

        By default this waits for the avatar profile component, so avatar is set. Pass { requireProfile: false } to be told as soon as the player's identity exists — see PlayerEventOptions for what each threshold guarantees about the name.

        By default this also fires once for each player who already satisfies the threshold — see replayPresent in PlayerEventOptions.

        Do not cache player.entity past the callback: the entity backing an address can be replaced without an event (see GetPlayerDataRes.entity).

        async handlers are supported; a rejection is logged and isolated, never left unhandled, and never stops the other handlers.

        Returns

        an unsubscribe function

        Example

        // rendering: wait for the profile, and render displayName (name may be unresolved)
        onEnterScene((player) => addNameplate(player.userId, player.displayName))

        // server presence: react as soon as the player exists
        onEnterScene(async (player) => {
        const profile = await store.load(player.userId)
        room.send('profile', profile, { to: [player.userId] })
        }, { requireProfile: false })

        Returns void

  • Called once per player when they go away — mirroring the threshold of the matching onEnterScene. With the default requireProfile, that means either the player left or their avatar profile went away; with { requireProfile: false }, only when their identity is gone.

    Do not rely on getPlayer(userId) here — what it returns depends on which threshold fired. On the identity threshold the entity is gone and it returns null; on the default threshold it can still return a live player, because only the avatar profile went away while the identity is still present. The last known state therefore arrives as the second argument, and is the only reading that is correct in both cases.

    Returns

    an unsubscribe function

    Parameters

    • cb: ((userId: string, lastKnown: Readonly<{
          displayName: string;
          isGuest: boolean;
          joinedAtMs: number;
          name: string;
          nameResolved: boolean;
          userId: string;
      }>) => void)
        • (userId: string, lastKnown: Readonly<{
              displayName: string;
              isGuest: boolean;
              joinedAtMs: number;
              name: string;
              nameResolved: boolean;
              userId: string;
          }>): void
        • Parameters

          • userId: string
          • lastKnown: Readonly<{
                displayName: string;
                isGuest: boolean;
                joinedAtMs: number;
                name: string;
                nameResolved: boolean;
                userId: string;
            }>

          Returns void

    • Optional options: PlayerEventOptions

    Returns (() => void)

      • (): void
      • Called once per player when they go away — mirroring the threshold of the matching onEnterScene. With the default requireProfile, that means either the player left or their avatar profile went away; with { requireProfile: false }, only when their identity is gone.

        Do not rely on getPlayer(userId) here — what it returns depends on which threshold fired. On the identity threshold the entity is gone and it returns null; on the default threshold it can still return a live player, because only the avatar profile went away while the identity is still present. The last known state therefore arrives as the second argument, and is the only reading that is correct in both cases.

        Returns

        an unsubscribe function

        Returns void

  • Called when a player's real profile name first becomes available, and on any later change. Subscribe to this instead of polling AvatarBase on a timer.

    Not called for a name that was already resolved when the player was first seen — that value is already on the arrival payload. It can, however, fire on the same tick as a default-threshold onEnterScene: a late-arriving profile is both what resolves the name and what satisfies that threshold, so a subscriber to both will be told twice. Identity threshold subscribers need this event, since their arrival payload predates the name.

    Returns

    an unsubscribe function

    Parameters

    Returns (() => void)

      • (): void
      • Called when a player's real profile name first becomes available, and on any later change. Subscribe to this instead of polling AvatarBase on a timer.

        Not called for a name that was already resolved when the player was first seen — that value is already on the arrival payload. It can, however, fire on the same tick as a default-threshold onEnterScene: a late-arriving profile is both what resolves the name and what satisfies that threshold, so a subscriber to both will be told twice. Identity threshold subscribers need this event, since their arrival payload predates the name.

        Returns

        an unsubscribe function

        Returns void