A minimal Python library for Uma Musume turn evaluation
Project description
UmaLite
UmaLite is a small Python library for scoring Uma Musume turn actions.
You give it a snapshot of the current state, a run context, and a list of candidate actions. It returns ranked results with a score breakdown for each action.
The library does not read the game or run automation. It scores actions from what the caller knows right now.
The goal is to keep evaluation logic isolated and reusable so other tools can use the same scoring engine.
UmaLite is snapshot-first. The more visible state the caller supplies, the more accurate scenario-specific scoring becomes. Missing optional data should reduce precision, not be silently invented.
Quick start
Most callers now use a scenario client.
The preferred entrypoint is:
from umalite import UmaLiteClient
umalite = UmaLiteClient()
ura_client = umalite.ura
unity_client = umalite.unity
trackblazer_client = umalite.trackblazer
Each scenario client exposes:
.snapshots.contexts.profiles.actions
For URA and Unity, the normal path is evaluate_turn(...).
For Trackblazer, the normal path is plan_turn(...).
from umalite import CheckpointContext, CheckpointKind, MoodLevel, RaceGrade, StatType, UmaLiteClient
ura_client = UmaLiteClient().ura
snapshot = ura_client.snapshots.minimal(
stats={
StatType.SPEED: 420,
StatType.STAMINA: 360,
StatType.POWER: 340,
StatType.GUTS: 250,
StatType.WIT: 390,
},
energy=58,
mood=MoodLevel.NORMAL,
fans=42000,
)
context = ura_client.contexts.basic(
checkpoint=CheckpointContext(
kind=CheckpointKind.GOAL_RACE,
turns_remaining=8,
),
)
career_profile = ura_client.profiles.basic(
target_stats={
StatType.SPEED: 1200,
StatType.STAMINA: 800,
StatType.POWER: 1000,
StatType.GUTS: 400,
StatType.WIT: 1100,
},
minimum_training_mood=MoodLevel.GOOD,
)
actions = [
ura_client.actions.train(
"speed_training",
training_type=StatType.SPEED,
stat_gains={StatType.SPEED: 18, StatType.POWER: 9},
sp_gain=5,
fail_rate=0.15,
),
ura_client.actions.race(
"g3_race",
race_grade=RaceGrade.G3,
fan_gain=5000,
),
ura_client.actions.rest("rest", mood_change=1),
]
result = ura_client.evaluate_turn(
snapshot=snapshot,
context=context,
actions=actions,
career_profile=career_profile,
)
print(result.best_action_id)
for bid in result.bids:
print(bid.action.action_id, bid.score)
Reusing an evaluator
If you're evaluating many turns, construct an evaluator once.
from umalite import Evaluator, ScenarioName
engine = Evaluator(scenario=ScenarioName.URA)
result = engine.evaluate(snapshot, context, actions, career_profile=career_profile)
Scenario support
| Scenario | Public entrypoint | Status | Notes |
|---|---|---|---|
| URA Finale | UmaLiteClient().ura |
Implemented | Evaluator-first baseline model |
| Unity | UmaLiteClient().unity |
Implemented | Evaluator-first with optional Unity-specific terms |
| Trackblazer | UmaLiteClient().trackblazer |
Experimental | Planner-first with preparation steps |
Scenarios are implemented as plugins so each mode can adjust reward projection and evaluation logic without modifying the core engine. Scenario clients provide the recommended public surface.
Core models
Evaluation uses three primary inputs.
TurnSnapshot- current visible state of the runRunContext- checkpoint horizon, local urgency, risk settingsActionOption- candidate action and its payload
CareerProfile is the run-intent object.
It is used by both evaluate_turn(...) and plan_turn(...).
It currently carries:
- final target stats
- milestone target stats
- minimum training mood
- year-specific training mood floors
- maximum training fail rate
If both CareerProfile and RunContext.target_stats are provided, the explicit context targets win.
The output is a ranked list of ActionBid results.
Action contract
Action inputs follow the same rule across scenarios:
- the caller supplies visible facts
- UmaLite projects hidden outcomes when needed
Training is mostly observable.
Callers usually provide visible stat gains, visible SP gain, fail rate, and training_type.
energy_delta is optional.
If omitted, UmaLite falls back to a bootstrap default.
Wit is the only training lane whose shared fallback energy_delta is non-negative.
The default Wit fallback is +5 energy.
Race is partly projected.
Callers usually provide race_grade and visible fan_gain.
If explicit race rewards are omitted, UmaLite projects a baseline reward bundle from the grade.
Rest is projected by default. Callers do not need to hardcode a fixed recovery amount unless they want an explicit override.
Recreation remains an explicit reward action.
The raw action builders remain available:
train_action(...)race_action(...)rest_action(...)recreation_action(...)
Scenario clients wrap the same builders behind .actions.
Minimal snapshot
The smallest useful snapshot:
from umalite import MoodLevel, ScenarioName
from umalite.models import TurnSnapshot
snapshot = TurnSnapshot.minimal(
scenario=ScenarioName.URA,
stats={
StatType.SPEED: 420,
StatType.STAMINA: 360,
StatType.POWER: 340,
StatType.GUTS: 250,
StatType.WIT: 390,
},
energy=58,
mood=MoodLevel.NORMAL,
fans=42000,
)
Additional fields such as bonds, facilities, turn metadata, conditions, and scenario state are optional enrichment.
String values are also accepted for convenience, but enums are the preferred public API.
Raw API
The raw API is still available:
result = evaluate_turn(
snapshot,
context,
actions,
config=None,
career_profile=None,
milestone=None,
)
plan = plan_turn(
snapshot,
context,
actions,
config=None,
career_profile=None,
milestone=None,
)
Use the raw API when you want direct control over snapshots, contexts, and action payloads.
Precision model
UmaLite does not require perfect state.
Required core state should always be present. Optional enrichment improves scoring quality. If optional scenario data is missing, the evaluator should fall back to a reduced path instead of inventing hidden game state.
In practice this means:
- minimal snapshots are valid
- enriched snapshots score better
- scenario-specific terms activate only when the needed state exists
Projection defaults are bootstrap library approximations, not final scenario truth.
Configuration
Most usage can rely on defaults.
If needed you can supply your own config:
from umalite.config import EvaluationConfig, UtilityConfig
config = EvaluationConfig(
utility=UtilityConfig(...),
)
Or attach the config to an evaluator instance.
Configuration is intended for policy, such as weights, urgency shaping, and risk tolerance. Core game semantics should remain owned by the library.
Examples
See the examples/ directory for:
- minimal URA usage
- enriched URA usage
- reusable evaluator pattern
- minimal Unity usage
- enriched Unity usage
- minimal Trackblazer usage
- enriched Trackblazer usage
The scenario client examples are the recommended starting point.
Developing locally
Clone the repo and install dependencies.
git clone https://github.com/yourusername/umalite.git
cd umalite
python -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
pip install -e ".[dev]"
Run tests.
pytest
Run linters and type checks.
ruff check .
ruff format --check .
mypy .
Install pre-commit hooks for automatic checks on commit.
pre-commit install
The project uses ruff for formatting and linting, mypy for type checking, and pytest for tests.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file umalite-0.1.0.tar.gz.
File metadata
- Download URL: umalite-0.1.0.tar.gz
- Upload date:
- Size: 68.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
671571cb816a1dda95c54e0796ac444628ee67986802d65a21c236888acf54a5
|
|
| MD5 |
ad1d5a38c7346a58ffd5963ec13e9f6b
|
|
| BLAKE2b-256 |
39fc22593f1b4e90e4d3d7c6d839fe9c838db57d1cf96104c95e7cf87d1cd16a
|
File details
Details for the file umalite-0.1.0-py3-none-any.whl.
File metadata
- Download URL: umalite-0.1.0-py3-none-any.whl
- Upload date:
- Size: 83.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc2df472540f8eafeb17d23f9bc274cfb0f9060e5d544fee2a99361159060072
|
|
| MD5 |
7a77ddbee04bf21809d3ba17a8968311
|
|
| BLAKE2b-256 |
45704c9cb7d6f4986cc8ea2cc1821a7877486034a0bc3a0c3afdcd89f97a58ed
|