Cut Off One Head…

Working on the CRPG and fixing bugs has been rather like fighting HYDRA lately… cut off one head, and two more take its place!

I decided to convert my item and spell lists to use bit-delimited strings to save some space and bring it more in line with how I was managing in-game text. Quest items and trap names are still in fixed size buffers because I would have to create a word-size look-up table to convert them, and the byte savings would be minimal at best. Maybe later…

I definitely have to be more careful now with swapping memory pages. For example, the transactions and the item names are in separate pages, so accessing the latter means losing the former, temporarily. So in some cases I copy data into a temporary workspace so I don’t have to page-switch in the midst of another operation.

At times I’ve wished I could swap memory pages into the cartridge RAM area at >6000 to >7FFF, but that would make the game require a SuperCart. (An Editor/Assembler cartridge with at least one 8K RAM bank.) It’s not necessary and I like that the game can auto-load from Extended BASIC.

I also re-wrote my Effects engine into something less platform. In practice the original design worked, but I kept having small regression errors creep in as I tested new things. So I just made each effect a separate function, with some copious recycling and re-use. It takes up about the same amount of space, and it’s much faster too.

I feel like I’m making progress though. I need to make sure the item and inventory systems are fully functional. I also need to test every mob type, which includes traps and doors still. After that, I should be able to pick back up combat engine work.

This entry was posted in Coding, CRPG, Design, TI-99/4a. Bookmark the permalink.

4 Responses to Cut Off One Head…

  1. Realms of Quest says:

    “I decided to convert my item and spell lists to use bit-delimited strings to save some space and bring it more in line with how I was managing in-game text. Quest items and trap names are still in fixed size buffers because I would have to create a word-size look-up table to convert them, and the byte savings would be minimal at best.”

    You know… now that I think about it, I could probably save at least 500 bytes in my core module alone by using bit-delimited strings — I have a lot of text elements like names for items, spells, races, classes, prompts, character sheet attributes, etc. It wouldn’t be all that hard to just look for the bit that distinguishes the end of a string instead of a zero value that separates everything. And since I use a non-traditional VIC-20 screen size, I cannot use the built-in system calls to output to the screen and I had to program my very own output functions. It’s just a matter of looking for a bit value instead of $00 to do that as well. It might take me about 60 minutes of work to just rewrite my program and do find+replace the zero value byte delimiters to accomplish this.

    Again, I will think about doing this.

    Recently, I went over all of my code to get rid of redundant and inefficient stuff. I didn’t think I would need to worry about making my own code efficient because I thought that a VIC-20 with 32K expansion would be more than enough memory that it could ever need, but I was wrong on that. But even if I had to revisit and fix my code, it helped me to get better reacquainted with the functions that I had written up to over a year ago at times. And even when your program is running on 100% machine language, getting rid of wasted CPU cycles that use mere microseconds makes the overall result feel smoother and more elegant.

    • adamantyr says:

      Nice! Yeah, I’m honestly surprised and pleased by how well they work. Having all your text in a nice compact block is really efficient.

      I found for complex displays like statistic screens, you can build them much more quickly this way as well. All you need is the start of a text block, a count of elements, and a list of screen addresses. Then you can just feed that into a “display engine” that writes it all out.

  2. Realms of Quest says:

    “Quest items and trap names are still in fixed size buffers because I would have to create a word-size look-up table to convert them, and the byte savings would be minimal at best.”

    How I find a string in my game is that I have a function where you pass a memory address by using the X and Y registers for the starting memory location, and the accumulator (A) as the string number that you want to find. What is “returned” is the address of the found string at the address stored at TEMP1,TEMP2 (6502 uses 16 bit addressing, or 2 bytes. So TEMP1 represents the lower 8 bits of the address while TEMP2 represents the upper 8 bits of the address).

    FINDSTRING:
    ; x/y is low/high to be passed of beginning of array
    ; # of string is in ACC
    ; returns TEMP1,TEMP2 address of string

    STX TEMP1 ; store the address passed through X/Y in TEMP1/2
    STY TEMP2
    LDY #0
    LDX #0
    STA AT_tempa
    CMP #0
    BEQ @PS4 ; if string number to find is 0 then there is nothing else to do
    @PS1:
    LDA (TEMP1),Y
    BEQ @PS3 ; we are looking for a byte delimiter of value zero.
    @PS2:
    JSR ADD1LOHI ; this increases the address pointer at TEMP 1/2 by 1 byte
    JMP @PS1
    @PS3:
    INX
    CPX AT_tempa ; have we found the correct string yet?
    BNE @PS2

    ; the string has been found
    JSR ADD1LOHI ; this increases the address pointer at TEMP 1/2 by 1 byte
    @PS4:
    rts

    I’m not sure how applicable this is to TI/99 machine language or if the nature of your game engine does not permit this type of searching, so pardon my ignorance if there are reasons why a search string function would be unfeasible in your case. With this, you can have a “string array” of up to 255 elements.

    • adamantyr says:

      That’s certainly possible to do! Right now my quest item list is incomplete, so I don’t know how large it will actually be.

      I haven’t written “string finder” algorithms yet, but it’s certainly doable. You’d just feed it a start address and have it look for delimiter bytes to determine each new string location. You could even generate an array of start addresses if you wanted to access several of them at a time, although you’d have to be careful and give it a set limit of how many to find, otherwise it would just merrily process your entire memory…

      Traps DO have some other metadata I could extend to add an address word. Right now I have more than adequate space for my needs. 🙂

Leave a Reply to Realms of Quest Cancel reply

Your email address will not be published. Required fields are marked *