Bixilon/Minosoft

explanation of physics

JanCantCode opened this issue · 13 comments

i am very much unsure wheter this is actually the right place to ask this, but can you give me a very brief explanation of how the physics in minosoft/minecraft work? i dont need exact values, just a general overview. for example what ive seen in other games with gravity is that you have a certain y motion, which every tick some value is added to, and the result is then multiplied by something like 0.99 and set to 0 if the player is on ground. same with movement in directions etc. can you help me there? (i want to have a very, very simple reimplementation of physics when falling, walking, jumping or being hit in a scenario where there are no blocks to collide with except an entirely flat floor

So, physics are quite complex in minecraft, there are a lot of things to consider here. I remember rewriting it, it took me months to complete and I added roughly 26k lines (including all tests and refactor).

So it works pretty much straight forward (in ticks):

var position = Vec3d.EMPTY
var velocity = Vec3d.EMPTY

fun tick() {
  if (goForward) {
    velocity += front * speed  // front is a Vec3, rotated by yaw
  }
  if (jumping && onGround) {
    velocity.y += 1.0f
  }

  velocity.y -= gravity
  
  velocity *= 0.98 // friction
 
  move(velocity)
}



fun move(velocity:Vec3d) {
  var movement = adjustForCollisions(velocity);
  // lot more

  if (velocity.y > movement.y) {
     onGround = true
     velocity.y = 0.0
  }

  position += movement
}

It is broke down and simplified a lot, but that is the concept.

woah thanks very much! what is the front vector before its rotated by yaw, tho?

also you rotate a vector by applying a rotation matrix if i remember correctly, is that right?

very much thanks for sharing that with me! just a few more questions:

1.) in the example code you provided way further above, are the values that are used there actually correct? e.G. 0.98 for friction and a velocity of +1.0 for jumping

2.) when pressing W adds a vector of yaw to the velocity vector, does pressing, for example S add a vector that is rotated by (yaw +180), pressing d (yaw + 90)?

also lets assume i have a flat ground and no walls or similar and i fall down, and want to reimplement the adjustForCollisions method in this context, i would just check if the player position is equal or smaller then the height of the floor (idk if i would use the actual position or the position + the movement velocity that was generated?) and if yes, return some vektor that pushes the player up so it is on top of the floor again, so probaply how much the player is below the floor

1.) in the example code you provided way further above, are the values that are used there actually correct? e.G. 0.98 for friction and a velocity of +1.0 for jumping

No, not at all. Feel free to look in the physics package and get all values that you need

2.) when pressing W adds a vector of yaw to the velocity vector, does pressing, for example S add a vector that is rotated by (yaw +180), pressing d (yaw + 90)?

Ehm, kinda: https://gitlab.bixilon.de/bixilon/minosoft/-/blob/master/src/main/java/de/bixilon/minosoft/physics/input/MovementInput.kt

adjustForCollisions

fun adjustForCollisions(movement:Vec3d) :Vec3d {
  if (position.y - movement.y > 123.0) return movement

  movement.y = position.y - 123.0

 return movement  
}

(where 123 is the height of your platform)

pushes the player

There is not pushing, just check every tick if the position is below 123 and if so, set it up

tysm for explaing :D

also might i ask why the velocity vector is being normalized here? https://gitlab.bixilon.de/bixilon/minosoft/-/blob/master/src/main/java/de/bixilon/minosoft/physics/input/MovementInput.kt#L49 (sorry if thats something really obvious, im not that good with maths xD)

oh ich merke grade du bist ja deutsch xD

also is the AIR RESISTANCE from physics/PhysicsConstants.kt the equivalent to ground friction in your pseudo code above?

actually not, just look into InputPhysics.kt