Advice on a unqiue problem regarding falling platforms

So I have an infinitely scrolling level that that uses a tilemap to designs levels that loop on themselves. I also have a falling platform that returns to its initial position after it leaves the screen. The problem lies when the tilemap shifts position to allow for seamless level looping and the falling platforms dont respawn at their initial position relative to the tilemap but instead wherever they were first placed. Simply changing it from global_position to position doesnt seem to work either. I’d really appreciate some insight as to how I could either better implement this or remedy this problem. Thanks.

falling platform code

extends AnimatableBody2D

var respawn_pos 
var falling = false

func _ready():
	await get_tree().create_timer(0.5).timeout
	update_pos()
	update_colors()

func _physics_process(delta):
	if falling:
		global_position.y += 50 * delta

func update_pos():
	respawn_pos = position + Vector2(576, 0)
	print(respawn_pos)

func update_colors():
	$Sprite2D.get_material().set_shader_parameter("replace_0", current_global.set_fg_color)
	$Sprite2D.get_material().set_shader_parameter("replace_1", current_global.set_bg_color)

func _on_area_2d_body_entered(body):
	if body.is_in_group("player") and body.is_on_floor():
		$Timer.start()

func _on_timer_timeout():
	falling = true

func _on_visible_on_screen_notifier_2d_screen_exited():
	await get_tree().create_timer(1.5).timeout
	global_position = respawn_pos
	if falling:
		$AnimationPlayer.play("blink")
		falling = false

In the node tree are the falling platforms childs of the tilemap?

technically? I dont know where exactly on the node tree they’d be if I use a tilemap to place them using with scene tilesets

Can you check their position while the game is running by using the “remote” tab?

Yeah, the falling platforms x position shifts from 3216 to -4208 when the level loops its position. The respawn_pos, which is its global x position is 3792. I don’t understand why or how its doing this. The stage looper can seamlessly loop fowards as well as backwards but I dont think this should affect it.

Stage Looper code

extends Node2D

var starting_gate = false
var check_point = false

func ratchet_check_point():
	$stage/check_point.ratchet_to_pos()

func destroy_starting_gate():
	starting_gate = true
	$stage/starting_gate.queue_free()

func _on_chunk_ahead_body_entered(body):
	if body.is_in_group("player"):
		ratchet_check_point()
		$stage/chunk_2.global_position = $stage/chunk_1/front.global_position
func _on_chunk_behind_body_entered(body):
	if body.is_in_group("player"):
		if !starting_gate:
			destroy_starting_gate()
		$stage/chunk_2.global_position = $stage/chunk_1/back.global_position

func _on_chunk_ahead_2_body_entered(body):
	if body.is_in_group("player"):
		ratchet_check_point()
		$stage/chunk_1.global_position = $stage/chunk_2/front.global_position
func _on_chunk_behind_2_body_entered(body):
	if body.is_in_group("player"):
		$stage/chunk_1.global_position = $stage/chunk_2/back.global_position

hmm, this is an odd one.

Have you tried switching this code to use global_position?

func update_pos():
	respawn_pos = position + Vector2(576, 0)
	print(respawn_pos)

You said in your reply that “repsawn_pos is its global “x” position”, but your code says it’s the platform’s local “x” position plus a vector.

Apologies I had accidentally uploaded an earlier version of this script. The current implementation does use global_position still to no avail

Awaits are bug magnets. Re-implement without using them.

I just did and this had no effect

It still made your code less bug prone.

Lets see the current state of the code.

The awaits have no major mechanical impact on how the platforms function and only controlled cosmetic elements

var falling = false
var respawn_pos

func _ready():
	update_pos()
	update_colors()

func _physics_process(delta):
	if falling:
		global_position.y += 65 * delta

func update_pos():
	respawn_pos = global_position

func update_colors():
	$Sprite2D.get_material().set_shader_parameter("replace_0", current_global.set_fg_color)
	$Sprite2D.get_material().set_shader_parameter("replace_1", current_global.set_bg_color)

func _on_area_2d_body_entered(body):
	if body.is_in_group("player") and body.is_on_floor():
		$Timer.start()

func _on_timer_timeout():
	falling = true

func _on_visible_on_screen_notifier_2d_screen_exited():
	global_position = respawn_pos
	if falling:
		$AnimationPlayer.play("blink")
		falling = false

Why just not parent platforms to the tilemap and shift the position of the whole thing.

I ran a test where i added it as a parent to the tilemap and this had no effect either. The tilemap also naturally shifts as well as part of the stage looper shown above. I think I just need to implement this but Im unsure as to how atm

Add what as a parent to the tilemap?

The idea is to have everything under one parent node, so when that node is moved - everything moves with it.

ohhh. It already does this actually. The looper shifts what I call chunks, and in those chunks are the tilemap, obstacles i that did not make sense to place with the tilemap, and finally a pair of area2Ds that detect when to shift the next chunk forward or behind the current chunk. The falling platform does not shift with the chunk whether its placed with a tilemap or with my obstacles

Is that the intent or the problem?

Thats the problem

So the platforms are children of the chunk’s top node but they don’t move with it?

yes and it doesnt shift with the chunk

Parent them to the chunk but never touch their global_position, only animate/reset position so they always inherit chunk’s position offset.