beyond-all-reason / spring

A powerful free cross-platform RTS game engine
https://beyond-all-reason.github.io/spring/
Other
178 stars 95 forks source link

Feature: Expose some common sense movement state data to lua #1520

Open GoogleFrog opened 1 month ago

GoogleFrog commented 1 month ago

Game mechanics involving unit movement usually have common sense formulations such as "when the unit is standing still, it hunkers down for extra armour". Turning game design into code involves checks for things like how fast the unit is moving, and where it is in relation to the ground.

This ticket is motivated by lua being in a much poorer position to do these checks than the engine. I have implemented a bunch of these, and it involves periodic speed checks against some threshold that doesn't result in too many edge cases, and checking whether the base position of the unit is exactly the same height as the ground. Units that are "standing still" can gain momentary velocity by being bumped by a unit, or hit by a weapon with impulse.

I think it would be useful to add Spring.GetUnitIsWalking that essentially returns whether script.StartMoving or script.StopMoving was called more recently, if the unit is in the "on the ground" state, and false otherwise. This will only be useful after StartMoving is fixed though, see https://github.com/beyond-all-reason/spring/issues/1519.

Some sort of Spring.GetUnitIsOnTheGround (good name pending) could also be useful, because while baseHeight == groundHeight seems to be reliable, it doesn't work for ships and hovercraft, takes two callouts to execute, and the check itself is obscure knowledge. By "on the ground" I mean able to move around and use pathfinding, as opposed to the "flying through the air" state that units enter when they are thrown somewhere. I've observed these states to have quite distinct behaviour, so exposing when a unit is in one or the other seems good.

These callouts wouldn't make sense for units in MoveCtrl, but that is fine, lua should know what it is doing with MoveCtrl anyway.

WatchTheFort commented 1 month ago

This sounds like it ties in to https://github.com/beyond-all-reason/spring/issues/657, in that games are interested in the current state of the unit?

GoogleFrog commented 1 month ago

Sure. Include landing, flying, taking off etc... Perhaps there could be a single callout that returns an enum describing the state the engine thinks the unit is in.

sprunk commented 1 month ago

There's Spring.SetUnitPhysicalStateBit which lets you set bits like "in air", "underwater", "skidding" etc but there is no corresponding getter. The interface is terrible though (bitmask).