Tune func_bob curve/timing, add trigger_push start_off/toggle - #938
Conversation
func_bob: - Scale the arrival-snap threshold to the leg's own distance (1% of travel, floored at .01 and capped at the old flat .25) instead of a fixed .25 units, which was a visible pop on short legs (e.g. ~3% of an 8-unit travel). - Auto-derive "compression" from the leg's duration when unset, via a continuous falloff in log(leg_time) peaking at 1.0 around a ~1s leg and tapering toward a .35 floor for legs much shorter (stutters) or much longer (slow crawl before the entity gets moving) than that. Explicit "compression" keys still override. - "drift" now defaults to 0 (no startup delay) instead of silently defaulting to a full-cycle random delay when unset, which was causing multi-second startup delays on entities that were never meant to be desynced. Negative values are clamped to 0 rather than risking UB in the float-to-uint32 cast. trigger_push: - Add start_off and toggle spawnflags so trigger_push can be spawned inactive and toggled on/off via Use, matching the pattern already used elsewhere (e.g. func_bob).
| // is from that ~1s sweet spot in either direction. Calibrated against two tested legs: ~1s | ||
| // (wants ~1.0) and ~7s (wants ~0.5) - solving for the width that fits both against a 0.35 floor. | ||
| // log(0) degrades gracefully to the floor for a zero-velocity leg, no special case needed. | ||
| const float compression = gi.EntityValue(ent->def, "compression")->value; |
There was a problem hiding this comment.
Heh, okay. These kinds of optimizations are pretty pointless. This will never show up on a profiler, I guarantee it. But it's fine if Claude thought it was being clever here.
There was a problem hiding this comment.
well, the problem that I found was that when using very small distances like 16u (was exp with bobbing lights)the movement stutters before resting and using compression to fix isn't accurate. Slow speeds like <15 are also affected. This fixes it so the movement is alot smoother.
There was a problem hiding this comment.
Oh, not the calculation. The storing of it on ent->random so that it's "not calculated every tick" was the silly bit 👍 It's a cheap calculation.
jdolan
left a comment
There was a problem hiding this comment.
Word. Don't forget the TrenchBroom / Radiant configs for the new / modified entity fields :)
Summary
func_bob (follow-up tuning after #911):
.01, capped at the old flat.25) instead of a fixed.25units.G_MoveInfo_Linear_Donesnaps position exactly to the destination once within this threshold, and a flat.25was a visible pop on short legs (e.g. ~3% of an 8-unit travel used for a shadow-sync bob).compressionfrom the leg's duration when the key is unset, instead of always defaulting to a flat1.0(pure sine). Uses a continuous falloff inlog(leg_time)that peaks at1.0for a leg around 1 second and tapers toward a.35floor for legs much shorter (too few ticks, stutters) or much longer (the sine's slow "wings" become a multi-second crawl before the entity visibly starts moving) than that. Calibrated against two tested legs (~1s and ~7s). Explicitcompressionkeys still override.driftnow defaults to0(no startup delay) instead of silently defaulting to a full-cycle random delay whenever unset - the old default caused multi-second startup delays on anyfunc_bobthat wasn't actually part of a desynced array. Negative values are clamped to0rather than risking undefined behavior in the float-to-uint32_tcast.trigger_push:
start_offandtogglespawnflags sotrigger_pushcan spawn inactive and be toggled on/off viaUse, matching the pattern already used elsewhere (e.g.func_bob).Test plan
game.vcxproj)trigger_pushstart_off/toggle behavior