Optimizing add_child

Godot Version

4.5

Question

Hi, I’m new to optimizing. My 3D game is not big nor spawn many objects but when I uploaded to test play on the web I noticed my game stutters whenever add_child is called. I’m using add_child in places such as when shooting bullet, changing scene, adding enemies/explosions.

Example of my game. Run fine on PC but on web it will stutter when bullet/explosions instantiate the first time.

Player.gd

@export var bullet : PackedScene
@export var flame_thrower : PackedScene
@export var laser_raycast3d : PackedScene
@export var missile_heatseek : PackedScene

func shoot():
	if is_shooting and can_shoot:
		if shot_type == 1: # Normal
			if is_instance_valid(flame):
				flame.queue_free()
			if is_instance_valid(laser):
				laser.queue_free()
			var bullet_instance = bullet.instantiate()
			bullet_instance.damage = 1.0

Enemy.gd

func death_explosion():
	var explosion = preload("res://FX/Explosion_03/explosion_03.tscn")
	var explosion_instance = explosion.instantiate()
	add_child(explosion_instance)
	if is_instance_valid(explosion_instance):
		explosion_instance.get_node("AnimationPlayer").play("play")

World.gd

func goto_game_scene(level_select : int, player_start_position_x : int):
	remove_scene_children_node()
	var game_scene = preload("res://Scenes/game_scene.tscn")
	var game_scene_instance = game_scene.instantiate()
	scene.call_deferred("add_child", game_scene_instance)

RockBoss.gd

func death_explosion():
	### EXPLOSION PUFF
	var explosion = preload("res://FX/Explosion_03/explosion_03.tscn")
	var explosion_instance = explosion.instantiate()
	world.add_child(explosion_instance)
	
	### EXPLOSION ROCKS
	var rock_explosion = preload("res://FX/Rock_01/rock_01.tscn")
	var rock_explosion_instance = rock_explosion.instantiate()
	add_child(rock_explosion_instance)

How should I optimize all these add_child?

I read that I should Instantiate() all the instances at the start of game.

So.. Like this??

eg.

level01.gd << Instantiate() everything here

@export var bullet : PackedScene
var bullet_instance = bullet.instantiate()
var explosion = preload("res://FX/Explosion_03/explosion_03.tscn")
var explosion_instance = explosion.instantiate()

then:

– player << add_child(level01.bullet_instance)

– enemy << add_child(level01.explosion_instance)

This is probably more to do with loading un-cached objects or shader compilation than add_child. Both of these are somewhat inevitable, currently for Compatibility mode (the only renderer available on web) the best way to prevent shader compilations stutters is to load the object, place a bullet somewhere inside your world, maybe just below the ground. Maybe your player could spawn in with the same explosion animation.

2 Likes

If I understand this correctly , I must get those instances to “appear and be played” somewhere at the beginning of level first so that all the stuttering will not happen during gameplay?

1 Like