Files
Bullosseum/debug_params.gd
T

252 lines
14 KiB
GDScript

extends Node
## Central registry for all runtime-tunable parameters.
## Add a new param with one _reg_f() call in _register_all() — the menu picks it up automatically.
## Access: DP.f("key") • Persist: DP.save() / DP.load_saved() • Reset: DP.reset_all()
signal any_changed(key: String, value: Variant)
const SAVE_PATH := "user://debug_params.cfg"
var _params: Dictionary = {}
func _ready() -> void:
_register_all()
load_saved()
func _register_all() -> void:
# ── Movement ──────────────────────────────────────────────────────────────
_reg_f("Movement", "thrust_impulse", 18.0, 1.0, 200.0)
_reg_f("Movement", "thrust_vertical", 2.0, 0.0, 20.0)
_reg_f("Movement", "thrust_min_angle", 15.0, 0.0, 90.0, 1.0)
_reg_f("Movement", "thrust_max_angle", 90.0, 0.0, 180.0, 1.0)
_reg_f("Movement", "thrust_charge_time", 0.5, 0.05, 2.0, 0.05)
_reg_f("Movement", "max_speed", 50.0, 2.0, 1000.0)
_reg_f("Movement", "roll_damping", 0.15, 0.01, 0.99, 0.01)
_reg_f("Movement", "jump_velocity", 4.5, 1.0, 200.0)
_reg_f("Movement", "visual_turn_speed", 12.0, 1.0, 200.0)
_reg_f("Movement", "bounce_restitution", 0.55, 0.0, 2.0, 0.05)
_reg_f("Movement", "bounce_min_impact", 1.0, 0.0, 20.0)
_reg_f("Movement", "wall_bounce_restitution", 0.6, 0.0, 1.5, 0.05)
_reg_f("Movement", "wall_min_bounce_speed", 6.0, 0.0, 30.0)
_reg_f("Movement", "kick_impulse", 8.0, 1.0, 50.0)
_reg_f("Movement", "kick_interval", 0.25, 0.05, 1.0, 0.01)
_reg_f("Movement", "kick_vertical", 0.0, 0.0, 15.0)
_reg_f("Movement", "kick_force_var", 0.2, 0.0, 1.0, 0.01)
_reg_f("Movement", "kick_spread", 10.0, 0.0, 45.0, 1.0)
_reg_f("Movement", "charge_kick_mult", 2.0, 1.0, 5.0)
# ── Dust speed thresholds ─────────────────────────────────────────────────
_reg_f("Dust", "dust_walk_spd", 1.5, 0.1, 10.0)
_reg_f("Dust", "dust_charge_spd", 7.0, 1.0, 20.0)
# ── Dust ──────────────────────────────────────────────────────────────────
_reg_f("Dust", "dust_lifetime", 0.9, 0.1, 4.0)
_reg_f("Dust", "dust_explosiveness", 0.35, 0.0, 1.0)
_reg_f("Dust", "dust_spread", 45.0, 5.0, 90.0)
_reg_f("Dust", "dust_gravity_y", -1.5,-15.0, 0.0)
_reg_f("Dust", "walk_scale_min", 0.35, 0.05, 3.0)
_reg_f("Dust", "walk_scale_max", 0.65, 0.05, 3.0)
_reg_f("Dust", "walk_vel_min", 0.8, 0.1, 12.0)
_reg_f("Dust", "walk_vel_max", 1.8, 0.1, 12.0)
_reg_f("Dust", "charge_scale_min", 1.0, 0.05, 6.0)
_reg_f("Dust", "charge_scale_max", 2.2, 0.05, 6.0)
_reg_f("Dust", "charge_vel_min", 2.8, 0.1, 20.0)
_reg_f("Dust", "charge_vel_max", 5.5, 0.1, 20.0)
# ── Tail ──────────────────────────────────────────────────────────────────
_reg_f("Tail", "tail_gravity", 9.8, 0.0, 30.0)
_reg_f("Tail", "tail_damping", 0.08, 0.0, 0.5, 0.01)
_reg_f("Tail", "tail_body_radius", 0.35, 0.05, 2.0, 0.05)
_reg_f("Tail", "tail_wag_freq", 4.0, 0.5, 15.0)
_reg_f("Tail", "tail_wag_idle", 0.3, 0.0, 2.0, 0.05)
# ── Charge (both mouse buttons) ──────────────────────────────────────────
_reg_f("Charge", "bull_charge_accel", 80.0, 1.0, 400.0)
_reg_f("Charge", "bull_charge_max_speed", 76.0, 5.0, 200.0)
_reg_f("Charge", "charge_ramp_time", 0.75, 0.1, 5.0, 0.05)
_reg_f("Charge", "charge_head_pitch", 0.3, 0.0, 1.2, 0.01)
_reg_f("Charge", "charge_head_speed", 5.0, 0.5, 20.0)
# ── Body ──────────────────────────────────────────────────────────────────
_reg_f("Body", "body_tilt_fwd", 0.015, 0.0, 0.1, 0.001)
_reg_f("Body", "body_tilt_side", 0.01, 0.0, 0.1, 0.001)
_reg_f("Body", "aerial_pitch_scale", 0.6, 0.0, 2.0)
_reg_f("Body", "aerial_pitch_speed", 5.0, 0.5, 20.0)
# ── Legs ──────────────────────────────────────────────────────────────────
_reg_f("Legs", "leg_step_threshold", 0.15, 0.01, 1.0, 0.01)
_reg_f("Legs", "leg_step_duration", 0.12, 0.02, 0.5, 0.01)
_reg_f("Legs", "leg_step_height", 0.15, 0.0, 0.5)
_reg_f("Legs", "leg_step_overshoot", 0.3, 0.0, 1.0)
_reg_f("Legs", "gait_freq", 1.5, 0.1, 5.0)
_reg_f("Legs", "launch_hold_time", 0.15, 0.0, 1.0, 0.01)
_reg_f("Legs", "ragdoll_wobble_amp", 0.15, 0.0, 1.0)
_reg_f("Legs", "tuck_apex_threshold", 0.5, -5.0, 5.0)
_reg_f("Legs", "jump_tuck_speed", 8.0, 1.0, 30.0)
_reg_f("Legs", "jump_tuck_up", 0.2, 0.0, 1.0)
_reg_f("Legs", "jump_tuck_fwd", -0.1, -0.5, 0.5)
_reg_f("Legs", "jump_land_threshold", 1.5, 0.5, 5.0)
# ── Camera ────────────────────────────────────────────────────────────────
_reg_f("Camera", "charge_zoom_factor", 0.65, 0.3, 1.0, 0.05)
_reg_f("Camera", "cam_lerp_power", 6.0, 0.5, 30.0)
_reg_f("Camera", "cam_sensitivity", 0.005, 0.001, 0.05, 0.001)
_reg_f("Camera", "cam_min_zoom", 3.5, 0.5, 20.0)
_reg_f("Camera", "cam_max_zoom", 40.0, 2.0, 80.0)
_reg_f("Camera", "cam_spring_length", 7.0, 1.0, 30.0)
_reg_f("Camera", "cam_min_vert_angle", -60.0, -90.0, 0.0, 1.0)
_reg_f("Camera", "cam_max_vert_angle", 45.0, 0.0, 90.0, 1.0)
# ── Matador ───────────────────────────────────────────────────────────────
_reg_f("Matador", "mat_spawn_count", 1.0, 1.0, 30.0, 1.0)
_reg_f("Matador", "mat_walk_speed", 4.0, 0.5, 10.0)
_reg_f("Matador", "mat_wander_radius", 22.0, 5.0, 50.0)
_reg_f("Matador", "mat_idle_min", 0.5, 0.0, 5.0, 0.1)
_reg_f("Matador", "mat_idle_max", 2.5, 0.5, 10.0, 0.1)
_reg_f("Matador", "mat_hit_threshold", 4.0, 1.0, 30.0)
_reg_f("Matador", "mat_ragdoll_impulse", 6.0, 0.5, 20.0)
# Ragdoll joint limits — lower swing/twist = stiffer corpse that keeps its
# shape; higher angular damp settles the flail instead of flopping flat.
_reg_f("Matador", "mat_joint_swing", 35.0, 0.0, 180.0, 1.0)
_reg_f("Matador", "mat_joint_twist", 40.0, 0.0, 180.0, 1.0)
_reg_f("Matador", "mat_ragdoll_damp", 1.5, 0.0, 10.0, 0.1)
_reg_f("Matador", "mat_flee_range", 3.5, 2.0, 40.0)
_reg_f("Matador", "mat_flee_speed", 5.5, 0.5, 12.0)
_reg_f("Matador", "mat_charge_speed", 10.0, 1.0, 30.0)
_reg_f("Matador", "mat_brace_range", 5.0, 2.0, 20.0)
_reg_f("Matador", "mat_brace_duration", 0.7, 0.05, 1.5, 0.05)
_reg_f("Matador", "mat_commit_dist", 2.5, 0.5, 6.0, 0.1)
_reg_f("Matador", "mat_step_speed", 3.5, 2.0, 20.0)
_reg_f("Matador", "mat_step_duration", 0.35, 0.1, 1.0, 0.05)
_reg_f("Matador", "mat_dodge_cooldown", 5.0, 0.5, 12.0, 0.25)
_reg_f("Matador", "mat_dodge_chance", 0.25, 0.0, 1.0, 0.05)
_reg_f("Matador", "mat_attack_range", 8.0, 2.0, 20.0)
_reg_f("Matador", "mat_attack_speed", 5.5, 1.0, 12.0)
_reg_f("Matador", "mat_attack_duration", 1.8, 0.5, 5.0, 0.1)
_reg_f("Matador", "mat_attack_min_dist", 2.5, 0.5, 6.0, 0.1)
_reg_f("Matador", "mat_roll_chance", 0.35, 0.0, 1.0, 0.05)
_reg_f("Matador", "mat_roll_duration", 0.45, 0.1, 1.5, 0.05)
# Playback rate of the Draw_weapon clip used for both drawing and sheathing —
# higher = snappier unholster/holster.
_reg_f("Matador", "mat_draw_speed", 1.25, 0.25, 3.0, 0.05)
# Cross-fade between matador animation clips — smooths Run/Attack/Taunt cuts.
_reg_f("Matador", "mat_anim_blend", 0.12, 0.0, 0.5, 0.01)
# ── Sword ─────────────────────────────────────────────────────────────────
# Local seating of the sword in the right hand (drawn / fighting).
# Defaults are identity — the bone is oriented in Blender to seat the sword
# directly; these exist to fine-tune in-game without re-exporting.
_reg_f("Sword", "sword_pos_x", 0.0, -1.0, 1.0, 0.01)
_reg_f("Sword", "sword_pos_y", 0.0, -1.0, 1.0, 0.01)
_reg_f("Sword", "sword_pos_z", 0.0, -1.0, 1.0, 0.01)
_reg_f("Sword", "sword_rot_x", 0.0, -180.0, 180.0, 1.0)
_reg_f("Sword", "sword_rot_y", 0.0, -180.0, 180.0, 1.0)
_reg_f("Sword", "sword_rot_z", 0.0, -180.0, 180.0, 1.0)
# Local seating of the sword in the hip holster (sheathed / wandering).
# Independent of the hand grip so each pose can be tuned without affecting the
# other. Defaults angle the blade down along the matador's side.
_reg_f("Sword", "sword_rest_pos_x", 0.0, -1.0, 1.0, 0.01)
_reg_f("Sword", "sword_rest_pos_y", 0.0, -1.0, 1.0, 0.01)
_reg_f("Sword", "sword_rest_pos_z", 0.0, -1.0, 1.0, 0.01)
_reg_f("Sword", "sword_rest_rot_x", -120.0, -180.0, 180.0, 1.0)
_reg_f("Sword", "sword_rest_rot_y", 0.0, -180.0, 180.0, 1.0)
_reg_f("Sword", "sword_rest_rot_z", 0.0, -180.0, 180.0, 1.0)
# ── Sword throw (matador ranged attack) ──────────────────────────────────
# Probability of committing to a throw each time the matador becomes eligible;
# kept low so they favour closing in for a melee Attack over throwing.
_reg_f("Sword", "mat_throw_chance", 0.15, 0.0, 1.0, 0.05)
# Delay before a fresh sword appears in the holster after one is thrown.
_reg_f("Sword", "mat_resword_delay", 2.0, 0.0, 10.0, 0.5)
_reg_f("Sword", "mat_throw_range", 18.0, 5.0, 40.0)
_reg_f("Sword", "mat_throw_min_dist", 5.0, 2.0, 15.0, 0.1)
_reg_f("Sword", "mat_throw_windup", 0.7, 0.2, 2.0, 0.05)
_reg_f("Sword", "mat_throw_release", 0.55, 0.1, 0.95, 0.01)
_reg_f("Sword", "mat_throw_speed", 18.0, 5.0, 60.0)
_reg_f("Sword", "mat_throw_spin", 14.0, 0.0, 40.0)
_reg_f("Sword", "mat_throw_arm_cock", 70.0,-180.0, 180.0, 1.0)
_reg_f("Sword", "mat_throw_arm_release", -90.0,-180.0, 180.0, 1.0)
_reg_f("Sword", "mat_throw_elbow", 80.0,-180.0, 180.0, 1.0)
# ── Abilities ─────────────────────────────────────────────────────────────
_reg_f("Abilities", "kick_cooldown", 1.5, 0.2, 10.0, 0.1)
_reg_f("Abilities", "kick_range", 3.5, 0.5, 8.0, 0.1)
_reg_f("Abilities", "kick_strength", 12.0, 1.0, 30.0)
_reg_f("Abilities", "slam_cooldown", 4.0, 0.5, 15.0, 0.1)
_reg_f("Abilities", "slam_jump_velocity", 7.0, 2.0, 20.0)
# Descent gravity multiplier — higher = faster crash, less airtime.
_reg_f("Abilities", "slam_fall_mult", 3.0, 1.0, 8.0, 0.5)
# Upward launch velocity (m/s) given to a slammed matador's ragdoll — pops them
# skyward. ~7 ≈ a 2.5 m hop; 0 disables the launch.
_reg_f("Abilities", "slam_launch_up", 7.0, 0.0, 15.0, 0.5)
_reg_f("Abilities", "slam_range", 4.0, 1.0, 10.0, 0.1)
_reg_f("Abilities", "slam_strength", 14.0, 1.0, 30.0)
_reg_f("Abilities", "dash_cooldown", 2.0, 0.5, 10.0, 0.1)
_reg_f("Abilities", "dash_speed", 66.0, 5.0, 200.0)
# ── Debug ─────────────────────────────────────────────────────────────────
_reg_b("Debug", "show_collisions", false)
func _reg_f(section: String, key: String, default: float,
min_val: float, max_val: float, step: float = 0.05) -> void:
_params[key] = {
"value": default,
"default": default,
"section": section,
"type": TYPE_FLOAT,
"min": min_val,
"max": max_val,
"step": step,
}
func _reg_b(section: String, key: String, default: bool) -> void:
_params[key] = {
"value": default,
"default": default,
"section": section,
"type": TYPE_BOOL,
}
## Read a float param. Panics on unknown key — intentional: typos should be loud.
func f(key: String) -> float:
return _params[key]["value"] as float
## Read a bool param.
func b(key: String) -> bool:
return _params[key]["value"] as bool
func set_value(key: String, value: Variant) -> void:
if not _params.has(key):
return
_params[key]["value"] = value
any_changed.emit(key, value)
## Returns the full metadata dict — used by DebugMenu to build UI.
func get_all() -> Dictionary:
return _params
func save() -> void:
var cfg := ConfigFile.new()
for key: String in _params:
var p: Dictionary = _params[key]
cfg.set_value(p["section"], key, p["value"])
cfg.save(SAVE_PATH)
func load_saved() -> void:
var cfg := ConfigFile.new()
if cfg.load(SAVE_PATH) != OK:
return
for section: String in cfg.get_sections():
for key: String in cfg.get_section_keys(section):
if not _params.has(key):
continue
var p: Dictionary = _params[key]
var val: Variant = cfg.get_value(section, key)
if p["type"] == TYPE_FLOAT:
val = clampf(val as float, p["min"] as float, p["max"] as float)
_params[key]["value"] = val
func reset_all() -> void:
for key: String in _params:
_params[key]["value"] = _params[key]["default"]
any_changed.emit("__all__", null)