How do I fix the issue of a proxy already being loaded

I am developing my proxies to ensure that when the door is touched the next level along is loaded, however I keep getting this error

Here is my loader, startup and door codes
Loader:


Door:
Screenshot 2024-04-11 200535
Startup:

Only thing I can think of is that as far as I can see self.current_room is never set so it will never unload the rooms.

1 Like

That sounds plausible, I’ll see what i can do

I changed the script a little


However, it returned this error when I loaded the first level

In Lua, only nil and false are Falsely. It means with self.current_room = 0 you will get into the if scope.

What do you mean by msg.post(self.current_room, "unload"). Current proxy isn’t that number

1 Like

What Chung_Xa said. With this approach you could join the first part of the url to the number msg.post("#proxy_room_" .. self.current_room, "unload") or something like it.

I tried your suggestion


but I only got this error and my first room didn’t load

any tips?

It’s strange that you have self.current_proxy but not using for that if statement but using self.current_room.

1 Like

Please share code as text, not screenshots!

You have:

self.current_room = current_room + 1

Spot the error?

function init(self)
	msg.post(".", "acquire_input_focus")
	self.current_room=0 -- creates variable to track which room is loaded
end

local function show(self, proxy) -- local function to handle the loading and unloading of the current room
	if self.current_room then -- checks if proxy is loaded
		msg.post("#proxy_room_" .. self.current_room, "unload") -- tells current proxy to unload
		self.current_room = current_room+1
	end
	msg.post(proxy, "async_load") -- sends async_load message to current room, once loaded it will send - "proxy_loaded"
end


function on_message(self, message_id, message, sender)
	if message_id == hash("show_room_1") then
		show(self, "#proxy_room_1")
	elseif message_id == hash("show_room_2") then
		show(self, "#proxy_room_2")
	elseif message_id == hash("show_room_3") then
		show(self, "#proxy_room_3")
	elseif message_id == hash("proxy_loaded") then -- handle proxy_loaded message
		self.current_room = sender -- store url of proxy that was loaded
		msg.post(sender, "enable") -- enable loaded proxy
	elseif message_id == hash("proxy_unloaded") then
		print("Unloaded", sender)
	end
end

However when I do this I get returned with this error

ERROR:SCRIPT: main/loader.script:9: attempt to perform arithmetic on global 'current_room' (a nil value)
stack traceback:
  main/loader.script:9: in function show
  main/loader.script:17: in function <main/loader.script:15>

ERROR:GAMEOBJECT: Component '/loader#proxy_room_0' could not be found when dispatching message 'unload' sent from main:/loader#loader

If you replace your show function with this code, I think it should work

local function show(self, proxy) -- local function to handle the loading and unloading of the current room
	if self.current_proxy then -- checks if proxy is loaded
		msg.post(self.current_proxy, "unload") -- tells current proxy to unload
	end
	msg.post(proxy, "async_load") -- sends async_load message to current room, once loaded it will send - "proxy_loaded"
end

But it seems you need self.current_room for something?

“attempt to perform arithmetic on global ‘current_room’ (a nil value)” this tells you that a variable on line 9 is global and that the value is nil:

self.current_room = current_room+1

self.current_room is a variable on the self “object” while current_room is a global variable. It should be

self.current_room = self.current_room + 1
2 Likes

I altered the code as specified

function init(self)
	msg.post(".", "acquire_input_focus")
	self.current_room=1 -- creates variable to track which room is loaded
end

local function show(self, proxy) -- local function to handle the loading and unloading of the current room
	if self.current_room then -- checks if proxy is loaded
		msg.post(self.current_room, "unload") -- tells current proxy to unload
		self.current_room=self.current_room+1
	end
	msg.post(proxy, "async_load") -- sends async_load message to current room, once loaded it will send - "proxy_loaded"
end


function on_message(self, message_id, message, sender)
	if message_id == hash("show_room_1") then
		show(self, "#proxy_room_1")
	elseif message_id == hash("show_room_2") then
		show(self, "#proxy_room_2")
	elseif message_id == hash("show_room_3") then
		show(self, "#proxy_room_3")
	elseif message_id == hash("proxy_loaded") then -- handle proxy_loaded message
		self.current_room = sender -- store url of proxy that was loaded
		msg.post(sender, "enable") -- enable loaded proxy
	elseif message_id == hash("proxy_unloaded") then
		print("Unloaded", sender)
	end
end

However, when I touched my door, this error was returned

ERROR:SCRIPT: main/loader.script:9: attempt to perform arithmetic on field 'current_room' (a userdata value)
stack traceback:
  main/loader.script:9: in function show
  main/loader.script:19: in function <main/loader.script:15>

ERROR:GAMESYS: The collection /main/rooms/normal/normal_2/normal_2.collectionc could not be unloaded since it was never loaded. Message 'unload' sent from normal_1:/loader#loader to normal_1:/loader#proxy_room_2.

Well, I mean, you start by assigning “current_room” a value of 1. Later, in on_message, you assign it the value of sender. Sender is a url. You can’t add 1 to a url.

I think you need to slow down and think about what you wish to do. Really look at the code and think if it makes sense or not. What is the purpose of self.current_room? Is it supposed to be a number? Or is it supposed to be the url of the currently loaded proxy? It can’t be both.

2 Likes

I have reverted back self.current_room = nil, this solved the issue of the collections being already loaded or not loaded, however, it now states that it is being loaded when nothing changes in the collection

WARNING:GAMESYS: The collection /main/rooms/normal/normal_2/normal_2.collectionc is already being loaded.

As a novice game programmer myself, take this advice with a grain of salt, but I have made a lot of mistakes recently and have found the following to often be the best solution most of my problems:

  1. Use print statements liberally. print and pprint are your friends.

For example, in your “show” function, print out the value of self.current_room before and after you post the message and update its value. Then you can verify that you are actually sending the message that you think you are. You could probably also do this with the proxy parameter.

  1. Read the manual, then take a break, then read it again. There is a lot going on in our games and sometimes it takes time for it to sink in.

  2. simplify your test case and then build in the complexity. So in this example, maybe instead of getting all the doors working, start with just one and then think about how you can take that an expand it to make it work for all the doors.

Just my 2 cents, I know how frustrating it is to feel like you are hitting a brick wall

Additional debugging info in the manual

4 Likes

Good news, the second room loaded, however it loaded on top of the first, I need to get the first to unload

However whenever I add proxy_level_1 to the other collections I always get returned with this error

Cyclic resource dependency detected. This is caused by a two or more collections referenced in a loop from either collection proxies or collection factories. One of the resources is: /main/rooms/normal/normal_1/normal_1.collection.

Any other solutions?

Here is the message i recieve

WARNING:GAMESYS: The collection /main/rooms/normal/normal_2/normal_2.collectionc is already being loaded.

room 1:
Screenshot 2024-04-13 151330

What I get when I touch the door:
Screenshot 2024-04-13 151337

room 2:
Screenshot 2024-04-13 151535

I suggest creating the proxies in the top collection (e.g. “main”, or “levels”).
The level collection itself shouldn’t contain a collection proxy. It should only need to send a message back to the main collection loader script.

e.g.

levels.collection
    go/
        loader.script -- the script doing the loading unloading of all levels
        gameover -- a collection proxy for the gameover.collection
        level1 -- a collection proxy for the level1.collection
        level2 -- a collection proxy for the level2.collection

and so on. The levels themselves would send a message to msg.url("levels", "go", "loader").

There are of course other ways of structuring the data, this is one way.

3 Likes

Exactly. Like this: Proxy