Glad to hear you solved it

Here is a modified version of your code that I think works as desired (as well as proper indentation

)
sync on
sync rate 60
k_f=17
k_b=31
k_l=30
k_r=32
make object box 1, 1.5, 1.0, 1.5
set object diffuse 1, rgb(255, 0, 0)
position camera 0, 7.5, 15.0, 7.5
point camera 0, 7.5, 0.0, 7.5
ang as float
do
if keystate(k_f) || keystate(k_b) || keystate(k_l) || keystate(k_r)
rem Determine target angle
targetAngle# = atanfull(keystate(k_r) - keystate(k_l), keystate(k_f) - keystate(k_b))
if targetAngle# < 0.0 then targetAngle# = wrapvalue(targetAngle#) ` Ensure we wrap negative angles to the corresponding positive angle
rem Approach the target angle from the current object angle
ang = curveangle(targetAngle#, object angle y(1), 10.0)
rem The above will never actually reach the target angle, so set it to that if it is "close enough".
rem We need to take care because 0° <==> 360°, thus we clamp the value if the difference is less than some theta value OR greater than 360.0 - theta#
theta# = 0.5
dif# = abs(ang - targetAngle#)
if dif# < theta# or dif# > 360.0 - theta# then ang = targetAngle#
if ang = object angle y(1)
if keystate(k_f)
p_z# = p_z# + 0.1
endif
if keystate(k_b)
p_z# = p_z# - 0.1
endif
if keystate(k_l)
p_x# = p_x# - 0.1
endif
if keystate(k_r)
p_x# = p_x# + 0.1
endif
endif
yrotate object 1, ang
position object 1, curvevalue(p_x#, object position x(1), 2), 0, curvevalue(p_z#, object position z(1), 2)
endif
text 0, 0, str$(object angle y(1))
text 0, 10, str$(ang)
sync
loop
