[SOLVED] How to create a queue of spawning game objects after one another and stopping based on a countdown timer

Remember this and check out book.script of book.go:

1 Like

I see, I’m still slightly a bit confused by this. So does that mean that it doesn’t matter when on_message is called? What I’m understanding when you say lua is top down is that it means the functions get built in order and has to be called from the top down? Should I be making self.book_id somewhere else.


I ended up debugging it, the typing works, the sound for it works. You seem to be right though, it’s got to do with the book.script so I tried reordering the init to be last. Wait, shouldn’t generate_book_code be run first, before even creating the book? Wait that doesn’t make sense. When you create the book, you’re running the initialising method.

The issue you’re having right now is not because of ordering, you already fixed that. You need to fix the errors you’re getting in the console. Nothing will work if your script crashes. Start from the very first one and fix what it tells you is wrong.

book.script:7: attempt to index global 'self' (a nil value)

1 Like

I see, thank you. About that error though, if the problem is that self.book_code = "" is nil, then I’m either thinking that my goal is to make it either a local variable or to reorder when I create that variable. With local variables, can you pass them through msg.post? I’m slightly confused on how to use it. I was thinking of passing it to my computer.script
image
but I don’t know if message call the book_code variable? I did read the documentation, I’m just confused about the message parameter. Yea no, reordering it wouldn’t work I think, I also just tried that.

No no, back up. Read the error message more carefully.

attempt to index

Attempting to index something means you’re trying to use it as a table and access a value inside it using a key.

attempt to index global

This means that the error is happening when your script attempts to access a global variable.

attempt to index global 'self'

The global variable that you’re trying to use is named: ‘self’.

'self' (a nil value)

The value of the global variable that you were trying to use is nil.
Since you were trying to get a value from the variable using a key, the variable was expected to be a table. Instead of a table, it was nil, hence the error.

[Edit]: Looking for a global variable means that no local variable was found with that name, in the current scope.

1 Like

I see. Oh I see, I’m reading your previous post on Explanation of the “self” argument for dummies and I think I’m somewhat understanding it. I originally used self to make it so the variable be different for every instance so I think I’m doing it right.So line 7 is self.book_code = "". So I’m debugging it again, reaching to the original error, clicking the triangle to forward it and jumping to here.

image

So if self is a table, and I’m indexing a global self from my book.script, then does that mean I was trying to access the self table inside of insert-book-code.script or vice versa?
Sorry, I’m just having a hard time grasping this.

I guess another question would be, what is the key in this case.

Wait, so I’m using the factory to create an instance of a game object, and I’m using self to make sure each variable of each instance of it is unique and not shared, but then inside of that game object, I have a script that’s also attempting to use self to make sure each instance of it has unique variable values. :thinking:

Wait a minute, if I’m already making a new instance of book.go inside of insert-book-code.script, why would I need self.book_code inside of book.script.

1 Like

Line 7 from the error is:

self.book_code = ""

So the key in this case is: "book_code", since

self.book_code

is just shorthand for:

self["book_code"]

The one and only problem is: no local variable named ‘self’ exists in the context where you expected it to. Just take a look at these few lines:

function init(self)
	generate_book_appearance()
	generate_book_code()
end

local function generate_book_code()
	self.book_code = ""

Where’s self?

2 Likes

OK, I’ll stop being annoying and just explain it :stuck_out_tongue: : ‘self’ is always given as a function argument. In other words, a local variable inside a function. The problem is, you are not passing ‘self’ on to the “generate_book_code()” function, so ‘self’ doesn’t exist inside that function when it runs. You want to do this:

function init(self)
	generate_book_appearance(self)
	generate_book_code(self)
end

local function generate_book_code(self)
	self.book_code = ""
1 Like

HOLY CRAP, I FEEL DUMB. Also I was having dinner and that popped into my head, I was thinking about how I had arguments inside of insert-book-code.script and they all passed self. THAT MAKES SENSE NOW. :man_facepalming:

Wait though, would I even need to make the variables inside of book.script unique? Considering I’m using the factory to make a unique instance each time?

Thanks by the way for sticking it out with me.

Ok, I’m making progress though, managed to fix another error, it was the msg.post one, I was passing a string instead of a table and it didn’t like that, and I fixed it, still got a few errors to go though.


It’s spawning a book at least.

ERROR:GAMEOBJECT: Component '/instance0#random_book_code_label' could not be found when dispatching message 'set_text' sent from default:/instance0#random-book
ERROR:GAMEOBJECT: Instance '<unknown>' could not be found when dispatching message 'play_sound' sent from default:/minigame_go#insert-book-code
INFO:DLIB: SSDP: Started on address 10.0.0.78
ERROR:SCRIPT: ...games/inventory/insert-book-code/insert-book-code.script:25: Could not send message 'game_over' from 'default:/minigame_go#insert-book-code' to 'main:/main'.
stack traceback:
  [C]:-1: in function post
  ...games/inventory/insert-book-code/insert-book-code.script:25: in function <...games/inventory/insert-book-code/insert-book-code.script:24>

Ah ok, I’d probably have to pass in that instance for the url then.

local function generate_book_code(self)
	self.book_code = ""
	local charset = {} do
		-- Ký tự [0-9a-zA-Z] dưới dạng  mã ASCII: https://www.rapidtables.com/code/text/ascii-table.html
		for c = 48, 57  do table.insert(charset, string.char(c)) end
		for c = 65, 90  do table.insert(charset, string.char(c)) end
		for c = 97, 122 do table.insert(charset, string.char(c)) end
	end
	-- [0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}
	while (string.len(self.book_code) <= 19) do 
		if (#self.book_code % 5 == 0) then
			self.book_code = self.book_code .."-" 
		else
			self.book_code = self.book_code .. charset[math.random(1, #charset)] 
		end
	end
	-- Ok, this is the issue here. I already tried to pass self"#random_book_code_label" but that didn't work
	label.set_text("#random_book_code_label", self.book_code)
	msg.post("/computer#computer", "actual_book_code", {book_code = self.book_code})
end

Wait nope, fixed that issue too, turns out I got the wrong name for the label. :rofl: There’s still the play_sound issue, will try to figure that out, in fact I’m trying to find where it is. Got the sound to work. Gotta figure out how to make my spawned game object bigger, I’ll figure that out, I think you can specify scale with factory. Unless there’s a way to do that in the game object itself. Another one is to figure out how to check to see if your typed input matches the book code, hm. Oh yea, and trying to figure out how to return to the main collection and then loading the next minigame. We’ll get to that when we get to that.


1 Like

Alright, it sort of works, just one odd problem now, with the timer, after it’s done it’s giving me an error where it can’t find the main collection.

What is the code you are running in the timer?

// timer
timer.delay(1, false, function()
		msg.post("main:/main#main", "game_over")
	end)

// main
function on_message(self, message_id, message, sender)
	if message_id == hash("game_over") then
		pprint("Create nested function for loading and unloading minigames?")
	end
end

ERROR:SCRIPT: ...games/inventory/insert-book-code/insert-book-code.script:24: Could not send message 'game_over' from 'default:/minigame_go#insert-book-code' to 'main:/main#main'.
stack traceback:

I wonder if it has to do with the directory.
image

No no no. The way you have arranged stuff in your Assets (the panel on the left) in terms of filenames and folder structure has nothing to do with the url used in msg.post. It is the structure in the Outline that matter, and the ids you have assigned there.

2 Likes


I see, I think I might know the issue, I’d have to load the main collection before sending message posts to it, and probably unload the current collection I’m in. Thank Britzl. Or I start from main.collection, then load in the current collection I’m on then unload the latter when the timer goes down, i.e. unload current collection then it should call inside of main

if message_id == hash("proxy_unloaded") then
       pprint("Cycle through the minigames again.")
    end

Hate to revive a thread, solved one scenario but now have a similar scenario to this one. Basically I’m now trying to spawn a bunch of game objects that have a different sprite for each instance (basically they’re just alphabetical letters) and am using Factory and Properties as an example, however I don’t think I need to add functionality to the game object I’m spawning in its own script since it’s just being used in this specific collection. I would assume that me using self.letter would make each instance unique, so I don’t understand why it wouldn’t recognise the id, and since self.letter is an instance of the spawned game object, shouldn’t go.animate recognise that path? Thanks to anyone who responds.

local function random_position()
	return vmath.vector3(math.random(1, sys.get_config("display.width")),  math.random(1, sys.get_config("display.height")), 0)
end

local function spawn_letters(self)
	local charset = {} do
		-- Ký tự [0-9a-zA-Z] dưới dạng  mã ASCII: https://www.rapidtables.com/code/text/ascii-table.html
		for c = 97, 122 do table.insert(charset, string.char(c)) end
	end
	for i,v in ipairs(charset) do
		self.letter = factory.create("#alphabet_factory", random_position())
		sprite.play_flipbook(self.letter.."#alphabet_sprite","keyboard_"..v)
		go.animate(self.letter.."#alphabet_sprite", "tint", go.PLAYBACK_LOOP_PINGPONG, self.color, go.EASING_INOUTCIRC, 2)
	end
end

function init(self)
	msg.post(".", "acquire_input_focus")
	spawn_letters(self)
	timer.delay(8, false, function()
		print("Failed.")
		msg.post("main:/main#main", "game_over", {score = 0})
	end)
end

function on_input(self, action_id, action)
end

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

Errors below:

ERROR:SCRIPT: ...est-service/where-to-find-book/where_to_find_book.script:14: Could not find any instance with id '<unknown>'.
stack traceback:
  [C]:-1: in function animate
  ...est-service/where-to-find-book/where_to_find_book.script:14: in function spawn_letters
  ...est-service/where-to-find-book/where_to_find_book.script:20: in function <...est-service/where-to-find-book/where_to_find_book.script:18>

image

You can’t use string concatenation. Use:

msg.url(nil, self.letter, “alphabet_sprite”)

Thanks for replying britzl, but how would I determine what image the sprite should be set to?

Is this not what you are looking for as Britzl suggested?

local sprite_url = msg.url(nil, self.letter, “alphabet_sprite”)
sprite.play_flipbook(sprite_url,"keyboard_"..v)

Ah I see, yea I realise I made a typo on my variable name (and now I feel dumb). :expressionless: Thanks selimanac for replying.

I guess the problem is the animating part now.

ERROR:GAMEOBJECT: Properties can not be of type 'nil'.
ERROR:SCRIPT: ...est-service/where-to-find-book/where_to_find_book.script:14: only numerical values can be used as target values for animation
stack traceback:
  [C]:-1: in function animate
  ...est-service/where-to-find-book/where_to_find_book.script:14: in function spawn_letters
  ...est-service/where-to-find-book/where_to_find_book.script:20: in function <...est-service/where-to-find-book/where_to_find_book.script:18>