Closing game after switching scenes causes Godot to crash

Godot version 4.3 stable_mono_win64

I’m having a problem where closing the game will cause the game to freeze my entire computer for a few seconds, close the editor and turn the game from a fullscreen to a windowed application. I’ve tried using both GetTree().Quit(); and GetTree().CallDeferred(“quit”); and both give the same result.

Heres the code:

using Godot;
using System;

public partial class Player : CharacterBody2D
{
	[Export]
	public float Speed = 300.0f;
	[Export]
	public float JumpVelocity = -400.0f;
	[Export]
	public float DownVelocity = 400.0f;

	public bool isFalling = false;

    public override void _PhysicsProcess(double delta)
	{
		Vector2 velocity = Velocity;

		if (!IsOnFloor())
		{
			velocity += GetGravity() * (float)delta;
		}else{
			isFalling = false;
		}

		if (Input.IsActionJustPressed("up") && IsOnFloor())
		{
			velocity.Y = JumpVelocity;
		}
		if (Input.IsActionPressed("down") && !IsOnFloor())
		{
			isFalling = true;
		}

		if (isFalling)
		{
			velocity.Y += DownVelocity;
		}

		Vector2 direction = Input.GetVector("left", "right", "up", "down");
		if (direction != Vector2.Zero)
		{
			velocity.X = direction.X * Speed;
		}
		else
		{
			velocity.X = Mathf.MoveToward(Velocity.X, 0, Speed);
		}

		Velocity = velocity;
		MoveAndSlide();
	}

	public override void _Process(double delta)
	{
		if (Input.IsActionJustPressed("ui_cancel"))
		{
			GetTree().CallDeferred("quit");
		}
	}

}

which is attached to the Player, and

using Godot;
using System;

public partial class World : Node2D
{
    public override void _Ready()
    {
        GetNode<Area2D>("killZone").BodyEntered += OnKillZoneBodyEntered;
		GetNode<Area2D>("WinZone").BodyEntered += OnWinZoneBodyEntered;
    }

	private void OnKillZoneBodyEntered(object body)
	{
		if (body is Player player)
		{
			GetTree().ReloadCurrentScene();
		}
	}

	private void OnWinZoneBodyEntered(object body)
	{
		if (body is Player player)
		{
			GetTree().ChangeSceneToFile("res://Scenes/Levels/Level1.tscn");
		}
	}

}

which is attached to the root of the current scene.

It only seems to happen after I’ve reloaded the current scene, and when it happens seems wildly inconcistent, and it once even caused a blue screen. Thanks for any help

You can try

    public override void _Ready()
    {
        GetTree().AutoAcceptQuit = false;

to disable auto accept quit and

    public override void _Notification(int what)
    {
        if (what == NotificationWMCloseRequest)
            GetTree().Quit(); // default behavior
    }

You can add some clean up in needed and to close game use:

 GetTree().Root.PropagateNotification((int)NotificationWMCloseRequest);

you also can create one management scene and add and remove scenes as children if GetTree().ChangeSceneToFile("res://Scenes/Levels/Level1.tscn"); make problems.

It seems to be working, thanks very much. Although I am still getting an error about not being allowed to remove a collisionobject during a physics callback, here’s the full error

E 0:00:10:0118   NativeCalls.cs:330 @ int Godot.NativeCalls.godot_icall_0_37(nint, nint): Removing a CollisionObject node during a physics callback is not allowed and will cause undesired behavior. Remove with call_deferred() instead.
  <C++ Source>   scene/2d/physics/collision_object_2d.cpp:98 @ _notification()
  <Stack Trace>  NativeCalls.cs:330 @ int Godot.NativeCalls.godot_icall_0_37(nint, nint)
                 SceneTree.cs:652 @ Godot.Error Godot.SceneTree.ReloadCurrentScene()
                 World.cs:18 @ void World.OnKillZoneBodyEntered(object)
                 Area2D.cs:682 @ void Godot.Area2D.BodyEnteredTrampoline(object, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant&)
                 DelegateUtils.cs:86 @ void Godot.DelegateUtils.InvokeWithVariantArgs(nint, System.Void*, Godot.NativeInterop.godot_variant**, int, Godot.NativeInterop.godot_variant*)

Thanks again for helping with the issue

I believe there’s problem because is called in frame while collision are calculated.
You can make with one of this:
defered call,
use tween,
add animation before change,
add screen with confirmation with press any buttons to continue or game GUI buttons.