{"id":20410912,"url":"https://github.com/mintlu8/bevy_stat_query","last_synced_at":"2025-07-18T11:08:20.912Z","repository":{"id":226278593,"uuid":"763550530","full_name":"mintlu8/bevy_stat_query","owner":"mintlu8","description":"A bevy framework for implementing complex RPG stat systems.","archived":false,"fork":false,"pushed_at":"2025-04-24T21:14:16.000Z","size":292,"stargazers_count":30,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-04T08:51:35.208Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mintlu8.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-02-26T14:04:08.000Z","updated_at":"2025-05-20T02:46:17.000Z","dependencies_parsed_at":"2024-03-06T20:13:44.991Z","dependency_job_id":"2337f44d-5a6c-438d-95dc-e1abe54f37e3","html_url":"https://github.com/mintlu8/bevy_stat_query","commit_stats":null,"previous_names":["mintlu8/bevy_stat_query"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mintlu8/bevy_stat_query","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mintlu8%2Fbevy_stat_query","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mintlu8%2Fbevy_stat_query/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mintlu8%2Fbevy_stat_query/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mintlu8%2Fbevy_stat_query/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mintlu8","download_url":"https://codeload.github.com/mintlu8/bevy_stat_query/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mintlu8%2Fbevy_stat_query/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265746781,"owners_count":23821734,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T05:49:01.808Z","updated_at":"2025-07-18T11:08:20.883Z","avatar_url":"https://github.com/mintlu8.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bevy-stat-query\n\n[![Crates.io](https://img.shields.io/crates/v/bevy_stat_query.svg)](https://crates.io/crates/bevy_stat_query)\n[![Docs](https://docs.rs/bevy_stat_query/badge.svg)](https://docs.rs/bevy_stat_query/latest/bevy_stat_query/)\n[![Bevy tracking](https://img.shields.io/badge/Bevy%20tracking-released%20version-lightblue)](https://bevyengine.org/learn/book/plugin-development/)\n\nVersatile RPG stat system for the bevy engine.\n\n## Overview\n\nIn order to represent stats, stat buffs and stat queries in an ECS,\n`bevy_stat_query` exclusively uses unordered operations to represent\nstats, this includes `add`, `multiply`, `min`, `max` and `or`.\n\nFor instance if we want to evaluate a character's strength,\ntaken into account buffs and debuffs this can look something like this:\n\n```rust\nclamp((42 + 4 + 7 + (-4)) * 2 * 0.75, 1, 99)\n```\n\nNote how the order of evaluation doesn't matter, which fits perfectly into\nthe \"insert component and have effect\" usage pattern of the ECS.\n\n## Qualified Stats\n\nWe describe each stat as a `Qualifier` and a `Stat`.\n`Stat` is a noun like *strength* or *damage* and\n`Qualifier` are adjectives that describes\nwhat this `Stat` can be applied to.\n\nFor example in *fire magic damage*, *(fire, magic)* is the `Qualifier`,\n*damage* is the `Stat`.\n\n## Modifier and Query\n\nThere are actually two types of stats, `modifier` and `query`.\n\nA `modifier` is something alone the lines of\n\n```text\nIncrease (fire, magic) damage by 5.\n```\n\nWhile a query is\n\n```text\nThis attack does (fire, magic) damage.\n```\n\nWhen querying for *(fire, magic) damage*, all modifiers that boosts\n*damage*, *fire damage*, *magic damage* or *(fire, magic) damage*\ncan apply to this query.\nWhile modifier that boosts a different qualifier *ice damage* or a\ndifferent stat *fire defense* does not apply to this query.\n\nIn `bevy_stat_query`,\na modifier is represented as `(Qualifier, Stat, Value)` while a\nquery is represented as `(QualifierQuery, Stat)`.\n\n* Conditional Modifiers\n\nA common trope in fantasy games is the modifier `elemental damage`, which applies to\nany of fire, ice, etc. In `Qualifier` this is the `any_of` field.\n\n* Exact Query\n\nImagine we have an effect like this:\n\n```text\nAdd 50% of the character's magic damage to physical damage.\n```\n\nIn order to avoid duplication, since effects boosting `damage` applies to\nboth, we can use `QualifierQuery::exact`.\n\n## Traits\n\nQualifier is usually a bitflags implementing `QualifierFlag`, Stat is usually an enum deriving `Stat`.\n\nAn app usually has a single `QualifierFlag` but multiple `Stat` implementors,\nsince each `Stat` can associate to a different type.\nFor example `strength` and `magic` can be a `i32`,\n`hp` can be a `f32`, `is_dragon` can be a `bool` etc.\n\nDifferent types of stats can still query each other via `Querier`\nto model effects like\n\n```text\nIf user is a dragon, increase damage by 50%.\n```\n\n## `StatStream` and `QueryStream`\n\nIn order for components to contribute to stats, you must implement `QueryStream`. `StatStream` can be used\nif no additional querying is needed. A `Component` that implements `StatStream` is automatically a `QueryStream`.\n\nIn order to use `QueryStream`, mark queryable entities as `StatEntity`.\nThen add `StatEntities` to you system and join it with various `QueryStream`s.\n\n```rust\nfn stat_query(\n    entities: StatEntities,\n    stat_maps: StatQuery\u003cStatMap\u003e,\n    weapons: StatQuery\u003cWeapon\u003e,\n    buffs: ChildQuery\u003cBuff\u003e,\n) {\n    let querier = entities.join(\u0026stat_maps).join(\u0026weapons).join(\u0026buffs);\n    let damage = querier.eval_stat(\u0026MyQualifier::Magic, \u0026MyStat::Damage).unwrap();\n}\n```\n\nUsing `bevy_stat_query` is significantly easier if you have access to `\u0026mut World`.\nOne-shot systems are recommended to perform queries.\n\n## Relations\n\n`StatStream` and `QueryStream` provides the `stream_relation` function that makes it easier to implement\nrelation based effects like\n\n```text\nIncrease damage of all allies within 3 yards by 5.\n```\n\nCheckout one of our examples on how to implement this.\n\n## Versions\n\n| bevy | bevy-stat-query |\n|------|-----------------|\n| 0.15 | 0.1 - latest    |\n\n## License\n\nLicensed under either of\n\n* Apache License, Version 2.0 (LICENSE-APACHE(LICENSE-APACHE) or \u003chttp://www.apache.org/licenses/LICENSE-2.0\u003e)\n* MIT license (LICENSE-MIT(LICENSE-MIT) or \u003chttp://opensource.org/licenses/MIT\u003e)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any\nadditional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmintlu8%2Fbevy_stat_query","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmintlu8%2Fbevy_stat_query","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmintlu8%2Fbevy_stat_query/lists"}