Skip to main content

Entities

Struct Entities 

Source
pub struct Entities { /* private fields */ }
Expand description

Container for all entities in the replay.

Entities represent all game objects (heroes, NPCs, items, wards, etc.). This container provides multiple ways to access them:

  • By index (direct position in entity array)
  • By handle (combined serial + index)
  • By class ID (entity type)
  • By class name (e.g., “CDOTA_Unit_Hero_Axe”)

§Entity Access Patterns

Different scenarios require different lookup methods:

§Examples

§Get the player resource

use source2_demo::prelude::*;

let player_resource = ctx.entities().get_by_class_name("CDOTA_PlayerResource")?;

§Find all heroes on a specific team

use source2_demo::prelude::*;

let radiant_heroes: Vec<&Entity> = ctx.entities()
    .iter()
    .filter(|e| {
        e.class().name().starts_with("CDOTA_Unit_Hero_")
            && try_property!(e, u32, "m_iTeamNum") == Some(2) // 2 = Radiant
    })
    .collect();

§Get entity by index

use source2_demo::prelude::*;

let entity = ctx.entities().get_by_index(256)?;
println!("Entity type: {}", entity.class().name());

Implementations§

Source§

impl Entities

Source

pub fn iter(&self) -> impl Iterator<Item = &Entity>

Returns an iterator over all active entities.

Iterates only entities that are currently alive/active in the replay. Deleted entities are automatically skipped.

§Examples
use source2_demo::prelude::*;
use source2_demo::proto::*;

#[derive(Default)]
struct MyObs;

impl Observer for MyObs {
    fn on_tick_start(&mut self, ctx: &Context) -> ObserverResult {
        let dire_heroes = ctx
            .entities()
            .iter()
            .filter(|&e| {
                e.class().name().starts_with("CDOTA_Hero_Unit")
                    && try_property!(e, u32, "m_iTeamNum") == Some(3)
                    && try_property!(e, u32, "m_hReplicatingOtherHeroModel") == Some(u32::MAX)
            })
            .collect::<Vec<_>>();
        Ok(())
    }
}
Source

pub fn get_by_index(&self, index: usize) -> Result<&Entity, EntityError>

Gets an entity by its index in the entity array.

Entity indices are in the range 0-8191. This is the fastest way to access an entity if you already know its index.

§Arguments
  • index - The entity index (0-8191)
§Errors

Returns EntityError::IndexNotFound if no entity exists at the given index or if the entity at that index has been deleted.

§Examples
use source2_demo::prelude::*;

let entity = ctx.entities().get_by_index(0)?;
println!("First entity type: {}", entity.class().name());
Source

pub fn get_by_handle(&self, handle: usize) -> Result<&Entity, EntityError>

Gets an entity by its handle.

A handle combines the serial number and index into a single identifier. This is useful when you have a handle reference from entity properties.

§Arguments
  • handle - The entity handle (serial << 14 | index)
§Errors

Returns EntityError::HandleNotFound if no valid entity exists for the given handle.

§Examples
use source2_demo::prelude::*;

let handle = 123; // Example handle from entity property
let entity = ctx.entities().get_by_handle(handle as usize)?;
Source

pub fn get_by_class_id(&self, id: i32) -> Result<&Entity, EntityError>

Gets the first entity with the specified class ID.

Typically only useful if you know there’s only one entity of that class, or if you only need the first one. For finding multiple entities of a type, use iter with a filter.

§Arguments
  • id - The class ID to search for
§Errors

Returns EntityError::ClassIdNotFound if no entity with the given class ID exists.

§Examples
use source2_demo::prelude::*;

// Find entity by class ID
let entity = ctx.entities().get_by_class_id(42)?;
Source

pub fn get_by_class_name(&self, name: &str) -> Result<&Entity, EntityError>

Gets the first entity with the specified class name.

This is useful for finding unique entities like “CDOTA_PlayerResource” or specific entity types. For finding multiple entities of a class type, use iter with a filter.

§Arguments
  • name - The class name to search for (e.g., “CDOTA_PlayerResource”)
§Errors

Returns EntityError::ClassNameNotFound if no entity with the given class name exists.

§Examples
use source2_demo::prelude::*;

// Find the player resource entity
let player_resource = ctx.entities().get_by_class_name("CDOTA_PlayerResource")?;

// Now you can get player info from this entity
let player_name: String = property!(player_resource, "m_vecPlayerData.{:04}.m_iszPlayerName", 0);

Trait Implementations§

Source§

impl Default for Entities

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Display for Entities

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.