x-post from Cemetech, horizontal lines indicate different posts
Earlier this year, I created a small TI-BASIC game that I creatively titled "Dodge". It's not a good enough game for me to release it into the archives, but it's relatively simple and fun. There are 6 rows of "dots" on the screen, and you can switch around rows. You get points for how many dots are on your row, but you lose if a dot makes it to the end of the row that you are on. (You have to switch rows to dodge
the dots) There's also a score multiplier/difficulty feature. Occasionally, some dots will not be shown (this is a bug, err, feature), so you have to look at the number in the top to see how many dots are on your row.
Here's a demonstration of that game: (Reminder, this is not a "released" program, it's buggy and stuff. It's also not the one being worked on in this thread.)
Now that I am learning Assembly, I think it would be fun to try and port this TI-BASIC game over. So that's what I'm doing.
I've shifted from a circular layout to a flatter layout, because it makes my math so much easier. I've also chosen to do 8 lines instead of six. I couldn't afford to do this in the TI-BASIC version because of speed, but here switching to 8 will actually make it faster because of how I plan to implement movement (I think it's really clever, I'm going to use circular bit shifts and then an [mono]and[/mono] instruction to check for collisions).
Here's the first actual screenshot:
This is a demonstration of how the game is going to look. The lines on the screen are debug features, I'll change them so they look better eventually.
The green dots are placeholders, too. I'm going to change them into piranha sprites later.
All of the rows on shown there are not random, they are just patterns I made to show off the drawing capabilities (I have checks to make sure that a row of 8 piranhas will never happen in-game). Each "piranha" is represented by one bit in memory (each row is a byte), so changing them is super easy.
I took that screenshot a few days go, when I started the project, I made all kinds of fun additions recently! Now, the screen will scroll with new rows being pseudorandomly (but deterministically, I want all games to be the same) generated on the fly.
Here's a new, updated screenshot:
I'm triggering the changes manually, but eventually it'll go on a clock, speeding up as you play more. This is opposed to the TI-BASIC game, because it generates more squares and goes slightly faster as you play, but this is a little tricky to do and I can make it just as difficult by speeding up more. All of the ones after the initial screen are generated pseudorandomly by a custom routine.
In the screenshot, the battery indicator is drawn and I happened to switch to the next row almost immediately after it did it. Apparently this is caused by the fact that I was using an OS routine (_GetKey) to add manual pauses between the redraws, so it won't be in the final program.
I don't think I'm going to release my source just yet, I want to get more of the core mechanics done first.
Since I wrote the above stuff, a lot has happened! I added player movement and the rows are now on a timer! I haven't done sprites for the player or the piranhas yet, but that is the next big step.
The program is about 450 bytes right now, but I think I can get this down quite a bit. It doesn't seem like a lot (to me, at least), but we don't have all of the features done yet. The sprites are probably going to be at least half of the whole program.
Huge update! I finished the player sprite and added him in to the game.
Here's the sprite I made for the player. His name is Robert, and he's adorable. :P
This is before I put him through convpng, we lose some detail in the hair afterwards, but I'm not going to go to 16bpp just because 8 pixels in the hair are weird.
I'm not entirely content with it and I'll probably change him a little eventually.
Here he is in situ
He's super tiny (this is a 2x scaled image so that you can actually see him without hurting your eyes). But it's fine, I'll probably scale him up programmatically so the piranhas aren't half his size.
I'm working on a three-frame running animation just for looks, too.
Conveniently (and intentionally) all three frames share the same upper part (only the legs/feet change) and are entirely reversible, so I can save almost 2.5kb (compared to having 3 full-body sprites for each direction) by writing a fun sprite routine.
TheLastMillennial expressed interest in IRC/SAX and in the cemetech thread to do the piranha sprite, so I'm letting him do that.
After a short break, I made a lot of progress today:
I added a functioning health bar and collision detection! I also added scoring, too, but you can't see what your score is (yet).
Obviously, the speed is a little fast, but I cranked it up for the screenshot. If run on-calc, there isn't as much flickering.
The black stuff on the top is just my laziness. I only draw the bar once will instead of each frame, so I don't erase it or the stuff around it. If I erase it all in the beginning it'll be all nice and white, but I'm not there yet.
I'm pretty terrible at the game when I play it on CEmu, as you can tell, but on-calc it is a lot easier :)
The code itself is 572 bytes, without the sprites and palette info. With the sprites and palette info it's 1172 bytes. I'm not too concerned about optimizing right now, I'm trying to get all of the main features in, but I think that I can save a hundred-ish bytes just by getting rid of repetitive code.
To-do (in order of expected completion):
Difficulty (speed gets faster as you play) completed! Score multiplier (as you play, this gradually increases, but when you lose health it resets.) completed! Custom font and some other sprites completed! Display score completed! Game balancing completed! Display multiplier completed!
- Highscores table
- Modify menu to include other options (adjust difficulty, view highscores)
- Maybe some other things?
Despite this decently-sized To-Do list, I think I'm about 50% done with the game. Most of the core mechanics are done and implemented. A lot of these features are already half-implemented and will be super easy to add because of good planning and foresight at the beginning. That planning step helps more than I anticipated, I should have listened earlier to all of the people who told me to plan my programs when I joined :P
Even though it just turned noon as I started writing this post, I've already made some pretty awesome improvements.
We are switching from fish to snails, for three main reasons:
- TheLastMillennial tried his best to make me a piranha sprite, but the result didn't, uhh, look al dente yes, I know I am using that term wrong, that's the point. (I couldn't make one better... I guess this might have been a bit much x.x)
- I decided that I am decent at drawing snails (despite never drawing a pixel art snail in my life) and created the sprite below.
- It's funnier that way
It's not too bad (I don't think), but I do want to do some shading on the shell, and make the overall sprite larger.
Here it is in-game (the black dots at the top are debug things, don't worry)
I also added the score multiplier and difficulty increase, it gets gradually faster as you play. In order to make the game not insanely fast too quickly, you start rather slow. (I might change some of my formulae so that this doesn't have to happen)
I'm super excited about releasing this. I think I'll work on my font today, I'm thinking about making a slimey font, as if it was traced by the path of a snail :)
Looking good! The circular layout looked really interesting and polished, but I'm still interested to see how you make the linear layout work. I like the sprites a lot!
A bit of a double post, but this is a huge update! I created and added a font!
I'm cheating a little bit and only implementing the 25 characters I need:
[size=0px]sorry that the image says " h o t s e x " that's entirely unintentional and a coincidence, and I don't have the time/can't be bothered to fix it. If someone takes offense to it I will change it on-the-spot.[/size]
I'm going for a loopy and twisted font that avoids straight lines and perfect circles. I love the way it turned out. If I get the time, I might do the whole alphabet (I can do a character in like 30 seconds, it's not that hard with this style), and create a nice font for other assembly programmers to use and modify.
I think the lowercase "f" and the "9" are a bit too closed, and the 0 looks a bit like a theta, but besides that, it looks great. Each character has 1 pixel of spacing on both sides (it's not monospaced) and the space character is 4 pixels wide.
I'm doing some pretty awesome compression (each bit in the font data part of the program is one pixel, and it's all uncompressed when the program starts in a fraction of a second) that lets me save over 3500 bytes. My font-drawing routine is relatively fast and small, but I can probably get it smaller and faster with a little bit of coercing.
Huge, huge progress!
Today, I wrote a slow, huge, complicated, and unreadable
font routine that can render strings in the above glorious font! The strings are converted into a semi-machine-readable format (read: a format only the most idiotic of idiots would use) using a small converter I wrote, then plopped into my program!
I think the output is fantastic, as you can tell by the very large banner at the top of this post.
On IRC/SAX, some users (namely Kerm and LAX18) expressed interest in me letting this font be used by the OS.
I think this is a great idea, because it would give the OS a much-needed usability decrease! I'll definitely keep this in the back of my head as I continue the program.
I plan on finishing the font (we only have the above 25 characters currently) and making it open source so others can suffer the same pain I am.
The font routine itself is a good 100 bytes, and it compounds this huge size with a lack of speed. I think I accidentally confused "obfuscation" and "optimization", because it's pretty unreadable.
No matter how much I make fun of the routine, I am very proud of it. I spent pretty much my whole day working out kinks in the routine and fixing bugs, and the intense problem-solving made it both extremely rewarding and enjoyable.
Unfortunately, I had to change how I am storing my font data. Each character takes up the same amount of space in memory, but the font is not monospaced. I just add padding to each character so that each one is exactly 17 bytes (Even though 16 is much easier to do for various reasons, I chose 17 because the character with the highest byte count had 17 bytes. It's just easier over all). This is good because it makes the code more readable, and I get to skip a second lookup table (I'm using one for the character widths) that would limit the number of chars we can store.
All of the numbers are monospaced, so I'm going to create a second, simpler font routine to draw them.
This is a huge milestone, because now I can progress with the game slightly obscure pun intended
and make my menus and a scoreboard.
The game isn't completely planned out, and I still want suggestions from you guys. What do you want to see? Do you have any tips/algorithm improvements? I'm waiting to release the source code until I polish it up a little bit, it's very messy and not something I want to share quite yet.
More progress has been made! I created a version of my font routine that is optimized for drawing numbers, and here you can see it drawing a small counter. It's blazing fast: this is with a dummy loop that runs 8 thousand times
slowing it down. I don't show this in the gif, but it pads the start with zeros if it needs to.
This will let me draw the score and do many other things, so I'm super excited!
It won't be too hard to make it draw the score and multiplier. The routine that draws the text can "chain" the position where it left off into this routine (and vice versa), so that I can draw some text, then draw a number, then draw some more text.
Using my skills of uncommenting sections of code that I wrote a while ago (this routine's inputs have been planned out for quite some time now), I added the code that draws the score (difficulty was vastly increased for the sake of brevity):
I've decided that I'm going to reduce the number of rows that are on the screen, it's too cluttered, and you gain points far too fast.
Today I got the menu to the point where I think I can show it off.
Here's the first screenshot of the menu:
It's very bland right now, but I'm adding icons and stuff soon!
The options don't work yet (both lead to the game), but it won't be too hard for me to add this functionality soon.
This was a lot of work, surprisingly. The menu routine itself is quite large, but it'll be able to be used with multiple menus in the game.
I'm running into the problem that I didn't implement all of the characters early on, so I have to add characters as I need them.
Mega-update (a.k.a. I forgot to crosspost, sorry)
I did all kinds of awesome things yesterday!
I eliminated all kinds of bugs that were present. This took a long time, as most of these bugs seemed to be caused by something that wasn't actually causing them. (i.e. all of the evidence pointed to my RNG routine modifying some internal variables, but it was actually because I deleted a few extra lines of code while trying to remove a comment).
I decided to make the menu options titlecase, only because I'm lazy and making them all uppercase would make me add 3 chars instead of 1 :)
I also added the code to draw in the multiplier. It pads the score to a length of 4, but I'm working on modifying my score-drawing routine so it only pads it to 2.
I also made the menu options functional! Before, both options would lead to "playing".
Here's a gif showing all of the changes I made today!
We are really close to release! I hope to have this project done before school starts for me on the 30th.
Mateo suggested that I make the snails "crawl" towards the player instead of "jumping". This is a fantastic idea, so I implemented it.
Here's what it looks like: (this is very slow, but the speed is easily adjustable)
I've decided that the snails at the top are going to do a little attack animation (I'll shift them up quickly, then shift them back down, to make it look like they are biting or whatever), then I'll make them fly out to the left.
The new snails coming in from the bottom will quickly fly in from the bottom in their own animation. I can't gradually make them slide in without lots of changes to my code, because I calculate the new snail row after the shifting is done.
I redid my timer code. Before I had one timer, but now I have two timers. The first one is the time between the shifting up of the snails. When it completes, I decrement the second timer, which is the time between new snail rows and eventually the animations.
I might try to stagger the movement of the snails within each row so it looks more realistic, but that's a lot of work.
Thank you so much Mateo, this suggestion made this game look a lot better! :)
Today (well, yesterday as I am posting this), I worked on the above animations!
I'm no longer afraid of doing more complex graphics, because I actually can work through most of the problems I encounter which is super awesome. There are still problems that evade me, though, but I can usually get around them with a bit of refactoring and duck tape.
I'm not going to post the animation just yet (it's very much not done and extremely buggy), but it looks awesome even if it is sped up a good 700 times (not CEmu's fault) for reasons I can't discern... But if you step through the code while looking on the memory viewer, it's pretty nice.
I've decided that I'm going to optimize the program for size, considering that a significant portion of my code is dedicated to slowing the darn thing down so it's even visible. I'm down to 1295 bytes (code only, no sprites or font) right now, but there are numerous unnecessary jumps and several sections of repeated code.
So I unfortunately did not have time to work on this project for quite some time (family/irl stuff), but I've made good use of the time I had today!
I fixed the timing stuff and added the part of the animation that makes the snails fly out! Here, check it out:half-way through the gif I'm like "this is never going to end x.x"
The gif shows off almost all of the features added so far, including the multiplier and how it gets reset if you run into anything. The game looks pretty sweet right now! I want to work on optimizations now, my code is getting quite large. My code is 1378 bytes from these additions, and after some optimizations I made during the writing of this post I got it down 20 bytes. I'm sure that with some more effort I could lop off more bytes.
This is really the first time I've been able to play the game, and it's a ton of fun. (I'm not saying this because I wrote it, either. I genuinely found it enjoyable) It's fast paced, but not too fast (for a while at least).
I might try to get the up and down animations more visible. I don't like how fast they are.
There's also a bit of a glitch in the beginning where it plays the animation sequence (you can't see it, but it's running the code) before it draws the snails, causing a uncomfortable wait. This is fixable and shouldn't take too long.
Here, have a public beta. You can download the current program from here (https://bit.ly/2NhlzJP)!
Be sure to back you calc up (emulator highly recommended). There shouldn't be any major bugs, but my debugging/testing is in no way complete. also don't reverse-engineer my code from the decompiled binary unless you want a major headache, just wait for the source
You can find a features list somewhere above, I'm too lazy to write down everything I've done.
I'm not releasing my source just yet, I want to have the time to optimize by myself before all of my code is compressed down into some unimaginably tiny space.
Attack of the Snails was accepted into the archives!
Check it out! (http://cemete.ch/DL1791)
The source code is available on GitHub (https://github.com/Legend-of-iPhoenix/Attack-of-the-Snails) for your enjoyment (and pain), so go check that out if you have the time and endurance.
Congrats! I'm glad you finally got it released. At some point, think about making a sequel with the layout similar to the unreleased program that inspired you -- that one looked really cool!