Sunday, December 11, 2016

Now you're playing with POWER ups

Originally I wasn't planning on including powerups (or powerdowns) in this game. I wanted to make everything dependent on the timer. If you waste too much time and the timer goes down to 0, something bad happens. If you score a good combo and push the timer beyond the max value, something good happens. While this is still the case (on a smaller scale), I have decided to change it when I found those breakout clones. Powerups, and especially powerdowns make for an interesting gameplay. Player will have to choose between getting a powerup (or avoiding a powerdown) and making sure to bounce the ball back. This adds to the challenge on the scale I am using - powerdowns can block off parts of the available area, forcing the player between picking up the unwanted effect or losing a ball. More than that it also allows me to to use those tried and true brekout bonuses. And who doesn't like a slow ball or a bigger paddle?


Anyway, let's get down to implementing the code I blatantly stole from this cart and tweaked it to work for my game.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
function _init()
bonuses = {powerups ={} }

powerups = {
 {spr = 18, col=12, func = function() padw+=4 padh+=2 end},
 {spr = 19, col=8,func = function() padw-=4 padh-=2 end}
}
end

function create_bonus(_x, _y)
 local _bonus = {x = _x-4, y = _y-4}
  local var
   if #bonuses.powerups<3 and rnd(1) <0.1+scoremulti/100 then
    var = flr(rnd(2)) + 1 
   else
    return
   end
    _bonus.spr = powerups[var].spr
    _bonus.func = powerups[var].func
    _bonus.vel = 0.5 + rnd(0.5) 
    _bonus.col = powerups[var].col
    add(bonuses.powerups, _bonus)
end

function bonus_update()
 for i in all(bonuses.powerups) do
  --clear bonuses when there are no bricks left
  if #bugs<1 then 
   create_explosion(i.x+4,i.y+8,i.col,8,2,5)
   del(bonuses.powerups,i) 
  end
  --move the bonus down
  i.y += i.vel
  --bonus/paddle collision
  if i.x+8 >= padx and i.x <= padx+padw 
  and i.y+6 >= pady then
   --make particles
   create_pixelfall(i.x+4,i.y+8,i.col,4,-1)
   create_pixelfall(i.x+4,i.y+8,i.col,4,-1)
   create_explosion(i.x+4,i.y+8,i.col,8,2,5)
   --change current frame to 1 for housekeeping
   frame_num=1
   i.func() --fire up what the powerup does
   --add some juicy effect for the paddle
   padcol=7
   pady+=1
   --destroy this brick after that
   del(bonuses.powerups,i)
  end
  --destroy brick when it 
  --reaches the bottom 
  if i.y+8 >= 128 then
   --and make it look cool with particles
   create_explosion(i.x+4,i.y+8,i.col,8,2,5)
   del(bonuses.powerups,i)
  end 
 end 
end

function bonus_draw()
 for i in all(bonuses.powerups) do
  spr(i.spr,i.x,i.y)
 end
end

Even that my first game has a bad case of messy spaghetti code, I did pick up some programming practices that I think are pretty good (correct me if I am wrong). Like implementing small features in 3 functions: one to establish it, one to update it in _update(), and one for drawing it in _draw(). This makes the code a little more manageable.

_init()

First we make a powerups table to keep our powerups. I might expand it in the future, but right now I have a sprite for the powerup (currently a placeholder), color used for particles and what the powerup does. This is where I will store all my powerups and call them when I want to spawn one. Next on my agenda is adding more powerups and making proper graphics for them.

I am not sure why the powerups are wrapped in another table (bonuses), but this is how it was in the original code and it works just fine (and as someone told me, if the code works it's a good code, so I am leaving it for time being). I might need to go through it and see if it works without the wrapper.

create_bonus()

I call create_bonus each time a ball hits a brick, with the coordinates where I want the powerup to spawn. In my case it is the brick's X and Y, adjusted to spawn it in the center of the brick on X and below the brick on Y (this is what the -4 in local variables helps with).

Then I am doing a quick random check, so a powerup does not spawn on every brick hit. It is 10% that goes bigger if you score a combo of bricks. I am also limiting the amount of active powerups on screen to 3 [line 13]. If that returns true, I am choosing a random powerup [var variable, line 14], else I am stopping the function with RETURN.

The powerup chosen with var is a new table that holds all the info [lines 18-21] and stores it in the powerups table [line 22], so I can call them in the next two functions. I know it is a little confusing - tables within tables - but once you wrap your head around it will make perfect sense.

update_bonus()

This function is responsible for making the powerup fall down, fire its function when caught with the paddle and destroying it when it reaches the bottom of the screen. There is one addon, that is there for keeping the board clean between levels by destroying all the active powerups when there are no bricks (called bugs because of earlier idea for the game) left.

This function reads the data we have stored in the previous function for each existing powerup [line 26] and changes them. So every frame each powerup moves down [i.y += i.vel] and when it touches either the paddle [lines 35,36] or bottom of the screen it does something else - check the code comments for that.

Store this function in your _update(), so it works each frame.

draw_bonus()

Lastly, we just draw all the powerups in _draw() with a simple function that will show a sprite at X and Y each frame until the entry is deleted.

END

...and that's it. With 3 functions and some tables we have added a feature to the game. Now, next step is adding cool powerups that the player will enjoy. My plan is to make more powerdowns spawn, the higher the level of the game. This will add to the challenge of the game and will create a a manageable difficulty curve. But, that's a topic for another post.

Monday, December 5, 2016

Not Quite Dead

Good News Everyone!


The rumors of this project's death have been greatly exaggerated (even after taking into consideration the fact, that no one was really talking about it). This arkanoid-ish first game of mine lives and it even got some new features implemented.

Real life forced me to go on a pretty long hiatus from blogging, programming and other past-times. Now, that real life is promising me some free time, I am planning on continuing this crazy adventure. I have re-started working on the game few days ago thanks to stumbling upon multiple breakout clones on Pico-8 BBS (I think there was some kind of Pico workshop, as many of them look alike).  The kicker was the powerup code inside those carts...which I have blatantly stolen :P

After orienting myself in my mess of a code for a bit, I transplanted the powerup code to my game. After few tests and tweaks, I caught the programming bug (no pun intended) once again. New features just kept flowing and I ended up adding some minor things and making tweaking the gameplay over the next few days. I was presently surprised how much I remembered of what I have learned about coding those five months ago.

While I have a couple busy days this week, soon after that I am going to resume working on this game (for which I still need a good title) and blogging about the process. I will start with going through the features I just added and I will take it from there. If everything will go my way (and I won't come up with even more big features I want to add), I should be releasing this guy by the end of the year. So, stay tuned!

Saturday, July 9, 2016

Side Quest

In the past week, I managed to add another glitch effect to the game - A VHS like corruption lines during the game that can double as a total program meltdown during game over. Originally the "game over" screen was supposed to just turn on red noise that would eventually fill it full, but I think this effect is much cooler, so it stays. I was going to add more to the game, but I got side tracked...

...because I decided to write a Pico8 Zine article! The 5th, RPG themed issue of the zine was struggling with getting enough article submissions. I have seen the call for submission for few weeks now, but I thought that writing such article was beyond my capabilities. This mindset of mine changed when the zine editor, Arnaud De Bock posted an example of a very simple RPG combat system from Choccobo World, that he could use a tutorial for. I thought I can figure out how to write such system...


I am a nerd. Outside of all computer related things, tabletop games, and RPGs in particular, were a big hobby of mine since my teens. I even have a whole blog dedicated to them! Messing with the mechanical aspects of those games still is something I really enjoy and making a fully finished RPG (of both tabletop and computer variety) is still a goal of mine, So I had the background for it, I just needed some time to figure it out.

The Choccobo World system is painfully simple, to the point of not being fun. So I took it as a base and added more interesting mechanics on top of it. On paper, I have a pretty good RPG combat system that takes mixes Final Fantasy's Active Time Battles with a skill system from Pokemon. The gameplay is about more than just chipping away HP, and focuses on choices. In my opinion it would be a pretty fun system...but it is waaaaaaay to big for a tutorial. Mainly because of the character limit of the zine article, which is around 6k characters  I had to scale the whole thing down drastically. So I found the essential parts, scrapped everything else and started coding.

Over the next three days I had a working system. To my surprise coding came to me pretty easily. It seems I have learned a lot of things from making the glitchy breakout game, much more than I thought I did.  Sure, the code was a little janky here and there, but I asked few experienced programmers from the Pico-8 community to give me some pointers on how to fix those. With their help, I managed to trim the code to just over 600 tokens in Pico-8. With some help I managed to make a pretty playable, if bare-bones jRPG combat system that can be expanded pretty easily. That's why I called it: Barebones Action Battle System!

As it is now, it focuses on 1on1 battles with an active timer. So the "faster" your character is, the more turns they can take. Because of the article's space limit, I had to forgo the classic RPG attributes and just used simple variables, but I can see how making those variables dependable on character stats would add to the game. The "meat" of the system are the skills. Different skills will will produce different effects. Sure, you can hurt your opponent's HP, but a better option might be to slow them down, or make them less likely to hit you. Sadly, I only managed to squeeze 4 very basic skills in into the game... even the expanded 8k character allowance does not seem like enough. I plan on expanding this system and making it into a series of blog posts after I finished my first game. On that note, I should get back to it...
Anyway, I hope you will check out the article when it comes out, until then, feel free to try the last build of the system here on the right.

P.S Maybe I should make some skeleton sprites for it... Barebobes? Skeletons? It simply makes sense!

Thursday, June 30, 2016

Glitches and Tweetcarts

Today I stumbled upon a piece of code on twitter that motivated me to start implementing the glitchy aspects of the game. The code came from Trasevol Dog's tweetcart. Carts like those are part of a somewhat unofficial Pico-8 jam to make a program in 140 characters or less. There is already a great amount of effects showing what you can do in this limited amount of code. You can look them up either by checking #tweetcart on twitter, or on Pico-8 BBS. Those carts are a great resource for both inspiration and learning. Sure, the tweetcart code is not very human readable, as most of the variables use single letter naming, but figuring out what 140 characters of code does is much easier than figuring parts of a whole finished game...
This is how I stumbled upon this effect. After seeing it on twitter, I added it inside my game and to my surprise, it produced a pretty cool distortion noise effect. Now to break it down and tweak it.


The original code was taking every other pixel on the screen and made another pixel a random amount away the same color. The problem was that the code made the game slow down pretty bad. Originally I was going to use it just as background for game over screen, but then I started tweaking that script. I found that if I will check and move less pixels around, the game will run pretty smoothly. With some trial and error I managed to to that! Then I just added a variable that will change how much noise is being rendered and came up with the code below:

function glitch_noise()
 if glitch_noise_factor > 0 then
  local f = glitch_noise_factor
  for tx=0,16 * f  do
   for ty=0,16 * f do
   tk=rnd(3)-1 
   ta=tx*(8/f)+tk 
   tb=ty*(8/f)+tk
   tc=pget(ta,tb) 
   tc+=flr(rnd(9)/8) 
   pset(ta+rnd(3)-1,tb+rnd(3)-1,tc)
   end
  end
 end  
end

Now I can just change the glitch_noise_factor and render the noise. The bigger it will get, the more noise will get rendered. Even the slowdown can now be used as a part of gameplay...after all slowdown is pretty common in machines that are bugged out and glitchy. Another bug that became a feature... as Rob Ross would say: "happy little accident."

Now that I finished the first glitch effect, the floodgates have been open and I am motivated to implement more glitches... after all, they were the one of the main ideas to behind this game.


Wednesday, June 29, 2016

Game Dev Vs. Life

Sadly the last two weeks or so were pretty slow on the gamedev front. I didn't have much time to think about what I want to add to the game, not to mention implementing it. Thanks real life.

Most of the time I spent in Pico-8 was toying with the background pattern to make it look less like random assortment of pixels and to add the life counter. It is still not perfect, but I think I will leave it for the time. It is not all doom and gloom. I have managed to tweak some small things to make the gameplay feel better and solved a small bug in which the ball would destroy bricks in a straight line under certain conditions. The biggest achievement in this time was the screen transition animation. This frame will show up in red when you lose, and in blue between the levels. I might have just wasted 300 tokens on something purely cosmetic, but I think it will be a good way to show some of the game's theme.

That's it when it comes to progress in those ten days. I will try to implement more things this week when I have a bit more time to spare. Maybe I will finally make a dent in the new enemy/brick types, add some of the long promised glitches or mess with the win/lose formula. Recently, it was that last one idea made me think most about the game.  Having score and lives is ok, but I have an idea for alternative approach where the ingame "system" would crash (lose condition) if you let too many bricks/bugs/errors exist for too long. It is kinda a time limit system, but it would be flexible to give a player more time the better he/she plays. This is something that will need to be tested to see if it is any fun. I am also toying with having limited amount of levels, as the game is infinite right now. Maybe some kind of "betting" mechanism, where the players could bet on  how many levels they could beat and get bonus points based on that? We will see...

Sunday, June 19, 2016

First month of gamedev

Past week was pretty busy on real life front, so there isn't much programming progress. I did manage to implement a two hit bricks (yellow), tweak the paddle movement to be a little smoother and add background graphics. Apart from those, most of the week was spent on testing, tweaking and making the game play, look and feel "just right." So far I am really happy with my progress, just to think that a little over a month ago I had no idea how to even start making a video game. Now I have that something that resembles an actual game! I am really stunned, that I managed to pull this off! More than that, I had gotten some good feedback (and even some interest about the game) from people online, which is a really humbling, but also really exciting. I never thought that anybody would be even remotely interested in a first game from a total programming noob. You are all making me want to push forward. Thank you.


Looking back on the past month, I think that the biggest surprise for me is how the process of making the game will actually dictate and shape the game. Only now I really understand why everybody urges new devs to go and actually make a games, instead of planning their Magnum Opus. You can plan all you want, but the game will only take shape as you are making it. I have spent a lot of time planning things on paper, only to find out that they sucks after I added it to the game. Such was the case with different variations of the two-hit brick, the general graphics of the bricks, and animations in the background among others. They all look great on paper, and even look great when drawn outside of game, but when put together they just don't gel well with anything else. Making games is as much as an art, as it is science...

Well, the first month is behind me. I have learnt a lot from making this game so far, and I have much, much more still to learn. Yet, the biggest lesson here is that virtually anyone can learn to make video games. If I can do it, so can you.

Sunday, June 12, 2016

Game feel and level progression

Particles, screenshake and level progression are in!
Before I added any more features to the game, I wanted to make sure the the basic brick breaking feels good. After watching few talks about the game "juiciness" and the art of screenshake, and reading about the "game feel" in general, I have decided to give those things a try...
...and I am really pleased with the results! The game is much more satisfying to play when the block breaking has a bit of a "weight" behind it. I was surprised how much of a difference a few lines of code can make. Also, that I managed to implement those things without much trouble. Sure, I looked up similar code in other games to get a hang of the particles and I was given a basic screenshake mechanic by @emu from the Pico-8 Slack, but making it work inside my game still felt like a triumph. As of now, I see the basic gameplay as complete. There might be some small tweaks done to it  in the future, but right now it's time to move to other things.


LEVEL PROGRESSION:

One of the main features of the game are randomized levels. I have opted to go this route for few reasons: Pico-8 sprite map limitations means I can only make so many levels, lack of knowledge about level design (and not wanting to make an exact clone of something like arkanoid) would lead to levels that are just boring to play,  and my fascination with randomization in games of all kind. A drawback of making the levels random is having some levels that are pretty easy to beat, so I needed more levels to keep the game from being disappointingly short.  So far I implemented the backbone of the level progression system, rest of it will come out of the algorithm that is responsible for generating each level. Anyway, here's the code:

level = 1
currentlevel = 0

function start_level()
 if currentlevel < level 
 and #bugs < 20+level then
  create_bug()
 else currentlevel=level 
 end  
end

function end_level()
 if #bugs==0 then
  ballxdir=0
  ballydir=0
  ballx=(padx+padx+padw)/2-2 --centers the ball on the paddle for serve
  bally=pady-6
  newball=1
  if btnp(4) then
   level+=1
  end 
 end   
end

I am using two variables to check if the levels has changed, and two functions that are placed inside the _update() function (so they are checked every tick). On the beginning of the game the current level is 0. After the start_level function has generated the level, it simply makes the current level, equal to the level the program has just generated.
When the player clears a level (there are no entries in the bugs table, that holds the bricks/enemies), I make the ball go back to the serving position and change the level variable to the next one. Then the start_level picks up again and does its thing. Done.

Unlike the previous approach of generating the level before the game starts, running it frame by frame as a game starts makes the bricks appear one by one. I haven't planned for that, but it is a cool effect, that is probably easier for Pico-8 to run, so it's a win-win. It just needs some animation of the bricks appearing to make it great. Oh, and sounds...but the sounds will come much later. Next step is to add some enemy variety and implement them into the level generator.

Tuesday, June 7, 2016

Finally some progress [on the graphics front].

The game actually moved past the "janky prototype" phase in this past week. I finally added some theme, but it took forever to zero-in on it. I knew I wanted a glitchy aesthetic and for the bricks to be somewhat representative of robotic bugs or some mechanical "body horror" thing or growth. Well, as it turns out making a good representative sprite on such a small scale, with limited palette, and on top of that, keeping them more or less rectangular (after all they need to work well as breakout bricks) is really hard. The sprites that look good on their own, end up looking really distracting once few of them are spawned in the game...not good  After spending close to a week on trying to make representative sprites I somehow found myself googling fictional 80s computer UIs. So I decided to try that. After all, Pico-8 is an 80s fantasy console, so an 80s aesthetic wouldn't hurt. After delving into artstyles of Tron, cyberpunk and 80s retrofuturism in general, I knew I was onto something.


Now, instead of trying to squeeze in some H.R Giger-esque cybernetic growths and other assorted horrors into tiny Pico-8 sprites (you can see some of my passable attempts here on the right), I am going with a simpler neon style reminiscent of  "as seen on TV" 80s computer interfaces. Those simple sprites will be applicably distressed with glitchy graphical effects (and glitchy game mechanics, coding skills permitting) to make the game more pleasing to the eye and to reinforce the theme of fighting against computer viruses, bugs in code, whathaveyous.

So far I only implemented the basic brick. I didn't go any further because: 1. I didn't make a final list of enemy/brick types, and 2. Adding more types will require re-writing of the code for creating those sprites, and I don't even have an algorithm for that yet. Nevertheless, I am happy with this style so far. It is simple enough not to be distracting to the player, but representative enough to carry the theme. For what it's worth, the "computer noise" inside the bricks is the thing that makes the sprite truly stand out. Both the idea and the code for this effect are blatantly stolen from the Ryukyu Circuit cart. Because why should you take precious sprite space for an animation that you can procedurally generate? This is another example that reinforces me that choosing Pico-8 was the right fit for me. Being able to lookup the source code to of existing carts to see how others have solved similar problems or implemented a cool feature is an amazing learning tool for someone like me. Before I dug into that source code, I was ready to make the exact same effect with sprites. It would take much more time and I am quite sure it wouldn't look as good when limited to few frames of animation. Now, I only need one sprite and few lines of code. Awesome! Also, a big shout out goes to Dan Anderson from Pico-8 Slack, who once again helped me understand code where my own brain has failed me. The code for the circuit cart doesn't have many comments, so I couldn't find the function responsible for the noise effect. But Dan could. Thanks Dan!

As for those mechanical sprites above, I might expand on them and use them in some robot inspired shooter in the future... I like their angular style, but man, do they suck as breakout bricks.

Tuesday, May 31, 2016

Back to the game code

After over a week of learning about random spawning, collisions and those confusing Lua tables, I finally came back to working on the game proper. Today, I added game states (so I can have a splash screen), and implemented the improved random spawner with a pretty solid collision between the ball and the bricks/enemies. This marks the basic play mechanics as complete, but there is still a lot to do for this game. The next step is coming up with a selection of enemies that will create interesting gameplay, then implementing a good algorithm for spawning them in such way to make the game challenging and fun. It will be interesting to actually try my hand at some video game design after learning  about gamedev and programming for over two weeks... oh and trying to make some passable pixel art.


In the meantime, I'll break down the code for the spawner used in the game:

function create_bug()
--responsible for assigning
--random values to enemies
 local sprites={17,19,21,23}
 local sn = flr(rnd(4)+1) 
 local o={}
 o.sprite=sprites[sn]
 o.x=flr(rnd(110))+1
 o.y=flr(rnd(60))+10
 o.w=2
 o.h=o.w
 o.x2=o.x+o.w*8
 o.y2=o.y+o.h*8
 o.xdir=flr(rnd(2)+1)
 o.ydir=flr(rnd(2)+1)

 overlapped = true
  while overlapped do
   overlapped = false
   foreach(bugs, function(bugs)
    if bugs.x<=o.x+o.w*8+1 and bugs.x+bugs.w*8>=o.x-1 and bugs.y<=o.y+o.h*8+1 and bugs.y+bugs.h*8>=o.y-1
    then
     test+=1
     overlapped = true
     o.x=flr(rnd(110))+1
     o.y=flr(rnd(60))+10
    end
   end)
  end
   add(bugs, o)
end

function col_bugball()
 for a=1,#bugs do
  if bugs[a]!=nil then
   if bugs[a].x<ballx+ballsize
   and bugs[a].x+bugs[a].w*8>ballx 
   and bugs[a].y<bally+ballsize
   and bugs[a].y+bugs[a].h*8>bally then 
    test+=1
    --bounce horizontal
    if ballcenterx<bugs[a].x
    or ballcenterx>bugs[a].x+bugs[a].w*8 then
     ballxdir= -ballxdir
     sfx(01)
    --bounce vertical  
    elseif ballcentery<bugs[a].y
    or ballcentery>bugs[a].y+bugs[a].h*8 then
     ballydir= -ballydir
     sfx(01)
    end 
    del (bugs, bugs[a])
   end
  end
 end  
end

The first part of the code is pretty similar to the one in the post before, but it has few important changes - mainly optimization and changing the enemies from simple rectangles to actual sprites (who are simple rectangles for time being, but that will change). The most important change is in the approach to spawning objects. Instead of running the whole function as in the previous version, I only change the X and Y of the spawned object if the collision is detected. This approach is less memory intensive, although can still manage to crash Pico8, if pushed too hard. Once I implement some enemy types, I will limit the amount of times the program will try to spawn something. Right now, it is a good tool for testing. The other change, swapping IF to WHILE when checking for collisions, solves the issue I had when a the function would check for object N, then spawn object N+1, but it didn't take into account any objects spawned before N so the new object would sometimes overlap the older objects.

The second part function col_bugball() takes care of the collision between the enemies and the ball. It cycles through every enemy in the table bugs and checks for their collision. I am using the formula for collision between squares, as the ball sprite is effectively a 5x5 pixels square and my enemies will stay in roughly rectangular shape. Once it checks for collision, the function checks if the ball hit the block from the side, or top/bottom. This then reverses the ball direction accordingly. I have some small issues with the ball behaving odd here (changing X and Y direction on the same block), which I am still to fix. I will look into it after I have made couple enemy types and see if the issue prevails. Finally, the object that was hit by the ball gets destroyed. This part will get changed to a hitpoint system, once the enemy types will start rolling in. Having some enemies take more than one hit is a staple of breakout games after all.

Sunday, May 29, 2016

I broke Pico 8 and I am not even mad.

Yesterday I made Pico 8 run out of memory. I was trying to figure out how to spawn "enemies" in such way so they wouldn't overlap (which is important for the game). So far it works, but it is not a great solution if you need more than a handful things spawned (which I don't). It can quickly start hogging the memory, because the program gets lost in an ever expanding loop of spawning and deleting those squares. The top left variable tracks how many times the program goes through that loop before it can find a square that does not overlap any of the existing ones, and I have seen it add 500 on few occasions. To be honest, 500 is still a very impressive number. As someone new to programming, I am amazed how much even the limited Pico8 can compute. Anyway, here's the code for this function...


function create_bug()
--responsible for assigning
--random values to enemies
 local o={}
 o.x=flr(rnd(110))+10
 o.y=flr(rnd(60))+10
 o.w=flr(rnd(12))+4
 o.h=o.w
 o.x2=o.x+o.w
 o.y2=o.y+o.h
 o.col=flr(rnd(14))
 o.xdir=flr(rnd(2)+1)
 o.ydir=flr(rnd(2)+1)
 add(bugs,o)
 
--check if the new bug is not overlapping
--with any existing bug.
 for a=1,#bugs -1 do
--by using the collision formula
   if bugs[a].x<=o.x+o.w 
    and bugs[a].x+bugs[a].w>=o.x
    and bugs[a].y<=o.y+o.h
    and bugs[a].y+bugs[a].h>=o.y
    then test+=1
    del (bugs,bugs[#bugs]) --delete overlapping bug.
    create_bug() --try again
   end
 end
 
end

I won't use that method as there is a possibility it will simply break the game. But, I will leave it here, as a pretty good example of the programming process (at least for newbies): code, find out it doesn't work exactly how you wanted, find the reason why, code more. I am quite proud that I was able to break PICO8 and that I could identify why it happened. So there's that. It seems that, instead of deleting and trying again, a better way is to move the new object so it is no longer on top of any of the existing ones. At least it seems better on the surface...

Friday, May 27, 2016

Collisions for randomized enemies also [mostly] work!

It feels like right now I am getting a bit too close to the deep end of the pool. While in the last few days I have managed to make the randomly spawned balls move (pretty easy) and even collide with each other (really hard), I couldn't have done the later without the help from the Pico8 communities on Slack and IRC. Those guys helped me understand Lua syntax much more, and on more than one occasion simply gave me the answer. My next step, after fixing few bugs in this code, is to go back to my pong game and start implementing those enemies in. I feel like I need to take a step back from trying to understand more advanced topics and actually work on the game, mostly because programming the game and seeing how it all comes together is much more rewarding than trying to perfect a single side mechanic.


Anyway, let's see how this code works...

MOVEMENT:

function update_bug(o)
--move the bug
  o.x+=o.xdir
  o.y+=o.ydir
--keep within world  
 if o.x+o.size>126
 or o.x-o.size<1 then
  o.xdir= (-o.xdir)
 end
 if o.y+o.size>126 
 or o.y-o.size<1 then
  o.ydir= (-o.ydir)
 end 
--avoid collision with wall
 if o.x-o.size<=0 then o.x=1+o.size end
 if o.x+o.size>=127 then o.x=126-o.size end
 if o.y-o.size<=0 then o.y=1+o.size end
 if o.y+o.size>=127 then o.y=126-o.size end
end

function _update()
 debug()
 foreach (bugs, update_bug)
end

This was the easier of the two tasks. Moving something (a shape, sprite, whatever) was covered pretty well in the Squashy tutorial. All we need is to change the X and Y values the object and then call this in the _update() function. The only difference here was instead of a single object, I had bunch of objects stored inside a table, each under its own number. This is where my lack of knowledge of Lua syntax, and of programming in general, slowed me down. On paper I knew exactly how to do it. Get a loop going that updates the X and Y values of each element inside the table. Now All I needed to get it going was to find a way to access stuff in that table. So I had spent some time looking for Pico8 carts that have random enemies and try to dissect their code. I have noticed few of them using the FOREACH statement in conjunction with a table and a function that had one parameter - o. This "got the ball rolling," so to speak.

At this point I thought that the naming of the parameter (o) had to be the same to the one used in creation of my table (which also was o). That's not the case. To my understanding FOREACH looks up the values from the table (in the case of bugs, it returns the table for each enemy), and plants it into the function. The function can now process each enemy one by one. Thanks to that it changes X and Y for enemy 1, then 2, than 3 and so on. The "o" parameter is simply a "placeholder" a local variable (as I said, I mostly understand tables )

After finding a way to update X and Y of every enemy I just added some IF statements to keep the balls on screen (bounce of the wall just like in Squashy) and another one to eliminate a bug where a ball would get stuck on one of the walls after collision. I guess I could have combined them into one function, but having them separated makes it more clear what each section does.

After I had the balls moving and bouncing of the walls I wanted them to bounce of each other. For that I needed...

COLLISIONS:

--check for collision between bugs  
function collision_bugbug()
--cycle thru the table get one enemy
 for a = 1, #bugs do
--cycle thru again get second enemy 
  for b = a+1, #bugs do
--formula for distance between circles  
  local distance=sqrt((bugs[a].x-bugs[b].x)^2+(bugs[a].y-bugs[b].y)^2)
--if distance is smaller than combined sizes
--of both enemies, it means they collide
    if distance <= bugs[a].size + bugs[b].size +1 then
--bounce the balls back on collision
      bugs[b].xdir= -bugs[b].xdir
      bugs[b].ydir= -bugs[b].ydir
      bugs[a].xdir= -bugs[a].xdir
      bugs[a].ydir= -bugs[a].ydir
--just for testing how many collision there are      
      test+=1
   end
  end
 end  
end
     
  
--system functions
function _update()
 debug()
 collision_bugbug()
 foreach (bugs, update_bug)
end

This was the tricky syntax part that I couldn't figure out on my own. It felt like it was within my grasp after figuring all the math and learning about FOREACH, but it felt like a strange blind spot in my brain whenever I was trying to create syntax to compare two different enemies from inside the table. I spent a day or so trying to find a solution, but again, documentation simply wasn't there (I really hope that Pico-8 manual will eventually become a little noob friendly). This is where the awesome community of this fantasy console stepped in.

This is the second version of the collision code. The original way was working fine, but used over twice as much CPU clock. It was based around FOR x in ALL(table) instead of FOR x=1,#table (length of the table) which meant that the code would check enemy 1 vs enemy 2, but also check enemy 2 vs enemy 1, which was not necessary, as we already checked if they collided. I am not really on the level of proficiency to optimize my code, but when there was an opportunity to do so, I jumped on it. Here's a comparison how the old (left) vs current (right) works:


Easiest way (at least for me) to understand it is to treat every unique number as an unique enemy. Each number holds a table for one enemy. So Bugs[1] holds X,Y and other attributes of the first enemy, Bugs[2] the second and so on. As you can see, the current version does "less work" as shown by the white spaces. Later on I added to the formula, so B starts at A+1 instead just A, so the function won't check collisions against against the same enemy. This saved a little more CPU time and a token, as I didn't have to add A != B (A does not equal to B) to the IF statement. Anyway, let's break down the current code...

function collision_bugbug() initiates the function, so we can call it later in _update(). Next two lines (for x in...) cycle through the enemies' table twice and generate pairs of numbers (A and B) which we can compare.
Next we need to find out the distance between the circles to see if they are overlapping. This is where Pythagorean Theorem comes in handy yet again (honestly I never thought I will get that much millage out of something I have learnt in primary school). We basically find the distance between two points (centers of the two enemies) and put it in a variable ( local distance=sqrt((bugs[a].x-bugs[b].x)^2+(bugs[a].y-bugs[b].y)^2) ) for clarity. Then we check if this distance is equal or smaller then the sum of the sizes (radiuses) of the circles. If it is, it means that the circles are touching / colliding. 
THEN we put whatever we need upon collision, in this test I just reverse the directions at which the circles travel (also add one to test variable, just for troubleshooting). 


That's it. When it is broken down like that it doesn't seem that difficult, but it took me a long time to get there, and would probably take me much, much longer without the community's help. 
If you want to check out the whole code for the spawner, feel free to download the cartridge to the left and mess with it. Right now there are still some bugs (circles can spawn on top of one another or can get stuck if multiple circles collide at the same time) that I will try to fix in the near future (well, basically as soon as I can figure out the syntax for it). My next step is to transplant this into the game code proper and do some tests with squares, sprites and maybe even pixel perfect collision (which maybe way beyond my skill level, but there is a Pixel Perfect Collision Demo cart that I plan on digging in). 

Monday, May 23, 2016

The randomized enemy spawner is working!

This bunch of circles might not look like much, but they took me over two days to figure out. The issue was not making them have random values, but wrapping my head around the concept of Lua tables. Lua is great at simplifying things to make the programming flow better. Unfortunately, a byproduct of this is making some concepts more difficult to understand by someone who has very little programming experience. This is the case with tables. They combine arrays and matrices (and probably some other things!) into a single object. This is a great thing for someone who understands how those base concepts work...for someone like me, it is a big hurdle. It didn't help that the Lua documentation focuses solely on the differences between tables and the things they replace...


It took a lot of reading, testing, looking up others' source code and a dash of frustration, but, with help from Pico8 community, I managed to (at least partially) wrap my head around it. The moment it finally clicked felt awesome!

To make it easier on myself, I wrote this randomized enemy spawner as a new program, away from my game code.  I used simple placeholders for most of the elements. That way, nothing else would come in the way of grasping this concept. I think it paid off, because I got it to work and even made some pretty clean looking code:

Edit: I was advised to change the table o from the create_bug function to local table to avoid other functions grabbing this data when they don't need to. I changed that in the code below.

--table for enemies
--enemies are bugs
--hence the name
bugs ={} 

function create_bug()
--responsible for assigning
--random values to enemies
 local o={} --make empty table
 --and fill it with below values
 o.x=flr(rnd(110))+10
 o.y=flr(rnd(50))+10
 o.size=flr(rnd(18))+2
 o.col=flr(rnd(14))

 --add this table to bugs table
 --this way, we have all the enemies
 --stored in one place so they can
 --be accessed all at once.
 add(bugs,o)
 return o
end

function draw_bug (o)
--draw an enemy with values
--established in create_bug
  circfill(o.x,o.y,o.size,o.col)
end 

--spawn enemy on button press
--used for testing the code
--yes, I know the name is 
--somewhat misleading
function debug()
 if btnp(4) then
  create_bug()
 end 
end 

--system functions
function _update()
 debug()
end

function _draw()
 rectfill(0,0,127,127,15) --draw background
 foreach (bugs, draw_bug) --draw all the enemies!
--this function goes through all the enemies
--stored inside bugs table and draws
--them one buy one.

 --show current amount of enemies
 print (#bugs,4,4,1)
end

There are still some small things I do not know exactly why they work, but I know how to make them work, so that's good enough for now. I will continue expanding this code to make those enemies move and possibly not overlay each other, then I can transplant it into the game proper. I hope that by doing so I will figure out the bits I don't fully comprehend.

Saturday, May 21, 2016

Quest for random numbers...

Now that I am happy with the general ball physics of the game I want to implement the next aspect - enemies. For this game I have this idea to mash-up breakout and a shoot'em'up / space invaders type game together. Player's goal is to destroy the enemies with the ball. The enemies alone don't attack the player's paddle, but instead make the game more difficult by producing glitch effects... but this post is not about that.

This post is about me basically wasting a whole day, because I was afraid to code. I spent the whole day today and a lot of yesterday NOT doing code, because I had no idea where to start. Like I know what I want for the enemies to work. I want them to spawn at random(ish) time at random(ish) place on the "board" and move about. Then I want to add collision between enemies and the ball and a way to destroy them. That's all.

But because I am a noob at programming I didn't even know how to generate random number in Lua! This small thing stopped me from doing any real work on the game for more than 24h. This is stupid!


I spent wasted some time looking for tutorials for "spawning enemies at random +lua" and similar shit, but generally I just avoided coding or anything related to it because this task of adding randomly spawning enemies seemed too complex for my meager skills. Then it suddenly occurred to me that I am not supposed to code it all at once. I have already broken down the task into smaller chunks, so what I need to do is to tackle one chunk at a time. This was an eye opener and something that I will need to remember if I ever get scared of coding again.

LEARNING TO LOOK FOR ANSWERS.

So now I had a manageable task in front of me: learn how to call random numbers, especially between two numbers (handy for coordinates between 0 and 127). I can do this.

Sadly the Pico-8 manual is not very newbie friendly right now, so it wasn't much help. It did give me the RND function, so I had a starting point. Next I just played different games on Pico-8 to see which one of them had randomized enemies and lookup the source code. This didn't help as much, because a lot of those games didn't have any comments explaining what is happening. It did give me some ideas though. Lastly I did something that I should have done much earlier, googled "+lua +rnd" - and this really broke me out of my code scare. I found couple websites that explained exactly how RND works. However, PICO-8 uses a custom version of Lua so I had to test it inside my game to see what does and doesn't work. This last part helped immensely, because it broke my temporary fear of coding. After all I only was testing one small thing. Nothing scary.

So, if you are a newbie like me, and you are stuck because you don't know how to proceed, do this:
  1. Break down the issue into small chunks. As small as you can. Think of everything that your program needs to do to make this thing happen. Write them down if it helps. Then try to implement them one by one.
  2. Lookup manuals and other documentation for the engine/framework you are working with to find out how to do each step. For me it was Pico-8 manual, that is still in very early stages and not overly helpful. But it doesn't matter. It can put you on the right track.
  3. Google what you need to know. Not the whole task, just the thing you are currently working on from your list of small chunks. Learn about that thing.
    1. If you are a Pico-8 user, lookup how others solved that problem. Get into that source code and try to understand it.
  4. Test. Implement something small to check how it works. Either as a new or inside your current program. If you are worried that you will mess up your code - don't. Just save a backup.
  5. Test it in a different way. Maybe expand your test to get you closer to your big goal or test some other aspect of what you learned from the steps 2 and 3.
  6. Test more, until you feel that you know what you are doing with this thing.
Now you can implement (at least a bit of) your code to solve the issue and you have, and you have learned something new in the process. Best of all, you managed to code something when it felt impossible. You got this.

EDIT:

Just my luck. Someone had a random number related question in the Pico-8 BBS as I was writing this post. Those answers would have helped me a lot. I guess I should be more open to asking for people's help even with my noob questions. But in the long run, maybe I am learning more by finding the answers on my own. Hmmm? Anyway, here's a small skeleton I made while I was NOT coding.