#Bro what I tried so hard to get smooth movement how’d you do it

1 messages · Page 1 of 1 (latest)

outer dawn
#

Bro what I tried so hard to get smooth movement how’d you do it

latent shaleBOT
#

Burner inserters have taken a restraining order against you, and will now run away if you get too close.

Author

SerotoninTheft

Downloads

0

outer dawn
#

For this

dry carbon
#

well for one it looks like they're using the gridless entity flag, which would be problematic when placing them by hand

open frigate
#
  • No gridless flag. In fact, there are no changes to existing prototypes at all.
  • The movement for grid-based entities isn't actually smooth. It only looks that way because the velocity is very high.
  • It is very performance heavy though. Especially for entities without unit_number (so e.g. trees/rocks)
open frigate
#

Source code for reference: https://github.com/k2aj/fq-core/blob/master/fq-core/runtime/motion.lua

How the motion works (simplified version):

  • Any entity can have a MotionComponent attached to it.
  • MotionComponent is basically a table which stores a velocity vector (vx, vy)
  • Whenever the mod applies knockback to an entity, it looks up the MotionComponent attached to that entity and adds the knockback vector to the velocity vector in that MotionComponent.
  • Every tick I loop through all the MotionComponents and their associated entities:
    • I simulate motion by teleporting the entity to {x=x+vx, y=y+vy} where x,y is the position of the entity and vx,vy is the velocity vector from the attached MotionComponent
    • Then I simulate drag by multiplying vx,vy by 0.9 (this is why moving entities stop smoothly)
GitHub

Contribute to k2aj/fq-core development by creating an account on GitHub.

#

The actual, ugly version:

The above simplified version causes entities to phase through walls because LuaEntity.teleport() doesn't care where you teleport something.

  • To avoid that I use LuaSurface.find_non_colliding_position() to check if the location where I teleport the entity is already occupied by something.
    • If the teleport location is occupied, I remove the MotionComponent from the entity (which stops the movement).
    • Except that doesn't actually work correctly, because for small velocities find_non_colliding_position() always fails, because it thinks the entity would collide with itself.
    • To avoid that I teleport the entity 100 tiles away before calling find_non_colliding_position(), then teleport it back.
  • Except at high velocities that doesn't help either, because the entity could e.g. end up on one side of a wall at tick N, then on another side of the same wall at tick N+1. So wall phasing would still happen.
    • To avoid that I don't apply the relative teleportation by {+vx, +vy} all at once, but do it in multiple small steps instead.

Also a bunch of optimisations:

  • Entities never have more than one motion component (to reduce lag). Any additional knockback/recoil just increases the velocity vector on the existing motion component.
  • I remove the MotionComponent from an entity if the velocity vector gets too low due to drag. (otherwise they would accumulate until you get lagged to death).