bevy_easy_stats

Crates.iobevy_easy_stats
lib.rsbevy_easy_stats
version
sourcesrc
created_at2024-12-01 05:52:03.87626
updated_at2024-12-01 05:52:03.87626
descriptionSimple and easy tool to manage stats in Bevy
homepagehttps://github.com/NoahShomette/bevy_easy_stats
repositoryhttps://github.com/NoahShomette/bevy_easy_stats
max_upload_size
id1467233
Cargo.toml error:TOML parse error at line 18, column 1 | 18 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include`
size0
Noah (NoahShomette)

documentation

README

Bevy Easy Stats

A simple and easy way to keep track of stats in one place.

Bevy Version

BES Version Bevy Version
0.2 0.15
0.1 0.14

Usage

1. Create a new stat identifier

pub struct EnemiesKilled;
impl StatIdentifier for EnemiesKilled {
    fn identifier(&self) -> &'static str {
        "Enemies Killed"
    }
}

2. bevy_easy_stats natively supports components and resources as stat collections. These can be automatically updated using built in events and command extensions

#[derive(Resource, Default)]
pub struct ResourceStats {
    stats: Stats,
}
impl AsMut<Stats> for ResourceStats {
    fn as_mut(&mut self) -> &mut Stats {
        &mut self.stats
    }
}

#[derive(Component)]
pub struct EntityStats {
    stats: Stats,
}
impl AsMut<Stats> for EntityStats {
    fn as_mut(&mut self) -> &mut Stats {
        &mut self.stats
    }
}

// If you want to take advantage of built in event based modification functionality make sure to register the stat resource in the app
app.register_stat_resource::<ResourceStats>();

3. Modify stats using several different ways to match your needs

fn modify(mut event_writer: EventWriter<ModifyStat<ResourceStats>>, mut commands: Commands) {
  // entity commands ext to modify component based stats
  commands.entity(entity).modify_stat::<EntityStats>(EnemiesKilled, ModificationType::add(5u64));

  /// Gain acces to an object to queue multiple commands across different types for component based stats
  let mut stats = commands.entity_stats::<EntityStats>(entity);
  stats.add(EnemiesKilled, 5u64);
  stats.add(TimePlayed, Duration::new(5, 0));

  // Use events to modify resource based stats
  event_writer.send(ModifyStat::add(EnemiesKilled, 2u64));
  event_writer.send(ModifyStat::add(TimePlayed, Duration::new(5, 0)));
}

4. Create your own stat types to keep track of whatever you want

// new stat data type
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct CropsGrownStat {
    map: HashMap<String, u64>,
}

// Impl the StatData trait
#[typetag::serde]
impl StatData for CropsGrownStat {
  #[doc = " Creates a new instance of the same kind of stat data"]
  fn default(&self) -> Box<dyn StatData> {
    Box::new(CropsGrownStat {
      map: HashMap::default(),
    })
  }
  #[doc = " Adds the given other to this stat data"]
  fn add(&mut self, other: Box<dyn StatData>) {
    if let Some(other) = other.downcast_ref::<CropsGrownStat>() {
      for (id, amount) in other.map.iter() {
        let entry = self.map.entry(id.clone()).or_default();
        *entry += amount;
      }
    }
  }

  #[doc = " Subtracts the given other from this stat data"]
  fn sub(&mut self, other: Box<dyn StatData>) {
    if let Some(other) = other.downcast_ref::<CropsGrownStat>() {
      for (id, amount) in other.map.iter() {
        let entry = self.map.entry(id.clone()).or_default();
          *entry -= amount;
      }
    }
  }
}

event_writer.send(ModifyStat::add(CropsGrown, CropsGrownStat::new(vec![("Potato".to_string(), 5)])));
event_writer.send(ModifyStat::add(CropsGrown, CropsGrownStat::new(vec![("Dandelion".to_string(), 100)])));
stats.get_stat_downcast::<CropsGrownStat>(&CropsGrown).unwrap() = CropsGrownStat::new(vec![("Dandelion".to_string(), 100), ("Potato".to_string(), 5)])

Future

Commit count: 4

cargo fmt