feat(client): Luck (deterministic gen/drift/descriptor) + GameState store
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
30
client/tests/unit/test_game_state.gd
Normal file
30
client/tests/unit/test_game_state.gd
Normal file
@@ -0,0 +1,30 @@
|
||||
extends "res://addons/gut/test.gd"
|
||||
|
||||
const GameState = preload("res://scripts/state/game_state.gd")
|
||||
|
||||
|
||||
func test_add_item_accumulates():
|
||||
var s = GameState.new()
|
||||
s.add_item("coin", 3)
|
||||
s.add_item("coin", 2)
|
||||
assert_eq(s.inventory["coin"], 5)
|
||||
|
||||
|
||||
func test_npc_disposition_clamps():
|
||||
var s = GameState.new()
|
||||
s.set_npc_disposition("oda_fenn", 250)
|
||||
assert_eq(s.npc_dispositions["oda_fenn"], 100)
|
||||
|
||||
|
||||
func test_drift_luck_respects_base():
|
||||
var s = GameState.new()
|
||||
s.luck_base = 10
|
||||
s.luck = 10
|
||||
s.drift_luck(100)
|
||||
assert_eq(s.luck, 13)
|
||||
|
||||
|
||||
func test_luck_descriptor_delegates():
|
||||
var s = GameState.new()
|
||||
s.luck = 4
|
||||
assert_eq(s.luck_descriptor(), "Fortune spits on you")
|
||||
1
client/tests/unit/test_game_state.gd.uid
Normal file
1
client/tests/unit/test_game_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://chxglv8kbep2i
|
||||
36
client/tests/unit/test_luck.gd
Normal file
36
client/tests/unit/test_luck.gd
Normal file
@@ -0,0 +1,36 @@
|
||||
extends "res://addons/gut/test.gd"
|
||||
|
||||
const Luck = preload("res://scripts/state/luck.gd")
|
||||
|
||||
|
||||
func _rng(s: int) -> RandomNumberGenerator:
|
||||
var r := RandomNumberGenerator.new()
|
||||
r.seed = s
|
||||
return r
|
||||
|
||||
|
||||
func test_roll_base_is_deterministic_for_a_seed():
|
||||
assert_eq(Luck.roll_base(_rng(42), 0), Luck.roll_base(_rng(42), 0))
|
||||
|
||||
|
||||
func test_roll_base_stays_in_range():
|
||||
for s in range(1, 30):
|
||||
var v := Luck.roll_base(_rng(s), 0)
|
||||
assert_true(v >= Luck.MIN and v <= Luck.MAX, "luck %d out of range" % v)
|
||||
|
||||
|
||||
func test_modifier_shifts_result():
|
||||
# +100 modifier clamps to MAX regardless of rolls.
|
||||
assert_eq(Luck.roll_base(_rng(5), 100), Luck.MAX)
|
||||
|
||||
|
||||
func test_drift_stays_within_base_band_and_range():
|
||||
assert_eq(Luck.drift(10, 10, 100), 13) # capped at base+3
|
||||
assert_eq(Luck.drift(10, 10, -100), 7) # capped at base-3
|
||||
assert_eq(Luck.drift(20, 19, 100), 20) # base+3=22 -> clamped to MAX
|
||||
|
||||
|
||||
func test_descriptor_bands():
|
||||
assert_eq(Luck.descriptor(4), "Fortune spits on you")
|
||||
assert_eq(Luck.descriptor(5), "The world is not on your side")
|
||||
assert_eq(Luck.descriptor(20), "The dice are kind today")
|
||||
1
client/tests/unit/test_luck.gd.uid
Normal file
1
client/tests/unit/test_luck.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://ca0o4rjy46crn
|
||||
Reference in New Issue
Block a user