Elevated Expectations

And back to CRPG stuff…

WP_20130330_002I was at a remote forested area which had a beautiful viewpoint from a forested hill of a waterfall across from it. I realized such an awesome view would be impossible to do in my current engine because the forests would automatically block your sight. That got me thinking about the concept of elevation in my CRPG.

If every tile on a given map had an elevation value, you could automatically consider anything lower than the current location’s elevation as viewable, and anything higher as not viewable. That way you could create canyons and depressions that limit visibility while hills or lookout points improve it! I’d only need to use about 3-bits (0-7) to get a good amount of range too. Tiles like forests would continue to block line of sight at the same elevation, unless you were above it.

As I pondered the implementations of it, I realized I had one small problem; I’d need more memory to support an elevation map in the game. Right now I have a 4k buffer for maps; I would need to either shrink it to support an elevation map, or find more memory somewhere. (I’m thinking I could use about 3k for tiles and 1.5k for elevation/light mapping… I’m sure I can dig up 512 bytes somewhere.)

Why don’t I compress the maps with something like RLE (Run Length Encoding)? Well, that’s mainly to save disk space. You still have to decompress into your local memory. And disk space isn’t an issue with this game; a primary difference from developing vintage games in the modern era is that you don’t have the concerns of manufacturing and packaging floppy disks. So you can use the biggest disks available without fear.

For now, I’m marking this idea as a P2 (Priority Two, nice to have but not strictly necessary) and shelving it. I really want to finish the combat system before I return to travel mode. And I should get the quest system and other elements done before I go around adding new things to other modes.

Combat engine work is still mostly idle; I’ve been trying to complete my spreadsheet of FX data before I go any further. This is so every spell has a combat effect that I can test and make adjustments to, as needed.

The way I handle FX in the game is essentially an engine that processes commands in 8-byte segments. There are commands to create sprites of a given pattern/color and animation style, move sprites from one point to another, create a circle, cone, or line effect, and so forth. But I have to have data to test.

One big element that will require a lot of testing is the timing. For several of my effects, I provide for a delay count so that the engine knows when to stop and move on to the next effect (if any). Sound effects are handled by the interrupts, which means they can’t really be used to time things. So I’ll need to try effects, make a judgement call on how well they look, and make adjustments as needed.

On the subject of sound effects, I’ve been doing a little redesign there too. I went back to the Tunnels of Doom sound effects to borrow a few (the monster ones are particularly good for negative effects) and I’m always impressed by them. The sounds are VERY small, only taking around 19-21 bytes of space each. Each seems to follow a pattern of three different tones, but also use the noise generator and different durations to achieve an effect. I’d like to go back and redo some of my positive sound effects (healing, curing, etc.) to match the same pattern, but that will take awhile and I have stock sounds I can use in the meantime.

Right now, my list of tasks is as follows:

  1. Fill in FX for all combat-oriented spells. Use placeholders if need be for some.
  2. Expand the action array to include direction of attack and other elements. I originally was trying to squeeze all action data into a single word (16 bytes), but now that I’m not processing sets of actions anymore, I can make this more informative and easier to use
  3. Fully split damage out from attack. My initial code had them closely tied together; this won’t work for area attacks, which ignore defense rolls. It also needs to consider effects, like positive/negative states.
  4. Make sure that area attacks that affect multiple units will process against all affected units and locations. I’m pretty sure this is set up, but it hasn’t been tested, and I may have biased it towards one unit while doing ranged attacks.
  5. Look into whether or not I can condense and data-orient the effects routine. Right now it’s 426 bytes of code that just changes a state array directly with addresses and instructions. Writing a data array structure that can do everything could be tricky though.

Plus I have two bugs to fix:

  • When the wizard uses a wand, the wand effect pattern doesn’t appear to be changing orientation, as opposed to the arrows/quarrels used by the other party members. Could be a data issue?
  • Some shots at particular angles are traveling well past screen boundaries and looping around. Smells like an overflow math issue with calculating the slope.
Posted in Coding, CRPG, Design, TI-99/4a | 8 Comments

Review: When a Star Falls

Time to take a short side trip in my blog to WhenAStarFallsreview a product…

“When a Star Falls”, UK4, was the first Dungeons & Dragons module I ever purchased. It was back around 1984, when book stores were selling D&D products and occasionally dice.

I bought it because it was for levels 3-5, a low-level module. I was still playing the box set of D&D at the time, and I didn’t realize the module was for Advanced Dungeons & Dragons. Given that at age 9 I could barely follow the regular D&D rules, Advanced was quite out of my means.

As I got older, though, I began to realize what a treasure I had accidentally purchased. The UK series of D&D modules were some of the best ever written. Most of them featured intricate plots and clever adventures that were far more than just a dungeon map with a list of encounters. It’s unfortunate that TSR UK was eventually closed down in the mid-80’s. The lead writer, Graeme Morris, actually left the gaming hobby entirely and his whereabouts are unknown.

So, on to the module…

The first bit of awesomeness about this module is how it begins. While traveling across a moor, the party comes across several dead monks, encased in a strange web. The web is a living entity that absorbs memories. After killing it, the memory web releases all its stored memories, which imprint themselves into the characters. There are over a dozen memories, described both with a few lines of dialogue AND an illustration.

ODerwythh yeah, the illustrations are incredible as well. The artist, Jeremy Goodwin, creates some incredible scenery and sinister characters with an asymmetrical style that really stands out from the U.S. D&D modules. Even his black and white illustrations rock. If I could find him and he was still a commercial artist, I would SERIOUSLY consider hiring him to do illustrations for my CRPG’s manuals.

Anyway, the memories give the players the information they need. A star fell from the skies (a meteor) in the region, and the monks were on a journey to take a valuable tome to a sage, who would be able to tell them where it fell. The monks were going to retrieve the star for their master, the sage and oracle Shalfey, who resides at the Tower of the Heavens.

SionDuring their travels, the players also have an unwelcome visitor, the monk Sion, who serves Shalfey’s principal apprentice, Piyarz. (I also LOVE the names…) Sion has undergone a terrible ritual to become a shade, a half-shadow man that gains strength in shadows and is effectively immortal. He stalks the party, attempting to learn their intentions and, if need be, slay them.

The sage Derwyth tells the party that the star has fallen to the north along the river. You eventually discover that it has fallen directly on the lair of a tribe of derro, small blue-skinned creatures of the Underdark known for their sadistic cruelty and insanity. (The Underdark was still two years away from being introduced into D&D at this point.) Most of the derro were killed in the blast, but the survivors excavated the fallen meteor to examine it. The party must enter what remains of their lair and retrieve it.

DerroAfter this, the party travels to the Tower of the Heavens. If they head north up-river, they have an interesting non-combat encounter. Tribal hunters and fishermen live on a lake there, but they’re isolationist and paranoid. Numerous derro raids have left them suspicious and hostile towards strangers. The party has to be diplomatic and careful to convince them to allow them to cross the lake. At one point in the village, while being hustled through by spearmen, a child screams from inside one of the huts, causing the party’s escort to panic and attack them. If the party manages to keep their temper, the mistake is discovered and all is well. These kind of quandaries for players to solve (preferably with no violence) are a welcome change from dungeon crawls filled with no ethical decisions to make.

At the Tower of the Heavens, the players discover the truth. Shalfey is being held prisoner by Piyarz and the other lesser sages. None of the other tower residents, including the gnomish mercenaries who guard it, know this. Piyarz desires to kill Shalfey and take over the tower, but Shalfey locked himself into the upper tower and threatened to destroy the books of prophecy, which are needed to see the future.

Again, the players face an ethical dilemma. While the lesser sages, Piyarz, and their monk guards are all fair game, the gnomish guard and the regular tower residents are all innocent and unaware. A party who charges in, slaughtering everything, will neither get very far (they’re SORELY out-numbered) or accomplish anything heroic. Pretending to be supplicants for an oracle reading and then sneaking in is the best route.

When the players deal with Piyarz and his minions, they learn the truth from Shalfey. The books of prophecy (which he just burned prior to the players coming in) were blank! Their knowledge of the future ran out, and the last clue given was that a fallen star must be taken to the nearby hills where a group of “dark smiths with a fabled library” live and exchange the meteor for a new set of books. So one final mission remains.

bozorgThe dark smiths are a group of Svirfnebli, underground gnomes, who found a prismatic sphere guarding a set of books and decided to build their forge and base around it. While not evil, the inference is that the smiths are anything BUT good. They have built a number of automated minions called Maschin-I-Bozorgs that look like giant  frisbees that fire darts and jets of steam. The party has to fight some before the Kagu-Svirfnebli will talk to them, and take the fallen star in exchange for the new books of prophecy. The star dispels the prismatic sphere guarding the books.

One last trick remains, though. The Svirfnebli leave the forge to return to their home in the Underdark, setting off the “self-destruct” button on the way out. The party must flee the cave before it collapses. When they reach outside, they find two red dragons waiting for them, allies of the Svirfnebli who are suspicious at the destruction of their home and angry at losing a source of treasure and food. This is the one part of the adventure I don’t like; aside from the meanness of dropping two major opponents on the party at a vulnerable time, and feeling like a cliche ending (you have to drop dragons into it, seriously?), the worst is that dragons are SOLITARY creatures and would never pair up for any long period of time.

The ending of the adventure leaves the party with questions. What was the fallen star, exactly? What are the intentions of the Kagu-Svirfnebli? Will they make a weapon of evil destruction from it? The great thing about this adventure is how it leaves an open thread for future endeavors.

The adventure recently became available on D&D Classics as a PDF. You can download it here: http://www.dndclassics.com/product/17075/UK4-When-a-Star-Falls-%281e%29?it=1

Posted in Gaming, Review, RPG | 1 Comment

Animated Changes

I’m still working on content changes right now… graphics, sound effects, actual FX for all the spells… a lot of work to do before I go back to coding up things.

One aside was to update my animation code. I’ve had the same block of code in place for several years, and it’s functioned adequately. But it’s hard to expand, as it’s really just a set of linear instructions for each character block. Some sample code is this:

* Tile animation
ANIME  DATA AWS,AM1
AM1    MOV  @CLOCK,R0
       ANDI R0,>0003
       JEQ  AM15
       RTWP
AM15   LI   R0,>2468
       LI   R1,HIBUFF
       LI   R2,40
       BLWP @VMBR
       LI   R1,32
       BL   @ANORTH
       C    @CHAR,@W1
       JLE  AM16
       CLR  R1
       BL   @ANORTH
       LI   R1,8
       BL   @ANORTH
       LI   R1,16
       BL   @ANORTH
       LI   R1,24
       BL   @ANORTH
AM16   LI   R0,>2468
       LI   R1,HIBUFF
       LI   R2,40
       BLWP @VMBW
       LI   R0,>0400
       LI   R1,HIBUFF
       LI   R2,104
       BLWP @VMBR
       LI   R1,64
       BL   @ASOUTH
       LI   R1,72
       BL   @AWEST
       LI   R1,80
       BL   @ANORTH
       LI   R1,88
       BL   @AEAST
       MOV  @CLOCK,R1
       CLR  R0
       DIV  @W16,R0
       MOV  R1,R1
       JEQ  AM2
AMEND  B    @AM7
AM2    MOV  R0,R7
       ANDI R7,>0003
       LI   R1,24
       BL   @AROT
       LI   R1,32
       BL   @ASOUTH
       LI   R1,40
       BL   @AWEST
       LI   R1,48
       BL   @ANORTH
       LI   R1,56
       BL   @AEAST
       CI   R7,3
       JNE  AM25
       CLR  R1
       BL   @ASOUTH
       BL   @AEAST
       LI   R1,8
       BL   @ASOUTH
       BL   @AEAST
       JMP  AM3

This kind of imperative linear approach is all right, if you don’t have a lot of things to do. Truthfully, in assembly language, you often have to balance whether or not a more generic data-driven approach wouldn’t just end up costing you more memory than its worth.

In my case, my animation requirements DID get up complicated enough I wanted to get away from this approach. I also wanted it to be easy to add new patterns or alter exiting ones (and their animation speed) with a simple change.

Here’s some of the new code, which uses a data array to store the VDP address, size, and speed and type of animation. It’s then processed in a short loop:

* Tile animation
ANIME  DATA AWS,AM1
AM1    MOV  @>8314,R10                 * Copy stack address to R10
       MOV  @CLOCK,R0
       ANDI R0,>0003                   * Check clock value for 1/15 interval
       JEQ  AM2                        * If not, skip animation
       RTWP
AM2    LI   R8,ANDAT0
       BL   @ANIMAT
       C    @GSTATE,@W2                * In combat mode?
       JNE  AM4
       LI   R8,ANDAT2
       BL   @ANIMAT
AM3    RTWP
AM4    C    @CHAR,@W2                  * Is character set 3-7?
       JLE  AM3
       LI   R8,ANDAT1
       BL   @ANIMAT
       JMP  AM3       

ANIMAT MOV  R11,*R10+                  * Animation looping for blocks
       MOV  R8,R9
       MOV  *R9+,R0                    * Load character data 
       LI   R1,HIBUFF
       MOV  *R9+,R2
       BLWP @VMBR
       CLR  R1                         * Clear pattern index
       SRL  R2,3                       * Get proper count into R2
       MOV  R2,R7
ANM1   MOV  @CLOCK,R3                  * Get clock value into R3
       CLR  R2
       DIV  *R9+,R2                    * Divide by speed factor
       MOV  *R9+,R0                    * Get animation routine into R0
       MOV  R3,R3
       JNE  ANM2                       * If not at interval, skip
       BL   *R0                        * Branch to animation routine
ANM2   AI   R1,8                       * Increment to next character
       DEC  R7
       JNE  ANM1
       MOV  *R8+,R0                    * Write character data 
       LI   R1,HIBUFF
       MOV  *R8+,R2
       BLWP @VMBW
       B    @SUBRET

* Pattern animation data for travel/combat mode 0-6 (56 bytes)
ANDAT0 DATA >0400,104
       DATA 16,ACIRC
       DATA 16,ACIRC
       DATA 16,AUPDW
       DATA 8,AROT
       DATA 8,ASOUTH
       DATA 8,AWEST
       DATA 8,ANORTH
       DATA 8,AEAST
       DATA 4,ASOUTH
       DATA 4,AWEST
       DATA 4,ANORTH
       DATA 4,AEAST
       DATA 32,ACIRC

My old approach was using around 436 bytes of code space. With the data arrays and the smaller routines, my new system uses about 100 less bytes, and is easier to use. On screen, speed seems unimpaired as well. Huzzah!

Posted in Coding, CRPG, Design, TI-99/4a | Leave a comment

From my Video to my Radio…

Bonus points if you can identify the source of today’s blog entry title…

Camtasia is a FANTASTIC video recording software tool. My trial period will be up at the end of the month, but I’m definitely going to go ahead and buy the full version. (No, I don’t hack trials. If you like something, give the creators their fair due so they’ll make more.)

I’m still a bit off from creating spell effects, which should be pretty cool to see and make changes and adjustments to. For now, here’s a video of the dynamic battlemap loading and random placement of units on opposing sides:

Posted in Blog, CRPG, TI-99/4a, Video | 6 Comments

Tactical Position

bm4It was a bit more work than expected, but battlemaps are now loading dynamically AND units are being placed dynamically as well.

The main problem I encountered was that my trigonometric functions were, well, not working right. I dug around and found a test program I’d written for them and discovered I had fixed the issues there, so I just had to port the code over into the CRPG source.

Experimentation with positions was a bit of work too. I wanted it to be intelligent when placing units. Your top two units are your “front-line” characters, so they should usually be the ones closest to your foes, while the others hang back. So I included a starting angle and two different coordinates for each side of the map. Interestingly enough, the second set of coordinates end up trying to place units off-map, which kicks in the directional placement, that scoots them back in on the back line. Wow, it’s like I designed it that way. 🙂

For ambushes, there’s only one coordinate at the center, and both sets of units are placed around it at a different radius. I haven’t written this code yet, since it requires monster A.I. to make sure that they get the first turn.

Now I’ll move on to the battle’s end, when treasure is determined and clean-up and updates are done prior to returning to travel mode. Eventually this will also involve updating data on disk; I do not want the game to have the same encounters (and treasure) in the same place. If there’s one thing I’ve learned from reading up on the CRPG Addict’s blog, it’s that CRPG’s should make you feel like your actions CHANGE the world.

Posted in Coding, CRPG, Design, Screenshots, TI-99/4a | Leave a comment

Battlemap Rebuild

As I continue working on the combat engine, finishing up other portions of “temporary” code has come up. One particular one is the use of battlemaps.

Most of the 2D CRPG tactical combat games feature some kind of varied terrain to conduct battles on. Ultima’s III-V all had them, one for each different terrain type. So obviously I intended to follow suit here.

bm1But, since I have the disk space for it, I intended to go much further than any of those games. Ultima V only features 16 unique battle maps. My CRPG? Oh, probably around 300+.

I started battlemap design several years ago, when I was still working in the MESS emulator. I actually had to port my work off an old work disk to continue it, and update the tiles, which had changed a few times since I made the original file. Now I’ve gone one step further and made a separate battlemap set for each tile set. That way I can have as many as I need to make combats always potentially interesting.

One complication I had to correct was the loading of different tile sets. Originally I had only a single set for combat. Now I’ve expanded it so that there’s a tied-in tile set for each of the major travel types. That lets me have maximum character space to do interesting features. If you’re in a town battle, lamp posts, crates, barrels, may show up on the map. A dungeon has manacles, skeletons, and other macabre items. All fun!

bm2An added bonus with my approach is that battlemaps will be alterable by player action. Spells exist that let you create barriers, area effects of damage spells can destroy the landscape, and so forth. I don’t think any classic CRPG offered this kind of feature, keeping most of the terrain fairly static.

Battlemaps are stored in two 128 byte records. The first 8 bytes are a compressed mini-map that indicates if the spaces are empty or occupied. The rest of the space stores the maps in RLE compression, using values lower than 128 to indicate a count of the next tile. My battlemap editor warns me if I exceed the record size. This usually happens if I get overzealous with spreading unique tiles around. (I don’t use RLE for the travel maps, because the high-byte is used to indicate lit/unlit squares on dark maps. No real need to compress those files anyway.)

One particular problem to solve is the placement of units on the battle map. I considered at first an array of common positions to just iterate through, but it was quickly adding up to a lot of bytes of data to store. So then I realized I could do this algorithmically with tools the code already has: the trigonometric functions.

Using that code, all I have to supply for the map is two things: a set of coordinates and a radius. Because I want units to spread out a bit, I actually supply two sets. The number of units is divided in half, and then each half is placed in a circle around that coordinate, with the angle being based on the number of units. (4 = 90 degrees, 3=120 degrees, and so forth.) For an ambush scenario, a single set of coordinates is used for both sides, with different radius’s, so one is surrounding the other.

bm3What to do if the chosen space is occupied? Well, first it will check all adjacent squares to that square for any open spots. If it finds one it takes it. If all four cardinal directions have nothing, then I just default to selecting completely random coordinates until an empty space is found. This means there’s a potential for a stray unit to end up in some bizarre place, but hey, that’s the fog of war…

I wrote up the necessary code to do the positioning this afternoon on paper, now I just need to get it written in code and incorporated into the source. I may also need to refactor my trigonometric functions a bit; they were assuming whole word values and I’m pretty much exclusively in bytes, for sprites and coordinates.

Oh yeah, the trigonometric functions. No, I’m not using the ROM routines. They’re difficult to implement and use, plus I’d have to convert everything to Radix 100 floating point. Instead I use whole integers, with a base of 256, and stored the main 90 degree set as values 0-255 in a data table. Ratios are then calculated by multiplying the angle by the data table value and dividing by 256. It’s obviously nowhere near as accurate as a floating-point method, but for what I’m using it for, it works pretty well.

When I get battlemaps loading and positioning of units working, I will probably move on to getting combat ending debugged and sorted out. I’d like to have the end-to-end of it mostly done before I get into the long arduous process of spell FX.

Posted in Coding, CRPG, Design, Screenshots, TI-99/4a | 13 Comments

Checkmate

Let’s take a moment to look at the monster A.I…

Monster A.I. can be as simple as just calculating the deltas of the positions and making them into coordinate change values. My favorite version of this came from an old BASIC program that used the SGN function on the deltas to just make them 1, 0, or -1. That makes the enemy move closer to the target.

For my CRPG, of course, something more complex is needed. I still regret that I can’t have multiple monster types in a single combat… it would be great to have melee types who charge the players while archers and spellcasters rain destruction upon them from afar… but I don’t have the codespace or graphic space to support that. So I definitely want the A.I. to be a bit more deep than “move towards player unit. Attack until dead.”

The first part is how smart the monsters are. I’ve decided on four levels of intelligence:

  1. Dumb – No brain to speak of, always attacks the closest enemy
  2. Animal – As #1, but also considers past attacks for optimal targets
  3. Smart – As #2, but also calculates threat for each movement vector based on closeness of enemy and allied units and obstacles
  4. Really Smart – As #3, but also considers ranged and spellcasting by enemy units as aggressive actions

For each monster, there are a potential four counters for each player unit, which are used to track aggression. These start at 0 for the beginning of combat, and are added to each time a player unit has a successful attack on the monster unit. That weighs the monster in favor of attacking that unit over others.

There are two phases to each action by a monster unit, acquiring a target and determining an action to take.

Targeting uses the distance of each enemy unit as a baseline, subtracting it from a high value so that closer units have higher weight values. If the monster considers aggression as a factor, this is also added. Targets that it can’t see (such as invisible units) are not added to the array at all.

If the monster is confused, ALL units are targetable, and it just picks one at random, skipping over weight calculations. In the case of only a single target (a solo party), it just picks that target. In the case of no targets (a solo invisible target) then a target isn’t factored into movement, and no targeted actions (like ranged weapons or spells) are done.

The next phase is actions. A monster only has a maximum of seven actions:

  • Move up
  • Move down
  • Move left
  • Move right
  • Fire a ranged weapon
  • Use a special attack
  • Guard (ending turn)

Each action is added to a weight array. For movement, distance to the target is added again as a weight, so that the move that gets the monster closer to the target has the highest value. Ranged weapons have a higher weight value if distance is greater, and a random value is added to it just to keep things a little random.

I’m still considering special attacks. They are basically spells, which means they could be buffing spells, area attacks, and so forth. This requires a bit more calculation to determine when the monster uses it.

The guard action will have a higher value if the monster’s action points are low compared to the maximum. That should push the monster into ending his turn unless a particularly valuable action over-rides it. Like players, once action points hits 0 the turn ends, and any negative value is taken as fatigue damage.

For movement, if the monster is smart, he also considers threat levels. This means that the target square’s adjacent squares are considered. Obstacles like trees or boulders are good, they offer cover and reduce chances of being flanked by enemies. Likewise, allied units are good and add to the value. Enemy units, on the other hand, reduce the value. So does screen edges, because the monster doesn’t want to retreat. And magical effects like a fire wall or thorny patch will also reduce the value.

The nice thing with this approach is a simple switch to a different array allows me to simulate a fearful or retreating posture as well. In that instance, screen edges are VERY valuable, and enemy units close by make movement undesirable in that direction. Confusion will just mean the monster picks an action entirely at random.

This same A.I. is also used for players in a negative state, such as confusion, charm, or fear. This means the work I did to encapsulate actions into small consumable data words that could be passed into an engine is still useful, because I’ll need it for both the monsters and players.

The main pain of implementing the monster A.I. will be debugging it. Since a lot of these actions occur offscreen, I’ll have to set up some VERY specific test use cases to try out different scenarios, and then use the debugger to view the resulting action and make sure the logic chains are all working out. I expect the code hit will be hefty as well, to do all these calculations.

But it should be worth it to give the player a worthwhile and challenging tactical battle.

 

Posted in CRPG, Design, TI-99/4a | Leave a comment

Ready, Aim, Fire!

Firing a crossbow Real life has been super busy and complicated lately, but I found some time to hammer out and get the ranged combat system fully functional.

The big addition was adding sprite movement to the FX engine. I wrote up a small model in Extended BASIC to test moving one point to another, and implemented that in assembly code. Unfortunately, I found out my design was flawed… steep angles weren’t lining up right. I had to go back and implement Bresenham’s algorithm closer to the standard to get it right.

A complicated bit of code was calculating the correct pattern to use for ranged missiles. There’s basically five types:

  1. No direction, just single pattern
  2. 8 direction pattern, cardinals and diagonals
  3. 4 direction pattern, cardinals
  4. 4 direction but either left/right or up/down only, cardinals
  5. 8 direction but either up/down, left/right/, NW/SE, NE/SW

The code to detRanged2ermine what pattern to use based on the slope to the target was tricky to figure out, but it turned out to only require a single data array and some clever bit-masking for the different types. It’s by no means PERFECT, but it’s good enough for the effect.

I found a host of small bugs on the way, many on the design side. I had implemented a lot of the work at different periods, and what the code was doing and what the data was set to was in places two different things. For example, I had in my spreadsheets that a set color of 0 meant to rotate through all colors, but this wasn’t done in the actual animation code.

So, now that ranged combat is finished, I can move on to spells. I just finished re-writing my spreadsheets of spells and types to accommodate the changes to the combat system. Now I can do the work of implementing it in code. Unlike ranged combat, spells also can affect multiple targets. The affected unit determination code is written and in use for single targets, but how it will work with multiple remains to be seen…

Ranged Combat (Video)

After spells comes monster A.I. I was doodling up some ideas here today on paper, and have a good idea of what I want to do here. Testing it will be a pain, though, since much of the action will be determined behind the scenes. I may have to model it in Extended BASIC as well…

Posted in Coding, CRPG, Screenshots, Video | Leave a comment

Things I Have Learned from Writing a Vintage CRPG

As I am now going into year 8 of creating my vintage CRPG, It’s time to take a look back at things and share what I’ve learned from the experience of having a hobby programming project. Or, you know, I’m just looking to write something in my blog today.

Know your Platform and Resources

Before you start out, you need to know what you can do, and what kind of tools you have.

Programming on your ACTUAL vintage computer sounds like fun at first. But the truth is, nostalgia has made you forget some of the little problems with that old hardware…

For one thing, old computers ran HOT. Even modern computers can warm the room, but your old computer would get hot enough to make that funny heated plastic smell. Could be a little alarming after all these years to smell it, it starts you thinking about whether or not you should keep a fire extinguisher close by.

On that note, old hardware is old hardware, after all. You don’t know how much longer you have on a given chip or device before it dies on you. Fixing it or finding replacements could prove time-consuming and costly; vintage hardware is not that much cheaper than modern-day due to rarity. And finally, old computers lock up a lot. My old TI was particularly sensitive around the side-port, one bump and goodbye to hours of work.

Obviously, an emulator is the way to go. There are a large variety of emulators available nowadays that do a great job of emulating the original hardware. Plus you have the added bonus of being able to write up your code in a text editor on your PC and just paste it into the emulator. AND emulators can usually be ran at much higher speeds for compiling purposes.

Some other useful tools:

  • Microsoft Excel. Spreadsheets are excellent to use to track data structures, graphics, and other aspects of your work
  • Hex Editor. You can find a number of commercial and freeware hex editing software which will let you directly alter your emulator’s data files
  • Paint Programs. Useful for creating graphics for your game

Engine First, Content Later

This particular issue happens a lot with game design. Namely, you get so excited about the end product that you start doing the content work before you’ve even written a single line of code.

For myself, I’ve wasted a LOT of 8-10 square per inch graph paper designing maps for my CRPG that was, in the end, a lot of wasted effort. I got so caught up in the story ideas I had that I just had to design the maps for it. I told myself it was important research work for the game engine of course… I had to know how much flexibility the engine needed, after all.

Of course, while you’re doing all this, you’re not actually doing any work on getting the game engine done. If you did things in the reverse manner, then at least you could update your story to match what the engine can do, and you have something substantial to keep working on.

Funny enough, I’ve seen the opposite as well. I read an interview of a programmer for an arcade clone on the TRS-80 Color Computer. He showed a remarkable degree of coding awareness and understanding of the platform and how to get the best performance out of it. But when he was asked about game design or what he thought of other games, he seemed lost and confused. He knew how to copy the game rules to an existing game and make it work on the platform, but creating his OWN rules or game was completely beyond him.

Commit to a Design and Stick With It

There is no way I would have finished this game as a teenager. The amount of compiling, debugging, and hunting down bugs would have bored me to tears. Plus, my disk drives would have burned out with all the compiling work I was doing.

The truth, though, is that any sizable programming project should be planned out WELL in advance, and almost written away from the computer entirely. With modern tools, it’s too easy to fall into the pattern of cowboy coding: Put something together and see if it works.

This also helps with another issue: Redesign. Software is never a step-by-step process. You often end up going back and changing something later, which affects your current work, which requires redesign and recoding, and so forth.

But the problem is made even worse when you change your mind about fundamental aspects of the project itself. For myself, I’ve altered the design of the game engine (as in, the rules by which the game is played) four times. Each time required a massive reorganization and updating of data, code changes, and even design alterations.

I could have avoided this problem had I sat down with a pad of paper or two and just wrote out my design and made sure it worked on paper first. Some redesign was inevitable; since I was discovering the capabilities of my computer in the process, some ideas proved to be too burdensome or grandiose to follow through on. But it’s almost better to finish something sooner than get stuck in a constant cycle of redesign.

Use Source Control

This one is a major requirement of modern-day software engineering. Source Control lets you maintain version history of your files, lock files so that multiple programmers can edit the same files but not overwrite one another, etc. You read stories about companies and teams who refused to jump on this bandwagon for years, but sorry, this is totally necessary.

But why for vintage game programming? And when you’re the only one on the team?

Well, the main value is the version history. If you have data sheets that are undergoing a lot of changes, it’s good to be able to refer to a past one. It also helps you consolidate changes easier. Truthfully, I still don’t have a source control system going for my CRPG, and I really should get one so it’s easier to sync up files between locations.

Comment Your Code

Yeah, you’re the only one writing it, right? And real programmers don’t need comments, they just figure out what the code does at a glance right?

No. Comment your code. Trust me.

If you’re working on a hobby project, you’re going to have a lot of other things that are going to interfere with it and make you stop it for long periods of time. Commenting your code will save you a lot of grief and time trying to figure out what you were doing.

Also, commenting can help you lay out the logic path of your code. Often in assembly language, you don’t have a lot of context as to what register is storing what value. Using comments to remind yourself of what this code is intended to do can help you find bugs later when you look at the logic and say “Hey, wait, that’s not right.”

Document Your Progress

Creating and maintaining a blog or website on your hobby project is very good to keep you motivated. You often create in a vacuum with no feedback on what you’re doing. Having a forum to share your work and experiences can do a lot to encourage you to keep going.

Take caution, though. If you’re the type to start and stop your project a lot, your support group may end up going into a “put up or shut up” mode of thinking. They will be waiting for you to deliver something rather than offer praise and encouragement with no return.

Posted in Blog, CRPG, Design, Gaming, Personal, TI-99/4a | 4 Comments

Debug Blues

Debugging the combat engine continues… it is really good to do so, though, since now it’s actually working and the bugs aren’t completely derailing it. Well, most of the time.

A simple register shift being one off caused all the problems with other characters not being able to hit without crashing the game. I was also adding health instead of wounds when striking monsters, meaning they actually got STRONGER with every hit… now monsters are dying correctly.

Currently, I have a few more bugs I want to fix up before I try and add any new FX, like ranged weapons:

  • The wrong monster graphics are periodically loading, and I can’t figure out why. It seems consistent for certain monster types, so I will statically fix it to one and debug into it to find out what’s going on
  • You can move about the entire map now easily enough, but moving OFF the edge doesn’t end the character’s turn, and actually do some funky stuff with the interface
  • You can’t actually end combat, there’s nothing tracking that all monsters are dead at present. If I get this wired up, then I need to test and debug the combat ending routines, including treasure and updating travel mode so the monster you fought is gone
  • Syncing up FX and their timing is needed. The regular hit graphic disappears long before control returns to the character, making it seem a little lagged. Part of this is also having a set amount of time always pass at minimum (Say, 1/2 second) so that you can see the combat update of a hit, miss, or critical hit, and also take longer if a FX lingers longer than that

 

Posted in Coding, CRPG, Design | Leave a comment