Restarting a game level

I have a main menu which calls this code to launch level 1 (using a collection proxy):

function on_message(self, message_id, message, sender)
	if message_id == hash("load_level") then
		print("LOAD LEVEL")
		msg.post(message.proxy, "load")
	...

After the player dies they may wish to restart the level.

Restart should (presumably) unload the collection object, then call that load_level code again (above).

For unloading the collection I have:

function on_message(self, message_id, message, sender)
	...
	elseif message_id == hash("clear_level") then
		print("CLEAR LEVEL")
		msg.post(message.proxy, "disable")
		msg.post(message.proxy, "final")
		msg.post(message.proxy, "unload")
	...

But when I call this code:

-- Restart level:
msg.post("main:/game#levelProxies", "clear_level", { proxy = "/game#level1Proxy" })
msg.post("main:/game#levelProxies", "load_level", { proxy = "/game#level1Proxy" })

I get the following output:

DEBUG:SCRIPT: CLEAR LEVEL
DEBUG:SCRIPT: LOAD LEVEL
ERROR:GAMEOBJECT: The collection 'level1' could not be created since there is already a socket with the same name.
ERROR:GAMEOBJECT: AcquireResources NewCollection RESULT_OUT_OF_RESOURCES
WARNING:RESOURCE: Unable to create resource: /levels/level1/level1.collectionc: OUT_OF_RESOURCES
ERROR:GAMESYS: The collection /levels/level1/level1.collectionc could not be loaded.

I assume this means I’m unloading the object/proxy wrong. Can someone please tell me what I’m doing incorrectly?

Thanks!

1 Like

I bet(didn’t test it) it is because you are unloading and loading on the same frame time. You should wait until level is unloaded and reload it again.
This script might help(not as it is but gives you an idea):

2 Likes

This is suspicious. It seems like you have more than one collection with id level1.

As @selimanac mentioned you have to wait for the proxy to finish unloading before loading it again.

Wait for a proxy_unloaded message before reloading.

4 Likes

Thanks for everyone’s replies. Waiting for the proxy_unloaded message fixed the issue for me.

Here is my levelproxies.script:

function init(self)
	msg.post(".", "acquire_input_focus")
	self.active_proxy = ""
	self.reload = false
end

function final(self)
	msg.post(".", "release_input_focus")
end

function on_message(self, message_id, message, sender)
	if message_id == hash("load_level") then
		print("LOAD LEVEL")
		msg.post(message.proxy, "load")
		self.active_proxy = message.proxy

	elseif message_id == hash("reload_level") then
		print("RELOAD LEVEL")
		self.reload = true

		if message.proxy ~= nil then
			self.active_proxy = message.proxy
		end
		
		msg.post(message.proxy, "disable")
		msg.post(message.proxy, "final")
		msg.post(message.proxy, "unload")

	elseif message_id == hash("clear_level") then
		print("CLEAR LEVEL")

		self.reload = false
		msg.post(message.proxy, "disable")
		msg.post(message.proxy, "final")
		msg.post(message.proxy, "unload")
	
	elseif message_id == hash("proxy_loaded") then
		print("PROXY LOADED")
		msg.post(sender, "init")
		msg.post(sender, "enable")

	elseif message_id == hash("proxy_unloaded") then
		if self.reload then
			msg.post(self.active_proxy, "load")
			self.reload = false
		end
		
	elseif message_id == hash("pause") then
		msg.post(".", "set_time_step", { factor = 0, mode = 1 })
	end
end

I can reload the level like this:

msg.post("main:/game#levelProxies", "reload_level", { proxy = "/game#level1Proxy" })

Or load the main menu like this:

msg.post("main:/game#levelProxies", "clear_level")
msg.post("main:/mainMenu", "enable")

Thanks again!

3 Likes