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!

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