Log In  


is there a non-stylistic reason that it's useful to define _init? i haven't been able to discern any practical difference between defining things in _init and defining things outside of _init other than that the former gives you slightly more flexibility in ordering your source code.



The flexibility is it, really; when you define things inline in global scope, you're limited to using symbols you've already defined by that point, whereas _init can refer to symbols defined below it.

Without _init, if you had a global variable that's populated by a function (a lookup table, say), then it would have to be declared after that function. The result is your source gets front-loaded with library and utility functions and the actual runtime behaviour of the game gets pushed down to the end of the file.

Which is a matter of taste, but I prefer the opposite order for my own pico-8 source so I can visualise the game's state more easily.


you've made explicit what i was referring to with "flexibility in ordering your source code". if that really is the reason for _init, i'll accept it; but it seems possible that there's something else to it.


You can easily call _init elsewhere in your code to reinitialise your game.


also a good point! however, you could do that with any function (likewise with Viggles's argument; you could call _init yourself at the end of the source code), not necessarily one that's an explicit "hook" like _init is.

so, for a related question, why make _init a hook like _update and _draw are? (i'm getting the feeling that this is more in the territory of what only zep might be able to answer)


For me it was completely expected, as I've encountered it many times in other frameworks and tools.

If you don't want to use _init you don't have to. But it makes sense to use it in conjunction with _update and _draw

For me it encourages best practice, and that's enough of a reason


I initially thought it was because of the run() instruction to reset your variables to their initial values, but I just checked and it seems that the cart is properly reloaded and the memory cleaned anyway.


I think the main thing is just that it lets you order the source code however you like. That's more than enough reason to use it.

I hate what the requirement to pre-define variables does to source code in c/c++. :/


it seems like most of the answers here come out to "just/mostly stylistic", which is great, i just wanted to make sure there wasn't some other factor when evaluating whether to use it. thanks for your answers!


I'm interested in reasons why you wouldn't use it? Given that it's "standard" pico8


When you execute your code, it'll call all the things not in a function (eg in the global scope) in order, and then Pico 8 hooks into it, calling init once, and then alternating between update and draw calls.

If you do or don't use init that's fine - just be consistent, because mixing and matching variable assignments in the global scope and init might lead to unexpected behavior on startup.


matt, i wouldn't consider something being "standard" sufficient reason by itself to use it. however, if you wanted specific reasons against it: it could mean more tokens used, and also it's usual to indent the contents of a function, leaving slightly less room on each line before it goes offscreen. i personally prefer to keep all my lines onscreen whenever possible, though am not sure about others.

Danjen, i'm already aware of everything you said in your first paragraph. but i would need you to demonstrate what you're talking about in your second paragraph because i can't think of any reasons why there would be "unexpected behavior", unless you were talking about not being aware of how ordering affects program flow or something similar.


1

Agreed that it's mostly stylistic, with two minor practical advantages: 1) _init() allows all top-level code to have no side effects other than to define functions, and 2) code in _init() can call any global function regardless of where it is defined in the file, because all global functions are defined before _init() is called. (This is not true for other top-level code, which is sensitive to ordering.)

I find it challenging to track and document globals and constants if they're not initialized in a common place. Due to experiences with other languages I would expect to find globals at the very top of the file. One option is to define _init() at the top of the file and put global inits there. Another is to init them in top-level code before any function definitions. To be especially persnickety, I might prefer init'ing globals in _init() in case any initial value needs to be calculated with a function call (either now or in the future). Even in a persnickety mood I would make an exception for defining classes, which technically involves initializing non-function globals in top-level code.

But that's the deep end of coding style. This is a casual platform, so do what you think is most comfortable. :)


@edo999: That memory cleaning behavior is consistently implemented in most PICO-compatible hardware implementations, including all known platforms in the US and UK regions, but other international systems may differ. Outside of a few mimeographed best practices guides, there was no official spec on clearing memory on reboot.

Now that we're talking about it, I wonder how many old games don't reinitialize scores in _init. Seems like a great way to artificially inflate your score in a shooter. If you had access to a PICO-compatible machine that didn't clear memory on reboot, you could probably reboot right before you die and start again with your score intact!



[Please log in to post a comment]