godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.56k stars 20.58k forks source link

Lag Spikes when moving CharacterBody2D through large TileMap2D with collision #83835

Open sZellwegerGit opened 11 months ago

sZellwegerGit commented 11 months ago

Godot version

v4.1.stable.official [970459615]

System information

Godot v4.1.stable - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1080 (NVIDIA; 31.0.15.3699) - Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz (8 Threads)

Issue description

After some testing, I found that if you change the global_position of a CharacterBody2D object, it will cause quite a lag spike if there is a TileMap2D with lots of tiles between its original position and the target position.

Steps to reproduce

Move a CharacterBody2D object with the global_position attribute between two positions with a TileMap between them.

Minimal reproduction project

CharacterBody2D Bug.zip

In this project the CharacterBody2D moves from 0, 0 to 2000, 2000. In between is a TileMap and some simple collisions. The lag spikes are clearly visible in the debugger

AThousandShips commented 11 months ago

Can you please try this with a supported version, like 4.1.2 (only the latest patch version is supported, and it might already be fixed)

sZellwegerGit commented 11 months ago

Can you please try this with a supported version, like 4.1.2 (only the latest patch version is supported, and it might already be fixed)

This problem still occurs in the latest version (4.1.2).

rpgshooter commented 11 months ago

Did some testing, the jump incurs a sudden physics check and is not specific to the 2k, 2k position. Changed the value from 2k, 2k to 1500, 1500, 1k, 1k, incurring the same spike in the physics check heres a 1800, 1800 with the same physics spike Screenshot 2023-10-25 195415 Done on an i7, and an rtx 2060

rpgshooter commented 11 months ago

As an addendum, the milliseconds are constant with 16ms, and the spikes are in frequent with anything lower than 1500, 1500 anything higher than 1500 - 2k are more frequent with the spikes in performance, and it seems to be incremental with higher values: here's 3k, 3k Screenshot 2023-10-25 203320 and 5k, 5k Screenshot 2023-10-25 203509 Valid as of 4.2-master or 4.2-beta 10, 25, 2023

gabpa-gaming commented 8 months ago

I stumbled upon this in my project in C# with a simillar setup. It seems to spike harder with a larger distance and larger amount of tiles in between. Godot v4.2.stable.mono - Windows 10.0.22621 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1660 Ti (NVIDIA; 30.0.14.9649) - AMD Ryzen 5 3600 6-Core Processor (12 Threads).

SpaceyStrife commented 7 months ago

This is happening in our project as well in 4.2.1.stable.official, NVIDIA GeForce RTX 3050, 11th Gen Intel(R) Core(TM) i5-11600K @ 3.90GHz 3.91 GHz. The spike occurs on larger tilemaps when we instantiate CharacterBody2D PackedScenes and set their global position to objects farther away from the top left corner of the tilemap.

Notably, setting the collision shape's "Disabled" property to true prevents lag spikes from occurring when repositioning the CharacterBody2D, and if some time is allowed to pass before setting Disabled to false, the lag spike is avoided. Although less than ideal, this could be a temporarily solution for those who are experiencing this issue.

d20volary commented 5 months ago

Try turning off v-sync, it solved my lag spikes. :)

inkusgames commented 3 months ago

Can confirm this is still a problem in the 4.2.2.stable.official.

inkusgames commented 3 months ago

Try turning off v-sync, it solved my lag spikes. :)

This didn't improve the lag spikes for me when trying to set the position within a TileMap.

MyrTheMoth commented 3 months ago

This is happening in my project as well

Godot Engine v4.2.2.stable.official.15073afe3 - https://godotengine.org Vulkan API 1.3.278 - Forward+ - Using Vulkan Device #0: NVIDIA - NVIDIA GeForce RTX 3060 Ti

Whenever it happens, there's a MASSIVE spike in _integrate_forces in the Physics 2D Profiler when warping the CharacterBody2D using global_position from a room to another, as if it is trying to calculate all the things it would have collided with from point A to point B

image

All I can think about is somehow turning off physics for CharacterBody2D before warping and enabling after warping, haven't managed to pull it off, I'll comment again if I find a suitable workaround.

MyrTheMoth commented 3 months ago

This is happening in our project as well in 4.2.1.stable.official, NVIDIA GeForce RTX 3050, 11th Gen Intel(R) Core(TM) i5-11600K @ 3.90GHz 3.91 GHz. The spike occurs on larger tilemaps when we instantiate CharacterBody2D PackedScenes and set their global position to objects farther away from the top left corner of the tilemap.

Notably, setting the collision shape's "Disabled" property to true prevents lag spikes from occurring when repositioning the CharacterBody2D, and if some time is allowed to pass before setting Disabled to false, the lag spike is avoided. Although less than ideal, this could be a temporarily solution for those who are experiencing this issue.

Oh! Glad someone had the same train of thought! Yeah, just tried it, this is the only mitigation that works at the moment.

sZellwegerGit commented 2 months ago

Unfortunately, turning collisions on and off is not really viable in my project. It would require a pretty ugly workaround.

I'm pretty sure that the CharacterBody2D shouldn't do any physics checks when just adjusting the global_position.

I have tried to look into to the the godot source code a bit to see if there is a clear obvious issue but unfortunately I am not very experienced with C++ or the Godot engine source code itself. Out of curiosity, how long does it usually take until performance bugs like these are resolved ?