Sunday, August 26, 2007

Lies, damned lies, and statistics

I needed something to use when deciding which tables benefit most from move to zero page, so I counted words and their occurences in all source files. In addition to giving me the info I wanted, it revealed something else.

Paradroid Redux Top 30 ML Instructions

1549 lda 202 adc 119 bmi
1362 sta 175 lsr 108 iny
679 jsr 167 bcc 106 clc
394 ldx 163 stx 100 sbc
380 ldy 151 bpl 85 dec
313 bne 144 asl 84 eor
251 rts 133 bcs 83 ora
245 beq 131 inc 82 bit
219 cmp 130 sty 81 sec
210 and 124 jmp 76 dex

Disclaimer: Above counts include some code which is commented out, and I didn't expand all macros either.

Saturday, August 25, 2007

Zero page roundup

I finally took the time to change all zero page variable declarations from

var = $02
var ds.b 1
and removed all variables which aren't used any more. I suspected I would end up with 30 to 40 free zero page locations, but it turned out to be about 70 bytes! I swiftly used half of it for the two most used object variable tables (16 bytes each), which makes accessing them both faster and smaller. I guess those tables really are accessed a lot, code size was reduced by over 100 bytes... I still have room for another two tables there, but I have to find the ones which gain most cycles/bytes.

Complete list of bug fixes since the previous release:

  • Droid teleportation doesn't send them outside the deck any more.

  • Waypoint chars are placed onto deck map every time when exiting lift, meaning no more completely confuzed droid army.

  • Door status is restored when exiting lift, so droids won't get stuck against them any more.

  • The first deck entered after load had waypoint magic chars visible, as they aren't hidden in EnterShip() routine but in EnterDeck(). Instead of wasting three bytes to add one JSR call, I changed the font so magic chars are there after load :)

  • Background stars are now really disabled during the intro sequence, that avoids random colors for lower half of "7" char. I disabled them earlier, but that broke when I added more run-time randomizing.

Important bits here.


Two more bugs fixed, one remains... Intro text scrolled beyond the end of page sometimes, and out-of-sight droids were paralyzed on C128. The remaining bug allows droid go through wall in certain conditions, something which I didn't notice on emulator.

Friday, August 24, 2007

Squish 'em

Two bugs found and fixed, both of them having the same root cause. Whenever you change deck in lift, it's built immediately, even if you don't actually enter that deck. This avoids a delay when you exit the lift. However, if you then decide to go back to the deck where you entered lift after, game keeps previous droid/deck status intact but deck map is reset to the default state.

Now, the two bugs:

  1. All waypoints are now marked with magic chars for faster detection, and I didn't restore them when re-entering deck. Mea culpa. Now waypoints are decompressed/marked correctly evrey time. This means that some work is done twice when entering a new deck, but it's fast enough to be unnoticeable.

  2. Doors keep their state on re-entry, but deck map has all doors closed after decompression. If droid had opened a door when you caused level build in the lift, droid got stuck against/in the middle of a door which was visually closed, but logically open. This bug was there from the beginning. I added some code to restore door visual state when entering a deck, and it seems to work. Doing this with minimum amount of new code made door code resemble spaghetti tho.

New beta out during this weekend, with almost all known bugs fixed. Well, make that all known bugs fixed if I have time for it :)

Sunday, August 19, 2007

Another week gone by

And so time passed by with nothing extraordinarily great done...

I found a bug in the latest beta - it teleports droids to the great unknown because I didn't adjust the teleport routine when I changed the waypoint system. Fixing that didn't take long, but with the released beta you need to enter another deck and come back to get droids back. Just visiting a lift doesn't work.

Multicolor is almost working. Almost, but not quite. I really should have done multicolor changes too when I changed the hires font...

I saved 70 bytes in the background star drawing by combining the top and bottom routine, it's not time critical so I could shrink the code without worrying about the speed. Adding random stars and blinking took most of the freed space, but I guess I can accept that.

I've used some of the new droid-specific data in old routines, speeding them up slightly as well as making them smaller. Inserting new droid AI makes every droid take slightly longer time to run, so I need every cycle I can get. I want to make big bad droids get irritated by the smaller ones when alarm is high if possible. I can already see 834 bumping into 329, shooting it out of the way and then rushing into the explosion. :)

One thing to consider is to make two passes through the droids when running them, handling visible ones in the first round and the remaining ones in the second. That way I could exit early if it looks like I'm running out of time. Sorting out-of-view droids by their distance would make it work even better, but sorting takes time...

Monday, August 13, 2007

How about a nice game of chess?

No chess here, I'm afraid. However, if you prefer more action then try the latest version of Paradroid Redux instead. Every bug listed here has been fixed (I hope).

I guess I now can go back to do multicolor changes. I really should have reordered the MC font when I did the hires one, now I need to dig out old notes telling which char ended where.


It seems that this version finally runs solid 25 Hz on PAL C64 when I remove all sanity checks. It does cheat a little, but if you can't notice it that doesn't matter, does it? NTSC C128 should do 30 Hz easily - I want one!

Sunday, August 12, 2007

Objects want to be free - but only be freed once

This weekend wasn't all bad in spite of having both my birthday and wedding anniversary (yes, my wife wanted to make sure i wouldn't forget the latter! ;) as I found the reason for the double-free bug - or at least one of the reasons.

I outlined the collision check loop(s) in an earlier entry. What's not shown in that code snippet is caching of outer loop object type, done to speed up the collision type decision. Even when the outer loop object gets removed in the collision the inner loop still continues afterwards. Check out the picture: the laser bolt colliding with two explosions is the object which gets removed twice. If the outer object type wasn't cached then all remaining collisions with it would be NOPs.

I have at least three ways to fix this:

  1. don't cache the object type

  2. exit the inner loop when outer loop object gets removed

  3. check object type against -1 (free object) every time before freeing one

I will do #2 although it means duplicating some code, as I hate to waste cycles for checking for special cases unless it's absolutely necessary. I will rethink my decision if object removal still bugs.

Wednesday, August 8, 2007

Hum Bug Betatesters

No one tells me about bugs... so I just have to play the game to find them myself! :)

  • Droid library had two bugs: every droid class text was the player class, and droid entries went from 0 to 23 instead of 1 to 24.

  • Droid count in console was wrong, it ignored some droids.

  • Deck layout horizontal scroll was broken. You all did know you can scroll it now, didn't you?

  • Maintenance deck had one droid too many on the left part, one too little in the right one. This one you really should have noticed!

  • Remaining bugs:

    • Radar is borken.

    • Lift ignores short fire button press just after up/down move.

    • Game tries to free same object twice, this causes a freeze when my sanity check catches it.

I bet there are more, but the last one is the most serious one. Thanks to trurl for first spotting it, now I can cause it too. The easiest way to do it is to enter ship 8 upper cargo when alert is red, then wait in the middle of bottom left room when berzerk droids circle around you shooting like there's no tomorrow. Well, without cheating there is no tomorrow for you...

Oh yeah, forget about the constant energizer animation part of the previous entry - I dropped it ages ago. I just hadn't played any of the official versions for a while, so when testing the Metal Edition it struck me as a difference to Competition Edition.

Saturday, August 4, 2007

Morphing into multicolor mode

I made a quick disassembly of Paradroid Metal Edition to see how much I need to change the code to make it possible to use either hires or multicolor graphics. The answer: not much. Color tables are different because only the lowest eight colors are available for character color and because of extra entries for multicolor registers. To use ME graphics I only have to reserve some extra space for the bigger tables and new title screen and add minimal amount of code. As I can do the patching inside the init routine which gets overwritten when game starts this will cost less than 80 bytes. The only thing that concerns me is the time taken by constant energizer animation, that's almost 4 lines more than changing the deck map. Does anybody notice if I drop it? ;)

The disassembly also showed that while Competition Edition was a quick hack to get something out for Xmas (in a double pack with Uridium Plus) Metal Edition got some more attention. Andrew Braybrook removed code which was disabled in the Competition Edition (raster checks which made sure that the original didn't run faster than 16 Hz), and enabled 2 MHz mode in the upper/lower border for C128 users. He also fixed the decimal mode bug which broke SFX randomly and adjusted background sounds for the faster frame rate, among other small things. Some of these changes will end up in Paradroid Redux, no doubt about that.

Too bad that I dislike Morpheus-like graphics in Paradroid myself. Anyway, those people who think that Metal Edition has the "correct" graphics can soon enjoy Paradroid Redux as much as fans of the original.

Friday, August 3, 2007

Weekend fun

After recovering from the last weekend I finished the latest changes. I hope I didn't break anything in the process... Check it out yourself.

  • Lots of flicker removed when changing screens.

  • Some internal changes which makes it run faster, although it still drops to every 3rd frame under extreme situations.

  • Game now knows about droid visibility changes which allows some more AI.

This version has most of the sanity checks removed, so if older routines get confuzed they will trash random memory. Only the droid allocator has code to hang the game "nicely" if it fails unpredictably.

Currently visibility change just flashes droid color. As you can see - or rather as you can't see - flash is only visible when going around corners and through doors. This means that droids approaching from distance have unfair advantage of spotting you before you spot them. This needs to be changed so that at least part of droid has to be visible on screen before it reacts to your presence.

Radar equipped droids won't get surprised as easily as other droids, and as alert status rises every droid with brains will react faster. I'm thinking of using different delay values for direction change, depending on droid's weight and drive. Surely 28 kg anti-grav 821 can stop and turn faster than 227 kg bipedal 751!