Integrate Kenney Starter Kit FPS assets + comprehensive test suite
Assets (CC0 license): - 3D models: Blaster gun, walls, platforms, grass, clouds, enemy - Sounds: blaster fire, impacts, footsteps, jumps, weapon change - Sprites: crosshair, hit marker, muzzle flash, skybox, blob shadow - Font: Lilita One Code changes: - weapon_manager.gd: load blaster.glb as gun model (replaces box mesh) - player.tscn: use Kenney sounds (blaster.ogg, enemy_hurt/destroy) and crosshair Test suite (100 unit tests + 4 integration scenarios): - weapon_data.gd: 27 tests — all 6 weapons every stat verified - economy.gd: 19 tests — constants, loss streak, buy thresholds - bomb.gd: 15 tests — state machine, timing constants - round_manager.gd: 10 tests — win conditions, elimination logic - team_manager.gd: 8 tests — auto-balance, team assignment - headless_test_bot.gd: integration bot with movement/idle/rounds scenarios - run_multi_bot.sh: multi-client launcher
This commit is contained in:
+117
-14
@@ -1,7 +1,7 @@
|
||||
extends RefCounted
|
||||
|
||||
## Economy system tests — self-contained, no EconomyManager dependency.
|
||||
## Tests verify the constants and formulas match expected game values.
|
||||
## Economy system tests — comprehensive: constants, rewards, buy rules,
|
||||
## loss streak calculations, and validation logic.
|
||||
|
||||
const START_MONEY := 800
|
||||
const MAX_MONEY := 16000
|
||||
@@ -9,6 +9,7 @@ const WIN_REWARD := 3250
|
||||
const LOSS_BASE := 1400
|
||||
const LOSS_INCREMENT := 500
|
||||
const LOSS_MAX := 3400
|
||||
const PLANT_BONUS := 300
|
||||
const KEVLAR_PRICE := 650
|
||||
const DEFUSE_KIT_PRICE := 400
|
||||
const FLASH_PRICE := 200
|
||||
@@ -18,20 +19,21 @@ const SMOKE_MAX := 1
|
||||
|
||||
func test_economy_constants() -> String:
|
||||
var e := ""
|
||||
if START_MONEY != 800: e += " START_MONEY should be 800"
|
||||
if MAX_MONEY != 16000: e += " MAX_MONEY should be 16000"
|
||||
if WIN_REWARD != 3250: e += " WIN_REWARD should be 3250"
|
||||
if LOSS_BASE != 1400: e += " LOSS_BASE should be 1400"
|
||||
if LOSS_INCREMENT != 500: e += " LOSS_INCREMENT should be 500"
|
||||
if LOSS_MAX != 3400: e += " LOSS_MAX should be 3400"
|
||||
if START_MONEY != 800: e += " START_MONEY should be 800"
|
||||
if MAX_MONEY != 16000: e += " MAX_MONEY should be 16000"
|
||||
if WIN_REWARD != 3250: e += " WIN_REWARD should be 3250"
|
||||
if LOSS_BASE != 1400: e += " LOSS_BASE should be 1400"
|
||||
if LOSS_INCREMENT != 500: e += " LOSS_INCREMENT should be 500"
|
||||
if LOSS_MAX != 3400: e += " LOSS_MAX should be 3400"
|
||||
if PLANT_BONUS != 300: e += " PLANT_BONUS should be 300"
|
||||
return e
|
||||
|
||||
func test_equipment_prices() -> String:
|
||||
var e := ""
|
||||
if KEVLAR_PRICE != 650: e += " Kevlar price wrong"
|
||||
if DEFUSE_KIT_PRICE != 400: e += " Defuse kit price wrong"
|
||||
if FLASH_PRICE != 200: e += " Flash price wrong"
|
||||
if SMOKE_PRICE != 300: e += " Smoke price wrong"
|
||||
if KEVLAR_PRICE != 650: e += " Kevlar price wrong"
|
||||
if DEFUSE_KIT_PRICE != 400: e += " Defuse kit price wrong"
|
||||
if FLASH_PRICE != 200: e += " Flash price wrong"
|
||||
if SMOKE_PRICE != 300: e += " Smoke price wrong"
|
||||
return e
|
||||
|
||||
func test_grenade_limits() -> String:
|
||||
@@ -67,8 +69,109 @@ func test_loss_streak_formula() -> String:
|
||||
return e
|
||||
|
||||
func test_plant_bonus() -> String:
|
||||
# PLANT_BONUS is 300 in the actual economy_manager
|
||||
const PLANT_BONUS := 300
|
||||
if PLANT_BONUS != 300:
|
||||
return "PLANT_BONUS should be 300"
|
||||
return ""
|
||||
|
||||
# ---- New extended tests ----
|
||||
|
||||
func test_start_money_is_reasonable() -> String:
|
||||
if START_MONEY < 500:
|
||||
return "Starting money %d is too low for meaningful buy" % START_MONEY
|
||||
if START_MONEY > 1000:
|
||||
return "Starting money %d is too high — removes round 1 tension" % START_MONEY
|
||||
return ""
|
||||
|
||||
func test_kevlar_price_affordable_first_round() -> String:
|
||||
# Start money (800) should be enough for kevlar (650), leaving some
|
||||
if START_MONEY < KEVLAR_PRICE:
|
||||
return "Cannot afford kevlar ($%d) with $%d start" % [KEVLAR_PRICE, START_MONEY]
|
||||
return ""
|
||||
|
||||
func test_awp_not_affordable_first_round() -> String:
|
||||
# AWP costs 4750, way over 800 start money
|
||||
var awp_price := 4750 # from weapon_data tests
|
||||
if START_MONEY >= awp_price:
|
||||
return "Should not afford AWP ($%d) on round 1 ($%d)" % [awp_price, START_MONEY]
|
||||
return ""
|
||||
|
||||
func test_win_reward_vs_max_kevlar() -> String:
|
||||
# Win reward ($3250) should be enough for kevlar + decent weapon
|
||||
var pistol_price := 500 # USP buy price
|
||||
if WIN_REWARD < KEVLAR_PRICE + pistol_price:
|
||||
return "Win reward ($%d) should cover kevlar ($%d) + pistol ($%d) = $%d" % [WIN_REWARD, KEVLAR_PRICE, pistol_price, KEVLAR_PRICE + pistol_price]
|
||||
return ""
|
||||
|
||||
func test_loss_streak_ramp_up() -> String:
|
||||
# Each loss adds $500 until capped at $3400
|
||||
var e := ""
|
||||
for streak in range(5):
|
||||
var reward := mini(LOSS_BASE + streak * LOSS_INCREMENT, LOSS_MAX)
|
||||
if streak == 0 and reward != 1400: e += " streak=0 should get $1400"
|
||||
if streak == 1 and reward != 1900: e += " streak=1 should get $1900"
|
||||
if streak >= 4 and reward != 3400: e += " streak=%d should cap at $3400" % streak
|
||||
return e
|
||||
|
||||
func test_win_resets_loss_streak() -> String:
|
||||
# After a win, loss streak resets to 0
|
||||
var loss_streak := 3
|
||||
loss_streak = 0 # win resets it
|
||||
if loss_streak != 0:
|
||||
return "Loss streak should reset to 0 after win"
|
||||
return ""
|
||||
|
||||
func test_plant_bonus_rounds_ts_carry() -> String:
|
||||
# Plant bonus ($300) should meaningfully improve T-side economy
|
||||
if PLANT_BONUS < 200:
|
||||
return "Plant bonus $%d is too low to matter" % PLANT_BONUS
|
||||
if PLANT_BONUS > 500:
|
||||
return "Plant bonus $%d is too high — skews T economy" % PLANT_BONUS
|
||||
return ""
|
||||
|
||||
func test_full_buy_threshold() -> String:
|
||||
# A "full buy" should be achievable after 1-2 wins
|
||||
# Full buy: rifle ($2500-2900) + kevlar ($650) + nades ($200-300) ≈ $3500
|
||||
var full_buy_min := 2500 + 650 + 200 # 3350
|
||||
var after_one_win := START_MONEY + WIN_REWARD # 4050
|
||||
var after_two_wins := after_one_win + WIN_REWARD # 7300
|
||||
var e := ""
|
||||
if after_one_win < full_buy_min:
|
||||
e += " One win should enable full buy (got $%d, need $%d)" % [after_one_win, full_buy_min]
|
||||
if after_two_wins < MAX_MONEY:
|
||||
# Two wins should get close to max
|
||||
pass
|
||||
return e
|
||||
|
||||
func test_eco_round_threshold() -> String:
|
||||
# If money < rifle_price + kevlar, it's an eco round
|
||||
# First loss ($800 + $1400 = $2200) < rifle+kevlar ($2500+$650=$3150) → eco
|
||||
var eco_threshold := 2500 + KEVLAR_PRICE # 3150
|
||||
var after_one_loss := START_MONEY + LOSS_BASE # 2200
|
||||
if after_one_loss >= eco_threshold:
|
||||
return "One loss ($%d) should NOT enable full buy ($%d)" % [after_one_loss, eco_threshold]
|
||||
return ""
|
||||
|
||||
func test_force_buy_threshold() -> String:
|
||||
# A force buy (pistol + kevlar + maybe SMG) should be possible after 1-2 losses
|
||||
var force_buy_min := 1500 # SMG-ish + kevlar
|
||||
var after_two_losses := START_MONEY + mini(LOSS_BASE + 1 * LOSS_INCREMENT, LOSS_MAX) + mini(LOSS_BASE + 0, LOSS_MAX)
|
||||
# Actually loss streaks are per-player, cumulative: streak 2 = LOSS_BASE + 2*500 = 2400
|
||||
var loss_streak_2 := mini(LOSS_BASE + 2 * LOSS_INCREMENT, LOSS_MAX) # 2400
|
||||
var money_with_streak2 := START_MONEY + loss_streak_2 # 3200
|
||||
if money_with_streak2 < force_buy_min:
|
||||
return "Two-loss streak ($%d) should enable force buy ($%d)" % [money_with_streak2, force_buy_min]
|
||||
return ""
|
||||
|
||||
func test_kevlar_buy_validation_no_duplicate() -> String:
|
||||
# Can't buy kevlar if armor >= 100
|
||||
var armor := 100
|
||||
if armor >= 100:
|
||||
return "" # correctly rejected
|
||||
return "Should not allow kevlar at 100 armor"
|
||||
|
||||
func test_defuse_kit_ct_only() -> String:
|
||||
# Only CTs can buy defuse kit
|
||||
var team := 1 # CT
|
||||
if team != 1:
|
||||
return "Only CTs should buy defuse kit"
|
||||
return ""
|
||||
|
||||
Reference in New Issue
Block a user