Dungeon Crawling

So… In the last post I mentioned working on some TI-99/4a side projects. Well, I have finished one! 🙂

It is a 3D dungeon game called “Wizard’s Doom”, a spiritual sequel to the “Wizard’s Lair” and “Wizard’s Revenge” games developed by Rainbow software in the mid 1980’s.

Background

“Wizard’s Lair” was the first TI game I personally bought with my own money, ordering it from the Triton catalog. It was one of those things I would anxiously check the mail for every single day. I let out a literal whoop of excitement the day it arrived. 🙂

And what about the game itself? For a game designed to run in TI Extended BASIC with no disk system or memory expansion, which means it had about 13k at most to work with, it’s pretty good. The game runs at a decent speed and has greater depth and nuance than most games produced for the TI-99/4a at the time. It was definitely worth money! The sequel is essentially the same game but with better graphics and some new twists.

The manual is very professional; the cover artwork is amazing and as far as I can tell, original. I can’t read the signature in the corner to determine the artist, but I’ve never seen it reproduced elsewhere. The manual was also not a cheap photocopy job; you can tell this because the cover has ink all the way to the edge, which is ONLY possible if you printed it on a printer at 9×12 size and cut it down. And the cassettes and diskettes for the game had a shiny embossed label in two colors.

The games are a derivation of “Dungeons of Daggorath”; they share the same plot and basic game play. However, in comparison to that classic game, they are laughably simple… Granted, Dungeons of Daggorath IS written in 100% assembly, so it has an advantage.

After 30 years, I thought “Why not write a sequel to Wizard’s Lair and Revenge? One that actually plays more like Dungeons of Daggorath in terms of depth and challenge? And uses a disk system and 32k RAM for maximum play-ability?”

And that’s how the project started…

Initial Design and Prototyping

The first step was to write my own maze generation algorithm. I’ve done some of this previously with experimenting doing a Rogue-style game, and in a Java project I did back in college over a decade ago.

The basic algorithm is: Create a 2-dimensional grid of empty squares. Pick a square, random or determined, mark that square “open”. Try and move in a random direction, and if you can, open the new square and make a connection between it and the prior square. You can either always look for empties, and back-track if you can’t find any, or just go through occupied squares. You can stop either when it runs out of chambers or have it track how many it’s created and stop arbitrarily. You can generate a lot of different styles of mazes with just a few simple changes to the algorithm in places, and it’s easy to seed with a fixed random value to generate the same maze time after time.

Studying Wizard’s Lair, I was amazed at how SLOW the algorithm was. It takes it several minutes to generate a maze, more than ten at some points, and other times it’s oddly fast. Part of the reason is the code infrastructure is sloppy with a lot of GOSUB and GOTO’s involved, rather than a clean linear approach. The other issue is that it doesn’t handle dead-ends well; if the maze is plotted without running into any other chambers it goes pretty quick, but once it has to deal with dead-ends it slows way down.

I wanted a fast generator, because I wanted each level to get progressively larger as you descended. I also wanted to use bit-wise operations to store directions in each chamber, which is much more efficient. (So the 1 bit becomes “north”, the 2 bit is “east”, and so forth.) I also added tracking for all open chambers by putting their row and column values into two strings. That gave me a record of chamber locations for backtracking, as well as placement of random monsters and items.

For dead-ends, I had to figure out how to handle them in a quick and efficient way. I wanted to keep the mazes from becoming too “single path” oriented, where one way just leads to a dead-end, I wanted 4-way crossings to be more common. So I put in a random check to determine if it backtracked to a prior chamber to look for new empties (using the chamber location strings) or if it just forged through an already open chamber. It also only tries once to backtrack; if it fails to find empties a second time it automatically plots through an open chamber. Playing with the randomness, I narrowed it down to a value that seemed to work and generate decent mazes that had the aesthetic I wanted.

After creating the maze, I wrote up the code to generate the 3D view. I wanted it to be faster than the original games were (which were okay but not great), but I quickly ran into problems…

The truth is, TI Extended BASIC is NOT very fast with video operations. Drawing characters on the screen with HCHAR and VCHAR is fast in a single statement, but the overhead of calling multiple statements is much slower, creating visible drawing artifacts. I tested using static DATA statements to store positions for drawing, but it was no faster. In fact, the probable FASTEST method is to do direct stacked lists of call commands that use no variables, only static values.

I had some more complications as well… While doing some graphics design, I decided I wanted to use brick patterns for the dungeon walls. For the far off and middle-range bricks, I only needed two repeatable patterns. But for the close-up view, I wanted to do 2×1 size bricks, which meant I had to alternate the pattern every other row. I tested using DISPLAY AT for this and it worked, but was so slow… Taking tens of seconds to draw your view was just not acceptable.

So this got my mind going another direction… why not use assembly language for the drawing routines? And maybe more…

Assembly and BASIC

Let me give you a bit of background on this subject…

TI Extended BASIC has always had the ability to support assembly language routines. 25% of your memory expansion is actually inaccessible to Extended BASIC except via assembly routines; the 8K lower RAM area. A command was supplied (LOAD, which also doubled as the POKE command) to load assembly files directly into the 8K RAM, where you could then call them using the LINK command, passing values back and forth to assembly language routines.

However, the documentation on setting up assembly language subroutines for BASIC and Extended BASIC is, well, absolutely awful. All the information is actually in the Editor/Assembler manual but it’s so hidden that you’d never find it unless you knew what you were looking for. Also, TI Extended BASIC and TI BASIC are two separate environments (three, if you included TI Extended BASIC with and without memory expansion), and the documentation is hazy at times about the differences.

The first big issue is figuring out how to pass data into an assembly routine. This is where things get messy because you have to be familiar with how Extended BASIC stores data on the stack and how to determine if the value is a static, numeric, or string. The original documentation recommends using a library package TI provided for all your access needs. But it’s an enormous waste of generic code designed to handle every potential combination, eating up a good chunk of that 8k. Plus, TI didn’t provide source code, only binaries.

The second issue is dealing with the character set bias. TI BASIC and Extended BASIC relocate the ASCII table upwards by 96 characters because they had to make room for other things in video memory in the lower character values. As a result, any characters you want drawn you have to add 96 to in assembly.

It took a lot of reading of documentation, and even experimenting in the emulator with the debugger screen to look at memory addresses during execution, but I finally figured out how to write my own routines to extract static and variable values from a passed LINK call. It helped that I only needed numbers and not strings. I then wrote up my own video plotting routines to draw the maze sections, using a passed numeral value to indicate which section and if it was a wall or corridor, so it could branch to the appropriate routines. And it worked beautifully!

My first design used an internal buffer approach. It would draw in the buffer and not on the screen, and then output the buffer to the screen after it was completed. To my surprise, this didn’t work well. While navigating the maze, you’d push a direction button and after a notable pause, the view changed without any warning. I realized that the lack of a “feeling” of movement was the problem.

So I altered the design so that the BASIC code just calls LINKS for each section, essentially replicating what the original games did, just replacing the HCHAR and VCHAR calls with a single LINK. Testing showed that the movement issue was solved; you saw the corridor being drawn but it was VERY fast and you had a definite sense of responsiveness.

The last issue with assembly routines in BASIC is loading them. The manuals advise you to use the LOAD command, which does work… but it’s incredibly slow. I only have around 2-3k of assembly code and it took several minutes to load in this fashion. It only needs to be done once at the game start, but having to wait 4-5 minutes for the game to finish loading is terrible!

Fortunately, another 99’er solved this issue years ago. Barry Boone wrote the Systex loader, which lets you take your assembly routine and merge it into an Extended BASIC program. The typical approach with Systex is to write a “loader” program which just runs your main program. You embed your assembly routines in that loader, and you’re good to go! It also has the advantage of obscuring your assembly binaries from casual viewing.

Graphics

The other advantage of going to assembly routines was I could do something else I truly wanted… monsters bigger than the original single sprite that was in the first two games.

Wizard’s Lair and Revenge used a single 16×16 size sprite for monsters; the first game even used the same monster graphic (an impish creature) for every monster in the game. This works all right, but the monsters appear very small against the larger large 3D dungeon window (which takes up more than 2/3 of the screen.)

I had already been considering using more sprites for monsters, but moving to assembly was necessary to make it a viable option.

Why? Well, TI Extended BASIC can handle sprites, but typically only when you’re just doing one at a time. The manual specifies you can control multiple sprites in a single command. But in implementation they are NOT in sync with each other. For example, telling two sprites to move at once, you can see that the second starts moving after the first one starts.

The problem is that the subroutines provided actually process sprites one at a time, doing a full video read and/or write, then looping for the next one. This makes multi-sprite operations where you either want them to be alongside each other or over-lapping very difficult to manage. In assembly, things can be done quickly and in blocks, which makes sprites move instantly, change color instantly as a group, and so forth.

I had one other issue to solve though… TI Extended BASIC has a very limited character set, and that limit still applied even in assembly. I decided to do pattern swapping when a monster was on screen so I could have the best number of 16×16 patterns (eight) available. This meant that items and other sprites that appear in dungeon corridors wouldn’t be available when a monster was present. I decided it was worth it for the better graphics. I also used the same technique when drawing the map of the dungeon; swapping out character sets so I could show a more better detailed map than the original games.

The monster graphics themselves turned out to be a bigger job than I’d imagined! I didn’t want to copy any existing game’s graphics, so I decided to draw them myself.

I started with the wizard on the cover of the manual. I drew some boxes on him and tried to approximate the pixel locations. Funny enough, as I worked, either my natural artistic ability came out or I just got lucky but he slowly changed to be slightly angled in profile.

The end result was very nice, so I decided to extend it to every other monster; find a picture online (thank you Google images!) and draw boxes on it and plot them out. Nearly every monster ended up looking radically different from their original artwork. So I didn’t feel like I was “stealing” anyone’s work, more that I was inspired by it.

Abandoned Ideas

With any project, you occasionally have an idea that doesn’t make it in… mine in the case of this project was the Speech Synthesizer.

I wanted the wizard to give an evil laugh when the player reached level 6, just to freak them out. When you actually found the Evil Wizard, he would say “Die fool!” when either you or he initiated combat. Possibly a scream of “Noo!” when you defeat him. And finally, anytime the player died you would hear the wizard say “And yet another does not return…” My own little homage to Dungeons of Daggorath. 🙂

Unfortunately, creating speech on the TI-99/4a is incredibly difficult.

The first obstacle is finding software that will record audio in mono. (The TI’s sound chip is not stereo…) The second obstacle is to find software that will convert the audio file into LPC encoding that the synthesizer understands.

Fortunately, the engineers at TI who worked on the synthesizer went on to found their own company years later. And they wrote software in DOS to create the speech encoding for a variety of chipsets. The only hitch is it was packaged with a blueprint for a slightly later model of the speech core. This creates some slight misalignment but it’s surprisingly close. It also only available as 16-bit binaries, which means can’t be run on a 64-bit PC. (32-bit will go back to 16-bit, though.)

I did get test speech working, both in emulation and on the actual hardware. But a host of issues cropped up with it…

The first problem was it was VERY quiet on the actual hardware, as opposed to the emulator. After puzzling for awhile, I realized I’d recorded my voice using a crappy laptop microphone in an open room. So I had to re-record, keeping my mouth close to the mike. This worked, but the software I had to convert it to a mono audio file kept messing up from the volume of the recording, creating a static sound. It took a lot of tries to get a clean audio file.

The second problem was the LPC encoding. It generated a text file containing all the bytes, but it was HUGE. An evil laugh took over 600 bytes alone. My intend was to embed the code into the 8K RAM rather than load on the fly, but I was concerned at running out of memory to even store the four phrases I wanted.

Final problem… I hated how my voice sounded. I don’t have a naturally deep voice, so it was very difficult to get something that sounded like an evil wizard, and was scary. Part of that may be my bias against my voice, but still… it just sounded lame.

After all of that, I decided I would just forgo speech in the game.

Original Game Mechanics

When designing game-play, my first step was to investigate the original games and how they worked. Both Wizard’s Lair and Revenge have nearly identical design.

Wizard’s Lair has a fixed number of chambers per level, the maximum on level 4 is 45. The actual mazes can be up to 8×8 in size. Wizard’s Revenge, possibly to save memory, only has mazes that go up to a maximum of 6×6 in size. That also means there are less monsters and items in the second game.

There’s no hit mechanic in either game; you just deal damage when attacking and take it in return from monsters. Your attributes also take damage with every attack, but at a much smaller scale. (Which is why the manual notes that you may observe your attributes drop in value against “stronger” monsters…)

Monsters only have two attributes of note, their name and their power level, which is both their health and their amount of damage. The Evil Wizard has the highest power level, plus any spell that would kill a monster outright doesn’t work on him.

Items and monsters are populated off of static data lists. Each item or monster has a specified count and a minimum and maximum dungeon level they are on. Because the games were written for a 13k cassette environment, they don’t try and optimize by loading the data into arrays; instead they just read the data statements as needed. This creates the interesting effect that when moving into a new chamber, it takes notably longer for certain items to appear on the screen than others. (As it has to read/search all the data until it finds the one it wants.) Traps on items have a small percentage change of being generated.

In both games, treasure is used solely to increase “treasure points” which is used to calculate your final rating. You can essentially skip every treasure chest in Wizard’s Lair if all you care about is defeating the Wizard. In Wizard’s Revenge, chests also store food on the last few levels, which restores health. Experience points have no effect on your character at all in either game, they’re only used for ratings calculations.

Wizard’s Lair doesn’t have exits to the next level. Instead, you move on to the next level anytime you want with a command or you automatically descend after a certain amount of time has expired. If you are on the last level when this happens, you lose the game. Wizard’s Revenge got rid of the time factor and added exit chambers, a change I agree with.

Both games have some interesting fun things…

Wizard’s Lair has three separate spells that get rid of monsters immediately; VANISH, DEATH, and GRAVITY. The latter actually levitates the monster off the screen! None of them work on the Evil Wizard.

Wizard’s Revenge has very interesting traps beyond just impacting your attributes and health. One creates leeches in your backpack, filling every available space, forcing you to waste time dropping them. Another teleports you to a random position in the dungeon. And one creates walls blocking you in your current chamber; you have to attack the walls and break them down to escape!

Wizard’s Revenge also has a new instant death spell, MEDUSA, which literally turns the monster to stone. You can even leave and return to the chamber and find their statue there. (Obviously, that one doesn’t work on the Evil Wizard.) There is also a CARPET which will whisk you to the next level immediately when used. (If used on the last level you lose the game though.)

I’ve played and won both Wizard’s Lair and Wizard’s Revenge of course. A typical game takes an hour or two. The games are pretty challenging due to the randomness. The first game in particular has a pretty steep curve of power for monsters; you’re feeling cocky finishing level 1 with a club and leather shield and suddenly on level 2 you’re facing an ogre or mummy and getting pounded into oblivion. The Evil Wizard himself IS a challenge but not overly so; I found that so long as you had a magic shield (using a spell) you could beat him fairly easily.

So now on to what I want to do…

Game Goals

Early on, I wrote up a list of things I wanted in my game:

  • Character classes, so you could play the game in different ways
  • Six levels, each one progressively larger than the prior one
  • A much more useful map that shows the exact layout of the dungeon
  • A hit mechanic to go with the damage mechanic, to make combat more complex and nuanced
  • A separate spell system by which you can use magic points to cast spells. Spells now become scrolls that can be written into your spellbook or used to cast the spell
  • A greater variety of items and individual items to use
  • A greater variety of monsters, with unique abilities and graphics
  • State tracking for spell and trap effects, both positive and negative
  • A truly powerful Evil Wizard, who can actually cast spells and has a few tricks up his sleeve…

I’m happy to say I was able to implement everything I wanted and I still ended up with around 3K of memory left in Extended BASIC! 🙂 The only additional feature I added was a save/load game option. This came about due to feedback from a good friend play-testing the game, who noted it was taking several hours to complete and that a save game feature would be handy.

Playtesting

This was probably the most challenging part of the design. After the game was finished, I had to fine-tune the mechanics and make sure the game was winnable.

I was impacted by an earlier game of mine, which I discovered LONG after the fact was not winnable. The final level was relying on some game physics I’d changed without realizing it would impact it. I promised myself in my future games that I would make certain they could be won before releasing them.

It took a great deal of time to get the game to a playable state. I discovered early on that it was pretty easy to make the game TOO difficult. Part of the problem was that as the designer, I am fully aware of the mechanics and of how things work, how to use items, and so forth. As a result, what seems a challenge to me is flat out impossible to anyone else! I had to scale the game back to the point that I felt slightly bored with it to get it just right.

Documentation

Since I was writing a spiritual sequel, I also wanted to create a manual for the game, modeled to look exactly like the first two game’s manuals. I intended to have a PDF copy of the manual AND to print a few copies, one for myself at least. 🙂

First, I scanned the original Wizard artwork as well as the graphics for the logos and other things. I then constructed the layout in Microsoft Publisher, and wrote up the text. Since my game was considerably more complex, I ended up with several more pages.

The main font used for the text was easy to discern; Helvetica, although I had to download it for Windows from a 3rd party site. Figuring out the font used for the title was harder; I eventually hunted it down as Parsons. Publisher has an option to publish documents at PDF files, which I took advantage of to create the final templates for printing.

Because the outer cover has ink all the way to the edge, I had to find a local print shop to print the covers. Fortunately I found a decent place right in town, the only tricky bit was getting my proofs and finished materials before they closed. (No weekend hours and closes at 5, usually when I’m on the bus home…) I considered the process to be a nice trial run for when I get manuals created for my CRPG.

I had 20 copies of the cover printed. In retrospect, I was probably optimistic on the count; I offered anyone who wanted a manual one for the cost of postage, and ended up selling maybe half-a-dozen. Oh well, I still have some if anyone wants one…

Final Thoughts

I quite enjoyed the experience of writing the game. It really came together exactly as I pictured it would! And expanding my knowledge of the TI’s capabilities with assembly routines and BASIC was very awesome as well.

I’m waiting now to hear if someone else has won the game. Regrettably, I’ve gotten little feedback, positive or negative… I suppose when you write a vintage game you should be happy for what you can get though.

I also discovered recently that another game already had the title I’d chosen… Wizard’s Doom is also the name of a Commodore 64 action/strategy title game. There was a lot of overlap in game titles back in the 80’s, so I’m not too worried about someone surfacing and filing a lawsuit over the name. 🙂

And my final challenge to anyone who has read this to the end…

Dare ye enter… and deliver unto the Evil Wizard his final doom?

Link: AtariAge thread on Wizard’s Doom

Posted in Coding, CRPG, Design, Screenshots, TI-99/4a | 1 Comment

Autumn Update

Hey all… if there’s anyone still out there! 🙂

It’s been a busy year for me… I migrated from an SDET (Software Development Engineer in Test) to an SDE (Software Development Engineer) role in my work, which seriously cut into my development time for the CRPG. I also have a vacation to Las Vegas with my girl coming up in early October. Life is as always very full…

I’ve also done some side projects in TI Extended BASIC. I’ll make some posts about them later. They HAVE contributed to the CRPG indirectly; any good game designing work always does.

Anyway, I’ve been working on content generation for the game, which primarily focuses on text and dialogue. I finally came up with a good way to store it using an Excel spreadsheet  that lets me both be creative and track data sizes.

So far, the numbers are adding up about what I expected. Each game disk has four dialogue files, with lengths of 16, 32, 64, and 128 bytes respectively. My compression technique for text gives me an average of 30% compression, which lets me get fairly wordy. My biggest challenge is writing out text and avoiding lengths of 17, 33, 65 and so forth… Right now, the 64-byte records are by far the most numerous, which I expected.

I’ve also found that in the process of designing the game’s towns, people, and various quests and things that I’m making changes to the item lists. I’ve actually reduced the amount of items in the game as a result; I don’t want the game to be like Dragon Warrior where each area is just progressively stronger weapons. Instead, I want specific item types to only be found in particular towns. One town, for example, would specialize in swords, another in plate armor, and so forth.

As part of the work I’m also drawing and re-drawing maps. I just reworked one area from a fairly generic coastline area to a glen with a large lake, for example, to drive some more interesting plot line work. Drawing maps in my editors actually takes a lot longer than I expected! But that’s all part of the fun…

My goal is to try and get all the content text done by the end of the year, and at least a pencil-drawn map of everything, if not actually digitized. I’ll try and be better about updating too…

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

Piecing it Together

Happy 2016 everyone!

I’m currently working on the world maps for the game. I realized that I needed to sit down and start generating the content… all of it. Towns, people, quests, items sold, locations… everything!

The main reason why is that until I do that, I really don’t know what other things the engine might need to do. Sometimes you only discover needs when you’re writing out content and you realize “Oh… I need it to do this right here.”

Another issue is I realized that too much focus on the engine can lead to games like Gates of Delirium and The Seventh Link. Both of these are excellent Ultima clones on the TRS-80 Color Computer line, but they have no soul at all. Although I’ll give the first one some credit, at least the towns have names… I really want each region to have character and each town to be a “place” in the mind of the player, not just “town #3” that sold “weapon #4”.

The good news is that I’ve had the basic map and regions in my mind for quite some time… it’s really all about piecing it together. Because I’m not doing a big continuous world map, each world map is connected via very narrow edges or through other transitional maps. It’s very much like classic World of Warcraft prior to the Cataclysm expansion; map exits are cleverly disguised to transition you in a seemingly clean fashion.

Here’s, for example, the complete world map:

WorldMapLayoutEach square is a block of 8×8 tiles, the total size of the map is slightly larger than the map of Ultima IV. However, it has significantly less wasted space, every map has at least 70% accessible area!

So right now, I’m in the process of drawing all the world maps so I can piece them together into a more cohesive whole. I’ve had several of them drawn up on graph paper (I love drawing maps with colored pencils!) for several years, so it feels good to break them out and finally get them crafted in the game! 🙂 It’s actually taking longer than I expected to make each map; there’s a lot of tile plotting to do and I have to figure out exit points that align right on each map.

In some cases it’s also leading to changes. I realized I needed another map when I realized that one I drew simply wasn’t large enough to contain all the content I wanted. I may also find that there isn’t enough tiles with varied looks to make each region a little different and unique; I may end up adding more as I progress.

Here’s a sneak peak of the world map in progress… Enjoy!

World Map

Posted in CRPG, Design, RPG, TI-99/4a | 2 Comments

Review – Ultima II: Revenge of the Enchantress

I’ve decided to start reviewing some classic CRPG’s I’ve played here on the blog recently. Why? Well, there are things I’ve always wanted to say about some games, and it also gives some insight into where I’m going with my own CRPG design.

Our first game, Ultima II: Revenge of the Enchantress!Ultima_II_cover

msdos_Ultima_II_-_Revenge_of_the_Enchantress_1983This game has a particularly personal meaning for me, because it was the first Ultima game I ever saw. I don’t know where exactly; my guess is that I saw it running in demo mode at a computer store, because the gorgeous tile graphics definitely are eye-catching. I was always frustrated and angry that the Ultima series weren’t available for my own computer, the TI-99/4a. Reading about Ultima games over the years, it felt like an entire world of adventure was passing me by…

I had a review of the game in an issue of Family Computing, which is an amusing read:

u2review

It’s fairly clear that the writer was going off of press materials for a lot of their claims. The text makes the game sound enormous and varied and full of places to go and things to buy and people to talk to. Plus their screenshot is perfect; it manages to capture one of the few towns in the game that doesn’t have a silly weird name.

hqdefaultI actually didn’t have a chance to play the game until years later, in 7th grade. My math teacher, who was also the head of the lab, had a copy of the game and let me play it. Words can’t describe how thrilled and excited I was! Then I started the game and realized I had no clue how to actually move around. After watching my character get pounded on while frantically pushing every button on the keyboard, I finally found the “/” key let you go down… only to get trapped and killed. I never thought to try the “Return” button for up, who makes “Return” do anything?

My teacher, with surprising honesty, told me I hadn’t missed a lot. He said that after awhile you were so powerful that you could kill everything in one blow, and the end game consisted of hitting the sorceress in one chamber and moving to another chamber she teleports to, over and over again. So at least he had finished the game, or at least read the solution somewhere.

He then told me something flat out bizarre; that the first town in the game had some festival going on and he couldn’t get anyone to help him, so he stowed away on a ship, after stealing a blue tassel. Uhm yeah… that doesn’t happen in the game. This is a case, I think, of a player injecting their own ideas of story in the absence of one.

Ultima_II_-_The_Revenge_of_the_Enchantress!I didn’t actually play the game in full until years later, when I purchased a PC and the Ultima I-VI compilation CD. I had to download the patches to make it work in modern DOS properly, and I had to live with the awful 4-color EGA graphics, but I was finally able to play it. I also played it in a Commodore 64 emulator; the version there is surprising in how they took advantage of the better color palette to make a prettier version.

If I was to sum up the game in a few words, it would be: unfinished, juvenile, simple, unrecognized potential.

To use a metaphor… Remember when you had that homework assignment due and you screwed around and didn’t do it until the very last day and was up until 4 in the morning throwing it together and it was just CRAP and you were sweating and knew everyone would see it and know…? But then, inexplicably, you turn it in and you get praise for your incredible work and you just smile weakly and wonder how you got so lucky…

Yeah, that’s this game in a nutshell. 🙂

ultima-ii-the-revenge-of-the-enchantress_3Ultima II was Richard Garriott’s first effort in programming in 6502 assembly. He spent two years on the game while going to college, which he dropped out of afterwards. Which honestly, if you’re making the kind of money he was, why would you need a degree? But I heard that when Origin later bought the source code back from Sierra for re-release, he was very reluctant for his team to see his old work, because he knew how shoddy it was.

My theory is that he spent a lot of time just figuring out how to program in assembly and get basic gameplay up and running. Once that was all done he had run out of time to give it much content. Two years in development in an era where most games were programmed in 1-3 months meant that he had a lot of pressure to finish from Sierra.

Most of the game logic is very simple, like a BASIC program converted to assembly language. Items in the game are a simple list structure with quantity values, NPC’s just spout the same dialogue unless they’re a special one (drawn from a table), and the “three disks of content” are just extra maps that aren’t necessary to finish the game. The last point makes sense; it was the only way to add content to the game easily.

Actual game play, once you know the controls, isn’t too bad. The game is very crisp and responsive. Combat, while simple, is quick and easy. Initially you spend a lot of time stealing food and just waiting for a frigate to come along. Once you have one of those and the ship’s cannons, you’ll level up fast. The whole “time gate mystery” the manual espouses turns out to be pretty simple; the gates do open and close at intervals but their target locations are fixed, so it’s not difficult to figure out. On the downside, you spend 90% of your time grinding for gold to buy hit points and ability score increases. A hex editor would let you skip all of this in seconds.

ultima-ii-the-revenge-of-the-enchantress_4Probably the worst thing about the game is that the 3D dungeons/towers, which is really what Ultima was originally built around, are absolutely unnecessary. The only reason to enter them is to get fuel for the rocket, and that can also be gained by just killing monsters around. So a whole portion of the game is just a waste of time. The fact that magic spells only work in dungeons or towers also makes playing a spell-casting class pointless. Ultima would continue to use 3D dungeons for three more games, which was always a detriment. (If you want a 3D dungeon game, play Wizardry. They do it the best.)

The game is also very, well, how to say this… stupid. There are tons of in-jokes and pop culture references that could only come from the slightly inebriated mind of a teenage developer. (Which, by an amazing coincidence, they did!) Most of the references now would make no sense at all to a modern audience, such as a (misspelled) magic phrase from the movie “Excalibur”.

Also, the game is set on Earth, but you can play Tolkien-style races like elves and dwarves? Not that race has any impact in the game on anything other than starting ability scores… My theory is that Garriott, in order to complete the game on time, ported his character system from Ultima I over into assembly as completely as he could.

So why wasn’t the game reviled for all of this back when it was released? Well, the fact is, for 1982, the game is REALLY impressive. At that time, more than half of your commercial games were written in BASIC and didn’t look anything like this.

The big cloth map and gorgeous box artwork can’t be ignored either; this was a game that looked quality. The fact it retailed for $60 (which adjusting for inflation would be well over $100 today) and it sold over 100,000 units meant it was a very profitable game too.

portbonificeIs it worth playing? Absolutely. This game is an excellent model of a CRPG engine with potential. Had Richard Garriott had more time or more immediate expertise with assembly language and platform building, or even a team of developers aiding him, the game would would have been far better. You just have to look at the following Ultima titles to see that he was able to refine and improve his CRPG designs. Ultima II is an excellent lesson for a CRPG design enthusiast to study.

For example, I’ve looked at the executable in a hex editor and found that all of the in-game text is hard-coded. From a platform standpoint, that’s very limiting. Ultima IV and onward stored NPC text in data files, which was much more flexible. Because Ultima II loads its maps from disk, it makes sense that most of the customization of places (like the names of stores) occurs on the maps themselves using the large letter blocks; this is the one area you could be creative in cheaply with the engine design.

So where can you obtain Ultima II, besides eBay? It’s available as part of a bundle on Good Old games (gog.com) for only $6. GOG does a great job setting the games up to run correctly, using DOSBox as an emulator. You may still need to download some patches if you want better graphics. Please note that the original DOS version also has a flaw in which the galaxy maps didn’t map over correctly. I don’t think GOG has corrected this.

You can find a lot of information on the different versions of Ultima II, as well as literal transcripts from the game, at Underworld Dragon’s Notable Ultima site. This site is older than the internet and was preserved by one of the Ultima dragons for posterity. (Underworld Dragon himself has disappeared, to my knowledge.)

The CRPG Addict reviewed Ultima II early in his blog history. His initial review was harsh and critical but he later admitted in comments he was being overly judgmental of the game, probably because he was comparing it too much to Ultima III and later.

RPG Classics has had a shrine to Ultima II set up for several years now. You can find complete information on the game’s content as well as maps for every planet, town, and dungeon.

One of my favorite reviews of the game is Spoony’s Ultima Retrospective review. He notes the amusing use of the Eagle’s song “Hotel California” in numerous places in the game, as well as the cryptic nature of clues in the game. (I’ve looked, there is literally NOWHERE in the game that tells you that only the Quicksword will hurt Minax. The manual mentions it is the most powerful weapon in the game that must be earned but nothing else.)

And finally… because of the game’s personal meaning to me, there WILL be a “Port Bonifice” in my CRPG. One, I really like the name, and two, it’s one of the few places in the game that has a fantasy-style name to it. I still wonder where Garriott got it from; Bonifice was the name of a pope from the Middle Ages…

Links:

Ultima II on Good Old Games

Ultima II on Wikipedia

Underworld Dragon’s Notable Ultima

CRPG Addict’s Ultima II Review

Spoony’s Ultima II Review

RPG Classics: Ultima II

Posted in CRPG, Design, Gaming, Review | Leave a comment

A Bird’s Eye View…

Sharing a map from the game!

pb

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

Holiday Updates

Working hard on this! I’ve been doing a lot of new things in preparation for the game itself. Here are some of the highlights:

No Demo

I decided that I’m not going to release a demo.

My reason? A demo provides an artificial milestone for completion. Just get the demo working and you’re good! The problem is, the demo doesn’t contain or encompass all the game has to offer. So you’re not really finishing anything other than a demo if you aim that way.

This means I’m focused on ALL the content in the game, not just for a very small part of it. This helps me figure out how much space I’m really using for everything as well as what kind of changes I’ll need to make to the engine to accommodate specific plot points.

Content Generation

I’ve had the story of the CRPG in my head for a number of years now… some of it has undergone revisions in my head, but for the most part I knew how I wanted it to end. It was all the middle stuff I wasn’t sure of. 🙂

So I sat down and started plotting out the various quest threads and stories for each region, and writing up the dialogue that would be needed. This has been very useful because it’s helped me identify new requirements for the engine, and helped me to flesh out certain areas.

One thing I wanted to really accomplish was to create a world you can believe in. If you play either of the first two Ultima games, you really don’t feel like they’re real worlds. They generally feel more like an amusement park. It’s strange that later games (like Ultima IX) actually regressed to that state.

Ultima III was the first in the series to really try and make it more like a real place, and it partially succeeded. The main problem was that there were still many towns and places that felt like “throw-in” material just to give you another place to go and buy stuff at, or find the ONE NPC in town that had something useful to say. The fact that the manuals didn’t even define the regions of the map as distinct places just reinforced it; you could literally redo the entire map of the game and move everything around and it wouldn’t matter.

So as I’ve been creating places and towns, I’ve really tried to think about the history and inject some interesting content and material to make it feel more like a real fantasy world. I’ve even made sure that the names of towns feel “fitting” for the region.

Elevated Maps

I’ve added map elevation to the game, which should help give the map viewing some depth, literally. 🙂 The idea that you can see over a forest if you get to a high point is very appealing! I had a kilobyte of RAM to spare to store up to 4 elevation levels. I had to completely re-write my map editor to accommodate adding elevation, and I also added light mapping to it as well.

My only concern, and it’s one I haven’t had a chance to fully test yet, is how it will impact the map view generation. In truth, areas that are over/under your elevation are MUCH simpler to calculate, they are either fully visible or not visible at all. But adding that extra bit of calculation to do may slow things down too much, I’ll have to see.

Graphics Crunch

I’ve had multiple character sets in the game for quite some time. As I’ve been focused more on finishing the primary engine, they’ve remained largely the same for a couple years now. Eventually I ended up with eight separate sets:

  1. World
  2. Town
  3. Castle/Keep
  4. Cavern
  5. Building/Interiors
  6. Dungeons
  7. Stat Screen
  8. Special (Non-disclosure on this one for now…)

Not long ago, I was looking at my Castle set and realized that I was largely using it for cosmetic purposes. So I decided to eliminate it and use building interiors for anything of the sort.

Recently, I started to try and draw out some dungeon maps, using some of my characters. I had planned to use tiles to create a false 2D isometric perspective; walls would appear to have top edges and slant down to the ground. The problem though, was that this proved incredibly time-consuming on the maps to draw, plus the walls were at odds with pretty much every other tile in the game.

So I decided to “crunch” my wall tiles down, using only a single tile. It’s much more simple and reminds me more of a BASIC game, but it also means I can consolidate my graphics into tighter sets. The only walls I kept was cavern walls; caverns I wanted to have some smoother edging in places, so it has five tiles.

So my new sets are:

  1. World
  2. Town
  3. Building/interior
  4. Cavern/Dungeon
  5. Stat Screen
  6. Special

One advantage this also offers is that maps can be less homogeneous; caverns and dungeons can freely break into one another in a much cooler fashion, where before they were either all one or the other.

My biggest challenge right now is figuring out how to portray elevation in a believable way that isn’t too confusing. I need to use a separator graphic of some kind to indicate an elevation change but also block the player from just moving up freely. Still working on this…

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

Bullet points

Another five months, another sporadic update… 🙂 Been busy with various things; my girlfriend and I completed our living room decor this weekend and it is beautiful! If only my office was that clean and zen…

After spending some time working in C# on a transaction parser, I went back to the assembly code to actually implement the transaction code itself. This was important because I suspected, correctly, that the act of actually writing out the implementation would help determine what transactions I needed.

For example, my original plan had a transaction code that would alter any byte/word value in the game’s data arrays. This meant tracking size, operation type, index, whether or not subtraction would go below zero, not allow below zero, etc. But I realized it burning up too much code space to do a single simple operation.

Instead I focused on making transaction codes for specific use cases. Because training points are earned by all players at once, I just wrote a code to do that and that alone, rather than engineer a solution that would do it for anything anywhere.

Writing up transactions also revealed I had a lot of “dead” code from older implementations lurking about. Removing these feels good as it’s cleaning up the codebase and freeing up memory. I have just under 5k of space left which looks like it will be enough to finish it!

I came up with a new idea as well; I’m adding gambling as an option to the game. Certain places will have a gambling sub-game, involving dice rolls. I’m a big fan of the CRPG Addict, and he’s noted that games to win money are useful for bypassing tedious monster fighting in games. Given I don’t want the game to focus solely on combat, it seems like a nice idea to have the option to earn money in other ways.

Right now, I’m working on buying and selling items. I’ve hit a particularly complicated and infuriating snag, which is ammunition. I decided to make the item # for ammunition types reflect the count of ammunition awhile ago, because I didn’t want to maintain separate counts of items for everything. This “special case” though is causing major headaches… I can’t just consider the number of items in a backpack as an indicator of fullness where ammunition is concerned, because it should add to an existing item… IF it’s in there. Plus I have to display the cost on screen a little differently, showing the number of ammunition you buy for the given amount. So more special casing, argh! For selling items, I’m not even going to allow you to sell ammunition back for money, it’s just too complicated…

The good news is that after I’m done with all the transaction code, my next step is to prepare a baseline “demo” data package for test purposes, compile the code, fix bugs, and start testing the hell out of the engine to make sure everything works. Once that’s done, I can start actually WRITING the game in earnest. Getting closer and closer…

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

Hammer and Screwdriver

What’s that title mean? That while you can drive nails and screw-in screws without tools, it’s a much longer and more exasperating process…

Tools for development are always needed. Besides my map and graphic editors, I have also wrote tools in Windows (in C# .NET) to handle some of the more automatable tasks. My text compression is an easy one; all I had to do recently to it was modify it to process a whole text fine line-by-line so that I could paste an entire block instead of one at a time.

But until I got VERY deep into design on transactions, I hadn’t realized that doing things by hand wasn’t going to cut it.

I’ve made one other decision; all NPC interaction is now tracked through transactions. This includes buying and selling items. As I was writing code, I realized it was just easier to have a single entry point for everything.

My original plan was to just hand-code the transactions myself, storing them in an Excel spreadsheet. I started to write out text files to describe each NPC and what they were doing. But as I did this, I realized how complicated it was getting. Plus, every small change would force me to re-do every single reference that was to an offset position. I would be reduced to gibbering insanity in a VERY short order if I had to do that. 🙂

The transaction system is a word (2-byte) language that tells the game what each NPC does. For example, the code to display a message on screen is “!MSG” followed by a list of dialogue codes. Dialogue is structured as “0-5”, which means dialogue file 0, message 5. If I have several comma-separated messages, it loads and displays all of them in a block.

Here’s an example of a text file describing a sage in the first town:

#Sage

?LOCAL_FLAG 0,Visited,NotVisited

NotVisited
!MSG 2-26,2-11
!LOCAL_FLAG 0=1
!BRANCH OptBuild

Visited
!PMSG Two,1-14,1-33

OptBuild
!OPTION 0-6,Q1,1-12,Q2
?QUEST_FLAG 1,OptBuild1,Select

OptBuild1
!OPTION 0-7,Q3

Select
!INPUT Select

Q1
!MSG 1-13,2-20
!INPUT AnyKey
!BRANCH Start

Q2
!MSG 2-25,2-18,1-6
!INPUT AnyKey
!BRANCH Start

Q3
!MSG 3-3
!INPUT AnyKey
!BRANCH Start

#Sage end

The # symbol is used to indicate the start and end of a transaction block. This allows me to add commentary in-between blocks if I need to; my intent is to have one large text file containing all of a disk’s transactions for processing.

When in a block, there are two kinds of commands, actions (!) and queries (?). Queries check values and branch to labels inside the transaction based on true/false conditions. Actions do things like display messages, alter data both in memory and on disk, start a battle, etc. Any line that has neither a ? or a ! is considered a label and gets added to a list to note it’s position in the transaction array. (For now I don’t have a “comment” symbol, but I could add one if I need to.)

Let’s go over it, shall we?

?LOCAL_FLAG 0,Visited,NotVisited

So first, we check a local flag. There are eight of them in a byte, so they are referred to by position, 0-7. Every NPC in the game has a local flag store of a byte, for tracking changes and states. #0 on all of them is being treated as the “visited” flag. This indicates whether or not this NPC has been interacted with before. This lets us have an NPC actually remember that the player has interacted with them already and respond as such. The first label after the flag number is the true case, and the second is the false case.

NotVisited
!MSG 2-26,2-11
!LOCAL_FLAG 0=1
!BRANCH OptBuild

If the player has not visited the Sage before, he has a few greeting messages. The visited flag is then set to 1, and we branch to the OptBuild label. After this, the player won’t see those messages again. When the player leaves the map, all the existing mob data is saved, including the new flag states, so returning later won’t restore them to blank.

Visited
!PMSG Two,1-14,1-33

If you have visited him already, he has a follow-up greeting. !PMSG is actually a “plural message” command. Given that the size of the party is entirely determined by the player, I wanted a message system that could deliver multiple messages based on how big the party is. The keyword “Two” indicates there are two variations, a single and a multiple. The first message is the singular party member version, the second message is the multiple party member version. There is also a “Three” version for cases where an NPC may say “You”, “Both of you” or “All of you”.

OptBuild
!OPTION 0-6,Q1,1-12,Q2
?QUEST_FLAG 1,OptBuild1,Select

OptBuild1
!OPTION 0-7,Q3

The !OPTION command specifies a number of dialogues and branches that are choices for the player to make. These are added to a local memory stack for processing later. Two are added for two questions that are always available to ask. Then we check the status of a quest flag (#1) to see if it’s true or false. If a particular quest has been completed, we add a third option.

Select
!INPUT Select

The !INPUT command pauses the dialogue and waits for the player to choose one of the pre-determined options.

Q1
!MSG 1-13,2-20
!INPUT AnyKey
!BRANCH Start

Q2
!MSG 2-25,2-18,1-6
!INPUT AnyKey
!BRANCH Start

Q3
!MSG 3-3
!INPUT AnyKey
!BRANCH Start

So for each option, the Sage has a different set of messages. It then waits for the player to press a key, then branches back to “Start”. This hard-coded label is always the beginning of the transaction.

#Sage end

And that’s the end of the transaction block. So I run my parser on it and I end up with this:

05 00 0E 04 0E 02 20 1A 20 0B 13 00 01 14 0F 00 10 0E 10 21 11 02 00 06 00 2A 10 0C 00 34 06 01 22 28 11 01 00 07 00 40 12 01 0E 02 10 0D 20 14 12 00 01 00 0E 03 20 19 20 12 10 06 12 00 01 00 0E 01 30 03 12 00 01 00

72 bytes, or 36 words, to define the entire transaction!

Transactions are all stored as 2-byte records in one large file per disk. Looking over my initial calculations of size for different things, I will end up with a couple thousand records per disk. If sizes remain at a consistent amount, I may also increase the record size and pad out some of them with zeroes for quicker load times. (I don’t think it should prove to be a particular problem; the TI disk controller loads an entire sector into VDP anyway so as long as transactions don’t cross sector lines it will remain fairly fast.)

Now I just need to write up the code to process the transactions and do all the displays… fun fun!

 

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

Dragon Questing…

While working on my transaction stuff I’m also doing some research on the needs of the story that I’ve had on my mind for the last several years and what the engine needs to do to make it happen. But… It’s not all work. There’s some play too!

dw1Recently I got an urge to re-play the old Dragon Warrior games on the classic NES. There were a few CRPG’s on the old Nintendo, but the two most well known were Dragon Warrior and Final Fantasy. I’ve already won the latter on the classic console (I still have the blister scars from buying 99 heal potions OVER AND OVER… stupid interface!) but I never played Dragon Warrior II to conclusion, only the first and third.

dw2Why? Well… these games were NOT easy. The level and XP grinding you had to do was insane. The first game required you to sit and kill slimes, the weakest monster in the game, for around an hour before your character was leveled up enough to explore further than a few steps from the starting castle and town. If you died you lost half your gold, so exploring early was punished harshly. And you NEEDED money because all the best gear was incredibly expensive. Playing the original Dragon Warrior on the NES was more painful than fun.

dw3Dragon Warrior II was a better game overall, offering a party of three characters and a much larger world to explore. You still had to grind hard-core though; many players took advantage of a small bug in the game to obtain a valuable item over and over again and sell it to make the money to buy the best gear. I didn’t win it back in the day primarily because I didn’t own it, I could only play a friend’s copy and I couldn’t borrow it long enough to win.

So I had an itch to play these old games, but at the moment, all my video game console stuff is still packed away… Plus, my general experience with the old games is that it would mean spending a LOT of time in front of the TV, doing the same repetitive things over and over, eventually muting the game so the music wouldn’t give me a headache…

dq1Fortunately for me, there was a solution… the games have been released for the Android mobile platform! (Under their original name “Dragon Quest“) So I was able to purchase them cheaply on Google’s Playstore and download them for my tablet and phone.

Compared to the originals, the games have some differences, all to the good!

One, the graphics are WAY better. When they did the port, they actually used the Super Famicom graphics for a version that was only released in Japan. I don’t mind the original 8-bit graphics of the NES versions, but it’s nice to have an upgrade.

dq3Two, the adaptations retain the the original “Athurian” language and some of the place names. Some of the mobile ports reverted entirely to the original Japanese, where the renowned hero “Erdrick” is named “Loto”. I’m relieved to have familiar names and places, although most of the towns in Dragon Quest II have different names. Spells have completely different names entirely; most of them have sound-effect style names like ‘Sizzle’, ‘Kazing’, and ‘Thwack’. Fortunately the mobile version interface helpfully tells you what each spell does so you know what it is.

The actual in game text is also much more loquacious, with a lot of style and nuance that was absent in the NES versions. This is partly because the old cartridges were very tight on memory, but also because Nintendo stripped out anything with religious overtones. This is very fascinating to me because the games have a VERY religious theme to them.

dq2For example: the enemy in Dragon Quest II, Hargon, is actually a high priest and not a wizard. There’s a lot of discussion about how he has perverted his position against the Goddess, the “god” in the Dragon Quest universe. Instead of “Wizard Rings” to restore magic points, you have “Prayer Rings”. Magical power is directly associated with divine energy. And so forth… I actually find it really enriches the game and makes it much more fantasy-feeling.

Three, playing the games on my tablet is much more comfortable and easy than playing in front of a TV. I can move about, take it with me to different rooms, and I can even leave the game running and not have to save constantly!

Best of all… the games are much easier to play. The interface has been reworked to function very well on a touch-screen interface. The first Dragon Quest game has clearly doubled experience and quadrupled (!) gold so you can level up and advance MUCH faster.

dq4Dragon Quest II is more subtle in the improvements, but they are there. If a targeted monster dies before a character attacks him, he switches his attack to another monster. I’m pretty sure a lot of the under-the-hood mechanics for determining hit chance and damage were tweaked as well, your characters seem much stronger and more capable than the NES version, where you always felt like you were one combat away from a TPK.

Advancement, particularly spells, don’t follow the original game. I was expecting to get the Firebane (or ‘Sizzle’) spell at level 18 with the mage/warrior character, and instead I didn’t get it until level 24 thereabouts! Curiously none of the walk-throughs note this discrepancy… Your priestess character also maxed out at level 35 in the original, but in this version I got her to 36 before I won the game.

The best aspect of these games, though, is that I can finally play ones that were never released in the U.S. I’m playing them through in order; I’m now on Dragon Quest III, and looking forward to moving into the ones that started a new story arc.

Posted in Blog, CRPG, Design, Gaming | 2 Comments

Transacting Scripts

My focus remains on turning out a working and complete demo of the game… I’ve written a bunch of code I haven’t even had a chance to test yet. And I’m currently working on plotting out a long-neglected portion of the game; complex transactions with NPC’s.

I’m doing SOME stuff that isn’t entirely practical. For example, I’m finally working on finishing the title screen. I had always been stymied by the fact I didn’t really want to take the time to plot out the thing in a paint program. (ESPECIALLY in TI-Artist, which is incredibly painful to use for pixel plotting. Multi-color mode, blech!) I finally found a low-tech sneaky way to do it… Transcribe the character graphics myself by the naked eye into the bit patterns and hex-edit them into a Paint N’Print file. (Paint N’Print is my favorite editor; the zoom mode is perfect!) I can then colorize it later in the paint program.

So, about those transactions…

I decided early on not to have a text parser in the game. (Basically, a cursor which would allow you to enter key words.) My decision was based upon two things:

  1. Text parsers are a pain to implement and error check in assembly language
  2. Too much like Ultima

How can being like Ultima be bad? Well, Ultima IV is actually very simplistic; there is a maximum of 32 NPC’s in each town, and each one has a single 288 byte record to store all their conversations. (Except for special NPC’s like Lord British and Hawkwind, of course.) If you look, the actual depth of each character is shallow; each character only has two potential keywords beyond the baselines (name, job, health) and a single question and virtue that is affected by it. Ultima V is slightly more complicated with the day and night cycles and NPC schedules, but conversations are largely the same structure.

Also, there’s a certain degree of “I want this to be MY game, not just a copy of Ultima.” There’s been too poor-man copies of Ultima over the years (Gates of Delirium comes to mind…) and I want my game to stand out as something that is entirely itself.

Another aspect of my design is, I want the game world to CHANGE based on the player’s actions. All too many old CRPG’s have worlds that largely remain the same, even after the player has accomplished things. You save the town and they’re STILL talking about the danger?

So, there are two kinds of NPC’s in the game, simple and complex. The simple ones are much like the NPC’s in Ultima III; they have a single response they say and nothing more. There will also be map flags for each area so that if you have achieved certain goals, they say different things.

Complex NPC’s though, are another matter. For those, I’ve had to create my own little scripting language.

Essentially, each complex NPC has a set of local flags (one byte’s worth, one of which is always the “visited/revisited” flag) and a set of transaction records, each one word (16-bit) long. If the average length of these transactions ends up being a consistent size I may just convert them to longer records and live with a little wasted space.

Each word has a code indicating either an action or a query, with a variant amount of data after it. For example, it may check that a certain flag is set. If so, it moves to the appropriate spot in the transaction string using a positive/negative offset value, and continues transaction processing from there. It can display messages, set up options for the player to select from a list to determine a series of next results. And it can give money (or take it), items, or make changes to the party and player data as needed. A veritable transaction engine!

Here’s an example of how it may look:

TRANSACTION

OPEN:
IF Visited_Flag    (4)
    DISPLAY Intro (4)
    SET Visited_Flag (2)
    BRANCH Options (2)
ELSE
    DISPLAY Revisit (4)
    BRANCH Options (2)
OPTIONS:
    OPTION Question_1, Question_2 (10)
    SELECT Option (2)
    IF Option_1
        DISPLAY Read_1, Read_2 (6)
        BRANCH OPEN (2)
    IF Option_2
        DISPLAY Take_1 (4)
        SET Quest_Item_0 (2)
        CLEAR Mob (12)
        END Transaction (2)

Total: 58 bytes (29 words)

In fact, as I was designing the system, I realized that I could use it to replace some things in game. For example, I originally had fountains as a stock object in game for dungeons and places, that would have variant effects upon you. But I’ve been leaning towards removing them as a more “gamey” object more appropriate to old-school first-person dungeon designs, and I realized that I didn’t even need to HAVE special code for them. I can just make a fountain a transaction if I still want one!

I did briefly consider integrating shopkeepers into the same transaction system, since it’s already going to be doing a lot of heavy lifting. I decided against it in the end, though, because with shopkeepers, I have much more predictable data structures. That will let me write much more streamlined code to handle the transactions for those.

The only pain point with this approach is that coding the actual scripts up is going to be a pain. Since all the offsets are going to be localized and fixed, that means they will need to be updated with any changes. I’m going to initially try and set up an Excel spreadsheet to store this for me so I can (hopefully) just copy out a clean hex string to paste, but we’ll see how it goes…

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