Jump to content
adamantyr

TI-99/4a disk-based CRPG

Recommended Posts

The video only gives me about 5 secs. of this:

 

post-2851-126763871935_thumb.png

 

If you're using Firefox, be sure to download the Firefox Windows Media Player plug-in.

 

Meanwhile, you can download the video directly from here: http://www.adamantyr.com/video/Combat1.avi

 

If the raw file doesn't work, then it's probably some codec issue or something. I recorded it through Classic99, then used AVS4You's Video editor to convert it to MPG4 format.

 

Adamantyr

The download worked fine.

 

Looks great. I'm not sure what I'm seeing though, exactly. Looks like prior to the turn you issue commands for each individual party member, and once they've all received their commands, those actions play out over the course of an uninterrupted turn; is that correct?

Share this post


Link to post
Share on other sites

The download worked fine.

 

Looks great. I'm not sure what I'm seeing though, exactly. Looks like prior to the turn you issue commands for each individual party member, and once they've all received their commands, those actions play out over the course of an uninterrupted turn; is that correct?

 

Correct! And they don't necessarily occur in sequential order.

 

I think I may need to add a "flashing arrow" to the direction selection, though. Just pressing a single key, while fast, isn't illustrative of what choice was made, and could be problematic if you're like "Wait, which way did I set it to again?" Also need to change it from SPACE to ENTER to select; it's too easy to press SPACE twice and accidentally end the turn of the character.

 

Adamantyr

Share this post


Link to post
Share on other sites

Oh, to continue about the complexities of combat, here's the pseudo-code I have to translate into assembly language in order to determine what happens when one unit attacks another:

 

Attack			
Check if Defender is Invulernable			
If so, attack fails, return Invulnerable code		
Determine attacker and defender base fatigue			
1 standard, 0 if empowered, 2 if weakened		
Determine attacker and defender power bonuses/penalties			
Determine if attacker is exalted/cursed		
	If exalted, +2 to attacker power. If cursed -2 to attacker power	
Determine if defender is exalted/cursed		
	If exalted, +2 to defender power. If cursed -2 to defender power	
Determine if defender is guarding			
If so, +1 to all defenses, +2 to defender power		
Goto appropriate attack type			
		
Attack Melee			
Adjust base fatigue			
If attacker has 2H weapon, +1 fatigue		
Determine if attacker is enraged			
If so, add +4 to attacker power		
Determine if defender is armored			
If so, add +4 to defender power		
Determine if defender is enraged			
If so, subtract -4 to defender power		
Attack:			
Determine if attack misses		
	If defender is blurred, miss chance is 50% (0 on a RND of 2)	
	If attack fails, return Miss code	
Determine if critical hit (0 out of 16)		
	If critical hit, defender cannot avoid attack	
		Set attacker power to 150%
		Set attacker fatigue to 0
		Goto Damage
Defense:			
Determine if defender can parry (Any melee except bare hands and dagger)		
	If so, defender parries, takes fatigue, return parry code	
Determine if defender can block (Has shield)		
	If so, defender blocks, takes fatigue, return block code	
Determine if defender can dodge (Open space available to move into, not immobilized)		
	If so, defender dodges, change position, takes fatigue+1, return dodge code	
Damage:			
Determine damage (Attacker power + bonus/penalty - defender power + bonus/penalty, minimum of 1)		
Defender takes {damage} wounds, attacker takes fatigue		
Return hit code		
		
Attack Ranged			
Adjust base fatigue			
If attacker has arbalest, -1 fatigue		
Determine if defender is shielded			
If so, add +4 to defender power		
Attack:			
Determine if attack misses		
	If defender is deflecting, miss chance is 50% (0 on a RND of 2)	
	If attack fails, return Miss code	
Determine if critical hit (0 out of 16)		
	If critical hit, defender cannot avoid attack	
		Set attacker power to 150%
		Set attacker fatigue to 0
		Goto Damage
Defense:			
Determine if defender can block (Has shield and attacker not using a firearm)		
	If so, defender blocks, takes fatigue, return block code	
Damage:			
Determine damage (Attacker power + bonus/penalty - defender power + bonus/penalty, minimum of 1)		
Defender takes {damage} wounds, attacker takes fatigue		
Return hit code		
		
Attack Sorcery (target)			
Adjust base fatigue			
If attacker using affinity spell, -1 fatigue, +2 bonus power		
If defender targeted by affinity spell, -1 fatigue, +2 bonus power		
Determine if defender is protected			
If so, add +4 to defender power		
Attack:			
Determine if attack misses		
	If defender is warded, miss chance is 50% (0 on a RND of 2)	
	If attack fails, return Miss code	
Determine if critical hit (0 out of 16)		
	If critical hit, defender cannot avoid attack	
		Set attacker power to 150%
		Set attacker fatigue to 0
		Goto Effect
Defense:			
Determine if defender can block (Has foci)		
	If so, defender blocks, takes fatigue, return block code	
Effect:			
Determine damage (Attacker power + bonus/penalty - defender power + bonus/penalty, minimum of 1)		
Defender takes {damage} wounds or {damage} duration effect, attacker takes fatigue		
Return hit code		
		
Attack Sorcery (area)			
Adjust base fatigue			
If attacker using affinity spell, -1 fatigue, +2 bonus power		
If defender targeted by affinity spell, -1 fatigue, +2 bonus power		
Determine if defender is protected			
If so, add +4 to defender power		
Defense:			
If defender is warded, miss chance is 50% (0 on a RND of 2)		
	If attack fails, return Miss code	
Determine if defender can block (Has shield or foci)		
	If so, defender blocks, takes fatigue, return block code	
Effect:			
Determine damage (Attacker power + bonus/penalty - defender power + bonus/penalty, minimum of 1)		
Defender takes {damage} wounds or {damage} duration effect, attacker takes fatigue		
Return hit code		

 

I also need to determine how this translates into direct screen action... I don't want to build a "cinematic event" array and post-process everything, so I'll probably just have to return codes to indicate what units are doing and go from there.

 

Adamantyr

Edited by adamantyr

Share this post


Link to post
Share on other sites

That's some pretty in-depth stuff!!! Man, I've got alot to learn. :). So Adam, how much money would you charge me to teach me a semester class on "The Ways and Means of a disk/based RPG?" :)

Share this post


Link to post
Share on other sites

adamantyr,

 

I have never written a CRPG of any kind, so this it just theory, but it seems that tracking stats on each player would make your combat system a lot easier. I think this is more what is done in games like WoW, but I can't be sure. Instead of doing all those checks during combat, make the modifications to base stats that are used in the calculations.

 

For example, part of your melee is:

 

Attack Melee

Adjust base fatigue

If attacker has 2H weapon, +1 fatigue

Determine if attacker is enraged

If so, add +4 to attacker power

 

 

To me is seems that every character would have a set of stats, and the moment you pick up a 2H weapon, it would adjust the fatigue stat at that time. Same with enraged. At the point when the player become enraged, adjust the attack power +4. Then when they are no longer enraged, decrease the attack power. When the player selects the defend stance, adjust the parameters at that point. So when it comes time to calculate the damage, you only have to throw in a few parameters to the equation:

 

damage = ((base_weapon_damage + attack_power + fatigue) - (defender_power + whatever_else)) * defender_immortal

 

The defender_immortal could be whatever you want, a combination of modifiers, but in this case if it was set to 0, then the damage is zero and they defender can take no damage. Every character would have an "immortal" parameter which would typically be 1 and thus not affect the calculation. So now instead of having to make that check right at the top, you simply do the calculation and the damage comes out zero.

 

Doing things this way saves having to make all those checks during the combat code. All the characters come with their stats already set according to what they are wearing, what weapon they have armed, their stance, etc., all you have to do is run the calculations.

 

Anyway, just some thoughts that came to mind when I was reading through that pseudo-code.

 

Matthew

Share this post


Link to post
Share on other sites

I have never written a CRPG of any kind, so this it just theory, but it seems that tracking stats on each player would make your combat system a lot easier. I think this is more what is done in games like WoW, but I can't be sure. Instead of doing all those checks during combat, make the modifications to base stats that are used in the calculations.

 

There is actually two parts to the player array. The entire thing is stored in VDP.

 

One part is the constantly changing bits, which is status of various effects, health and stamina, wounds and fatigue, and so forth. This is copied down into CPU memory for quick updates and access, and only pushed back to VDP prior to a game save.

 

The second part is the less often changing things, like what equipment the player has, how much ammo of each type, and his defense and miss chances. I don't need them in CPU memory at all times. For now, I'm reading this in as a block from VDP for usage in attack determination, so these values COULD be adjusted directly without harm, since I'm throwing it away afterwards.

 

To me is seems that every character would have a set of stats, and the moment you pick up a 2H weapon, it would adjust the fatigue stat at that time. Same with enraged. At the point when the player become enraged, adjust the attack power +4. Then when they are no longer enraged, decrease the attack power. When the player selects the defend stance, adjust the parameters at that point. So when it comes time to calculate the damage, you only have to throw in a few parameters to the equation:

 

There is no permanent fatigue statistic; I would have to actually create and carry one in memory all the time. A lot of the "special cases" like various weapons are going to be tricky to do; they don't really fit into an easy categorization that can be made into a pure data form. (More on this below)

 

Fatigue has nothing to do with damage either, incidentally, it's just a measure of how much fatigue the attacker takes on a successful attack or the defender on a successful defense.

 

damage = ((base_weapon_damage + attack_power + fatigue) - (defender_power + whatever_else)) * defender_immortal

 

The defender_immortal could be whatever you want, a combination of modifiers, but in this case if it was set to 0, then the damage is zero and they defender can take no damage. Every character would have an "immortal" parameter which would typically be 1 and thus not affect the calculation. So now instead of having to make that check right at the top, you simply do the calculation and the damage comes out zero.

 

Doing things this way saves having to make all those checks during the combat code. All the characters come with their stats already set according to what they are wearing, what weapon they have armed, their stance, etc., all you have to do is run the calculations.

 

Multiplying the whole thing like that is something easy to do in a high-level language like C, but EXTREMELY difficult in assembly. Plus, there's a case of "Why am I doing all these calculations when they're pointless anyway? Hey, he's invulnerable, return a code and stop!" Not that's speed an issue; even on a 3mhz machine all this gets done in the blink of an eye.

 

I wrote up my first permutation of the code last night and wow, it was a big chunk of code. At least a kilobyte. Since I still have special effects with sprites with a huge unknown on memory consumption, I definitely want this to be as tight as possible.

 

My current thoughts is to categorize each attack type and the adjustments into a matrix of arrays, which can then be processed. Essentially, I'd write a data-driven statistic crunching engine. Just say "Use the melee array" and it will grab the indexed values from the right places, add the bonuses/penalties specified, and all the determinations are made with the same code. This is a bit of work, and it may mean losing the special cases initially until I find a clever way get them back in, but it should reduce the footprint quite a bit from just straight linear processing.

 

Adamantyr

Share this post


Link to post
Share on other sites

I would love to see another screen video of gameplay, like the first

one you posted. Thoroughlly enjoyable man... Hope to see a playable demo sometime soon! :)

Share this post


Link to post
Share on other sites

I would love to see another screen video of gameplay, like the first

one you posted. Thoroughlly enjoyable man... Hope to see a playable demo sometime soon! :)

 

Long way to the demo, alas... I'll post another video when I got something interesting going on. Since I'm saving special effects (actual animation in combat) for later, it will be a bit.

 

Adamantyr

Share this post


Link to post
Share on other sites

I wish there was a way to get RSS Push notifications on the iPhone. I am not getting notifications on your updates. :(

 

Yeah, doesn't help I'm kind of sporadic on updates either. :)

 

I just posted a new blog entry today on attack pattern mapping.

 

Adamantyr

Share this post


Link to post
Share on other sites

Great post man!!

 

Synopsis: a compression method of using a single 8x8 character grid to

mimic the 8x8 battle screen implemented using old animation code. Brilliant compression method!

Share this post


Link to post
Share on other sites

Adam... do you have a storyline for the game you could share? How do you plan to implement it? In games like Final Fantasy I,II,III, etc, there is typically an extended intro sequence where you get the storyline, the background of the characters, and a hook... to draw you in...

 

FFII for SNES is a good example of this.

http://www.youtube.com/watch?v=CH1oWbo7GZw&feature=related

 

But then there are games like Pool of Radiance and Secret of the Silver Blades which just kind of throw you into it... "Here's half a page of info... enough to get you moving, and now kill a red dragon."

 

http://www.youtube.com/watch?v=vjJN5bx7wbQ&feature=related

 

I'm curious as to what the TI is capable of. Could an intro be done in bitmap mode and then the actual gameplay be in standard mode? This would allow very detailed screenshots while music plays and text is displayed at the bottom of the screen.

intro04.gif

 

 

It's not a pressing priority right now, but I'm starting to think about graphics and gameplay quite a bit lately. It keeps my mind sane while I battle it out with my battle engine. In any case, I was curious as to how YOU were planning on implementing your story... Story is so important to an RPG and if you under-do your story, you're doing the game a disservice. I know absolutely nothing about your storyline, but I was curious as to how often your story would interact with your gameplay. How do NPCs play a role? Just curous. =)

Share this post


Link to post
Share on other sites

Adam... do you have a storyline for the game you could share?

 

That would be telling... ;)

 

How do you plan to implement it? In games like Final Fantasy I,II,III, etc, there is typically an extended intro sequence where you get the storyline, the background of the characters, and a hook... to draw you in...

 

I'll have an intro sequence on the character creation disk after you've made a new game disk. The actual game disk will just launch into the game. There will probably be an end sequence as well.

 

I'm curious as to what the TI is capable of. Could an intro be done in bitmap mode and then the actual gameplay be in standard mode? This would allow very detailed screenshots while music plays and text is displayed at the bottom of the screen.

 

Of course. I would advise, though, that the "intro sequence" be a completely separate program from the game itself. You don't want to waste those resources when you could just push them to disk. Keep in mind, though, that music playing while disk accesses are going on are TRICKY to implement... I haven't tried it myself yet, it's possible, but would require you to have your code do it's own interrupt management ("Play some music, load some data, back to music, back to data, etc.")

 

Also, keep in mind a full bitmap image on the TI takes up about 12k of disk space, uncompressed. So you'd only have room for a handful of unique images. Coming up with an effective compression technique may help, but it would be hard to do on the TI's bitmap implementation...

 

It's not a pressing priority right now, but I'm starting to think about graphics and gameplay quite a bit lately. It keeps my mind sane while I battle it out with my battle engine. In any case, I was curious as to how YOU were planning on implementing your story... Story is so important to an RPG and if you under-do your story, you're doing the game a disservice. I know absolutely nothing about your storyline, but I was curious as to how often your story would interact with your gameplay. How do NPCs play a role? Just curous. =)

 

A lot of text. Story and game-play are intertwined, and players actions make visible differences. NPC's I'm still working details out on.

 

Adamantyr

Share this post


Link to post
Share on other sites

Handling a large amount of text... That's something I had been contemplating too... Do we use the text directive? I assume this is the way to go--- but I hear it's expensive. I had done a mockup of several pages of story/instructions but just used entire screens. Obviously unnecessary, but it showed me how much space all this text takes up!!!! I may have to look at a two disk system here.

Share this post


Link to post
Share on other sites

Handling a large amount of text... That's something I had been contemplating too... Do we use the text directive? I assume this is the way to go--- but I hear it's expensive. I had done a mockup of several pages of story/instructions but just used entire screens. Obviously unnecessary, but it showed me how much space all this text takes up!!!! I may have to look at a two disk system here.

 

Oh yeah. On vintage systems, text takes up the equivalent space to graphics. Bizarre! :dunce:

 

I am compressing the narrative text in the game using a simplified technique that crunches it 20-30%. Functional text like spell names are just stored in indexed files uncompressed.

 

You should consider pushing text to disk, rather than storing it in RAM. I mean, if it's only displayed at one instance of the game, do you need it taking up space?

 

Adamantyr

Share this post


Link to post
Share on other sites

Well definitely the intro sequence will be a totally separate program. =) I'll have to do a bunch of figuring to do for my game... I need to balance story and gameplay, but without storing all the NPC dialogue in RAM, I'll have to access it via diskette, and I have NO idea what kind of realtime lag that will bring on. That's another discussion for another thread.

 

In any case, for "Realms," are you planning on having the entire game on one disk (aside from the save disk) or will it be spread over multiple disks? I'm interested in this subject and I couldn't find the answers on your blog. If you've addressed disk access in your blog and I've missed it, please link it here so I can read. =) Your blog is a freakin' roadmap--- truly informative and a blast to read.

Share this post


Link to post
Share on other sites

Well definitely the intro sequence will be a totally separate program. =) I'll have to do a bunch of figuring to do for my game... I need to balance story and gameplay, but without storing all the NPC dialogue in RAM, I'll have to access it via diskette, and I have NO idea what kind of realtime lag that will bring on. That's another discussion for another thread.

 

In any case, for "Realms," are you planning on having the entire game on one disk (aside from the save disk) or will it be spread over multiple disks? I'm interested in this subject and I couldn't find the answers on your blog. If you've addressed disk access in your blog and I've missed it, please link it here so I can read. =) Your blog is a freakin' roadmap--- truly informative and a blast to read.

 

It's one game disk, one start disk, and four data disks, all 180k. So you need at least two floppy disk drives to play.

 

Adamantyr

Share this post


Link to post
Share on other sites

Yes, I set it up to randomly load monsters, I have about two dozen for the Demo version. The full game will support up to 255. Whether or not I use the full capacity remains to be seen...

 

I fixed my text offsetting issue by, ironically, converting it to use null-terminated strings instead. Normally I avoid these since they're prime targets for buffer overruns. In this case, it was the cleanest way to display text that shifts down a line if it hits a width threshold.

 

Looking over my code, I discovered that I did have all my code wired up to determine attack results... but I've no way of knowing what's going on during the fight. So right now I'm wiring up "combat announcements", and I may implement a little FX of melee attacks. Since none of my attack code has actually been ran through, I suspect there's going to be a lot of debugging going on there.

 

Adamantyr

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...