0 votes

My game will often spawn a large amount of "point tokens", specifically when defeating a boss all of the boss' active projectiles will at once be transformed into tokens that the player absorbs.
Even when hundreds of bullets are converted at once, there is no issue, not even a framedrop because I add them to a list and queue them to convert them over several frames, rather than doing them all at once, so it still looks instant while in reality the conversion is spread over 10-20 frames.
The issue is, when the player absorbs those point tokens, the game will consistently crash if there's enough of them.
Right now this is what the code looks like for the point token itself:

 func _on_Area2D_area_entered(area):
    if position.y>60 || area.name=="Pointbox":
        queue_free()

(Note that Pointbox is the name of the Area2D that detects collision with point tokens)
And this is what it looks like on the player's side:

func _on_Pointbox_area_entered(area):
    pass
#   match area.Type:
#       "W":
#           HUD.WP+=1
#           if Level<8 && HUD.WP>=HUD.MaxWP:
#               LevelUp()
#       "E":
#           if HUD.Energy<HUD.MaxEnergy:
#               HUD.Energy+=1
#       "P":
#           LargePointQueue+=1
#       "P-":
#           PointQueue+=1

Note that it's pretty much not doing anything right now, as I was concerned my code was creating the errors elsewhere I disabled all of it temporarily, and still it consistently crashes. Supposedly, all there's going on is a queue free on the token's side and a pass on the player's side, which should be minimal stress on the engine, despite how many tokens there are.
When it crashes, the window simply closes and the engine gives me no error reports. What's more, I only recently updated to Godot version 3.5.1, before updating I was still using 3.2.3 and I was not experiencing these consistent crashes. I had an packed version still running on 3.2.3 with practically the same exact code, and recreating the circumstances never gives me any crashes, despite the crashes happening 2/3 times when doing it in 3.5.1.
If there's anyone with any ideas or any help, please reply as I've wracked my head against this wall for quite a while now.

Godot version 3.5.1
in Engine by (23 points)

1 Answer

+1 vote
Best answer

Nevermind, I guess it's true that once you write something down you'll actually understand it yourself better.
I tried removing queue_free() from the token's code on collision, instead moving it far off-screen and the game stopped crashing. In other words, the issue was that queue_free was being called too many times at once. Fixing this was easy, but I'll post my solution just in case other people run into a similar situation.
Token's new code:

func _on_Area2D_area_entered(area):
    if position.y>60 || area.name=="Pointbox" && !MarkedForDeath:
        MarkedForDeath=true
        get_parent().KillQueue.append(self)

It's parent's code:

func _process(delta):
    if KillQueue.size()>0:
        while KillQueueCounter:
            if KillQueue.size()>0:
                KillQueue[0].queue_free()
                KillQueue.remove(0)
                KillQueueCounter-=1
            else:
                KillQueueCounter=0
        KillQueueCounter=10

Meaning only up to 10 tokens are freed each frame.
Sorry for wasting time and bandwidth, I suppose.

by (23 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.