Optimizations towards server
Asked Answered
P

5

0

Hello! I have a headless server build for my game. It runs on my VPS which is weak (single core and 1 GB of RAM). Now, my game allows users to create maps which is saved with JSON and big JSON files while loading on server can be very tough and causes the complete VPS to crash. My current deserializer script is:

extends Node

onready var level = get_tree().get_root().get_node("Game/Level")
onready var Game = get_tree().get_root().get_node("Game")

onready var Cone = preload("res://pref/Cone22.tscn")
onready var Sphere = preload("res://pref/Sphere.tscn")
onready var Wedge = preload("res://pref/Wedge.tscn")
onready var Cube = preload("res://pref/Cube.tscn")
onready var Cylinder = preload("res://pref/Cylinder.tscn")

func deserializeGame(game_data:Dictionary)->void :
	Game.send_discord_message("START MAP INIT ON SERVER", "SERVER -> DESERIALIZER")
	PhysicsServer.set_active(false)
	var level_data = game_data["Level"]
	var objects_data = level_data[0]["children"]
	var startTime = OS.get_unix_time()
	for object_data in objects_data:
		var object_instance = deserializeObject(object_data)
		level.add_child(object_instance)

	var endTime = OS.get_unix_time() - startTime

func deserializeObject(Object_data):
	var ToInstance
	match Object_data.type:
		"Cube":
			ToInstance = Cube.instance()
		"Sphere":
			ToInstance = Sphere.instance()
		"Cone":
			ToInstance = Cone.instance()
		"Wedge":
			ToInstance = Wedge.instance()
		"Cylinder":
			ToInstance = Cylinder.instance()
		"Script":
			ToInstance = deserializeScript(Object_data)
		_:
			print("Error: Object type not found")
			return null
	var Meshe = ToInstance.get_node("MeshInstance")
	var collision_shape = ToInstance.get_node("CollisionShape")
	var newMat = SpatialMaterial.new()
	newMat.albedo_color = Color(str(Object_data.color))
	
	ToInstance.translation = Vector3(Object_data.position[0], Object_data.position[1], Object_data.position[2])
	ToInstance.scale = Vector3(Object_data.size[0], Object_data.size[1], Object_data.size[2])
	ToInstance.rotation_degrees = Vector3(Object_data.rotation[0], Object_data.rotation[1], Object_data.rotation[2])
	
	if Object_data.color != "#NULL":
		Meshe.set_surface_material(0, newMat)
	
	var children_data = Object_data.children
	for child_data in children_data:
		var child_instance = deserializeObject(child_data)
		ToInstance.add_child(child_instance)
	
	return ToInstance

func deserializeScript(script):
	pass

What should I do?

Puerperal answered 18/8, 2023 at 5:35 Comment(0)
A
0

Puerperal it is definetly the CPU going 100% and RAM since I just ran a much smaller map which is 0.8 MB and the other map is 2MB

This sentence is difficult for me to understand. It is the CPU or RAM?

CPU going 100% for a small time (below 1 min) is not a problem, and should not crash the server. Percentages in RAM are not informative if we don't say how much RAM are we talking about.

Puerperal Should I consider using C# since its 4 times faster then GDScript?

This is a big decision (huge I would say), and I would consider other options first. Especially when we don't know if switching languages will solve the issue.

Puerperal Or consider changing the server?

Honestly, I am not sure if you have finished with the profiling. Godot has a Debugger/Profiler, I would try to monitor your script with it, see which parts are the heaviest, which ones are consuming more memory and CPU, and try to investigate why.

Once we have this clear, and see that our code is good, then I would go for a bigger server

Aam answered 18/8, 2023 at 6:38 Comment(0)
A
0

What I would do is investigate what the crash caused. Is it an out-of-memory or is it any other kind of issue? Difficult to go for solutions when the problem is not confirmed.

I would try to run the code in my locally where I can do extensive profiling. See how much memory the script requires. If I confirm it requires much more memory than the server has I would really consider upgrading the server. Optimization is complicated, costly and many times affect future maintenance costs. In comparison, more ram can be the cheaper option.

(Of course, on top, if during profiling I find an obvious and unnecessary memory leak I'll try to remove it)

Aam answered 18/8, 2023 at 5:57 Comment(0)
P
0

Aam Alright! I will now test the map on my local computer.

Puerperal answered 18/8, 2023 at 6:2 Comment(0)
P
0

Aam it is definetly the CPU going 100% and RAM since I just ran a much smaller map which is 0.8 MB and the other map is 2MB. Should I consider using C# since its 4 times faster then GDScript? Or consider changing the server?

The smaller map used 7% of RAM but 27% of CPU

Puerperal answered 18/8, 2023 at 6:19 Comment(0)
A
0

Puerperal it is definetly the CPU going 100% and RAM since I just ran a much smaller map which is 0.8 MB and the other map is 2MB

This sentence is difficult for me to understand. It is the CPU or RAM?

CPU going 100% for a small time (below 1 min) is not a problem, and should not crash the server. Percentages in RAM are not informative if we don't say how much RAM are we talking about.

Puerperal Should I consider using C# since its 4 times faster then GDScript?

This is a big decision (huge I would say), and I would consider other options first. Especially when we don't know if switching languages will solve the issue.

Puerperal Or consider changing the server?

Honestly, I am not sure if you have finished with the profiling. Godot has a Debugger/Profiler, I would try to monitor your script with it, see which parts are the heaviest, which ones are consuming more memory and CPU, and try to investigate why.

Once we have this clear, and see that our code is good, then I would go for a bigger server

Aam answered 18/8, 2023 at 6:38 Comment(0)
P
0

Aam Okay, I will debug further more.

Puerperal answered 18/8, 2023 at 6:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.