How do i use move_and_slide() on a different variable than the default characterbody velocity and positions

Godot Version

Godot v.4.7.1

Question

how do i call the function move_and_slide(), however it outputs the position to my own variable, and i input my own velocity into it. i basically am making a server authoritiative multiplayer game and for the server’s code I need to make it so that it acts basically the same as the clients’ prediction.


	player_input.delta = delta
	player_input.direction = direction
	player_input.timestamp = time
	if player_input is PlayerInput:
		#process_input(player_input, server_velocity)
		server_calculate_input(delta, player_input, server_velocity)
		server_velocity = PlayerGhost.velocity
	
	if !multiplayer.is_server() && !is_multiplayer_authority():
		position = server_position
	
	print_debug("Server Position : " + str(server_position))
	print_debug("Server Velocity : " + str(server_velocity))

# ^^^ above is in physics process function

func server_calculate_input(delta, input : PlayerInput, velocity_old : Vector3):
	if !multiplayer.is_server():
		return
	
	PlayerGhost.velocity = calc_player_movement(input, velocity_old)
	PlayerGhost.move_and_slide()

func calc_player_movement(input : PlayerInput, velocity_old : Vector3):
	if !check_input_valid(input):
		return
	
	# Currently, the vector's length is greater than 1 while trying to move diagonally
	# This means the player moves faster in diagonals than when going in cardinal directions
	# (which is not very good)
	# Normalizing the vector ensures the length will always be 1, and the movement speed
	# will be the same regardless of if the player is moving diagonally or

	# Because we aren't using the transforms for the direction anymore, we need to rotate
	# the vector using our yaw so movement is aligned with it
	
	print(movement_speed)
	var vel : Vector3 = velocity_old
	
	input.direction = input.direction.rotated(Vector3(0, 1, 0), rotation.y)
	
	vel.x = input.direction.x * movement_speed 
	vel.z = input.direction.z * movement_speed
	
	if not is_on_floor():
		vel.y -= 16.34 * input.delta
	

	if is_on_floor():
		if input.jump:
			vel.y = 2.
		if vel.is_zero_approx():
			vel.move_toward(Vector3(input.direction.x, vel.y, input.direction.z), 5 * input.delta)
	
	return vel


# player_input.gd
extends Object
class_name PlayerInput

var input_buffer : Array
var timestamp : float
var direction : Vector3
var jump : bool
var delta : float

currently my solution is to use a duplicate characterbody

however this is plain not working idk why

What if you tried extending the script with a character body . that way you might not need a node

the script is extended with a characterbody its just that i need to simulate another characterbody as well

basically i just need to have 2 velocities and 2 positions ,one syncrhonised for the server and one for the client

You can switch out the velocity and position:

velocity = velocity1
position = position1
move_and_slide()
position1 = position

velocity = velocity2
position = position2
move_and_slide()
position2 = position

Yeah, it’s ugly and stupid and not a good solution at all, but it should work. Which is always better than not working.