Monday, January 30, 2017

SUBstandard text framework

A TODO list for your features is actually really good tool to keep you focused. Who knew?

A week ago I was messing around with code, adding small things and fixing things that weren't really broken. After making that silly todo list I started cracking on designing the bosses (only on paper so far) and making the logic behind the 80s computer style, letter-by-letter, text printer so I can add more theme to the game through it. Also, because I hate myself, I added text wrapping so I don't have to split the text into multiple strings.

There are some much more sophisticated textbox solutions for Pico-8 here and here, but to work for my game they both would need a lot of tweaking of a code I didn't really understand and I thought it would be a good learning experience to write one from scratch. I managed to squeeze one in under 300 tokens.

The logic is a little janky, but works well enough for what I need. You can get it from the .png to the right, the BBS or check out the source and explanation below, but beware, it is a noobish code...but hey, it works.

Before I started writing this thing, I wasn't even aware of the SUB function. Fortunately, I stumbled upon in thanks to the fact that you can look up others' code and Pico-8 highlights built in functions. Then it was only a short trip to the Pico-8 wiki (which is a great resource btw) to learn what it is about. From that, making the printing letter-by-letter happen was pretty simple by using the SUB function with a simple timer (e.g print(sub(text,1,counter),x,y,col) counter+=1) The tricky part was making the text wrap and not split words and after a lot of trial and error I made a framework that works.

The framework comes in 4 functions. All the tbx_ functions need to be called in their respective Pico-8 functions (_init, _update and _draw) and you call the textbox function whenever you want to start a new text being printed. Because as it is now, the function only allows for one text to be printed at a time. You can change that by expanding on the tbx_lines table, by storing each new piece of text under an index. I didn't really need that for BIT.bash, and I wanted to keep the token count low.

function tbx_init()
 tbx_counter=1
 tbx_width=25 --characters not pixels
 tbx_lines={} --table that stores text in lines
 tbx_cur_line=1 --current line
 tbx_com_line=0 --completed lines
 tbx_text=nil --text to print
 tbx_x=nil --x to where printing starts
 tbx_y=nil --y to where printing starts
end


function tbx_update()
 if tbx_text!=nil then --don't call if there is no text
  --local variables for first and last letter
  local first=nil
  local last=nil
  --create enough rows to fit all the text
  local rows=flr(#tbx_text/tbx_width)+2 
 
 --split text into lines
  for i=1,rows do
   first =first or 1+i*tbx_width-tbx_width
   last = last or i*tbx_width
   
  --cut off incomplete words
  --check if the row's last letter and the one 
  --after that are not spaces
   if sub(tbx_text,last+1,last+1)!="" or sub(tbx_text,last,last)!=" " 
   and sub(tbx_text,last+1,last+1)!=" " then
    --if true then check where the word ends
    --by checking for space
    for j=1,tbx_width/3 do --
     if sub(tbx_text,last-j,last-j)==" " and i<rows then
      --once you find the space, cut off that
      --line at the space by changing last letter
      last=last-j
      --and end the function there
      break
     end
    end
   end
  
  --if first char is a space, remove the space
  if sub(tbx_text,first,first)==" " then
  --if first letter is space then move text
  --one to the left
   tbx_lines[i]=sub(tbx_text,first+1,last)
  else
   --otherwise, print as is.
   tbx_lines[i]=sub(tbx_text,first,last)
  end
   --jump to the next part of text to create 
   --new line by changing first and last vars
   first=last
   last=last+tbx_width
 end
 
 --lines are now made
 
 
 --change lines after finishing a line
 --when the counter is equal to line width
 if tbx_counter%tbx_width==0 and tbx_cur_line<#tbx_lines then
  tbx_com_line+=1
  tbx_cur_line+=1
  tbx_counter=1 --and reset counter  
 end

 --update text counter
 tbx_counter+=1
 --make it skip over spaces
 if (sub(tbx_text,tbx_counter,tbx_counter)=="") tbx_counter+=1
 end
end


function tbx_draw()
 if #tbx_lines>0 then 
  --print current line one char at a time
  print(sub(tbx_lines[tbx_cur_line],1,tbx_counter),tbx_x,tbx_y+tbx_cur_line*6-6,tbx_col)

 
  --print complete lines
  for i=0,tbx_com_line do
   if i>0 then
    print(tbx_lines[i],tbx_x,tbx_y+i*6-6,tbx_col)
   end
  end
 end 
end


function textbox(text,x,y,col)
 --x,y and col are optional
 tbx_init()
 tbx_x=x or 4
 tbx_y=y or 4 
 tbx_col=col or 7
 tbx_text=text
end

The whole thing looks pretty complicated, and I bet could be simplified (especially to remove some of those nested functions of doom), but I don't want to focus on that now. The purpose behind all of this is to finish and release BIT.bash. It already suffers from a serious case of spaghetti code, so I will focus on cleaner code for my next game.

Now it is time to add the rest of the cool text to the game (there will be some after finishing a level and for game over) and then moving to implementing the bosses (of which names and descriptions you can see in the gif above)!

Sunday, January 22, 2017

I've got a title! ...and a serious case of Feature Creep

Finally, my first game has a name: Bit.Bash!

My first game was just a breakout/arkanoid clone, but Bit.Bash evolved into more than that. It is  a game about breaking down corrupted data blocks to troubleshoot a computer in the 80s.  You play as the person who "jacks-in" into the malfunctioning computer and tries to fix it with this new software designed for recovering data by breaking up the corrupted sectors. Why such a theme? Because what pseudo-80s game doesn't need an outrageous theme! That's why!

It took me a loooooong time to come up with the title. I had the theme/backstory in mind almost from the very beginning, but no title. I wanted something that was reminiscent of both the brickbraker gameplay as well as the game's theme and art style.

So, I settled on using a computer term and a word somewhat connected with the gameplay and separated them by a dot (because computer file naming conventions!). I want to keep that formula for the rest of the games in the series, but we'll see how that will go. Oh yeah, I plan on making a series of games, all connected by the theme and the narrative, basically in the same universe. It is yet another vision of grandeur I have. I got so far without an idea about gamedev, so it is possible I will get there as well. That is, if I won't get lost in the limbo of...

Feature Creep

For the past days I was mostly working on the start screen above (which started with a tweetjam from electricgryphon) and some gameplay tweaks, when I should have been focusing on adding the big features. I think it seemed a little to overwhelming...again.

I just wanted to add too much stuff. At some point I decided that I need arkanoid style bosses and some moving enemies. After adding the title screen, I wanted flavor text. And, that was on top of a better random generator, multiball, redoing graphics, etc. I was suffering from a serious case of feature creep and I had to draw the line somewhere, otherwise, I would never finish my first game.

So, I decided to make a proper TODO list inside the file. I think it will be a jarring reminder to stay focused. To be honest, the game is playable from start to finish right now, but I think I can make it a bit better. After some thinking, I have narrowed the extra feature list down to three big things, and that's it. I am not allowing myself to add any more. I need to release this thing to the wild and let it be. This is the whole point of gamedev, right? Actually releasing a game.

After those three features the game will be done. Well, I also need to do sound, but I might ask someone to contribute music, and maybe the sounds if I am lucky. Learning the tracker might be something I need to learn next time...

For now I am diving back to Oli414's textbox library trying to change it so it works for my game.

Monday, January 9, 2017

[January Memory Dump]

This month was far from a good gamedev month. The holidays combined moving to a new place put a big strain on my free time.

Originally I wanted to have the powerups and bosses implemented by January. Powerups are semi-finished. The functions that control them are there complete and I am now happy with how they look. I just need to add few more powerups to the list of 6 I have now and maybe add an extra effect when they are picked up (especially the powerdowns, they could make the ball/paddle glitchy). The bosses on the other hand, only exist on paper right now and are not even complete there. I still need to sit down and think how to implement them into the existing framework. Then I need to think of how to make them fun; they need to use the same basic mechanic to be destroyed, but need to be different enough to make reaching them rewarding.

I hope I can finish those two soon. After that all I need is some small tweaks, an intro screen and that's it, the game would be complete (outside of sound, that I will probably need some help with anyway). Normally, there would be plenty of polish happening at the end of the project, but I have spent a lot of time making sure that each feature feels good to play as I was implementing it. I think that might save me from the limbo of the final 5% of the game being extra polish. From what I read this is where most gamedevs start experiencing burnout. Fingers crossed I can avoid it!

My urge to finish it is even greater after reading a devlog of another newbie coder - Alex Wiltshire of rockpapershotgun fame. He managed to finish his first game in a week - a timescale that puts my efforts to shame...

So, I now I really want to finish this game (damn, I still need to find a good title for it) and start another one. This breakout clone would be a part of a bigger narrative, that goes through different arcade-y/8bit genres to tell one big overarching story. It is a lofty goal for around 5 games culminating in a small RPG that will use the expanded version of the system I designed for the (yet to be released) Pico-zine #5.

Because I feel that this would be the biggest and the most complex game of the lot, I decided to start experimenting with some stuff for it early. I got Pyxel Edit from the recent Humble Bundle, so I started learning pixelart with Pico-8 restrictions in that program. I started by developing a somewhat post apocalyptic tileset:


The one on the left is my first attempt - a bit of Zelda inspired look. This evolved into the one on the right - a more bleak representation that fits with the idea of the game more. So far I have used over 40 tiles to create that. I will need to be careful about the amount of tiles I use, as there are only 128 8x8 tiles available if I don't use the shared memory. 

Anyway, just wanted to share the lats month's progress here. If you want to stay more up-to-date, I post a lot of smaller updates on Twitter. Now, back to those bosses...