Log In  


Not sure if this is a "bug" per se, but I'm new to Pico-8, and am starting a new project. It's supposed to be a SHMUP.
Problem is, I'm stuck on movement. For some reason, My ship doesn't move when I press the arrow keys.

I'm sure it's just something simple I'm missing, but I've been staring at my screen for hours trying to figure out what I'm doing wrong. Here's my code so far:

function _init()
--ship
shipx = 64
shipy = 110
shpspd = 2
shiphealth = 4
shipspr = 192

end

function _update()
end

function _draw()
cls()
spr(shipspr,shipx,shipy,2,2)
--moves the ship
function move_shp()

if btn (0) then
shipx=shipx-shipspd
elseif btn (1) then
shipx=shipx+shipspd
elseif btn (2) then
shipy=shipy-shipspd
elseif btn (3) then
shipy=shipy+shipspd
end
end
end



I think you should move your move_shp() function outside the _draw function and call it in the _update function... Right?


you have declared a ‘move_shp’ function but no code is actually calling it.
new to programming?


freds, yes. I vaguely understand what you are saying though. So Move_shp isn't called, but even though I just watched a tutorial on this, I can't quite recall the best way to do that. Would I just put "move_shp()" somewhere else in the draw function?

Miez, tried your advice, but I get a syntax error during runtime when I press an arrow key. it says I'm trying to perform arithmetic on a nil value (shipspd) but I established it in _init with a value of 2 so that doesn't make sense. Isn't a nil value a just a variable that doesn't return anything?

edit: I get the same syntax error when I call the move_shp() function anywhere else.


go through that entry-level tutorial: https://mboffin.itch.io/gamedev-with-pico-8-issue1
and check the manual for everything that seems fuzzy:
https://www.lua.org/manual/5.2/

good luck!


@junkRock there's a slight misspelling in your code: shpspd in _init, shIpspd in the rest of the code...


freds, will do. Thank you for the resource.

miez, getting somewhere but there's more errors. I might just scrap it and read the material freds recommended. Thank you both.


Freds, thank you for the reading material. So far, things are going well, and Learning is a blast. Still, I can't help but be confused by tables. I've been able to type what the tutorials tell me to, and it works, but I don't know why it does. The explanation on tables in both the zine and the Lua manual doesn't seem to "click" with me.

For instance, why are tables needed? What's the difference between setting one up, and say, just listing a bunch of variables? It seems to take a similar amount of characters to type, so does their usefulness go any further than just saving some tokens? Do you have any examples of how a game would use tables, and why it would even need them?


I'm the author of the resource freds72 pointed you to, so hopefully anything I write here won't be as equally "unclicky" as my explanation in the zine, but I'll give it a go. 😬😁

Tables are basically a way to store a bunch of information under one variable name. The useful thing is that you don't have to know how many things you'll store in that table when you are writing your code vs when you're running your code. (While you're writing your code is called "design time" and while your code is running is called "run time".)

For example, at design time, you may think, "Hmm... I need a way to store information about a bunch of particles." At design time, you don't really know exactly how many particles you'll use. Maybe you'll use 20? Maybe you'll use 200? Who knows! And it would be super tedious to write 200 separate variables named particle1, particle2, particle3, particle4, etc. all the way up to particle200 just in case you use that many particles.

So instead, you make a table called particles! That table is just a big empty bucket where you can store lots and lots of particles, all under one variable name. If you need to get to a particular particle, you can use, say, particles[12] and get to the 12th particle in your table. Or if you need to know just how many particles you're storing in particles, you could use #particles and it'll tell you how many there are.

One useful thing with that kind of usage is that you could have a loop somewhere that updates all your particles to make them move. Now, you don't know at design time how many particles you might be using at run time, so you just make a loop that basically says go through every particle in this table and do X to it. Well, neat, now you only have to write one simple loop to deal with every single particle. And if the particles table has no particles in it? Well, then the loop just doesn't do anything and moves right along to the next thing.

And then, let's say something explodes, and you need a bunch more particles all of a sudden. Well, you just add a bunch of new particles to the particles table. Now your loop that updates all the particles will make sure to update those too, and it doesn't really care how many there are. It'll just do all of them. And then, maybe when each particle gets too old, it deletes that particle from the particles table.

That's a specific example of when tables are needed. But they can be used to keep track of lots of other things too. For example, maybe you want to track all the enemies in the game. You'd have one enemies table that has all the enemies in it. And as new enemies spawn, you add them to the enemies table, and as they die, you remove them from the enemies table. Or maybe a bullets table to keep track of active bullets in the game. Basically, any time you have "a bunch of things, but I don't know how many at any given time", that's when a table would be handy.

Here's where it can get tricky...

Now, there's another use for tables that's a bit more specific. In this case, each piece of info being stored in the table has its own variable name, rather than just a number. In that case, it's kind of like having a variable with "sub-variables" inside it. Like, you might have a table named player and then in that table, you have a piece of info named x and y and health. Well, now you can get a player's health variable by writing player.health or their coordinates by writing player.x and player.y.

But while you can specify each individual piece of info, you could also just use the variable name player in your code, and that's going to refer to that entire collection of info (player.x, player.y, and player.health) without having to specify each individual piece of info separately.

This is useful if you want to send a whole player table to a function. Rather than sending that function 3 separate variables, you just send the one big table variable, and then the function can look inside the table you sent and get the specific pieces of info it needs by name.

I hope that makes a little more sense and I haven't confused you further. 😬


MBoffin, I unfortunately am even more confused XD I assure you concepts like tables, arrays, and matrices have always stumped me. C++, HTML, C# and even Python all seem easy enough at first, but I hit a wall the minute we get into the aforementioned concepts. The beginning of your lesson felt natural to me but for some reason, even with an example right in front of my face, I have so much trouble understanding the significance of tables, or how they work.

It's really frustrating. This is a battle I've been fighting for 7 years now, and no one seems to be able to explain it in a way I understand.

It's so hard to even figure out how I would word my questions, but it seems like everything you explained about tables would still be doable in a list of variables.

But this is obviously wrong because tables wouldn't be a thing if they weren't needed.

But if I had to spend time numbering these parts of the table, specifying what to do with the data, and using combinations of integers, bools, and strings, how is that any different than a list of variables? How does that require any less work for me or the computer? What would be the difference between telling my computer "Hey remember these variables" and "hey remember this table.", if I'd still be able to call separate parts of that table, and the computer would still be "looking" for it?

I know this seems like a superfluous point to hang onto, but if I can't even grasp the significance of tables, I don't feel any confidence that I would be using them correctly, and that's why I'm stuck on this. As much as I'd love to just paste your code and move on, I know that won't teach me anything in the long run, and I'm shooting myself in the foot by doing that if Tables are revisited anywhere in your later lessons.


There's 3 differences between a list of variables and a table:

  1. You don't need to know beforehand how many things you will be working with. The particle example is probably the most relevant here for pico-8, as a really flashy game could have any number of dots flying around, but in a different engine tables would also be helpful for reading data from files without knowing how much data is needed.

  2. You can use loops on a table to make the code much more compact. This may not seem like much, but imagine if you had to change 10 variables on an in-game object every update, and you had 30 of them. Clearly written, that'd take 300 lines of code. In a loop it would only take 12.

  3. You can duplicate the table without naming conflicts, then pass the different copies to functions or loops and use the same code without change. Taking the 30 objects idea again, imagine the 30 objects needed to change their 10 variables at different times. Then imagine that you found out you screwed up the way their variables changed and needed to adjust the code for all of them. If you made a function that takes an object as a parameter and changed the 10 variables, then you could call the function on each object and only have to fix one part of the code rather than searching around for all 30 parts.

kimiyoribaka, that actually helped me better understand MBoffin's explanation.
This new understanding doesn't seem to give me a better grasp on how to use them, but I'm at least past asking "why not just variables?" Maybe more practice will help whatever apprehension I have left.

If I follow you correctly:

A table is a good way to change a big group of things at the same time, change an unknown amount of things, or change a lot of things without writing a line of code for each thing.

Maybe it's just because I'm a visual thinker, but they still don't make complete sense to me.

Your explanation helped me see the utility of them, but I have more questions:

  1. MBoffin mentioned enemies dying, then being "removed" from the table. Is this all happening at runtime?

  2. I've seen tables with different types of data in some of these games/examples. Not just a bunch of integers, but combinations of integers, bools, and strings within the same table. If a table is meant to be able to change several objects with the same code, how does it know that I just want to change the integers and not the strings and bools in the same table?
    If I said "add this value to that table" assuming the value is... say, an integer, what stops pico from trying to add the integer to a string?

To visualise: think of tables as cabinets with drawers. Every element in the table is a drawer in the cabinet. These drawers can contain data, you can add or remove drawers and every drawer has a label (the index in the table).


Yes, adding and removing things from the table is done at runtime. Literally everything you see happen in Pico-8 is done at runtime because it's an interpreter language. Also, in general, any time you want variable usage to be flexible it has to involve messing with dynamic memory. However, since lua uses automatic memory management, coders aren't supposed to have to worry about that.

Regarding the types within the table, the code doesn't know the types you want to change until you try to change them. It just does what you tell it to and throws an error when things don't work.

Here's an example:

--this creates an empty table named t
t={}

--this code adds the number 0 to the first 10 numeric indices
for i=1,10 do
  t[i] = 0
end

-- this code adds the number 1 to the next 10 numeric indices
--  (# retrieves the last index that has a value)
for i=1,10 do
  t[#t+1] = 1
end

-- this adds the string "example" to the table as the table's value for "x"
t.x = "example"

-- this adds 1 to all the spaces that have numeric indices rather than a name
-- starting from 1 and going until a numeric index that doesn't have anything
for i=1,#t do
 t[i] = t[i] + 1
end

The result of the code is that t has a value "example" at t.x, which isn't changed because the code wasn't told to change it. Meanwhile all the numbers that can be accessed through indices have either the value 1 or the value 2. If one of the indices was assigned a string instead before the final for loop, pico-8 would respond with "runtime error: attempt to perform arithmetic on a string value". If instead the table needed to alternate between numbers and strings, the loops would need to be a bit more complex to handle them.


2

Kimiyoribaka, I see. So it is finally making at least some sense. I was going mad for a bit.

Miez, that actually helps a bit too. Too bad tables aren't just called "Cabinets" XD


@junkRock Definitely don't feel bad about not understanding aspects of this. I would be happy to help you 1-on-1 over Zoom or Discord (voice chat with screen sharing) in a more visual way with real examples in PICO-8 itself, if you'd like. I teach for a living, and if you're having a tough time understanding this, I guarantee there are students of mine who are running into similar difficulty, so helping you understand it better would actually help me help those students better as well. Totally up to you, though. If you are interested, feel free to DM me on Twitter (same username) or by email (this username at Gmail.com) or via Discord (MBoffin#1337).


@MBoffin, I appreciate the offer, and I sent you a friend request on Discord. schedule's been really hectic lately so I'm not sure how good of a student I'd be, and It would be hard to set up any consistent times for learning. Still, my free time is usually devoted to this so we're bound to have the chance to go over it every once in a while.

I will say that after some practice (and some sleep), it is getting easier to wrap my head around tables. I think part of it was that my past difficulty with C++ was making me overcomplicate Lua. I was not aware of Lua's automatic memory management, for instance.


@junkRock That's great to hear it's getting easier. I think I just accepted your Discord friend request. (Let me know if that wasn't you.) :D



[Please log in to post a comment]