Overview
IObjectTable represents the currently spawned FFXIV game objects. It provides access to all entities visible to the client, including players, NPCs, monsters, and other objects.
Namespace
Properties
Address
public nint Address { get; }
Gets the address of the object table.
The memory address of the object table
Length
public int Length { get; }
Gets the length of the object table.
The total number of object slots
LocalPlayer
public IPlayerCharacter? LocalPlayer { get; }
Gets the local player character, if one is present.
The local player character, or null if not logged in
PlayerObjects
public IEnumerable<IBattleChara> PlayerObjects { get; }
Gets an enumerator for accessing player objects. This will only contain BattleChara objects. Does not contain any mounts, minions, or accessories.
PlayerObjects
IEnumerable<IBattleChara>
Enumerable of player battle characters
CharacterManagerObjects
public IEnumerable<IGameObject> CharacterManagerObjects { get; }
Gets an enumerator for accessing character manager objects. Contains all objects in indexes [0, 199]. Includes mounts, minions, accessories, and players.
Enumerable of character manager objects
ClientObjects
public IEnumerable<IGameObject> ClientObjects { get; }
Gets an enumerator for accessing client objects. Contains all objects in indexes [200, 448].
Enumerable of client objects
EventObjects
public IEnumerable<IGameObject> EventObjects { get; }
Gets an enumerator for accessing event objects. Contains all objects in indexes [449, 488].
Enumerable of event objects
StandObjects
public IEnumerable<IGameObject> StandObjects { get; }
Gets an enumerator for accessing stand objects. Contains all objects in indexes [489, 628].
Enumerable of stand objects (housing fixtures, etc.)
ReactionEventObjects
public IEnumerable<IGameObject> ReactionEventObjects { get; }
Gets an enumerator for accessing reaction event objects. Contains all objects in indexes [629, 728].
Enumerable of reaction event objects
Methods
Indexer
public IGameObject? this[int index] { get; }
Gets an object at the specified spawn index.
Spawn index (0 to Length-1)
A GameObject at the specified spawn index, or null if empty
SearchById
public IGameObject? SearchById(ulong gameObjectId);
Searches for a game object by their Object ID.
The game object, or null if not found
SearchByEntityId
public IGameObject? SearchByEntityId(uint entityId);
Searches for a game object by the Entity ID.
The game object, or null if not found
GetObjectAddress
public nint GetObjectAddress(int index);
Gets the address of the game object at the specified index of the object table.
The memory address of the object
CreateObjectReference
public IGameObject? CreateObjectReference(nint address);
Creates a reference to an FFXIV game object.
The address of the object in memory
GameObject object or inheritor containing the requested data
Example Usage
public class MyPlugin : IDalamudPlugin
{
private readonly IObjectTable objectTable;
public MyPlugin(IObjectTable objectTable)
{
this.objectTable = objectTable;
}
public void ListAllObjects()
{
foreach (var obj in this.objectTable)
{
if (obj == null) continue;
Log.Information($"Object: {obj.Name} (Kind: {obj.ObjectKind}, ID: {obj.EntityId})");
}
}
public void ListPlayers()
{
foreach (var player in this.objectTable)
{
if (player is IPlayerCharacter pc)
{
Log.Information($"Player: {pc.Name} (Level {pc.Level} {pc.ClassJob.ValueNullable?.Name})");
Log.Information($" Position: {pc.Position}");
Log.Information($" HP: {pc.CurrentHp}/{pc.MaxHp}");
}
}
}
public void FindNearbyEnemies(float maxDistance)
{
var player = this.objectTable.LocalPlayer;
if (player == null) return;
foreach (var obj in this.objectTable)
{
if (obj is IBattleNpc npc && npc.BattleNpcKind == BattleNpcSubKind.Enemy)
{
var distance = Vector3.Distance(player.Position, npc.Position);
if (distance <= maxDistance)
{
Log.Information($"Enemy: {npc.Name} at {distance:F2}m");
}
}
}
}
public IGameObject? FindObjectByName(string name)
{
foreach (var obj in this.objectTable)
{
if (obj?.Name.TextValue.Equals(name, StringComparison.OrdinalIgnoreCase) == true)
{
return obj;
}
}
return null;
}
}
Advanced Usage
Filtering by Object Type
public void ListObjectsByType()
{
// Get only players
var players = this.objectTable
.Where(o => o?.ObjectKind == ObjectKind.Player)
.Cast<IPlayerCharacter>();
// Get only battle NPCs
var npcs = this.objectTable
.Where(o => o?.ObjectKind == ObjectKind.BattleNpc)
.Cast<IBattleNpc>();
// Get only event objects
var eventObjs = this.objectTable
.Where(o => o?.ObjectKind == ObjectKind.EventObj)
.Cast<IEventObj>();
}
Working with Specific Object Ranges
public void CheckPlayerRange()
{
// Only check character manager objects (includes players)
foreach (var obj in this.objectTable.CharacterManagerObjects)
{
if (obj is IPlayerCharacter pc)
{
Log.Information($"Found player in CM range: {pc.Name}");
}
}
}
Distance Calculations
public IGameObject? GetClosestEnemy()
{
var player = this.objectTable.LocalPlayer;
if (player == null) return null;
IGameObject? closest = null;
float closestDistance = float.MaxValue;
foreach (var obj in this.objectTable)
{
if (obj is IBattleNpc npc && npc.BattleNpcKind == BattleNpcSubKind.Enemy)
{
var distance = Vector3.Distance(player.Position, npc.Position);
if (distance < closestDistance)
{
closest = npc;
closestDistance = distance;
}
}
}
return closest;
}
Searching by ID
public void FindSpecificObject()
{
// Search by Entity ID (visible in game as target ID)
var objByEntity = this.objectTable.SearchByEntityId(0x12345678);
// Search by Object ID (internal game object ID)
var objById = this.objectTable.SearchById(0x123456789ABCDEF0);
}
- The object table implements
IEnumerable<IGameObject> so you can use LINQ
- Not all object slots are always populated; check for null
- Objects can be cast to more specific types like
IPlayerCharacter, IBattleChara, IBattleNpc, etc.
- The object table updates every frame; objects may appear or disappear
- Object addresses and references become invalid when objects despawn
- Use
LocalPlayer instead of the deprecated IClientState.LocalPlayer