Sunday, December 17, 2017

Half-height collisions

I'm back at the metroidvania game tonight. I had just gotten collisions mostly working, at block sizes of 16x16 pixels.  But the artist I'm working with (the amazing Frankengraphics) asked if we could do it at half-height -- so 16x8 pixel collision resolution.

One thing I've learned in life is to try to say yes to every feature the artist recommends. It will make your game better (which is why the original Anguna turned out so well: Chris had tons of great artistic suggestions, which required me to completely rewrite the engine after he came on board!) 

In this case, I reserved 1 byte of data for each metatile of 4 16x16 blocks, which means 2 bits per block. That could allow 4 different collisions types: open, blocked, destructable, and "special" where special depended on the room (with options being things like lava, water, etc). To add half-height collisions, something was going to have to change. But I didn't want to re-tool the whole engine to support EVERYTHING operating at a 16x8 level.

So the answer I settled on (for now, at least...we'll see how it works) is that I'll add an extra byte of collision data per metatile, meaning each block gets 4 bits, which is 16 different collision types. One of those collision types is half-high-blocked.  So I check for that separately in my collision routines, but everything else (block destruction, etc) can still operate at the 16x16 pixel level, which should make everything easier.

We'll see if that holds true....

It's hard to really tell, but the big block that the vehicle is
sitting on near the top-left is 32 pixels wide, and 24 pixels high.  Meaning the top
layer is 2 half-high-collisions.

Wednesday, November 29, 2017

PRGE 17

I just realized I never did a post after the Portland Retro Game Convention talking about how great it was!

The first great part was just standing in line to get in.  I started chatting with the fellow in line behind me, who not only was familiar with my Atari version of Anguna, but had actually bought a copy just a few weeks before the convention!

The convention itself was a blast -- the biggest highlight was meeting (in person) many homebrewers that I've gotten to know in the AtariAge, NesDev, or NESDev twitter communities.  It's nice to finally put faces with names (or real names with internet names!).




Other than that, I spent a lot of time hovering in the background, watching people try out the Quadtari. It was fun seeing people pick it up and give it a try.  (What surprised me most was the number of teenagers who had no idea how to hold an Atari joystick.)  At one point, Joe Decuir, the engineer who designed much of the hardware of the original Atari, made a stop by to see it!

As they were walking away from trying Quad-Tank, I overheard of these guys say,
"That was the most fun I've ever had playing Atari!"


Albert, the mastermind behind AtariAge, hard at work.



Now I have a lot of work to do. The first prototype took me hours of soldering, about $25 in parts, and is already getting a little unreliable after being jostled so much.  So it's time to design a proper PCB and it get it properly made.  I've got a board designed that I hope is the same as what I prototyped, and I'm in the process of getting quotes on PCB fabrication and soldering assembly from a place in China. We'll see what happens!

3 weeks

So one of the main goals of Robo-Ninja Climb was to see how quickly I could crank out a reasonably playable NES game.  Nothing ground-breaking, but a short fun game.

The answer is 3 weeks of evenings.  Approximately 40 hours, maybe. I've got a game that's certainly playable (although by all reports, a little too hard. Oops, I'm bad at that) 

I decided partway through to ditch the "endless" part of it -- I realized I didn't have a good plan for making random levels that were actually fun to play.  So I designed 5 short levels, with a few power-ups part way through.  Each has slightly different background graphics, to give the player a sense of progression.


A few thing that I felt like were somewhat interesting during the development:

  • I used the NES's Sprite-0 flag to make the spikes at the bottom not scroll away with the background. But to make it more interesting, I cycle sprite 0 up and down slightly, to make the spikes bounce and look a little scarier.  
  • Robo-Ninja is a giant character by NES standards. Most games have characters that are 16x32 or so.  Robo-Ninja is 32x48 or larger (depending on the animation frame).  I can get away with it because there aren't many other sprites in the game.  Most games have enemies, bullets, and so forth to deal with. Robo-Ninja mostly dodges background elements.
  • I didn't feel like mapping levels out manually in a tile editor (mostly it's blank space!), so I mapped them all out using text like this, and then have a pre-processor as part of my build script that converts it to actual binary level data:



>.......
>.......
>.......
>.......
>.......
>.......
>.......
>.......
........
........
...*....
.......<
........
........
.......<
........
........


Well, other than collecting feedback, tweaking difficulty, and possibly adding some music from another composer, I think it's done. And I still have 2 months left before the deadline! You can try it out using any NES emulator, and grabbing the rom from my bitethechili site.  If you do, let me know if you have feedback!

Friday, November 10, 2017

Robo-Ninja Climb

Well, out of the blue, I decided that I was missing out by not entering something into this year's NesDev competition, so a couple weeks ago I decided to see how quickly I could churn out a simple-but-fun game.

My idea is an endless-climber type of thing, based on the Robo-Ninja character. You just bounce back and forth scaling walls while dodging obstacles.


It's been fun, trying to churn this out as fast as possible.  To be as efficient as I can, I reused a number of routines from my primary nes project, and then have been coding everything in a mix of C and assembly, switching back and forth at whim, using whichever seems easier for any given part of the game.

I just finished my 7th day of development, and it's almost a playable game -- I just need to make collisions with the obstacles actually work, and tweak the controls a bit, and it will be time for some preliminary testing: the standard "is it actually fun" sort of thing. We'll see.

There's a lot more I'd love to say about some of the technical challenges of writing this game, but with trying to finish it as quickly as possible, I end up not wanting to waste time writing about it.

Like last year, I don't have a lot of intentions of winning the competition, but I couldn't pass up a chance to at least enter something.

Tuesday, October 17, 2017

Metatile Designer

For the NES game, I'm building my levels out of 32x32 pixel metatiles.  What is a metatile?  The NES background tiles are 8x8 pixels, but that's too small for a lot of purposes.  Loads of games were built out of bigger blocks (16x16 is very common, which is what Mario or Zelda used, making the standard "block" size you see in many NES games).

The smaller your blocks, or metatiles, the more ROM space a level takes up, but the more flexibility you have in laying out your levels.  For this game, I'm planning to use 32x32 blocks.  (which I've built the whole engine around, so if that changes for some reason, I'm in for a lot of work)

Here's a picture of Super Mario Bros.  By this time your eyes are glazing over
and you don't even remember why I was talking about Super Mario Bros anyway.
Warning: the next paragraph is even worse.


The reason I chose 32x32 is because of how the NES handles palettes. In memory, there's a byte for each 8x8 pixel space on the screen, to indicate which tile should be drawn there. But each tile can have one of 4 palettes, and that byte doesn't include any palette information. There's another block of video memory where you assign palettes to tiles.  BUT, there's a few limitations.  You can only assign one palette for every 16x16 pixel block (group of 4 tiles), which is one reason it's so common to have blocks that size in games.  AND 4 of those groups (a 32x32 pixel block) shares a byte in memory (2 bits for each 16x16 block).  So in my case, each 32x32 metatile can map to a byte of palette memory, which simplifies writing palettes. 

So between the ROM savings for large levels (64 bytes to represent a single screen) and the ease of writing palettes (also called attribute tables), I picked 32x32 metatiles.

Now the problem is that I need a better tool for designing my metatiles.  There are a few tools out there (NES Screen tool by Shiru, Sumez's editor, etc).  But for one reason or another, none of them quite did want I wanted.  So it was time to start tool building, which is a sometimes-miserable, sometimes-nice distraction in the middle of a project.

In the past I've tried a few different technologies for quick-and-dirty gui tools.  It used to be Borland Delphi.  Then C#.  Then the web with either raw javascript, or Angular.  This time I wanted something cross-platform but I hate the web, so I decided to try javafx, which I've heard is decent.

I considered forcing myself to use Kotlin or Clojure for the sake of learning another language, but once again, the pragmatism of getting something done quickly set in, so I cranked it out in java.  Java 8's lambdas makes gui programming a little less unpleasant, so it didn't take long to have my metatile designer working but ugly.



Now it's time to actually try to put together some decent-looking metatiles and start building a cool demo level.

Monday, October 16, 2017

Quad-Games and PRGE

Well, I have 3 games (of hopefully 4) of my "Quad-Games" collection done: Quad-Joust, Quad-Tank, and Bomb-Defense.  Thanks to some friends that came over for an evening of testing (thanks guys!) we found a bunch of bugs and potential new features.

I've spent the past couple weeks hammering out bugs, and re-testing repeatedly, mostly with my family.  Now PRGE is almost here, so I'll have to call it done for now.  I'm pretty excited to have it out to demo, and see what people think when they play it.

Bomb Defense is the preferred game for my wife and daughter, who prefer co-op play.


A few other updates:

  • Some bugs have been reported in Atari Anguna, so I've been working feverishly to fix and test them before PRGE, so new carts sold there can include the bug fix
  • I've also had a request for a PAL-compatible version of Anguna, so I've been working on a PAL-60 version that will play in whatever places used PAL TVs.
  • I've finally gotten back to work on the NES game.  The scrolling engine seems to finally be working, so I was pretty quickly able to add a main character that can jump around and collide semi-properly with the environment.  More on that soon!

Wednesday, September 20, 2017

Atari QuadGames

Well, the first prototype adapter is finished, Quad-Joust is undergoing testing (ie making my kids come down to the basement and play it with me), and I'm almost done with the 2nd game to be included on the QuadGames multicart: Quad-Combat (or Quad-Tank).  Basically, just a 4-player variant of the original tank/combat game.



Using the same basic code layout as Joust was a great starting point, and made it easy to the game 99% of the way there.  The problem, though, was time.  Most of the time during gameplay, it worked great. But under a few worst-case conditions, I ran out of processing time, and the screen would roll.   It didn't help that there were really 8 objects that had to be dealt with every frame -- 4 tanks and 4 bullets.  (as opposed to just the 4 birds from joust)  Reading over the code a few times, there wasn't anything grossly inefficient.

Which meant it was time for optimizing.

Because I wrote this all in batari basic to save programmer time, I wasn't sure how efficient the compiled assembly was.  Step one was to just read through the assembly that bB generates. Which turned out to be not too bad.  Very little that was egregious.  But a lot of places where I could do a tiny bit better by hand.

So I tonight I ended up rewriting about half the game into assembly. Having the compiled basic code to work off of made it pretty fast, but it was easy to find places where it was being dumb. For example, I had code like:

temp1 = player0x + 4
temp1 = temp1 / 4

which naively got transformed into:

lda player0x     ;3
clc              ;2
adc #4           ;2
sta temp1        ;3
lda temp1        ;3
lsr              ;2
lsr              ;2
sta temp1        ;3
                 ;total: 20 clock cycles

Not terrible, but a bit wasteful. Knowing the state of the carry flag going in, I was able to rewrite it


lda player0x     ;3

adc #4           ;2
lsr              ;2
lsr              ;2
sta temp1        ;3
                 ;total: 12 clock cycles


8 clock cycles isn't much, but doing this sort of thing in a handful of places throughout the game ended up making it work!

Now it's time to test some more....

Don't look too closely, turns out I'm REALLY bad at making holes in plastic boxes.


Thursday, September 7, 2017

4-player adapter progress

The past few weeks have been a fun balance between working on my NES game (still slogging through getting my scrolling engine right!) and the Atari 4-player adapter.

I'm too tired tonight to go into too much detail, but the adapter is moving along great!  The way it works is this:


  • The Atari allows setting 4 of each joystick port's pins to either input or output mode. Normally you want them on input mode, because they are the pins that read the 4 directions of the joystick. But they planned well for future-proofing the console, and set it up so that you can control them as outputs as well.
  • So to allow 4 controllers, I use a really simple multiplexing scheme -- the first joystick port is used in normal input mode for reading all 4 controllers, and the second joystick port is used in output mode to select which controller to read at any given time.
So with just a few multiplexer ICs and some pull-up resistors, we have a working adapter!

Well, mostly-working. So far, the left, right, and up directions work. I still need to finish wiring up the down and fire buttons!

Right now my desk is just a giant mess of wires waiting to be soldered.

I was a bit nervous at first that the Atari wouldn't let me write to the output pins fast enough to switch to each joystick during a frame, or that the input might be latched once in a frame and not updated as I switched it.  But neither of those were the case, and so far, it seems to be working perfectly!

Next step: finish wiring the last pins, and put this thing into some sort of sturdy box. Then hopefully get it all cleaned up to possibly show off at PRGE!

Friday, August 18, 2017

Batari Basic and Fixed Point

When I'm too tired/frustrated to work on my NES game, I've been playing around with ideas for another hobby project that I've head for awhile: a 4-player atari adapter.

I'll get to the details of the hardware of the adapter at some other time, but right now I want to talk about a thing called Batari Basic.

Batari Basic was created by a talented guy (Fred "batari" Quimby) as an easy way to make games for the Atari 2600. It's a really-slimmed-down version of BASIC with a bunch of special keywords and such specifically for Atari.   The idea is that you write simple game logic in a very limited set of basic commands, which can easily be compiled to assembly language.  Then, for the display kernel, which is where you normally really have to work to optimize things and get assembly timings perfect, you just select and use one of a handful of pre-written kernels.

The end result is super-easy-to-write games that often have a very similar look (due to using the same kernel).

Blocky playfield with blank lines between chunks.
Nice-but-generic-looking scoreboard at the bottom.
Two sprites and not much else on the screen?
Looks like a standard Batari Basic game to me

The ease of using Batari Basic to make an Atari game has led to quite a few really interesting or cool games being made, but also boatloads of bland shovelware.  I wasn't remotely interested in using it for Anguna, as it removed most of what makes Atari programming interesting to me -- a challenge of working on the metal, understanding what the system can do, and trying to push the system a little (which admittedly, I didn't do much of)

BUT, for my four player adapter project, I'm going to need a sample game or two to sell with the thing.  But I really don't feel like taking the hours to fine tune a display kernel for something like this.  I never expected this, but I've become a Batari Basic programmer.

It helps that there's now a kernel that uses an on-the-cartridge-arm-co-processor (named DPC+, modeled after David Crane's co-processor that he invented for Pitfall 2), that allows multiple sprites, and selectively flickers them if 3 are overlapping.  (Similarly to what I did with Anguna, but that took me AGES to get right. Here, it's built into the kernel).

Batari Basic's DPC+ kernel makes it REALLY EASY to make a multi-sprite game like this.
So based on that, I'm going to use Batari Basic to churn out at least one four player game to go with this adapter.  I'm starting with something that's a modified version of Joust.  But for Joust to work, you need to use fixed point math, so that you can have smooth levels of acceleration and velocity.

Batari Basic supports fixed point math.  But only sort-of.  You can add and subtract fixed point numbers (with certain limitations).  BUT you can't really do comparisons with them.  It just doesn't work right.  Simple stuff like "if foo > 0" doesn't really work right.

Which means I'm doing a lot of hacky workarounds, dropping to assembly and such, to manage my fixed point math.

That said, it's still WAY faster to make a game this way.  Just a few hours of work, and I have a mostly-working joust game.  With four players.  Although I still haven't gotten the hardware in the mail to make the actual adapter, so I ended up hacking the Stella emulator to add emulated support for my controller.  But that's a different post for a different day.


Monday, July 24, 2017

Optimization and C

Starting this next game in C, I've known there will be places where C isn't fast enough, and I'd have to drop to assembly to optimize things.  Particularly because the 6502 processor really isn't a suitable target for C.  There's just too large a gap between how C structures things and how the 6502 needs things to be done.

Well, this week I decided to see how long my background updating routine takes.  The easiest way to see how long a long-running routine takes on the NES is to play with the color/bw register.  You can set a frame to render in B&W, and when the routine finishes, change the register to color.  The screen will switch partway through the frame, and you can see by where the color starts how much of your frame's computation time you've used.


In this example picture, you can see that the routine being checked runs from the beginning of rendering, to somewhere around 10% of the screen height.  So it's taking up somewhere in the general order of 10% of the total processing time available.

Well, my background updating routine (which renders a new slice of background just offscreen to prepare for scrolling) was taking somewhere around 40% of my total time.  It was horrible.  After playing around, it turns out that this loop was the culprit:



    while (temp > 0) {  //temp is just a counter of how many times to do this
        cj = *tempPtr2;  //get the current metatile into cj
        slicePtr = (u8*) metatile_ptr[ci]; //figure out which slice array to use
        vram_NEXT_BYTE(slicePtr[cj]);
        ci += 4;
        if (ci == 16) {    //if we've finished a tile, go to the next one down
            ci = 0;
            tempPtr2 += yIncrement;
        }
        --temp;
    }

It's not important to get into the details of exactly what this loop is doing, but a few things ended up being problematic:

1.  I look up slicePtr each time through the loop, although if you pay attention, it turns out there are only 4 different values it can be.  Pulling those out of the loop gained me about 5%.  

2. More importantly, and this is where C starts to fall apart, getting a value by index into an array can be super-slow if the array isn't contant. (ie if it's a non-constant pointer pointing at an array of data).  This is because the 6502 only allows indirect indexed addressing from zero page.  And what exactly does that nonsense mean?  The 6502 has a single special page of memory, the "zero page" that's, well, special.  To do a pointer-based lookup, you first have to copy the pointer to the zero page, then do an index from that.  So for a single slicePtr[cj] lookup, it's something like:
     
lda slicePtr
sta tempPtr
lda slicePtr+1
sta tempPtr+1
ldy cj       
lda (slicePtr),y

That's 21 clock cycles, if I haven't forgotten all my instruction timings in the months since making an Atari game.

So to improve this, I allocated space on the zero page for 4 pointers, and not only pulled them out of the loop (like I was talking about in step 1), but dropped to inline assembly, and saved them on the zero page once, so I wouldn't have to jump through those hoops every time.   This ended up being a huge savings in time.

3. By this point, I figured I had optimized it that far, I might as well go further, and unroll the loop a little, and do most of the computation in inline assembly:



    tempPtrA = (u8*)metatile_ptr[ci];
    ci += 4;
    tempPtrB = (u8*)metatile_ptr[ci];
    ci += 4;
    tempPtrC = (u8*)metatile_ptr[ci];
    ci += 4;
    tempPtrD = (u8*)metatile_ptr[ci];

    while (temp >= 4) {  //temp is just a counter of how many times to do this
        cj = *tempPtr2;  //get the current metatile into cj
        __asm__("ldx %v", vram_buffer_current);
        __asm__("ldy %v", cj);
        __asm__("lda (%v),y", tempPtrA);
        __asm__("sta %v,x", vram_buffer);
        __asm__("inx");

        __asm__("ldy %v", cj);
        __asm__("lda (%v),y", tempPtrB);
        __asm__("sta %v,x", vram_buffer);
        __asm__("inx");

        __asm__("ldy %v", cj);
        __asm__("lda (%v),y", tempPtrC);
        __asm__("sta %v,x", vram_buffer);
        __asm__("inx");

        __asm__("ldy %v", cj);
        __asm__("lda (%v),y", tempPtrD);
        __asm__("sta %v,x", vram_buffer);
        __asm__("inx");

        __asm__("stx %v", vram_buffer_current);

        tempPtr2 += yIncrement;
        temp = temp - 4;
    }


It's certainly a bit uglier, but it went from the whole routine being somewhere around 40% of my frame time, to about 10%.   I'll take that optimization.

Edit: And if you're wondering why my variable names are so awful, that's once again an artifact of the 6502 way of doing things.  C's method of allocating local variables on the stack isn't a particularly good fit for the 6502, so it's much faster to allocate a handful of generic global variables on the zero page that can be reused all over the place.  So most of these oddly named variables are common globals that are used for all sorts of things. (ie ci and cj are common index variable that I use in all sorts of loops)

Thursday, July 13, 2017

Level loading and scrolling engine

Well, after a bit of work here, a bit there, between baby feedings and lack of sleep, I've managed to get the first bits of my level-loading and scrolling engine done.

First, I needed to figure out a level format. The NES native background tiles are 8x8.  But levels stored at that resolution end up being huge in ROM space, so most people use something else. Sometimes some sort of compression (gzip? run length encoding?) but that works best with games that either only scroll one direction, or that have a big ram buffer on the cartridge to decompress the data into.  The cheap cartridge mapper/board I'm planning to use, GT-ROM (which has some awesome features) doesn't have extra ram.  So that's out.  Instead, I'm going to try doing 32x32 pixel metatiles.  Where each "tile" of my level data represents 4x4 hardware tiles.  The convenient thing about this is that the NES tracks palette data for backgrounds in 32x32 chunks, so this will simplify that calculation.

So first, I had to build the system for defining and accessing metatiles.  And figure out tooling for having a UI to work with them.  Luckily a guy on the nesdev forums made a cool editor that does just that.  I don't particularly like the level editor piece of that tool, but it's perfect for a metatile editor, and it can spit out the definition in JSON format, which made it really easy to write a python script that gets run as part of my build process to transform the JSON format into the necessary source code data format.

Then, for actual level editing, I decided to stick with Tiled, which I used with Robo-Ninja, and is super flexible.  It can save levels in a nice textual format, so again, I wrote a python script to be run as part of the build process to convert these levels into the format the game needs.

Next up was drawing a level to the screen, and then scrolling.  It's late and the baby finally fell asleep, so I'll talk about that later.  Until then, here's an ugly picture of my test level data.  Frankengraphics gave me some beautiful background tiles to work with, and I turned them into a horrible ugly mess for now. But at least it's starting to look something like a game....



As an addendum:  Python drives me crazy. I know the kids say it's great, but the significant whitespace, the duck-typing, the ugly-formatted documentation - it all drives me nuts.

Friday, June 30, 2017

I had a baby

The new baby showed up a few weeks sooner than we expected.  Everyone is healthy.  But I'm tired. That's all.

Tuesday, June 6, 2017

Blaster MetroidVania

Well, I've been working on the next game, but not saying much.  Mostly because the majority of my free time involves working on fixing things in my new house, or getting ready for the arrival of a new baby in a couple weeks.  So when I do manage to squeeze in some development, I don't have time to say much about it.

That said, I've found someone to collaborate with on the next game, so things are moving forward!  We're doing a metroidvania-style Blaster Master-inspired adventure.

First things first, while Frankengraphics is working on some preliminary art, I'm trying to get a scrolling engine working.  Which on the NES, is a beast.  The nametables (the chunk of video memory that tells the graphics chip which background tiles to draw where) work somewhat similarly to how they worked on the GBA, but with a few things that make the whole thing more complicated, the primary ones being a slow processor, and a slow and unwieldy method for accessing video memory.

The biggest hassle is doing the math to keep track of what address corresponds to what location on the screen, once the screen starts scrolling around.  I won't go into detail now (I'm too tired -- see this post from Spacey McRacey which talks about some of it), but it's math that's simple until you have to do it quickly on a primitive 6502.

All that to say, getting a multidirectional scrolling engine working isn't quick work.

Tonight, I got fed up with trying to debug my function that renders a new column of tiles when scrolling left or right, and decided it was time to add some on-screen debugging.  Usually with any project, there's a point where I get fed up enough to write some decent on-screen debugging features, and that time is now.  The trick is, because I'm trying to debug background tile rendering, I need to make my debugging tools use sprites instead.  So while normally a text system on the nes is rendered using background tiles (because the nes can only render 8 sprites per scanline), I'm going to display it using sprites for now.  Which means no matter how badly I goof up the background layout, I should be (in theory) able to see debug information on the screen as sprites.

I haven't gotten very far with the debugging system yet.  Mainly because I don't have any sprite code at all yet, so I need to start from zero.  That was tonight's goal: get some basic functions set up for rendering general sprites.  Then next time I can add some debug functions that dump data to the screen.

Ok, bedtime.  I realize this post has been pretty rambly and incoherent.  I guess that means I'm tired.

Monday, May 1, 2017

Sixer problems

Well, once again the folks at AtariAge are smart.

The usual cause of this problem is accidentally reading from a write-only register.  On many systems, this will return the address you are trying to read from, but some will give garbage.  But it's an easy mistake to miss:

lda #13 ; loads the value 13 into the accumulator
lda 13  ; loads the value at memory location 13 into the accumulator
; (which actually is a write-only register, so on some systems will accidentally load 13 into the register, but others will load garbage)

There's actually a setting in Stella (the emulator) that lets you force it to return garbage when reading from these registers, so by setting that flag, I can reproduce the problem that happens on the sixers.  And knowing what sort of typo to look for, I can probably sort this out relatively quickly.

Sunday, April 30, 2017

Atari Anguna: bugs on a sixer

First, a brief bit of Atari history:  The original Atari 2600s had 6 switches on the front -- the power, B/W, Select, Reset, and one difficulty switch per player.  Later models moved the difficulty switches to the back.  All the Atari versions now have goofy names that the collectors call them.  The original "heavy sixers" were bigger and heavier than the "light sixers" but both are sixers (having the 6 switches).  You could also have a 4-switch "woody" (that still sported the awesome late 70's wood-grain), or the darker "vader".  Or poor saps like me have the cheap little re-released Junior.

Well, I had only tested Anguna on my Junior, and a 4-switch woody (and in the Stella emulator).  It worked fine, so I figured we were good (theoretically, all the models are supposed to work the same).

Well, I just found out that that's not the case.  The main character doesn't animate correctly on the sixers.  I'm not completely sure what to do about it -- how do I debug a problem that only shows up on hardware I don't have?

Current possibilities, from least to most painful:

  1. Somebody on the AtariAge forums has a guess about a possible difference in the hardware, and I can just go fix it (this would be a long shot)
  2. Get a sixer.  That means either buying one (maybe $50 if I'm lucky) or borrowing one.
  3. Make changes. Email them to someone with a sixer. Wait for report. Try again.
Ugh.

Saturday, April 22, 2017

Why retro games?

Recently my friend Bryan asked the question "Have you written before about what motivates you to create retro games?"

I've somewhat hinted at it a few years ago, but there's a few reasons:

Nostalgia is one piece of it. I grew up playing Atari and NES, and so the idea of being able to make a quality game for the system I grew up with is really fun.  As a kid, I wondered what it was like to make games for these systems, and spent hours sketching game designs on paper.  It's fun to finally get to do what I dreamed about back then. (I've wanted to make a NES game ever since the system first came out. After 30 years of preparation, I finally feel like I can pull it off!)

Another factor is the challenge, and how different it is from my day-to-day work programming.  I like programming, but the change of being so close to the hardware is a nice change..  The problems are somewhat similar to what I might solve at work, but really different in actual code.  And learning how new (old) video game systems work is not only a fun challenge, but also interesting from a history/nostalgia persepctive. (ie "oh, THAT'S how and why they did that on that game!").  Add in some crazy limitations (only 76 processor cycles per scanline!?) and you have a good fun technical challenge.

Really, the biggest reason, though, might be about the community involved.  For modern platforms (PCs, phone games, etc), the indie market is incredibly flooded right now. There are tons and tons of games being created all the time.  While there are a few crazy success stories like flappy bird, the vast majority of indie games don't really ever get noticed.  So you either pick a goal of just trying to be financially profitable (which requires more commitment than I'm willing to make right now, and a team of artists, musicians, etc), or just be happy making a goofy little game for the fun of it (which is what I did with Robo-Ninja).

In the case of Robo-Ninja, about 3000 people installed it.  Other than my friends, I got about one message about it, a couple of store ratings (some 1 star, some 3-5 stars), and that's about it.  I had fun making it, I enjoyed hearing from my friends that played it, but it just felt lonely, like I was riding a big crowded subway car alone in a big city.

In contrast, when I started making Anguna for Gameboy Advance 12 years ago, the GBA was just at the end of its commercial life, so it wasn't about retro gaming: it was just about the fun of making a homebrew game for a video game console.  What surprised me was hearing people talk about it. I'd get emails from people asking about it, reviews appeared on some websites, and there was a community of people to talk about it with.

Atari Anguna was also started just for the fun of it, but upon finishing,  people on the AtariAge forums expressed an interest in the game.  Realistically, it was a lot fewer than the 3000 that had downloaded Robo-Ninja. But it was a lot more fun and rewarding, having a small number of people be vocally interested, as opposed to a few thousand nameless installs.

The height of this was at last year's Portland Retro Games Expo when I got to chat with other Atari and NES developers, many of whom had made games I had played, and a number of whom had played and enjoyed Anguna.

So really, it's not just about the "retro" aspect of retro games, although that's part of it.  It's also about knowing that people play and enjoy my games, and getting to talk to them about it.  Right now that means retro gaming is the fun niche where I can make a cool game without a big team, have a ton of fun doing it, and hear about people enjoying it.  

Oh yeah, and retro games are hip right now.  I'ts fun to be doing something hip.

But who knows, I've always been a bit non-committal in my hobby projects. Maybe I'll suddenly decide I want to try something else in a couple years once I finish this game....

Tuesday, April 18, 2017

Starting the next game

Now that Spacey McRacey is done, it's time to move on to the next game: a large adventure game for the NES.

I've had two ideas in mind for awhile, either my Blaster Master-style metroidvania game that I've talked about before, or another Anguna sequel.  After asking around to see if I could find any artists interested in working with me, I found someone that's interested in doing the Blaster Masteresque game.  So that's where we're starting.

First steps involve picking some technology.  On the Atari, unless you were going for some crazy advanced cartridge with a co-processor on board (which was really rare back in the day -- I think Pitfall 2 was the only commercial game that did this), all the cartridges boards are pretty similar, other than ROM size and the exact method of bankswitching to map all that ROM to the limited address space of the Atari.  (Ok, some also had some RAM on board. But still, there wasn't all that much that was different).

NES cartridges are a different story. The NES was designed for the cartridges to have a bit more control, so there's a lot more variance depending on what cartridge hardware you're going to pick.  And certain types of cartridge hardware are more expensive to produce on actual cartridges than others.  So I need to pick a cartridge mapper type.  I've been doing some experimentation -- there's a new one out called the Cheapocabra that's both cheap and powerful.  The only downsides are the fact that not all the emulators support it yet, and it has no expansion RAM.   So I'm still trying to decide for sure.

The other question is whether I stick with pure 6502 assembly, or do a mix of assembly and C.  I've been doing some experiments with writing the core game logic in C, and dropping to assembly for the bits that need to have better performance, and it seems to be working reasonably well, so I think I'm going to start with that.

Next steps are to start thinking about a scrolling engine and internal level data representations.

Wednesday, April 5, 2017

Testing on hardware

Everytime I title a post like that, it's never good news.

We moved across town, which primarily means that I've spent more time fixing up an old house (to sell) and a new house (to live in) than I have programming for fun.  But I also had space to set up a nice desk space for writing/testing my games, including my NES and Atari attached to an old little tube TV (thanks, Jake!)



After hours of frustrating with faulty Compact Flash cards (remember those?), I finally got my PowerPak working, so now I can test my game on the real Nintendo! (as well as play all my NES games without fighting with dirty contacts every time!)

Well, as usual, it didn't go well at first.  Spacey McRacey was a jumbled mess of flickering as it scrolled. It bounced all over the place.

With some advice from the fine folks at nesdev.com, I had a number of things to try, but none of them worked.  BUT simplifying things by disabling my split-screen scrolling (the status bar at the top is locked into place by having a scroll split at it), and everything worked.

So I went back and tightened up the timing of my split screen scroll.  The NES PPU has some weird quirks, where underlying registers change automatically during rendering, so it's quite possible that I was taking too long, and things changed out from under me in the middle of setting up my split-screen scroll.  So optimizing the timing of the scroll actually ended up solving the issue.  WHEW, that only took about an hour (which is about 4 hours less than the time I've spent so far trying to fix the bad wiring in my house that fried my TV and desktop computer)

There's still one new issue that appeared on hardware that I need to fix, with the title screen getting corrupted, but I think I know what's going on there.

And here I thought I was done. Oops.

Friday, February 24, 2017

NESDev Results and more

Well, Spacey McRacey got 14th place out of 18 games.  Which is really about where it belonged; there were some really high-quality entries for this competition!   They're now in the process of trying to figure out how to build the competition multi-cart, which you'll be able to eventually buy, with all these games on it.

In other news, we're finally getting close to the Atari Age release of Atari Anguna. It's taken awhile to get all the boxes/manuals/etc printed, but it's almost there!

And I've got a partner lined up for my next game, which will hopefully finally be my dream of a Blaster Master-inspired metroidvania for NES.  Well see.

Tuesday, January 31, 2017

Spacey McRacey done

Well, I've submitted my game to the competition.  I think that means I'm done.  You can download it and try it from http://www.bitethechili.com/spaceymcracey/.

Now that I've already submitted it, my PowerPak arrived in the mail.  So I guess I can go back and test it on hardware now that it's already done.  We'll see what happens.

Now it's time to start planning my next project!

Sunday, January 22, 2017

AI

Well, I managed to squeeze in some terrible AI into the game.  So it's actually playable one-playered now.

I've got a week. Time to test thing thing and get it out the door.

Thursday, January 19, 2017

Testing time

Well, Spacey McRacey is at that point.

That point where I feel like I'm finished.  But I need to play through the game a hundred more times.  Well, except that to properly test, I need more players.  And time.  The deadline for the development contest is in about a week, but I'm currently in the middle of buying and selling a house.

I really hoped to add AI as well, so you could play the game with 1 player.  Not sure I'll get to that now, at this point.  We'll see what happens.

If anyone wants to download and play with it, let me know.  I'll eventually put it up on my Bite the Chili website, but for now, just email me or comment if you want to give it a try.

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...