Thursday, December 22, 2016

Title Screen

What I really need is a title screen.  I don't have tons of graphics rom space left (this game is using the most simple, primitive cartridge setup, with very minimal graphics space), but I'm sure I can come up with something better looking than this.  I just don't have much inspiration, or confidence that I can make something that looks cool, given the limitations I have.

Pay no attention to the green background on the small "press start" subtext.
That's just a palette issue that I haven't fixed yet.


That being said, it's close to being done!   My todo list is down to only minor things: adding a scoreboard between rounds, adding additional music (the single song is going to get pretty annoying!), improving title screen and player-select screen UI, etc.

Oh, and testing, tweaking, and testing, testing, testing.

Saturday, December 17, 2016

Testing the fun

Well, it's been about a month since my last post. I haven't said much.  Partially because I haven't done much.  Another consulting gig has kept me busy.  But also what I have been doing is mostly uneventful things that I haven't felt like talking about.

Getting a per-round splash screen working, getting different graphics and palettes for different rounds, etc.

But I did decide it's far enough along to actually start play-testing the fun.  Before I get much further, I need to know if I'm remotely on the right track.  First I got a coworker to play a 2 player match with me just to see if it seemed playable.  Despite some bugs, that worked out ok.

Tonight I made my family play with me.  My son (8) loved it. My daughter and wife put up with it.  That was a better test.  We found a few bugs and confusing things, but it seemed like there might possibly be some fun involved.  (Although the girls didn't exactly play competitively) I still need to get a few people that actually LIKE video games to come over and test and see how it plays.

So far it seems.....ok enough.  Not amazingly exciting (which I hoped) or completely boring (which I feared) or just completely broken (which seemed possible).  It's really hard to design a really exciting party-style game, so I'm fine with "ok" for my first shot at it.

Time to make some tweaks, fix a few bugs, then hopefully recruit some testers over the Christmas break....

Friday, November 18, 2016

Making the game fun

The real trick for Spacey McRacey (as I'm calling it now) is going to be making it fun.  And that's what I'm rather unsure about at this point.

I have a game design that basically works. The technical issues are mostly sorted out, I just need to get a few more implemented before I can seriously play test it.

But fun? It's hard to know if it's actually going to be any fun to play.  With a 4-player party-style game, it's seems like it might be hard to hit that fine line where everyone is close and competing, where everything feels exciting and tense, as opposed to tedious and boring.  And despite envisioning my game as fun, it might just be boring to play.

Some of that comes down to tweaking it. Tweaking the speeds, difficulties, etc, will make a difference. (If it's too easy to shoot people from behind, then it will be nearly impossible to hold a lead for very long, which could ruin it and make it no fun. If it's too hard to kill the guy in front, it will be tedious the other way. If the barriers are too hard to dodge, then players won't have any attention left to fighting each other, which will be boring.  If they are too easy, then they will be pointless, and it will just be a shoot-em-up)

So I'm really looking forward to getting a bit more done, and then conscripting some friends to come over and spend an hour or two playing it.  I might need to have multiple builds ready that night, with slight variations in the timings and speeds and difficulties, to see which works the best.


The Theory of Fun and books about game design

I got a book out of my local library called Theory of Fun for Game Design which is (or is supposed to be) all about this concept. I was a bit disappointed. I thought it would give some good principals for coming up with a good game design.  But it really didn't.  It was mostly fluffy stuff about how the author thinks about games from a theoretical point of view, but didn't really have anything practical.   We have another book in our library called The Art of Game Design which I read once years ago (it was checked out when I recently went looking for it), and is a MUCH better resource about this topic. I don't really remember much about it, but I remember being really inspired to try to make something fun after reading it.

Thursday, November 17, 2016

Killer Queen

So at PRGE, I played an arcade game that just left me amazed.  Killer Queen.

It's a 10-player game. You have 2 cabinets linked together, and 5 players huddled on each one. Each one is a team of 5 people, working together to play a simple one-screen 2d platformer.  But what made it work was the high quality game design.
I'm not sure it would be as fun with only 4 people instead of 10.

First, the game is relatively simple, yet there is a lot going on at once.  One player plays the queen, the most important and powerful character on the team. The others start as workers, but can become warriors who can fly around and attack in a very joust-like flappy contest of height.  The real trick is that there are three completely different ways to win: either collect a bunch of berries and bring them back to your base, or ride a REALLY SLOW snail across the screen (while other people try to kill you, and you hope your team protects you), or kill the enemy queen 3 times.  There's some other things going on as well (using berries to upgrade, capturing upgrade points with the queen, etc), which means there's a lot going on at once.




The joy of it is that it really pulls you together as a team in a super fun and exciting way.  You'd jump into a game with a bunch of strangers, but suddenly you're talking back and forth (in close proximity as you're squeezed around a tight arcade setup) about what everyone needs to do, how to stop the other team, etc.  My description doesn't really do it justice -- the game is so simple, yet did such an amazing job of pulling in people to work together and have fun.

My only complaint is how hard it is to find a way to play the game. There's only a handful of the machines made, and no way to play it other than to go somewhere that has it.  I keep daydreaming of somehow coming up with a way to buy one and put it somewhere in my town, because I was so impressed with the game design.  There's just very few times you play a game where they nailed the game design so perfectly.

Really, I'm jealous that I didn't think of it. Any programmer could make a clone really easy. But to come up with the design like that that worked so well?  Sigh.

Tuesday, November 8, 2016

PRGE

I couple weeks ago I had the chance to go out to the Portland Retro Games Expo, where Al from AtariAge had Anguna set up to demo.



What an amazing time. I could talk for a long time about how cool it was, but a few highlights:



  • Getting to see my game on display, and see people try it out
  • Meeting people who had played previously Anguna and enjoyed it
  • Meeting other homebrewers that I've interacted with on the forums
  • Hearing from and talking to the developers of the old original Atari games, hearing about what it was like to make those games, and how they dealt with many of the exact same technical issues that I do now.  (At one talk, they started drawing out how the display kernels work, and talking about how you can use the RESP0 register to set up your kernel to reuse sprites on multiple scanlines....I'm not sure how many people in the crowd enjoyed that level of technical detail, but I had a blast)
  • Playing Killer Queen, a ridiculously well-designed 10-player arcade game.  I'm going to post my thoughts about that game at some point, but I was blown away by what they accomplished with it.
  • Meeting up with my friend Tim Lapetino, author of the awesome new Art of Atari book

Atari Anguna is finished at this point, I'm waiting for some art, and then I'll declare it officially "released"  whenever we get a chance to release the cartridge through Atari Age!


That's Howard Scott Warshaw.
The genius behind Raiders of the Lost Ark, Yars Revenge, and E.T.

Sunday, October 16, 2016

Titles

Thanks for the title suggestions everyone!

The 3 suggestions that I like the best were:

  • Pew Pew Pew
  • Reginald McGillicutty's Big Boom Blast Party
  • Spacey McRacey

After some thought, I decided:

Pew Pew Pew just isn't google-able enough. There's too many cultural references to "Pew Pew Pew" nowadays, which will make my game get buried even if people are looking for it. And alternative spellings (someone suggested Pew Pue Pu) are just too weird.

Reginald McGillicutty blah blah blah....I love this one from author Jeffrey Aaron Miller. What disqualifies it is really the format of the game required for the game competition I'm hoping to enter with this. The requirements of the game use a NES cartridge format that's quite limited in video ROM, which means I have to share space between the title screen and gameplay.  Which means I can't spend a ton on a giant fancy title screen. (Unless I'm misunderstanding the specs of the format, which is quite possible).  

Which leaves Spacey McRacey. Which is what I'll go with for now until something changes my mind otherwise.




Tonight's work was the "start game" screen (not the title screen), where players push start to register that they're in the game. (since it's a 4 player game).  Mostly, that involves drawing 4 big frames on the screen that each say "press start".  So I've been working on a reusable routine for drawing frames on the screen of arbitrary size and location.  

That's a task that should be pretty easy. But with the limitations of the 6502 combined with the oddities of how the NES handles background data updates, it's slightly more complicated that intuition would lead you to believe (to write any given chunk of background tiles, you have spend 4 instructions telling it what tile address you want to write to, then serially write data to a register, which is great for horizontal or vertical stripes, but annoying for an arbitrary rectangle in the middle of the screen, as you have to keep re-positioning the address register).

Anyway, it's getting there!

Saturday, October 8, 2016

Rapid Progress

I told my office-mate that if I ever finished that background mess, I'd start making much faster progress.  And it turned out to be true.

Earlier this week, I decided it was time to look at audio engines. I understand the concept of how audio engines work on the nes, but I just don't want to take the time to build one myself.  After trying out a couple of them, I found one that integrated really easily, and lets you play music imported from the popular famitracker format. After digging around, I found some interesting famitracker compositions under a Creative Commons license from a guy that goes by Ozzed.net. Turned out to be a really nice guy and was helpful in providing me info to get some of his music integrated into the game. So now I have background music!

The next steps were collision checking, explosions, and player bullets. No problems there!  Most of that is pretty simple stuff, or would be in C. In assembly, it's a little more error-prone and slower-going, but not substantially more difficult: the logic is the same, but at a lower level. In just a few hours of work this week, I've those things all working!  (Well, there's still a bug where if a barrier's gap isn't aligned on a 16-pixel boundary, my collisions don't work quite right. Should be easy to fix though).

At this point, it's quickly starting to take shape!  I just need to add the points system, and suddenly the skeleton of the game is complete.  Then comes the fun part: adding the actual polish.

This includes:

1. Title screen and screen to select number of players
2. Sound effects
3. More interesting background graphics behind the barriers
4. Powerups
5. Different rounds with slightly different behavior

The last one needs a little more explanation.  The first round will be straightforward, with no tricks.  To keep it interesting, subsequent rounds will have a theme, such as:

  • Speed round (everything is super fast)
  • Battle round (the barriers are spaced out more easily, but everyone is maxed out with all sorts of weaponry, and you also gain points for kills)
  • Collision round (touching other players kills you)
  • Survival round (you lose points for dying)
  • (and I'm trying to think of other similar ideas)

That all being said, send me ideas for a title. I'm serious, I need help with this.

Monday, October 3, 2016

PRGE, and I need a name

It's been awhile since I posted anything here!

First off, Anguna 2600 is pretty much done. I'm currently in the process of working on some promo material for the Portland Retro Game Expo, where we'll be showing off the game at the AtariAge booth.  I'm excited to be in a giant room full of people that are into retro-gaming, and have my game on display.  Should be a fun time.

I'm still slowly working on the nes game I talked about. I got hung up for awhile on displaying the barriers. I just kept running into bugs trying to get the game model to work right, then have it render properly based on the game model.  Part of it was scrolling -- the game has the appearance of scrolling through a world, but because the 6502 is only an 8-bit processor, I didn't feel like doing the math to track giant scroll values. So it's somewhat fake in terms of in-memory model.  The barriers move, the player stays motionless.  But because the nes background register is scrolling, (and it thinks that the top of the screen is 32 pixels off because of my top status bar), and because of mistakes I made while using fixed point path, and because the vertical resolution wraps at 240 pixels instead of the nice 256, I kept getting my math slightly off.

(it would have been easier if I just decided it scrolled 1 pixel per frame, so I'd know that every few frames, we'd hit an exact 8-pixel boundary, and would know to draw the next tiles. But because I'm scrolling by a variable amount (using fractional fixed-point math), it's more work to know when I cross that boundary.

Anyway, I FINALLY just threw away most of my background code and sat down with a pencil and paper and worked all the numbers out on paper, then re-coded it to match my paper-work. It worked much better when I did that.

Once that was out of the way (ok, I'm lying somewhat...I still have some issues with the background palettes, but I'll tackle that math later), I've finally got back to some of the game logic -- player collisions, etc. Fun stuff.  Today it was adding explosions and resetting the player position when you hit a wall:


It's actually started to vaguely resemble a real game at this point.

Next up: I need a title.  It's a party game with spaceships racing through barriers. My first thought was "Space Jam" until I remembered that that was that terrible movie with Michael Jordan. (Ok, I never saw it. Maybe it was actually awesome?)  I need a name.  And eventually a cool title screen to go with it.  Any suggestions?

Monday, September 5, 2016

Backgrounds and debugging

One of the hard things. Ok, so far the ONLY hard thing about NES development is how the background tile maps work.  In theory, they're pretty simple -- a big array of memory where you write a tile number, and the PPU (the video chip) draws that tile at that position.

But there's so many little gotchas:


  • The nes addresses 4 different screens' worth of data, but by default only has ram for 2 of them. So unless you provide more RAM on the cartridge, you set up (via actual wiring on the cartridge!) mirroring where data is duplicated between screens. 
  • The screen nicely pans and wraps between screens'-worth of background data. Except that there's only 240 tiles high, so you have to do math instead of letting bytes just wrap around
  • Setting color palettes for tiles is painful -- you do it in a separate block of memory, mapped in a funky way where you map 4 tiles to 2 bits of a particular byte.  Which means you have to do odd math to work out how to change colors of backgrounds.
  • Mid-screen scroll changes are weird.  To do a header bar, many games will switch scroll positions after the header (since there aren't layered backgrounds). But switching scrolling mid-frame requires more weird math, because you can't just write to the scroll registers like normal -- you have to do weird gymnastics with the various PPU registers instead.
It's not horrible, but it's driving me a little crazy. Really, I just wish I had better debugging tools. I got really used to Stella (the Atari emulator)'s quirky debugger, and realized how awesome it was. The nintendo debuggers I've used just aren't nearly as usable, at least with my current level of experience with them.

This is a debugging diagram of the four screens of data. I'm mirroring vertically, so the top and bottom are cloned.
The left half is my game background. The right half is the header bar.
Each frame, I start by telling the NES to set the scroll to where the header bar is.
Once it's drawn, I reset the scrolling to point to the correct position on the left half.


I finally broke down today and wrote routines for my game that let me do some primitive on-screen debug messages, displaying decimal versions of values using the player score headers. That will help, I hope.

Tuesday, August 23, 2016

Atari vs NES

It's really interesting to me the differences and similarities between Atari and NES programming. They both use the same 6502 processor (well, a variation on the same processor -- the Atari's is missing a few address lines, and the NES is missing a BCD mode), clocked at similar speeds (the nes is about 50% faster).

But beyond that, things start to diverge.  The most interesting to me is fundamentally where things happen, based on how their video chips work.

On the Atari, the video chip (the TIA) is designed to handle a scanline at a time. Which means that, like I've mentioned before, the whole time your TV is drawing, you spend that time babysitting the process, using all your processing time updating each scanline.  Then during vblank (the time the TV is repositioning the electron beam), you get to hurry and do your game logic updates.

On the NES, it's practically the opposite. The video chip (the PPU) is designed to handle a whole frame at a time (GASP!).  So during rendering, unless you're doing any fancy effects, you get all that time free to do your game logic updates, while the PPU does its thing in the background. Then during vblank, you hurry to push new data to the PPU so its ready for the next frame.

There's still hurrying involved in the NES -- there can be a lot of data that you want to shove into the PPU (new tiles for scrolling, etc), and not a lot of time to do it (most video data has to passed to the PPU over a janky serial interface, written one byte at a time), but compared to the Atari, I feel like I have EONS of time to work with.

It also helps having more RAM than I know what to do with. The Atari had 128 bytes. The NES has 2048 bytes. (Two whole kilobytes!)  It's crazy town.

There's still some challenges. Talking to the PPU is weird, you're limited to only 8 sprites per scanline, mid-screen scrolling (ie if you want to add a status bar) is tricky.  But so far, it's a different world.

Sunday, August 7, 2016

NES Game and LiveCoding

Well, I started messing around with making a NES game. I'm not sure I'm ready to tackle another big project right now, and there's still bits of work to be done with Atari Anguna (mostly fixing bugs as they get reported, then getting it ready for production), so I'm doing a little project:  sort of a simple 4-player space race game.

Tonight's tasks was writing the code to support the 4-player adapter, and scrolling the starfield.


The fun part is that I thought I'd try LiveCoding it, which is basically where you live stream yourself writing code and explaining it as you do.  I've tried this for the past 3 nights.  It's a really weird experience.

First, I don't know why anybody would want to watch someone code. I mean, at least watching someone stream video games is interesting because there's a lot of action. Coding is mostly thinking and typing.

Second, it's REALLY HARD.  Now I'm trying to do all my thinking out loud. Which is a really weird process.  Everything feels blurry and sluggish in my head. I feel like I'm not coding well, and not explaining well.  Maybe it gets easier, I don't know.  Then on top of that, trying to actually be somewhat entertaining while coding and talking?  Yeah right.

Third, I'm used to writing my hobby game code in the late evenings, as a way to sort of wind down. Only this doesn't wind me down, it winds me up. I've been finishing a bit after 11, and I'm all jittery and high-strung. There's just no way I can go to bed after spending an hour performing for strangers on the internet.  And I can't really do it sitting next to my wife on the couch as she watches TV, which is normally where the coding happens.

So I don't know how long this will last. On the one hand, it's tons of fun, because I have an audience. On the other, it's exhausting.  But hey, I might as well have fun with it for now.



Friday, July 29, 2016

Finished world map

Well, I'm still making a few tweaks (the most recent was based on feedback that the off-centered sword was annoying, so I made the sword centered by default, but let you use the difficulty switches to change it back to the old off-centered setting), but thought I'd share the final finished world map:


Sunday, July 24, 2016

Beta Testing Time!

Ok, Anguna 2600 is ready for some testing!  I'm looking for testers to try playing the game (either in an emulator, or on an actual Atari with a Harmony cart or similar device), and let me know what bugs and issues you find!

The main features aren't likely to change at this point, but I'm looking to fix any bugs and possibly tweak the game difficulty.

You can download the instruction manual and current build from this post on AtariAge.  Please email me (nathantolbert at gmail) or leave comments if you find any bugs or issues.  If you find any problems that I fix, I'll also credit you in the instruction manual if you'd like, if so, let me know how I should credit you.


Next steps:

  • My friend Tim Lapetino, author of the upcoming Art of Atari book, is designing art for the cartridge label (hopefully to be re-used on the manual as well).
  • I'll be updating the game and manual to fix any issues found during the beta test
  • Hopefully later this fall, if all goes well, everything will be finished, and I'll do a cartridge release through the AtariAge store.



Tuesday, July 19, 2016

First full playthrough finished!

When I get near the end of a video game release, I have this phase. Where I play through the game, fix all the bugs I found, play through it again, fix all the bugs I found, play through it again....and so on....until I finally play through and don't find any new bugs.  (I've done this before)

It's somewhat miserable. But here we go again.

I finished the first full-playthrough tonight. Fixed a ton of bugs. Tomorrow I need to do another full playthrough, and then attempt a full playthrough on the actual Atari (which I'm not sure if I'll pull off, because my Atari controller is in poor enough shape that it will be really painful to go through the whole game!)

For anyone that wants to try the always-newest build and help me test, you can grab it from my jenkins server, which I'll be happy to email you the address to.....


Sunday, July 10, 2016

Tons O Bugs

Well, my friend Daniel (AmishHack3r on Twitch) decided to give my game a try. And let me tell you folks, this guy is an amazing tester.

He found ALL SORTS of bugs for me. And diligently recorded video of each one, made drawings on a map of areas with glitches, and so on.  I couldn't ask for a better tester, thanks Daniel!

That being said, I have a lot to fix!

Thursday, June 9, 2016

Getting close to done

I've been quiet here, because at any given point, playing Overwatch has sounded more fun than blogging about my game.

That being said, I've finished a preliminary "first draft" of the game, and on my first quarter of a playthrough, I've discovered quite a handful of little bugs. Mostly minor things (a couple screens where enemies glitch out, the reset switch not working exactly right, etc), but a few might take a little bit of work.

After this playthrough and testing round, then I get to play through it AGAIN, fixing any bugs along the way. When that's done, it's time for a sort of beta test, and hand it out to anyone willing to test it.  Once I get the bugs fixed that others discover, it's time to call it good!

Monday, May 23, 2016

Updated Map (Spoiler alert)

I've been chugging along filling out content, and getting really close to being finished!

Tonight I added a bunch more rooms, then realized that I really need a few more room layouts for variety. With some playing around, I was able to create 3 new room layouts using the existing graphic chunks, only rearranged slightly. So each of these layouts only requires 4 bytes of rom space each, instead of the 75 that I'd normally need!  I haven't added them in yet, I'll need to go back and replace some other rooms.

Until then, here's the current map! Just a few white spaces left to fill in!


Monday, May 16, 2016

Overworld finished!

As the title says, I finished the overworld tonight. 45 out of 196 rooms left to go (dungeons 4 and 5).

I don't have an updated map to show yet (I updated the engine by 1 scanline, so my new screenshots don't exactly match the old, I need to update my script that crops and adjusts them before I can get the new rooms on the graphical map).

I'm at the point now though, where every bug that gets fixed requires searching through old code to find places I can optimize a few bytes away. Fun times.

Friday, May 13, 2016

Optimizing space, adding a switch.

Thanks to the nice folks at AtariAge, I got some feedback, mostly about various bugs, which have been cleaned up.  Now I'm trying to power through and add the rest of the content. Which is tricky, because I just don't have that much space left.

The biggest area of concern right now is enemies.  My space left in the bank where I store enemy data is small. Just a couple hundred bytes.  And I needed to add definitions for at LEAST 3 more enemies (bosses for the next 3 dungeons). And hopefully, another 3 or so more general enemies, so the 2nd half of the game isn't completely boring.

The first order of business was to read through the existing enemy definition code, and start optimizing. The first few enemy functions were unnecessarily huge. The amount of code for the slime and toady were just silly. I managed to compact it all a little bit, and squeezed in the 3 boss monsters.

Without much space left, the next 2 enemies were just palette/graphic swaps with more HP/Damage of previous enemies.

But one thing I wanted to add in dungeon 3 was a switch that controlled doors. How could I manage that with only about 10 bytes left?  I'm handling it like an enemy (it's a non-player object, and enemies are the only things I have in that category). The first hurdle was that my index that points to the enemy definition overflowed.

I have my enemies laid out in a big block of data, one after another:
EnemyDefSlime
    .byte #<SlimeFrame0
    .byte #>SlimeFrame0             
    .byte #<SlimeFrame1
    .byte #>SlimeFrame1             
    .byte #8                        ;sprite height
    .byte #$86                      ;color
    .byte #<EnemySlimeUpdate
    .byte #>EnemySlimeUpdate
    .byte #1                        ;hp
    .byte #1                        ;damage
    .byte #ENEMY_SIZE_NORMAL


EnemyDefGreenSlime
    .byte #&lt;SlimeFrame0
    .byte #>SlimeFrame0             
    .byte #&lt;SlimeFrame1
    .byte #>SlimeFrame1             
    .byte #8                        ;sprite height
    .byte #$D8                      ;color
    .byte #<EnemyGreenSlimeUpdate
    .byte #>EnemyGreenSlimeUpdate
    .byte #1                        ;hp
    .byte #1                        ;damage
    .byte #ENEMY_SIZE_NORMAL

Actually, on the 6502, this is a pretty inefficient way of laying out data, which I'll talk about another data. But anyway, for each room, I store an index of which enemy type we're dealing with (ie #0 for slime, 1 for Green Slime). Then I multiply that number by 11 (the number of bytes per enemy), add it to the address of EnemyDefSlime, and we have the address of our enemy definition.

But the switch was my 24th enemy. 24 times 11 is 264. (do you see where I'm going with this?) The 8 bit number I used to track the index overflowed.  

Well, I really didn't want to switch to a 16 bit number for this (math beyond 8 bits is a hassle on the 6502), so I ended doing a one-off hack, and hardcoding a special case for #24 to just go to the right definition.

The update code for the switch was tiny, and I managed to squeeze it in by doing another optimization pass at my other enemies.  But now I needed to add code in the door handler to open/close the doors based on my switch.  But my bank that handled that logic was also full. So I ended up moving a bunch of code to my kernel/graphics bank to free up space in my main bank.

Long story short (too late), I got it working. I have exactly 0 bytes of space remaining in my allocated enemy area, and 1 byte left in my main bank.  I still have 200 bytes of space in the graphic bank and the room definitions bank, so there's a TINY bit of wiggle room left.

But not much.  Let's hope I don't find any other bugs, or come up with any other crazy things that I feel I need to add.


Edit: Oh no, I just realized that I forgot to actually implement the power increase that happens when you find the power ring item. That would only be about 5 bytes, but it needs to be in the main bank. Sigh.

Tuesday, May 3, 2016

Looking for feedback

I've posted a build of Anguna on AtariAge, with most of the code of the game finished, and about 1/2 the world done.  At this point, I'm looking for people to try it and give feedback. Does it work? Is it fun?  Are there major issues with it?



If you have time and an Atari emulator, let me know what you think. Thanks!

Monday, April 18, 2016

Prepping for 1/2-finished demo

As far as I can think of, I've finished all of the major features of the game now, so mostly what's left is mapping out new rooms, and making new enemies.  I've finished the entire eastern-half of the world map (including dungeons 1 and 2), and so my next goal is to get it all cleaned up, and post another demo on AtariAge to try to get feedback from the fellow Atari nerds.

This week I've been trying to clean up the most obvious bugs, so I can then go back and do some actual play-through tests myself. (I've played through the first dungeon a number of times, but haven't yet played through all the content that I have in sequence -- I just change the starting room to whatever room I'm currently working on).

Things on my radar this week for fixing:

  • When you die, it should automatically select "continue" instead of "start" on the title, so you don't inadvertently start over.
  • Right now, the mechanism for restarting in whatever respawn location you've reached doesn't work - you always start in the first starting room
  • Based on some feedback on AtariAge, I made the first blue slimes a little easier, and made all enemies have a minor "bounce-back" when you attack them.
  • From all y'all's feedback, I've added experience and level-ups. Right now, it's simply based on the average of the enemy's HP and attack power, so I don't have to add another stat for each enemy.


There's still a few minor things: some glitchy stuff where the ball object gets displayed on the title screen, the subscreen doesn't work right when you're in a dark room, etc. I think I can get those hammered out in the next few days so I can start seriously testing!

SPOILER ALERT!
Here's my world map so far.
(Other than the 6 right-most rooms that I haven't bothered to screenshot yet) 

Saturday, April 16, 2016

Deadly Towers

After talking about Deadly Towers a couple weeks ago, I decided to try that game again. Like Super Pitfall, I've always been intrigued by this game. It was no fun to play, simply painful. But I always felt a sense of mystery and adventure from the large sprawling world that seemed to be hiding behind the misery of actual gameplay.

So using my trusty emulator on my phone, complete with save-state cheating, I decided I needed to play through the game to see if the game-behind-the-game was any good.

Unlike Super Pitfall, this game wasn't 100% horrible once you understood it. It was just mostly horrible.

Anyone who's played the game knows how frustratingly hard it is. There's usually tons of enemies on the screen at once, and one or two hits will either kill you or knock you back off a cliff where you die. To make it worse, there are invisible warps all over the place that take you to these vast dungeons filled with tons of featureless rooms (each dungeon is a 16x16 maze of death), many of which are packed with enemies that literally kill you the second you step inside. When I was younger, I thought these were secret warps to a later hard part of the game. I didn't realize they were just stupid nonsense.

This is what you have to explore if you step on the wrong patch of ground.
Really, you might as well just hit the reset button instead.


Well, it turns out if you use a map to avoid the dungeons, and carefully go get all the right powerups in the right order, the game is playable. (getting most of the powerups involves stepping on other invisible warp spaces)  The vast world really isn't very vast, or interesting. By the end of the game your armor is good enough that you don't die instantly.  But at that point, there's not much to do but hack your way through all the enemies. There's 10 or so bosses, but most of them are basically the same thing, and require very little effort. It's not as horrible as it seems at first, but it just never gets fun.

That being said, this game could have been fun if:
1. The dungeons didn't exist.
2. All the secret spaces weren't secret, but were visible warps
3. The difficulty curve wasn't stupid. Make the character a lot stronger at the beginning, and the monsters harder at the end.
4. I give up, I don't think all those things would fix it. It wouldn't be known for being so terrible if they fixed those, but I'm not sure it would actually be any fun.  I'm tired of thinking about this game. I'll stop now.

Wednesday, April 13, 2016

Experience!

Thanks for the comments, all.

Sounds like my everyone likes the idea of leaving in the XP/levels. Like Rob said, I'll have to play with the tuning, I definitely don't want grinding to be necessary.

Right now, the only random drops are meat (hp restore) and arrows (once you have the bow, the way to get more arrows is by picking up drops).  The idea of randomly dropping significant powerups sounds really tempting, but I'm not sure that it will work nicely into the system of persistent state that I've built so far. I'll have to think about it.

Right now, the direction I'll plan on going with it is that max HP is determined by your level and experience, and attack/defense is determined by which pre-set powerups you've found. But you never know, I may end up changing it after all.


Monday, April 11, 2016

Experience?

Ok, I need feedback from all 2 of you people that read this.

In GBA Anguna, you were motivated to fight enemies as you explored the overworld, because they dropped money, and you needed money.

In Atari Anguna, there's no money. I just don't have the ROM space for shops. I'm toying with the idea of replacing it with experience/level-ups. You get enough experience, your max HP goes up a level.

The advantage is that it motivates you to fight your way through the overworld instead of just running past everything.

The disadvantage is that it encourages/allows grinding, which I hate.

Opinions?

Friday, April 1, 2016

Is it fun?

This week I ran into the same introspective question that I hit multiple times with Robo-Ninja: Is this game going to be any fun?

It's just really hard to tell, as the developer. I'm way too closely attached to every minute detail to have any idea if this game is remotely fun to play.  I'm pretty sure that's what happened with Deadly Towers.  The only explanation I can come up with is that they didn't get outside input to tell them how bad their game was, and they were too close to see it.  I really don't want to make the next Deadly Towers.


Thursday, March 24, 2016

Asymmetrical rooms

One of the weird quirks of the Atari is that, while there are some registers to control the playfield layout (so you don't have to "chase the beam" to draw the entire background/playfield), there's only enough registers for half the screen, so it repeats the same graphics on both halves of the screen. There's another register that lets you determine whether it should be mirrored or duplicated.

Some games get around this by updating that register in the middle of the screen (which I also do when I'm drawing the subscreen map), but with the other stuff I'm trying to display (multi-colored main character, multiple enemies, missiles, etc), I don't really have time to do that. (as a counter-point, see the game Super Cobra, where they manage to cram that all in along with updating the background, although they have some clever limitations on movement to simplify things very slightly)

I've read bad reviews about this game, but I'm convinced the programmers are geniuses.

ANYWAY, my solution in Anguna is just to force every screen to be symmetrical (other than doors/walls on the far edges, which I fake with the Ball object). This makes for slightly less interesting room layouts, but makes my life a lot easier.  Except that my overall world design called for (at least) 2 rooms that broke that rule, and needed to be asymmetrical.  I had punted thinking through the design of how I was going to make these rooms work, assuming I'd come up with something eventually.

And so I did.

The 2 rooms are mirror images of each other, but not symmetrical themselves. It was a place where the river turned a corner:



How did I accomplish this, you may be asking? (If you are crazy enough to still be reading this)  I cheated.  The first half of the cheating is what you don't see, a grass-colored rectangle "enemy" that's just sitting on the left-hand side, hiding the river from view. Here's a similar picture of the room while I was working on it, and had the enemy colored red for debugging:


That accomplished half of what I needed -- making it look asymmetrical. But the hardware-based collision mechanism still knew I was walking into the playfield when I tried to walk through it. So I had to add a special exception in my general collision-processing code, so that playfield collisions in this particular region of these two particular rooms just didn't get counted.

The biggest drawback of cheating this way is that I can't have other enemies in this room -- I only allow one type of enemy per room, and the grassy overlay is using up the enemy for these two rooms. But that's ok -- I don't mind a few rooms here and there with no enemies in them. And I managed to get my asymmetrical rooms working.

And now, partially because it visually shows off my progress, but mostly because I'm obsessed with maps, here's the world map so far. It's about 1/4 to 1/3 of the total world that I have planned out.



Thursday, March 10, 2016

Compact it, Compress it, Recycle, Make Less of it!

My mission this week was to compress things. To compact it. Make less of it.  I was running out of space, and I needed more.

First pass was to go through my code looking for macros that I could convert to proper subroutines. I found a couple, which freed up a little space, maybe a couple hundred bytes total.

Next pass was to do with enemies what I had previously done with room layouts:  In my room definitions, I had a pointer to the enemy type that would be in that room. Pointers in 6502 are 2 bytes. I have less than 256 enemies, so it made sense to, instead of storing a pointer in each room definition, just use an index.  It took a tiny bit more code, but quite a bit less total space. That saved another couple hundred bytes.

The biggest savings, though, was redoing my room layouts.  Because of how the atari playfield registers work, and 6502 indexing works, it's easiest to store 3 chunks of data for each room layout -- one for the outside edge, one for the middle of each half-screen, and one for the middle of the screen.  So I stored 23 bytes of layout data for each of those chunks, for each room.

Well, it turns out that a lot of room layouts share similar chunks. For example, either they have completely blank outside edges, or nice square doors on the outside, etc. I had quite a few chunks that were repeated throughout my graphics data. So instead of clustering the 3 chunks together, I added yet another lookup table, where for each room layout, I store the indices of the 3 different chunks that make up that room.   That freed up about 400 bytes.

The bonus of this is that now I can make different permutations of my existing chunks, for nearly free. This gives me a lot more options for making different room layouts and keeping the game at least slightly interesting.

So, that's done.  Now back to content.

(Although some of the nice folks on AtariAge have convinced me that I should try to support the SaveKey, a hardware doodad that someone made, which plugs into the player 2 joystick port, and has some flash memory to allow game saves.  I guess it takes between 100 and 200 bytes of code to use it. Now that I've freed this up space, I may try to do it. We'll see)

I'll leave you with this nice picture of things being broken as I tried debugging my new room layout code.


Sunday, March 6, 2016

Darkness, and running out of space

This weekend's work was to add dark rooms. (at least, dark until you have the lantern) Which has been tough. I've given it a ton of thought, and have never been completely happy with what I've come up with. But with a good bit of trial, error, and wasted code, I've got something that works:


Dark rooms are limited to a single enemy. What I do is a trick that dates back to the catacombs from Adventure: I use an enemy sprite (set to 4x width) in yellow as a glowy area around the player. Then I change the background and walls to the same color, but change the rendering priority flag to put the playfield (walls) on top, the sprites 2nd, then the background last. Which means that everything looks black unless the glowy light is there, which gets rendered underneath the walls, showing where the walls are.

Thank you, Warren Robinett, for this awesome idea.



Now because I have other enemies that I want to render as well, I have to have some flicker going, and render the light and the enemies in alternating frames. (I just don't have the code space to do the more complex alternation if I have more enemies).

The one thing I have left with the darkness is that I want to hide the enemies until they get close to you. Which actually should be pretty easy, i believe.

Now the problem that I'm having is that I'm running drastically low on ROM space. I've got about 1K left of my 16K. In that space, I need to add a bunch of room layouts and color schemes, code for the dynamite, a bunch more enemies, and a sequence for winning the game. I also wanted to add support for the SaveKey, a cool doodad that someone made that plugs into the 2nd player controller port, and allows persistent storage for game saves. Adding the code for that takes about 100 bytes, which is about a tenth of what I have left. Ugh.

Thursday, March 3, 2016

Password Entry

It's late. I'm tired.

But by golly, I got the password entry UI working. With 133 bytes to spare. WHEW.


Of course, it doesn't actually let you start the resumed game from here yet, so maybe that's what I'll do with those leftover bytes.....

Wednesday, March 2, 2016

Password

Tonight I started working on what happens when you die, and where you respawn, which ended up getting me excited about trying to make the password system work.  So tonight's project was building a reusable bit of code to both display the current password, as well as display the password UI while the user is entering a password.

I don't really have the UI part of it working yet, but after a couple of hours tonight, displaying the current password is working fine, including a checksum to keep people honest:



As I stare at it, I think the password logic might be a little too obvious, so I may end up obfuscating it just slightly by rearranging some of the graphics for the numbers/letters in the password. We'll see.

Sunday, February 28, 2016

Subscreen Map

Well, I had originally said that I planned to wait and see how much space I had before making the subscreen map that I planned on.  But this past week, after working on the overworld, I realized that with my limited range of different screen layouts, the overworld was going to be a big boring place that's easy to get lost in.

What I really needed was a map.  With a map, at least the overworld becomes a big boring place that's not quite so easy to get lost in.


So I added the map on the subscreen. It took a bit of work to get the colors all lines up the right ways, using the different graphical objects available, but I think it's working now. The white dot tracks where you are on the world.


I did manage to get the kernel all working with my multiple colors, like I mentioned last time. I was even able to animate the water of the river, so the color moves down the screen, which is fun.



I think it's time to post some builds to the Atari homebrew forums to try to get some feedback.  That's scary.

Saturday, February 20, 2016

Squeezing and compacting

I've been plowing away at the game, adding some nicer graphics on the subscreen, fixing a bunch of minor issues, getting some bugs worked out with items, and starting on the overworld.

When I got to the overworld, I realized that my first couple screens were really boring.  Here is the hero standing outside of the cave that leads back to the first dungeon. I want to add some trees or something to the bottom half, but the way my engine works, each room only has 1 wall color.  I stared at this for awhile, but just wasn't happy with it.


Thus I started a new quest to squeeze yet one more thing into my display kernel. This seemed like crazy talk to me, as I already was having trouble getting all my timings right during the kernel. But Atari programming is all about crazy, so I stayed up WAY too late last night trying to find places to slightly tighten up the speed of my kernel code, so that I could squeeze in just a couple more instructions to update the color every few lines.

Turns out, by squeezing part of the calculation on one scanline, and the other half on the next, and by getting my timings just right so that I could eliminate a WSYNC, I got it working. (WSYNC is the instruction where you tell the Atari/TV that you are done with the current scanline, and it should start on the next. It takes 3 clock cycles -- but you can omit it, and the next scanline will just start when it's time. You often use it to force the timing to reset on each line, but if you have everything timed right, you can omit it and just start on the next line).

So now I have the ability to change the playfield color every 4 scanlines. The problem now is that this means that I have to devote 23 bytes of ROM to each different color layout that I want. And my 4k bank where the kernel and graphics live is already getting dangerously full.

Which meant that I started another crazy quest to tighten up the ROM space of the kernel code. Originally I had a lot of loops that were unrolled for the sake of speed, and no subroutines (which waste 12 clock cycles during the jump and return, which I generally can't afford in the kernel)  So now I'm going back and selectively re-rolling loops and moving things around, trying to free up a few bytes here and there. I've managed to free up about 200 so far (which is about 5% of the space of this ROM bank, so that's something), and have some ideas about places I can free up more.

So....progress is slowly happening. Although if I keep thinking of new features, I might no longer be able to squeeze things in anymore! (I'm already down to only 160 bytes of ROM left in my "main" bank, although that's less timing-intensive, so I can jump to other banks for subroutines if necessary)

Saturday, February 13, 2016

Subscreen

Ok, I finally took the time to sit down and work on the subscreen, and it turned out to be pretty fun, actually.

For now, I omitted the password portion -- I want to include it, but because the total ROM space is going fast, I want to make sure I have the rest of the content first. So right now the subscreen looks a little weird, all bunched up at the top. I'll spread it out a bit if I decide not to do the password.  And I need to adjust a few things (key colors, horizontal alignment of the keys, etc)

I'm also alternatively considering adding some sort of low-resolution map to the bottom half instead. I have no idea how that might actually work, or if I have any possible way of actually doing it with the limited resources I have. But it sounds cool.


The picture above shows all 6 keys, 17 out of 17 HP, 0 attack and 0 armor (which shouldn't ever happen), 0 arrows, and all the special items (bow, dynamite, lantern, ring, and boots).

Thursday, February 11, 2016

More with title screen

I've currently spent some time working on the inventory screen, which for some reason hasn't been easy to get excited about. It seems like a lot of hassle trying to get everything to nicely display.

The first part is getting the player's keys to display. Because you can tell the atari to triple each sprite, it's easy to get potentially 6 keys to line up on the screen. The trick is getting the timings exactly right to change the color appropriately for each key.  I'm pretty close at this point.

Unfortunately, my code to pick the colors based on the key type isn't quite right yet.

The next part will be to display numbers (or if that's too hard, bars) for health, attack power, armor level, number of arrows, and other items.

Then what I really want to do is also have a password system, similar to early NES games, where you can continue by entering a password.  But I'm not sure that I'm going to have ROM space -- showing the current password is pretty easy, but a password entry system might take up too much room. We'll see.

So getting bored and annoyed with that, and after seeing some of the amazing title screens that folks on AtariAge have come up with, I decided to rework my title screen. I played around with a few designs (I tried a sky into ocean with waves that come and go on a beach, but when I asked my friend Tim what he thought it was supposed to be, he couldn't tell, so I gave up on that idea), but finally settled on this road going off to the horizon, with trees around it. It was fun to make, and pretty simple to put to together:

I guess now it's back to the subscreen....

Tuesday, February 2, 2016

Working on hardware

Well, I bought a new RF adapter, soldered on a new controller jack, and bought a Harmony Cartridge.

With that in place, it only took about an hour to solve the problem:


Going through the process of starting with ridiculously simple sample code, testing on the Atari, and then slowly adding complexity until it broke, I finally narrowed it down to a relatively small subset of places that the problem could be.

It turns out that I was trying to do some fancy bank jumping acrobatics before properly zero'ing out everything.  Ok, boring explanation time:

When you turn on the Atari, the entire block of ram, and the state of the CPU registers, are completely unknown. So the first thing you should do is start zero'ing them out.

Now one of the things that's unknown is also what memory bank you're running in. Which means that although you know what memory address the program starts at, it could be in any bank. So one of the first things you need to do is, in the same place in every bank, run code to jump to the bank that has your actual program beginning in it.

Jumping banks is as simple as writing to a magical memory location, BUT that just immediately switches banks, leaving your program counter (ie memory location of the next instruction) as it was. So you have to make sure everything lines up nicely. I previously explained how I made some general routines for doing bank jumps, which involved writing an address to the stack, then issuing an RTS command, (return from subroutine), which makes the CPU pop an address off the stack and jump to it.  And I was using those for my initial beginning-of-program jump to my actual code.

Well, it turns out that if your stack and stack pointer are all in a broken random state, you can't reliably write an address to the stack and return to it.

The awesome Stella emulator has some settings to randomize memory on startup, which helps you generally find these issues, but I guess it wasn't randomizing something quite enough. Because once I properly zeroed out and initialized everything BEFORE doing my bank jump, everything worked!

Now I need to figure out why the colors are so completely different....

Friday, January 22, 2016

Ugh Ugh Ugh

Well, I've run into 2 big problems.

First, is that although I thought I had all the scanline jitter solved, it turns out that I had a few places where there was still jitter. And this has been really hard to track down.  After a few angry evenings staying up too late debugging, I finally realized that it wasn't actually my display kernel causing the problem (where I had spent the longest time debugging), but that occasionally I was taking too long in my main update code, and not rendering the screen in time.  So I need to do some combination of optimizing, removing code, or running updates every other frame.

The other problem is harder to deal with. I asked a friend if he could test with his Harmony Cart (an sd-card-based atari cartridge to run on a real Atari), and the game doesn't work. AT ALL. It won't do anything, not even display anything on the screen. So something's really wrong.  Unfortunately, I have no idea what.  At this point, I think the only thing I can do is get my Atari up and running, buy a Harmony Cart myself, and go through my git history testing different builds. At one point, about a year ago, I know that it ran.  I need to find out where it stopped.

So I got the Atari out of the garage last night, and went through about 8 or 9 combinations of adapters and cords trying to get it to work.  (The RF switch box that came with it is somewhat broken. I tried with my NES RF box, SuperNES switch box, and a few other gizmos from my box of adapters. I had the most luck with the NES switch) The best I got was an extremely blurry screen that you could somewhat see. Not enough to really enjoy playing on. Now do I want to spend $60 on a special cart just to debug this on my terrible TV?

I have a few more things I can try to get it working better. If I'm going to spend the money on a flash cart, I want it to at least look good.  We'll see what happens.

Tuesday, January 19, 2016

Title screen

Thanks to the sample code of really smart people out there, I now have a working title screen!

The hardest part was similar to the last problems I talked about: cycle timings getting messed up while crossing a page boundary.

To get a nice large "hi-res" graphic on the atari, you have to take both sprite objects, tell the Atari to repeat them 3 times close together, and then stagger them.  (Imagine the 3 repeated planes on Combat, or the 3 players on Football. Then imagine 2 sets of those interleaved with each other) That gets you halfway there, but then you have to very exact timings to update the sprite's graphic data mid-scanline.  Because the Atari is so doggone slow, the timings are really tricky. (Although the technique eventually became fairly well-known -- any game with a 6-digit score display most likely used this technique).

I got the code all working thanks to that sample code I posted to above, but if I fiddled much with the graphics data, the timings would get off by 1 clock cycle, and it would fail. Turns out, again, that it was crossing a page boundary. This time with a LDA instruction (loading the accumulator from memory) -- if you do a "LDA foo,X" command, which loads the accumulator with whatever byte is at memory location (foo + the value of the X register), and foo+X crosses a page boundary from foo, it takes 5 cycles instead of 4.

Luckily the assembler gives you a nice "align" pseudo-opcode that lets you force alignment of your data into page boundaries, which fixed it.

After getting the title displayed, I wanted to make it pretty. I have 8 whole clock cycles free per line to do what I want with, but to update the color of the whole thing, I have to write to 2 registers (COLUP0 and COLUP1, the color registers for each sprite), which alone takes 6 cycles. There's not enough time left to pick or calculate the color for the scanline.

So I unrolled the kernel loop by half, which lets me use 16 clock cycles every 2 lines. That's plenty of time to load a base color, add to it based on the current line, and then write it to the color registers. The end result is a pretty animated title graphic:

Right now the PASSWD option doesn't do anything :-(

The half-unrolled loop ended up looking like:
.loop:
    sty     tmpVar              ; 3

    ;update the color
    tya                         ; 2
    adc     PlayerColorDef      ; 3
    sta     COLUP0              ; 3 = 11

    lda     (ptr+$0),y          ; 5
    sta     GRP0                ; 3
    lda     (ptr+$2),y          ; 5
    sta     GRP1                ; 3
    lda     (ptr+$4),y          ; 5
    sta     GRP0                ; 3
    lda     (ptr+$6),y          ; 5
    sta     tmpVar2             ; 3 = 32

    lax     (ptr+$a),y          ; 5
    lda     (ptr+$8),y          ; 5
    ldy     tmpVar2             ; 3
    sty     GRP1                ; 3        
    sta     GRP0                ; 3
    stx     GRP1                ; 3
    sta     GRP0                ; 3 = 25

    ldy     tmpVar              ; 3
    dey                         ; 2

    ;burning 3 cycles in place of the bpl since the loop is half-unrolled
    sty     tmpVar              ;3 (in place of the bpl)


    sty     tmpVar              ; 3

    ;update the color
    tya                         ; 2
    adc     PlayerColorDef      ; 3
    sta     COLUP1              ; 3 = 11

    lda     (ptr+$0),y          ; 5
    sta     GRP0                ; 3
    lda     (ptr+$2),y          ; 5
    sta     GRP1                ; 3
    lda     (ptr+$4),y          ; 5
    sta     GRP0                ; 3
    lda     (ptr+$6),y          ; 5
    sta     tmpVar2             ; 3 = 32

    lax     (ptr+$a),y          ; 5
    lda     (ptr+$8),y          ; 5
    ldy     tmpVar2             ; 3
    sty     GRP1                ; 3         
    sta     GRP0                ; 3
    stx     GRP1                ; 3
    sta     GRP0                ; 3 = 25

    ldy     tmpVar              ; 3
    dey                         ; 2

    bpl     .loop               ; 2/3 =  7/8

NES Anguna

Well, I had a little bit of time still, while Frankengraphics is finishing up her game Project Blue, to have a little downtime on Halcyon, s...