16 releases (4 breaking)
0.5.0 | Oct 14, 2023 |
---|---|
0.4.12 | May 28, 2023 |
0.4.5 | Apr 25, 2023 |
0.4.4 | Mar 12, 2023 |
0.1.0 | Feb 9, 2023 |
#330 in Testing
42 downloads per month
1MB
24K
SLoC
SAPTest

Database and testing framework for Super Auto Pets.
Game information is queried from the Super Auto Pets wiki page and stored in a SQLite
database.
Usage
Add it to a project with cargo
.
cargo add saptest
Teams
Build a Team
and simulate battles between them.
Then visualize the results in .dot
format!
use saptest::{
Pet, PetName, Food, FoodName,
Team, TeamCombat, Position, create_battle_digraph
};
// Create a team.
let mut team = Team::new(
&vec![Some(Pet::try_from(PetName::Ant).unwrap()); 5],
5
).unwrap();
let mut enemy_team = team.clone();
// Set a seed for a team.
team.set_seed(Some(25));
// Give food to pets.
team.set_item(&Position::First, Food::try_from(FoodName::Garlic).ok()).unwrap();
enemy_team.set_item(&Position::First, Food::try_from(FoodName::Garlic).ok()).unwrap();
// And fight!
team.fight(&mut enemy_team).unwrap();
// Create a graph of the fight.
println!("{}", create_battle_digraph(&team, false));
digraph {
rankdir=LR
node [shape=box, style="rounded, filled", fontname="Arial"]
edge [fontname="Arial"]
0 [ label = "Ant_0 - The Fragile Truckers_copy" ]
1 [ label = "Ant_0 - The Fragile Truckers", fillcolor = "yellow" ]
2 [ label = "Ant_3 - The Fragile Truckers", fillcolor = "yellow" ]
3 [ label = "Ant_4 - The Fragile Truckers_copy" ]
0 -> 1 [ label = "(Attack, Damage (0, 2), Phase: 1)" ]
1 -> 0 [ label = "(Attack, Damage (0, 2), Phase: 1)" ]
1 -> 2 [ label = "(Faint, Add (1, 1), Phase: 1)" ]
0 -> 3 [ label = "(Faint, Add (1, 1), Phase: 1)" ]
}
Graphs can be as simple as the example above... or extremely complex.
Using Graphviz Online.
Shops
Add shop functionality to a Team
and roll, freeze, buy/sell pets and foods.
use saptest::{
Shop, ShopItem, TeamShopping, Team,
Position, Entity, EntityName, Food, FoodName,
db::pack::Pack
};
// All teams are constructed with a shop at tier 1.
let mut team = Team::default();
// All shop functionality is supported.
team.set_shop_seed(Some(1212))
.set_shop_packs(&[Pack::Turtle])
.open_shop().unwrap()
.buy(
&Position::First, // From first.
&Entity::Pet, // Pet
&Position::First // To first position, merging if possible.
).unwrap()
.move_pets(
&Position::First, // First pet.
&Position::Relative(-2), // To pet 2 slots behind. Otherwise, ignore.
true // And merge them if possible.
).unwrap()
.sell(&Position::First).unwrap()
.freeze_shop(&Position::Last, &Entity::Pet).unwrap()
.roll_shop().unwrap()
.close_shop().unwrap();
// Shops can be built separately and can replace a team's shop.
let mut tier_5_shop = Shop::new(3, Some(42)).unwrap();
let weakness = ShopItem::new(
Food::try_from(FoodName::Weak).unwrap()
);
tier_5_shop.add_item(weakness).unwrap();
team.replace_shop(tier_5_shop).unwrap();
Pets
Build custom Pet
s and Effect
s.
use saptest::{
Pet, PetName, PetCombat,
Food, FoodName,
Entity, Position, Effect, Statistics,
effects::{
trigger::TRIGGER_START_BATTLE,
actions::GainType,
state::Target,
actions::Action
}
};
// Create known pets.
let mut pet = Pet::try_from(PetName::Ant).unwrap();
// Or custom pets and effects.
let custom_effect = Effect::new(
TRIGGER_START_BATTLE, // Effect trigger
Target::Friend, // Target
Position::Adjacent, // Positions
Action::Gain(GainType::DefaultItem(FoodName::Melon)), // Action
Some(1), // Number of uses.
false, // Is temporary.
);
let mut custom_pet = Pet::custom(
"MelonBear",
Statistics::new(50, 50).unwrap(),
&[custom_effect],
);
// Fight two pets individually as well.
// Note: Effects don't activate here.
pet.attack(&mut custom_pet);
Logging
Enable logging with a crate like simple_logger
.
Config
To configure the global SapDB
's startup, create a .saptest.toml
file in the root of your project.
- Specify page versions for pets, foods, and tokens to query.
- Toggle recurring updates on startup.
- Set database filename.
[database]
# https://superautopets.wiki.gg/index.php?title=Pets&oldid=4634
pets_version = 4634
filename = "./sap.db"
update_on_startup = false
Graph building can also be disabled in [general]
with build_graph
.
[general]
build_graph = false
Benchmarks
Benchmarks for saptest
are located in benches/battle_benchmarks.rs
and run using the criterion
crate.
- Compared against
sapai
, a Super Auto Pets testing framework written in Python. - Both tests were run on an AMD Ryzen 5 5600 6-Core Processor @ 3.50 GHz.
# saptest
git clone git@github.com:koisland/SuperAutoTest.git --depth 1
cargo add cargo-tarpaulin
cargo bench && open target/criterion/sapai_example/report/index.html
# sapai
cd benches/
git clone https://github.com/manny405/sapai.git && cd sapai
python setup.py install
# Then run `battle_benchmarks_sapai.ipynb`.
saptest (No Graphs)
- TODO
saptest (Graphs)
- TODO
sapai
- 4.29 ms ± 51.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
TODO:
- Add trait for randomly generating teams.
- Add method to iterate through record fields/fieldnames and build macro to construct SQL statements.
- Manually adding fields is tedious and error-prone.
- Build lexer to parse raw effect text into
Effect
struct. - Add feature flags for each pack.
- Improve interface.
- Function arguments with impls like
AsRef
andInto/TryInto
. ex.Shop.add_item
- Type state pattern with
Shop<Open/Close>
- Function arguments with impls like
Sources
Dependencies
~38MB
~627K SLoC