fix(leaks): what play allocated every frame and never freed - a shadow uniform's name, the Tick, a ridden vehicle's moves
Found with malloc_history over 1200 frames of play without the interface (the first Ludic function on each allocating stack, live bytes at two marks): sh_loc built `name + "[0]"` per program per pass per frame - 24.6 MB of 33 in the window; its callers pass both names as literals now. tick_set fills the frame loop's one Tick instead of tick_new making one a frame. A ridden boat or horse said VEHICLE_MOVED as a new fact every frame; the metres are added up in VehiclesState and taken once (vehicle_moved_take / _kind / _x / _z). Play's growth without the interface: 92 -> 14.7 MB a minute (maroon-lake tests/leakcheck.sh); what is left is phys_push (Physics' fix on lang/nav) and the HUD's strings. Packages 407, ludic-dev test 305 pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8fbb1f7d03
commit
231715bf98
9 changed files with 47 additions and 10 deletions
|
|
@ -5,7 +5,7 @@ const VE_HORSE_GALLOP: float = 11.0
|
|||
const VE_HORSE_ACC: float = 4.0
|
||||
const VE_HORSE_TURN: float = 1.6
|
||||
|
||||
function ve_ride_horse(vehicles_st: VehiclesState, v: Vehicle, ix: float, iz: float, run: bool, dt: float) -> void {
|
||||
function ve_ride_horse(vehicles_st: mut VehiclesState, v: Vehicle, ix: float, iz: float, run: bool, dt: float) -> void {
|
||||
var top = VE_HORSE_WALK
|
||||
if run and v.fuel > 5.0 { top = VE_HORSE_GALLOP }
|
||||
v.speed = v.speed + Math.clamp(iz * top - v.speed, -VE_HORSE_ACC * dt, VE_HORSE_ACC * dt)
|
||||
|
|
@ -29,7 +29,7 @@ function ve_ride_horse(vehicles_st: VehiclesState, v: Vehicle, ix: float, iz: fl
|
|||
|
||||
# the legs carry it from where it is; what they covered along its heading is its speed now, never
|
||||
# more than was asked, so a trunk or a rise it cannot take brings it to a stand
|
||||
function ve_legs_walk(vehicles_st: VehiclesState, v: Vehicle, vx: float, vz: float, dt: float) -> void {
|
||||
function ve_legs_walk(vehicles_st: mut VehiclesState, v: Vehicle, vx: float, vz: float, dt: float) -> void {
|
||||
if not VehicleLegs.walk(v.nid, v.x, v.y, v.z, vx, vz, dt) { return }
|
||||
let dx = VehicleLegs.x() - v.x
|
||||
let dz = VehicleLegs.z() - v.z
|
||||
|
|
@ -39,7 +39,7 @@ function ve_legs_walk(vehicles_st: VehiclesState, v: Vehicle, vx: float, vz: flo
|
|||
let got = (dx * -Math.sin(v.yaw) + dz * -Math.cos(v.yaw)) / dt
|
||||
if v.speed > 0.0 { v.speed = Math.clamp(got, 0.0, v.speed) } else { v.speed = Math.clamp(got, v.speed, 0.0) }
|
||||
let moved = Math.sqrt(dx * dx + dz * dz)
|
||||
if moved > 0.0 { ve_say(vehicles_st, VEHICLE_MOVED, v, moved) }
|
||||
if moved > 0.0 { ve_moved_add(vehicles_st, v, moved) }
|
||||
}
|
||||
|
||||
# a gallop spends stamina and a walk gives it back; every metre costs hay
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import "call.ludic"
|
|||
import "keep.ludic"
|
||||
import "mount.ludic"
|
||||
import "ride.ludic"
|
||||
import "moved.ludic"
|
||||
import "horse.ludic"
|
||||
import "legs.ludic"
|
||||
import "system.ludic"
|
||||
|
|
|
|||
19
packages/ludic.vehicles/moved.ludic
Normal file
19
packages/ludic.vehicles/moved.ludic
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# moved.ludic - the ground the ridden vehicle covers, added up rather than said a frame at a time: a
|
||||
# fact a frame was a new record a frame, and Ludic frees nothing. The game takes the sum when it asks.
|
||||
function ve_moved_add(vehicles_st: mut VehiclesState, v: Vehicle, d: float) -> void {
|
||||
vehicles_st.ve_moved += d
|
||||
vehicles_st.ve_moved_kind = v.kind
|
||||
vehicles_st.ve_moved_x = v.x
|
||||
vehicles_st.ve_moved_z = v.z
|
||||
}
|
||||
|
||||
# the metres covered since the last take (0 when nothing moved), and the sum starts again
|
||||
export function vehicle_moved_take(vehicles_st: mut VehiclesState) -> float {
|
||||
let d = vehicles_st.ve_moved
|
||||
vehicles_st.ve_moved = 0.0
|
||||
return d
|
||||
}
|
||||
# what covered them, and where it was when it last moved
|
||||
export function vehicle_moved_kind(vehicles_st: VehiclesState) -> int { return vehicles_st.ve_moved_kind }
|
||||
export function vehicle_moved_x(vehicles_st: VehiclesState) -> float { return vehicles_st.ve_moved_x }
|
||||
export function vehicle_moved_z(vehicles_st: VehiclesState) -> float { return vehicles_st.ve_moved_z }
|
||||
|
|
@ -43,6 +43,10 @@ export state VehiclesState {
|
|||
ve_kept_boat: bool = false
|
||||
ve_kept_food: float = 40.0
|
||||
ve_ids: int = 0
|
||||
ve_moved: float = 0.0 # metres the ridden vehicle covered since the game last took them
|
||||
ve_moved_kind: int = 0
|
||||
ve_moved_x: float = 0.0
|
||||
ve_moved_z: float = 0.0
|
||||
ve_sx: float = 0.0
|
||||
ve_sz: float = 0.0
|
||||
ve: VehicleTable = ve__new()
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ function ve_row(vehicles_st: mut VehiclesState, v: Vehicle, ix: float, iz: float
|
|||
let take = ve_swell(vehicles_st, v, iz, dt)
|
||||
VehicleHull.row(v.nid, iz * VE_ROW * (1.0 - take), -ix * VE_ROW_TURN)
|
||||
let d = Math.abs(v.speed) * dt
|
||||
if d > 0.0 { ve_say(vehicles_st, VEHICLE_MOVED, v, d) }
|
||||
if d > 0.0 { ve_moved_add(vehicles_st, v, d) }
|
||||
}
|
||||
|
||||
# where the hull is now, and how fast it goes along its bow
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export function vehicles_reset(vehicles_st: mut VehiclesState) -> void {
|
|||
tb_clear(vehicles_st.ve.tab)
|
||||
imap_clear(vehicles_st.ve.nids)
|
||||
vehicles_st.ve_cur = null
|
||||
vehicles_st.ve_moved = 0.0
|
||||
vehicles_st.ve_have_dock = false
|
||||
vehicles_st.ve_swell_said = 0.0
|
||||
vehicles_st.ve_kept_horse = false
|
||||
|
|
|
|||
|
|
@ -236,7 +236,9 @@ program VehiclesTest {
|
|||
vehicle_mount(vehicles_st, h)
|
||||
ride(physics_st, vehicles_st, 0.0, 1.0, false, 3.0)
|
||||
expect_near(h.speed, 4.5, 0.05)
|
||||
expect(count(facts(vehicles_st), VEHICLE_MOVED) > 100)
|
||||
expect(vehicle_moved_take(vehicles_st) > 10.0) # 3 s at 4.5 m/s, added up
|
||||
expect_eq(vehicle_moved_kind(vehicles_st), VEHICLE_HORSE)
|
||||
expect_near(vehicle_moved_take(vehicles_st), 0.0, 0.0001)
|
||||
ride(physics_st, vehicles_st, 0.0, 1.0, true, 3.0)
|
||||
expect_near(h.speed, 11.0, 0.1)
|
||||
expect(h.fuel < 100.0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue