Monday, July 23, 2007

Another Droid in the Wall - not any more!

As expected the game has some trouble running after the changes in droid allocation, but that did make me disable all collisions (which are the only remaining thing bugging because of allocation change) and enabling them one at a time. This pinpointed droid reversal bug into droid-droid collision.

Simplified droid movement logic is as follows

  • Move droid unless it's paused.

  • If pause count is not NULL, decrease it.

  • If pause count is still not NULL, exit movement phase.

  • If droid is on waypoint, pause it or give it new x/y speed.

The collision logic for droid-droid logic may also reverse droid direction. If that happens during the game frame when droid was given new direction from waypoint, the droid ends up in the wall unless it was lucky and ends onto another waypoint by sheer luck. To avoid that game checks if droid is on a waypoint and pauses it instead of reversing it in that case.

Waypoint check needs droid character position to compare against waypoint positions. Guess what? Droid char position isn't properly set at that point! Doh!

There are couple of ways to fix this

  1. Calculate char pos for the droid to be reversed.

  2. Set flag for each droid, telling if it was on a waypoint in a movement phase. That avoids the check altogether.

  3. Add two more attribute bytes to each droid, and store the char pos there.

I don't like option 1, as that may require multiple calculations per droid for one game frame. Option 2 is good, as it avoids waypoint check altogether. This saves one to three raster lines if droid needs reversing. Option 3 is good too, as it is guaranteed to save at least one 44-cycle subroutine call per droid. Calculating char pos for explosions is extra work, but explosions are much cheaper than any other object types so that evens it out.

Forgetting to set droid char pos wasn't the only stupid error... My collision check determines colliding object types by calculating index into offset table, then doing calculated jump like this:

lda jumpoffset,x
sta jump-1
bpl *

dc.b droid_droid-jump,droid_laser-jump,...

It would have worked much better if assembler told me that jump offsets got big enough to get negative... This means that the current beta version skips some collision checks.

With those bugs fixed I just need to find out what's wrong with collisions involving droid fire. At least one of them messes up my droid_to_sprite and sprite_to_droid links.

No comments: