• General Chat
  • Inconsistent collision with move_and_collide() between different computers (with the same project)

Hi! I made a Godot project where I use the move_and_collide() function to check if the player is colliding with platforms and ground. I have two computers that I use to work on my projects depending on the circumstances, and my problem is that my collision system works perfectly in one of the computer (basically the one I programmed the core of the game in), and does not on the other, with the exact same project (I use Google Drive so it's literally the same files).

I basically use the move_and_collide() function to later check if it returns collisions or not:

collision = move_and_collide(velocity * delta)

Then I check if collision is null or contains objects I collided with:

    func is_colliding():
    	if collision != null:
    		return true
    	else:
    		return false

Then I have a function to check if the player is on air or not (basically return the opposite of is_colliding):

func is_on_air():
	return !is_colliding() 

And I also have a function that make the player stick to a platform until he jumps:

if !is_on_air():
		velocity = Vector2.ZERO
		print("Not on air")
	else:
		print("On air")

Now, while that works perfectly on one of my computer, it does not on the other. The reason is clear when I try to print if the player is "on air" or not... See below:

You can see in the console that, on this computer, the player is never on air when it's on the ground (this version is working as intended)

But in this one, it's not the case:

EDIT: Ok when I look close enough I can see that, on the computer where the game that does not work properly, the character jiggle a bit. I have no idea why but this is definitely where the problem come from. Any idea on why?? Here is a GIF so you can see what I'm talking about:

I have a link to the project if some of you want to directly check the code: https://we.tl/t-seNvnM9Khp

So I have two questions: 1. Am I using the move_and_collide() function incorrectly, or doing something wrong or stupid ? I guess so, but I'm not sure because it's working perfectly on one of the computer. 2. Even though it's a stupid way to program a player that sticks on the platforms, and even though I'm definitely interested in a different and better/proper way to do it, I'm also VERY interested in understanding why the exact same project works perfectly on one of my computer and not on the other ??

I'm very new to Godot and this kind of engine in general (before I was working with Love2D engine to make games), but I want to understand this inconsistency, because that's very scary to think that such a simple project can works well on my computer but absolutely not on a player's computer... Like, it sincerely worry me...

Thanks for the help guys.

Are you using the _PhysicsProcess function?

Yes I'm using the function _physics_process()

I uploaded my project but since it can be a pain to actually download it and everything, here is my code for the player script (I'm sorry my commentaries are in French, but since my code is very simple I hope it does not matter):

extends KinematicBody2D

var spawn_position = Vector2(48, 671)
const GRAVITY = 900
var current_gravity = GRAVITY
var velocity = Vector2.ZERO
const JUMP_FORCE_X = 290*1.5
const JUMP_FORCE_Y = 600*1.5
const JUMP_MIN_Y = (JUMP_FORCE_Y/8)
const JUMP_MIN_X = (JUMP_FORCE_X/4)
var collision = null
var jump_angle = 0

onready var sprite = $Sprite
onready var aim = $Aim

func _ready():
#	global_position = spawn_position
	pass

# Update physic du joueur
func _physics_process(delta):
	
	# Calcule la gravité
	if is_on_air():
		current_gravity = GRAVITY
	else:
		current_gravity = 0
	# Applique la gravité
	velocity.y += (current_gravity * delta)
	
	# Aim
	aim_to_mouse()
	
	# Le joueur colle aux plateformes (et l'empêche de slide trop)
	if !is_on_air():
		velocity = Vector2.ZERO
#		print("Not on air")
#	else:
#		print("On air")
	
	# Jump
	if !is_on_air():
		if Input.is_action_just_pressed("jump"):
#			process_jump()
			process_jump2()
	else:
		# Animation jump
#		animation_player.play("Jump")
		if Input.is_action_just_released("jump"): 
			if velocity.y < -JUMP_MIN_Y:
				velocity.y = -JUMP_MIN_Y
#			if velocity.x < -JUMP_MIN_X:
#				velocity.x = -JUMP_MIN_X

	collision = move_and_collide(velocity * delta)
print(collision)
	
	# test
	if velocity.y > 0:
		self.modulate = Color(1, 0, 0)
	else:
		self.modulate = Color(0, 0, 1)
	
	# Vérifie les collisions mortelles
	if is_colliding_with_killer():
		kill_player()
	
# Vérifie si le joueur est en train de collisionner
func is_colliding():
	if collision != null:
		return true
	else:
		return false
	
# Vérifie si le joueur collisionne avec un objet en particulier
func is_colliding_with(pObject):
	if pObject and collision:
		return collision.collider == pObject
	return false
	
# Vérifie si le joueur collisionne avec un objet mortel
func is_colliding_with_killer():
	if collision != null:
		if collision.collider.is_killer :
			return true
	return false
	
# Vérifie si le joueur est dans les airs
func is_on_air():
	return !is_colliding()
	
# Permet de viser dans une direction avec la souris
func aim_to_mouse():
	var mouse_vector = get_global_mouse_position() - aim.global_position
	aim.global_rotation = atan2(mouse_vector.y, mouse_vector.x)
	
# Calcule la vélocité du saut
func process_jump():
	var mouse_vector = get_global_mouse_position() - global_position
	mouse_vector = mouse_vector.normalized()
	velocity.x = mouse_vector.x * JUMP_FORCE_X
	velocity.y = mouse_vector.y * JUMP_FORCE_Y
	
# Calcule la vélocité du saut (V2)
func process_jump2():
	var jump_vector = get_global_mouse_position() - global_position
	jump_vector = jump_vector.normalized()
	velocity.x = jump_vector.x * JUMP_FORCE_X
	velocity.y = jump_vector.y * JUMP_FORCE_Y
	
# Tue le joueur
func kill_player():
	print("You are dead!!")
	global_position = spawn_position

EDIT :yeah that definitely comes from my move_and_collide() function as we can clearly see that collision is equal to null sometimes... I used the line print(collision) just after the line collision = move_and_collide(velocity * delta) and you can see sometimes it's equal to an object and sometimes to null (even though I just stand on the ground and do nothing) look:

Maybe it's frame rate related. Is the computer it doesn't work on any slower?

Honestly I don’t think so. They’re both pretty recent computers, I guess the game run 60 FPS on both (I’ll double check that to be sure though).

I will try to change the move_and_collide() func by the move_and_slide() one just to see what it does…

For those who are used to Godot Engine: is my way to check collisions weird or dumb or is it ok?

Maybe I’m doing it the wrong way? I have to say I like to learn an engine by myself with documentation rather than by watching lots of tutorials, so I may do stuff the wrong way.

Ok an update to say that I changed my system and went with the move_and_slide() function instead of the move_and_collide() one and everything seems to work properly on my two computers. Still not sure why it was not working before, so if anybody has an idea on why I’m very interested! It’s always good to understand why things don’t work properly, and I’m eager to learn more about Godot engine as a beginner.

But I consider the problem solved anyway.

@MonsieurBouboule said: Ok an update to say that I changed my system and went with the move_and_slide() function instead of the move_and_collide() one and everything seems to work properly on my two computers. Still not sure why it was not working before, so if anybody has an idea on why I’m very interested! It’s always good to understand why things don’t work properly, and I’m eager to learn more about Godot engine as a beginner.

But I consider the problem solved anyway.

Strange that using move_and_slide fixed it, but I'm glad the problem is solved! I don't know why right off though move_and_collide would function differently. Without investigating, I want to say this sounds like a bug in the move_and_collide function but I'm not experienced enough in the physics code in Godot to say with any certainty.

You should not use delta inside move_and_slide or move_and_collide (as delta is already calculated internally). So probably what is happening is that delta is being applied twice (once internally and once by you) meaning that any performance differences between the computers is being amplified. Same reason some modern games have physics glitches if you try to set to refresh rate above 60Hz (when 60Hz was hard-coded into the physics).