How to optimize memory usage

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By hashak
:warning: Old Version Published before Godot 3 was released.

First sorry for poor English.

I am beginner in Godot and game development. I make a brick breaker 2d game with 7 level for android. Everything is OK But my problem is memory usage.

When i run my game (for test in Windows 7, Godot 2.1.4) and open Windows Task Manager (Performance tab), level after level increases memory and game will be lagging.

What can i do?

That sounds like a very small game, so my guess is you’re doing something very wrong. However, nobody can really give you advice unless you provide more information about how your game is set up. What is your scene/node setup? Your code? Have you tried narrowing down the problem?

kidscancode | 2018-01-14 04:46

Scene setup image
My scene setup image direct link

Thanks for you answer. Can you tell what causes it to increase memory (For example a checklist)

It is my scene setup and i repeat these in other level. Level by level some object (like bricks) and animation are increase.

“audio” have several sound (StreamPlayer type).

“camera” have a code for shaking when ball is lose. (I learn this code from Angega Studios youtube user)

“Player” and “enemy” have 2 animation and i set those to play random when finished animation.

func _ready():
	anim.connect("finished", self, "_random_animation")

func _random_animation():
	var randNum = randi() % 2
	if randNum == 0: anim.play("idle")
	else: anim.play("ready")

“brick container” have 24 bricks, and level by level these will be increase.

“ball” have a for loop condition for collision check and bricks queue_free, play sound when contact to object. and a condition for check ball that when ball get out at scene, reset ball position for new game.

func _fixed_process(delta):
	if _global.is_ball_play && self.get_global_pos().x <= 0:
		self.set_sleeping(true)
		self.set_pos(Vector2(220, 190))
		_global.is_ball_play = false
		container.add_child(fade_white.instance())
		_global.player_life -= 1
		camera.shake(8, 0.2)
		ballSpeed = BALL_SPEED

		if _global.is_sfx:
			snd_ball_gone.play()

	# Colliding ball
	var collision = get_colliding_bodies()
	for i in collision:
		ballSpeed += 3
		ballSpeed = clamp(ballSpeed, BALL_SPEED, BALL_SPEED*2)

		# Ball sound
		if _global.is_sfx:
			snd_ball.play()

		if i.is_in_group("g_brick"):
			i.queue_free()

		# Change direction ball by hit
		if i.get_name() == "hit_player":
			var p = i.get_node("position2D").get_global_pos()
			var changPos = self.get_global_pos() - p
			var velocity = changPos.normalized() * ballSpeed
			self.set_linear_velocity(Vector2(velocity.x, velocity.y))

“container” is a place for add “white fade-out animation” when ball is lose and “hit shape” for change direction ball (like a paddle), and after finished animation these will be queue_free.

“ui” is a simple menu for go to next level, close or restart game.

I hope these information be enough

hashak | 2018-01-14 10:59

How are you loading new levels? I notice that you’ve named that scene “level_1” so I assume you have a scene for each level. Is it possible that you are not removing the scene for the previous level when the player continues?

literalcitrus | 2018-01-14 22:32

Thanks for your answer.

I add a global variable called “level_number” in AutoLoad. If player win in this level, a window will be open and there is “Next level button” inside that, If user click on that i add 1 to “level_number”. And change scene to next level with this:

func _on_pressed_next_level():
	_global.level_number += 1
	_global.is_ball_play = false
	if _global.level_number < 8:
		get_tree().change_scene("res://stages/level_%s.tscn" % str(_global.level_number))
	else:
		get_tree().change_scene("res://stages/level_end.tscn")
	pass

hashak | 2018-01-15 03:44

:bust_in_silhouette: Reply From: QuentinCaffeino

You forgetting to free current scene.

We use this SceneManager from one of demo projects:

extends Node


# @var  SceneTree
var _tree

# @var  Viewport
var _root

# @var  Node
var _currentScene = null


func _init():
	_tree = get_tree()
	_root = _tree.get_root()
	_currentScene = _root.get_child( _root.get_child_count() - 1 )


# Go to scene
# @param  string  path
func goto(path):  # bool
	var f = File.new()
	if !f.file_exists(path):
		print('SceneManager: goto: Scene doesn\'t exist: ' + str(path))
		return false

	# This function will usually be called from a signal callback,
	# or some other function from the running scene.
	# Deleting the current scene at this point might be
	# a bad idea, because it may be inside of a callback or function of it.
	# The worst case will be a crash or unexpected behavior.

	# The way around this is deferring the load to a later time, when
	# it is ensured that no code from the current scene is running:

	call_deferred('_deferredGoto', path)
	return true


# @param  string  path
func _deferredGoto(path):  # void
	# Immediately free the current scene,	
	# there is no risk here.
	_currentScene.free()

	# Load new scene
	var s = ResourceLoader.load(path)

	# Instance the new scene
	_currentScene = s.instance()

	# Add it to the active scene, as child of root
	_root.add_child(_currentScene)

	# optional, to make it compatible with the SceneTree.change_scene() API
	_tree.set_current_scene(_currentScene)

Add it to autoload and use it like this:

SceneManager.goto("res://stages/level_%s.tscn" % str(_global.level_number))

Hello, I wanted to ask, doesn’t change_scene() and change_scene_to() delete the current scene automatically. I am having a similar problem where, I load a scene with thread and then change_scene_to() after waiting to finish the thread but it hangs up in mobile phone, I am thinking it is some kind of memory problem. Can you help? I also have a question asked but no one has answered The question I asked

hamza_memon | 2020-08-23 05:53