umalite 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- umalite-0.1.0/LICENSE +21 -0
- umalite-0.1.0/PKG-INFO +374 -0
- umalite-0.1.0/README.md +347 -0
- umalite-0.1.0/pyproject.toml +114 -0
- umalite-0.1.0/setup.cfg +4 -0
- umalite-0.1.0/tests/test_contracts.py +330 -0
- umalite-0.1.0/tests/test_planning_api.py +276 -0
- umalite-0.1.0/tests/test_trackblazer_basic.py +771 -0
- umalite-0.1.0/tests/test_unity_basic.py +154 -0
- umalite-0.1.0/tests/test_ura_basic.py +229 -0
- umalite-0.1.0/umalite/__init__.py +62 -0
- umalite-0.1.0/umalite/actions.py +137 -0
- umalite-0.1.0/umalite/api/__init__.py +46 -0
- umalite-0.1.0/umalite/client.py +23 -0
- umalite-0.1.0/umalite/config/__init__.py +20 -0
- umalite-0.1.0/umalite/config/career_profile.py +83 -0
- umalite-0.1.0/umalite/config/evaluation_config.py +38 -0
- umalite-0.1.0/umalite/config/missing_data_mode.py +6 -0
- umalite-0.1.0/umalite/config/utility_config.py +85 -0
- umalite-0.1.0/umalite/contracts/__init__.py +3 -0
- umalite-0.1.0/umalite/contracts/planner.py +23 -0
- umalite-0.1.0/umalite/contracts/scenario.py +33 -0
- umalite-0.1.0/umalite/engine/__init__.py +3 -0
- umalite-0.1.0/umalite/engine/evaluation_engine.py +77 -0
- umalite-0.1.0/umalite/engine/intent_resolution.py +50 -0
- umalite-0.1.0/umalite/engine/planning_engine.py +72 -0
- umalite-0.1.0/umalite/evaluation_core.py +244 -0
- umalite-0.1.0/umalite/evaluator.py +58 -0
- umalite-0.1.0/umalite/math/__init__.py +21 -0
- umalite-0.1.0/umalite/math/core.py +137 -0
- umalite-0.1.0/umalite/models/__init__.py +50 -0
- umalite-0.1.0/umalite/models/action_bid.py +32 -0
- umalite-0.1.0/umalite/models/action_option.py +18 -0
- umalite-0.1.0/umalite/models/action_payloads.py +166 -0
- umalite-0.1.0/umalite/models/checkpoint.py +27 -0
- umalite-0.1.0/umalite/models/enums.py +119 -0
- umalite-0.1.0/umalite/models/evaluation_result.py +26 -0
- umalite-0.1.0/umalite/models/preparation_step.py +15 -0
- umalite-0.1.0/umalite/models/reward_bundle.py +28 -0
- umalite-0.1.0/umalite/models/run_context.py +78 -0
- umalite-0.1.0/umalite/models/scenario_terms.py +21 -0
- umalite-0.1.0/umalite/models/turn_plan.py +35 -0
- umalite-0.1.0/umalite/models/turn_snapshot.py +163 -0
- umalite-0.1.0/umalite/projection_defaults.py +216 -0
- umalite-0.1.0/umalite/registry.py +29 -0
- umalite-0.1.0/umalite/scenarios/__init__.py +1 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/__init__.py +44 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/actions.py +144 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/client.py +272 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/config.py +210 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/enums.py +89 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/planning/__init__.py +17 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/planning/candidates.py +833 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/plans.py +138 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/plugin.py +303 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/projection/__init__.py +13 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/projection/prepared_state.py +124 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/projection/race.py +345 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/projection/recovery.py +151 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/projection/training.py +105 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/scoring/__init__.py +13 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/scoring/common.py +42 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/scoring/fatigue.py +110 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/scoring/race.py +383 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/scoring/runtime.py +193 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/scoring/training.py +143 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/state.py +365 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/support/__init__.py +1 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/support/item_catalog.py +380 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/support/pressures.py +270 -0
- umalite-0.1.0/umalite/scenarios/trackblazer/support/trace.py +28 -0
- umalite-0.1.0/umalite/scenarios/unity/__init__.py +10 -0
- umalite-0.1.0/umalite/scenarios/unity/client.py +301 -0
- umalite-0.1.0/umalite/scenarios/unity/config.py +44 -0
- umalite-0.1.0/umalite/scenarios/unity/evaluation.py +178 -0
- umalite-0.1.0/umalite/scenarios/unity/models.py +27 -0
- umalite-0.1.0/umalite/scenarios/unity/plugin.py +128 -0
- umalite-0.1.0/umalite/scenarios/unity/reward_projection.py +118 -0
- umalite-0.1.0/umalite/scenarios/ura/__init__.py +4 -0
- umalite-0.1.0/umalite/scenarios/ura/client.py +249 -0
- umalite-0.1.0/umalite/scenarios/ura/config.py +18 -0
- umalite-0.1.0/umalite/scenarios/ura/evaluation.py +47 -0
- umalite-0.1.0/umalite/scenarios/ura/plugin.py +129 -0
- umalite-0.1.0/umalite/scenarios/ura/reward_projection.py +96 -0
- umalite-0.1.0/umalite.egg-info/PKG-INFO +374 -0
- umalite-0.1.0/umalite.egg-info/SOURCES.txt +87 -0
- umalite-0.1.0/umalite.egg-info/dependency_links.txt +1 -0
- umalite-0.1.0/umalite.egg-info/requires.txt +6 -0
- umalite-0.1.0/umalite.egg-info/top_level.txt +1 -0
umalite-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 UmaLite Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
umalite-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: umalite
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A minimal Python library for Uma Musume turn evaluation
|
|
5
|
+
Author: UmaLite Contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ReaVNaiL/UmaLite
|
|
8
|
+
Project-URL: Repository, https://github.com/ReaVNaiL/UmaLite
|
|
9
|
+
Project-URL: Issues, https://github.com/ReaVNaiL/UmaLite/issues
|
|
10
|
+
Keywords: umamusume,uma-musume,simulation,evaluation,python
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
23
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
24
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
25
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# UmaLite
|
|
29
|
+
|
|
30
|
+
<img width="1701" height="124" alt="image" src="https://github.com/user-attachments/assets/9089e8f3-e6dc-45f2-840b-672ad043c0ba" />
|
|
31
|
+
|
|
32
|
+
UmaLite is a small Python library for scoring **Uma Musume turn actions**.
|
|
33
|
+
|
|
34
|
+
You give it a snapshot of the current state, a run context, and a list of candidate actions.
|
|
35
|
+
It returns ranked results with a score breakdown for each action.
|
|
36
|
+
|
|
37
|
+
The library does not read the game or run automation.
|
|
38
|
+
It scores actions from what the caller knows right now.
|
|
39
|
+
|
|
40
|
+
The goal is to keep evaluation logic isolated and reusable so other tools can use the same scoring engine.
|
|
41
|
+
|
|
42
|
+
UmaLite is **snapshot-first**.
|
|
43
|
+
The more visible state the caller supplies, the more accurate scenario-specific scoring becomes.
|
|
44
|
+
Missing optional data should reduce precision, not be silently invented.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Quick start
|
|
49
|
+
|
|
50
|
+
Most callers now use a scenario client.
|
|
51
|
+
|
|
52
|
+
The preferred entrypoint is:
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from umalite import UmaLiteClient
|
|
56
|
+
|
|
57
|
+
umalite = UmaLiteClient()
|
|
58
|
+
ura_client = umalite.ura
|
|
59
|
+
unity_client = umalite.unity
|
|
60
|
+
trackblazer_client = umalite.trackblazer
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Each scenario client exposes:
|
|
64
|
+
|
|
65
|
+
- `.snapshots`
|
|
66
|
+
- `.contexts`
|
|
67
|
+
- `.profiles`
|
|
68
|
+
- `.actions`
|
|
69
|
+
|
|
70
|
+
For URA and Unity, the normal path is `evaluate_turn(...)`.
|
|
71
|
+
For Trackblazer, the normal path is `plan_turn(...)`.
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from umalite import CheckpointContext, CheckpointKind, MoodLevel, RaceGrade, StatType, UmaLiteClient
|
|
75
|
+
|
|
76
|
+
ura_client = UmaLiteClient().ura
|
|
77
|
+
|
|
78
|
+
snapshot = ura_client.snapshots.minimal(
|
|
79
|
+
stats={
|
|
80
|
+
StatType.SPEED: 420,
|
|
81
|
+
StatType.STAMINA: 360,
|
|
82
|
+
StatType.POWER: 340,
|
|
83
|
+
StatType.GUTS: 250,
|
|
84
|
+
StatType.WIT: 390,
|
|
85
|
+
},
|
|
86
|
+
energy=58,
|
|
87
|
+
mood=MoodLevel.NORMAL,
|
|
88
|
+
fans=42000,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
context = ura_client.contexts.basic(
|
|
92
|
+
checkpoint=CheckpointContext(
|
|
93
|
+
kind=CheckpointKind.GOAL_RACE,
|
|
94
|
+
turns_remaining=8,
|
|
95
|
+
),
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
career_profile = ura_client.profiles.basic(
|
|
99
|
+
target_stats={
|
|
100
|
+
StatType.SPEED: 1200,
|
|
101
|
+
StatType.STAMINA: 800,
|
|
102
|
+
StatType.POWER: 1000,
|
|
103
|
+
StatType.GUTS: 400,
|
|
104
|
+
StatType.WIT: 1100,
|
|
105
|
+
},
|
|
106
|
+
minimum_training_mood=MoodLevel.GOOD,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
actions = [
|
|
110
|
+
ura_client.actions.train(
|
|
111
|
+
"speed_training",
|
|
112
|
+
training_type=StatType.SPEED,
|
|
113
|
+
stat_gains={StatType.SPEED: 18, StatType.POWER: 9},
|
|
114
|
+
sp_gain=5,
|
|
115
|
+
fail_rate=0.15,
|
|
116
|
+
),
|
|
117
|
+
ura_client.actions.race(
|
|
118
|
+
"g3_race",
|
|
119
|
+
race_grade=RaceGrade.G3,
|
|
120
|
+
fan_gain=5000,
|
|
121
|
+
),
|
|
122
|
+
ura_client.actions.rest("rest", mood_change=1),
|
|
123
|
+
]
|
|
124
|
+
|
|
125
|
+
result = ura_client.evaluate_turn(
|
|
126
|
+
snapshot=snapshot,
|
|
127
|
+
context=context,
|
|
128
|
+
actions=actions,
|
|
129
|
+
career_profile=career_profile,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
print(result.best_action_id)
|
|
133
|
+
|
|
134
|
+
for bid in result.bids:
|
|
135
|
+
print(bid.action.action_id, bid.score)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Reusing an evaluator
|
|
141
|
+
|
|
142
|
+
If you're evaluating many turns, construct an evaluator once.
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from umalite import Evaluator, ScenarioName
|
|
146
|
+
|
|
147
|
+
engine = Evaluator(scenario=ScenarioName.URA)
|
|
148
|
+
|
|
149
|
+
result = engine.evaluate(snapshot, context, actions, career_profile=career_profile)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Scenario support
|
|
155
|
+
|
|
156
|
+
| Scenario | Public entrypoint | Status | Notes |
|
|
157
|
+
| -------------- | ------------------------ | -------------- | ---------------------------------------------------- |
|
|
158
|
+
| **URA Finale** | `UmaLiteClient().ura` | Implemented | Evaluator-first baseline model |
|
|
159
|
+
| **Unity** | `UmaLiteClient().unity` | Implemented | Evaluator-first with optional Unity-specific terms |
|
|
160
|
+
| **Trackblazer** | `UmaLiteClient().trackblazer` | Experimental | Planner-first with preparation steps |
|
|
161
|
+
|
|
162
|
+
Scenarios are implemented as plugins so each mode can adjust reward projection and evaluation logic without modifying the core engine.
|
|
163
|
+
Scenario clients provide the recommended public surface.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Core models
|
|
168
|
+
|
|
169
|
+
Evaluation uses three primary inputs.
|
|
170
|
+
|
|
171
|
+
- `TurnSnapshot` - current visible state of the run
|
|
172
|
+
- `RunContext` - checkpoint horizon, local urgency, risk settings
|
|
173
|
+
- `ActionOption` - candidate action and its payload
|
|
174
|
+
|
|
175
|
+
`CareerProfile` is the run-intent object.
|
|
176
|
+
|
|
177
|
+
It is used by both `evaluate_turn(...)` and `plan_turn(...)`.
|
|
178
|
+
It currently carries:
|
|
179
|
+
|
|
180
|
+
- final target stats
|
|
181
|
+
- milestone target stats
|
|
182
|
+
- minimum training mood
|
|
183
|
+
- year-specific training mood floors
|
|
184
|
+
- maximum training fail rate
|
|
185
|
+
|
|
186
|
+
If both `CareerProfile` and `RunContext.target_stats` are provided, the explicit context targets win.
|
|
187
|
+
|
|
188
|
+
The output is a ranked list of `ActionBid` results.
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Action contract
|
|
193
|
+
|
|
194
|
+
Action inputs follow the same rule across scenarios:
|
|
195
|
+
|
|
196
|
+
- the caller supplies visible facts
|
|
197
|
+
- UmaLite projects hidden outcomes when needed
|
|
198
|
+
|
|
199
|
+
Training is mostly observable.
|
|
200
|
+
Callers usually provide visible stat gains, visible SP gain, fail rate, and `training_type`.
|
|
201
|
+
`energy_delta` is optional.
|
|
202
|
+
If omitted, UmaLite falls back to a bootstrap default.
|
|
203
|
+
Wit is the only training lane whose shared fallback `energy_delta` is non-negative.
|
|
204
|
+
The default Wit fallback is `+5` energy.
|
|
205
|
+
|
|
206
|
+
Race is partly projected.
|
|
207
|
+
Callers usually provide `race_grade` and visible `fan_gain`.
|
|
208
|
+
If explicit race rewards are omitted, UmaLite projects a baseline reward bundle from the grade.
|
|
209
|
+
|
|
210
|
+
Rest is projected by default.
|
|
211
|
+
Callers do not need to hardcode a fixed recovery amount unless they want an explicit override.
|
|
212
|
+
|
|
213
|
+
Recreation remains an explicit reward action.
|
|
214
|
+
|
|
215
|
+
The raw action builders remain available:
|
|
216
|
+
|
|
217
|
+
- `train_action(...)`
|
|
218
|
+
- `race_action(...)`
|
|
219
|
+
- `rest_action(...)`
|
|
220
|
+
- `recreation_action(...)`
|
|
221
|
+
|
|
222
|
+
Scenario clients wrap the same builders behind `.actions`.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Minimal snapshot
|
|
227
|
+
|
|
228
|
+
The smallest useful snapshot:
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
from umalite import MoodLevel, ScenarioName
|
|
232
|
+
from umalite.models import TurnSnapshot
|
|
233
|
+
|
|
234
|
+
snapshot = TurnSnapshot.minimal(
|
|
235
|
+
scenario=ScenarioName.URA,
|
|
236
|
+
stats={
|
|
237
|
+
StatType.SPEED: 420,
|
|
238
|
+
StatType.STAMINA: 360,
|
|
239
|
+
StatType.POWER: 340,
|
|
240
|
+
StatType.GUTS: 250,
|
|
241
|
+
StatType.WIT: 390,
|
|
242
|
+
},
|
|
243
|
+
energy=58,
|
|
244
|
+
mood=MoodLevel.NORMAL,
|
|
245
|
+
fans=42000,
|
|
246
|
+
)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Additional fields such as bonds, facilities, turn metadata, conditions, and scenario state are optional enrichment.
|
|
250
|
+
|
|
251
|
+
String values are also accepted for convenience, but enums are the preferred public API.
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Raw API
|
|
256
|
+
|
|
257
|
+
The raw API is still available:
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
result = evaluate_turn(
|
|
261
|
+
snapshot,
|
|
262
|
+
context,
|
|
263
|
+
actions,
|
|
264
|
+
config=None,
|
|
265
|
+
career_profile=None,
|
|
266
|
+
milestone=None,
|
|
267
|
+
)
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
plan = plan_turn(
|
|
272
|
+
snapshot,
|
|
273
|
+
context,
|
|
274
|
+
actions,
|
|
275
|
+
config=None,
|
|
276
|
+
career_profile=None,
|
|
277
|
+
milestone=None,
|
|
278
|
+
)
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Use the raw API when you want direct control over snapshots, contexts, and action payloads.
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Precision model
|
|
286
|
+
|
|
287
|
+
UmaLite does not require perfect state.
|
|
288
|
+
|
|
289
|
+
Required core state should always be present.
|
|
290
|
+
Optional enrichment improves scoring quality.
|
|
291
|
+
If optional scenario data is missing, the evaluator should fall back to a reduced path instead of inventing hidden game state.
|
|
292
|
+
|
|
293
|
+
In practice this means:
|
|
294
|
+
|
|
295
|
+
- minimal snapshots are valid
|
|
296
|
+
- enriched snapshots score better
|
|
297
|
+
- scenario-specific terms activate only when the needed state exists
|
|
298
|
+
|
|
299
|
+
Projection defaults are bootstrap library approximations, not final scenario truth.
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Configuration
|
|
304
|
+
|
|
305
|
+
Most usage can rely on defaults.
|
|
306
|
+
|
|
307
|
+
If needed you can supply your own config:
|
|
308
|
+
|
|
309
|
+
```python
|
|
310
|
+
from umalite.config import EvaluationConfig, UtilityConfig
|
|
311
|
+
|
|
312
|
+
config = EvaluationConfig(
|
|
313
|
+
utility=UtilityConfig(...),
|
|
314
|
+
)
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Or attach the config to an evaluator instance.
|
|
318
|
+
|
|
319
|
+
Configuration is intended for **policy**, such as weights, urgency shaping, and risk tolerance.
|
|
320
|
+
Core game semantics should remain owned by the library.
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## Examples
|
|
325
|
+
|
|
326
|
+
See the `examples/` directory for:
|
|
327
|
+
|
|
328
|
+
- minimal URA usage
|
|
329
|
+
- enriched URA usage
|
|
330
|
+
- reusable evaluator pattern
|
|
331
|
+
- minimal Unity usage
|
|
332
|
+
- enriched Unity usage
|
|
333
|
+
- minimal Trackblazer usage
|
|
334
|
+
- enriched Trackblazer usage
|
|
335
|
+
|
|
336
|
+
The scenario client examples are the recommended starting point.
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Developing locally
|
|
341
|
+
|
|
342
|
+
Clone the repo and install dependencies.
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
git clone https://github.com/yourusername/umalite.git
|
|
346
|
+
cd umalite
|
|
347
|
+
python -m venv .venv
|
|
348
|
+
source .venv/bin/activate # or .venv\Scripts\activate on Windows
|
|
349
|
+
pip install -e ".[dev]"
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
Run tests.
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
pytest
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Run linters and type checks.
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
ruff check .
|
|
362
|
+
ruff format --check .
|
|
363
|
+
mypy .
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Install pre-commit hooks for automatic checks on commit.
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
pre-commit install
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
The project uses ruff for formatting and linting, mypy for type checking, and pytest for tests.
|
|
373
|
+
|
|
374
|
+
|