Jump to content
IGNORED

Diablo-look a like possible on A8?


Recommended Posts

ok. last update for today...

 

more items (4096 weapons plus approx each of them in 4-6 variations >16385 individual wepaons!). if you don't believe it... just load the debug version and play around. the debug version just drops a lot more weapons than the "real game". any comments here?

 

when entering the character stat screen (press C)you can see now in details how the weapon affects your stats. and most important.... by pressing any other key you can go back to the game and continue to play...

 

so...time to think about an inventory system. the diablo approach is too complicated at the moment but maybe a simple list will do it as well... each item gots a char assigned (like in any game dos) and by pressing the key you can wear that item.

 

and when all this works... next will be the item background buffer...

diablo5m.zip

Link to comment
Share on other sites

ok. last update for today...

 

more items (4096 weapons plus approx each of them in 4-6 variations >16385 individual wepaons!). if you don't believe it... just load the debug version and play around. the debug version just drops a lot more weapons than the "real game". any comments here?

 

when entering the character stat screen (press C)you can see now in details how the weapon affects your stats. and most important.... by pressing any other key you can go back to the game and continue to play...

 

so...time to think about an inventory system. the diablo approach is too complicated at the moment but maybe a simple list will do it as well... each item gots a char assigned (like in any game dos) and by pressing the key you can wear that item.

 

and when all this works... next will be the item background buffer...

 

Your game seems to be coming along quite nicely. I especially like the sound effects and backgound music.

 

-tjb

Link to comment
Share on other sites

thanks. at the moment the whole game logic as it stands right now is 4k pure assembler... not counting the RMT-player...

 

when finished the item engine (generator+individual picking up+equip) we can go back to the 3d-iso-engine...

 

btw. the music is just a place holder...

Link to comment
Share on other sites

Wow, the game really starts to *feel* like diablo :-) can't wait to see further progress :)

I think the enemy logic would have to change before I'd say that but it's definately cool and an excellent start.

 

To feel more like Daiblo or most other action RPGs, the player must pass within a certain distance of enemies before they come after you. It looked like more enemies were just being sent as soon as one died. But then I didn't mess with it for long.

 

I think if you want another action RPG to borrow ideas from you should also look at Champions of Norrath for the PS2.

Link to comment
Share on other sites

i am just back from the games convention... it seems that RPG are one of the most covered genres... ;) but back to the enemy engine.

 

i just implemented a simple hunt algorithm because it is simple and i could mess around with the player routines first. as i said... there are a lof of sub-engines in diablo which you dont "see" on the first look.

Link to comment
Share on other sites

i am just back from the games convention... it seems that RPG are one of the most covered genres... ;) but back to the enemy engine.

 

i just implemented a simple hunt algorithm because it is simple and i could mess around with the player routines first. as i said... there are a lof of sub-engines in diablo which you dont "see" on the first look.

In Diablo and most other RPGs there's a line of sight and distance issue.

This actually makes your job easier and faster.

 

I'm not sure you want help but here's a possible way to implement this.

 

Keep two lists. One for close enemies and one for distant ones.

 

Scan the close object list for enemies that are no longer in range.

If they aren't test to see if that enemy will continue to follow or not and if not, move them to the long list.

Scan the distant one to find enemies within range and move them to the short list.

You can sort it by distance if you like to make it faster.

Any enemies within the minimum attack distance and line of sight (optional) are moved to the short list. Then the distance to the next closest enemy is calculated for testing. Your character must move at least that distance from the current location before you need to scan the long enemy list again.

 

The short list is used to update enemies on the screen by calling each routine associated with that enemy for it's logic. That way different enemies can be given unique behavior and speed. It can also track it's own timer to know whether or not it has sat long enough to move. A bonus of this is that an attack can stun a character simply by increasing the timer.

 

Killed enemies are removed from the short list simply by pointing it to the routine that continues to the next location.

 

Distance is pretty easy since it could be as simple as abs(difference in x) plus abs(difference in y).

 

I haven't written 6502 code in a long time but an indexed page 0 table might be able to handle the short list of enemy pointers.

It depends on how many bad guys are chasing you. I suppose you could limit it and then do a scan of the long list once when an enemy dies to see if another one can take it's place. In that case a sorted long list makes it easier since you just fill the short list with the closest baddies in range.

 

Obviously sprite or player missile limitations will dictate how you do a lot of this. It's easier for bitmapped graphics since you don't have those limits.

To compensate and prevent too many baddies from following you to another group of baddies you'll have to make baddies be persistant so they have to be killed before you move on.

Link to comment
Share on other sites

james, thanks for your info. but keep in mind that the atari has not unlimited horse power to handle that... i doubt he can do this all in a nice speed. as i said earlier i am not sure how many enemies can be handled at once...

 

this is not gauntlet wth a lot of enemies on screen as we have a lot more stats to handle and to calculate each frame.

 

if we are just able to handle 4 enemies than we might handle each one separatly. but i like the list approach. but again its an 8bit cpu and unfortunatly we can just move 8bits per 2 cycles... ;)

Link to comment
Share on other sites

james, thanks for your info. but keep in mind that the atari has not unlimited horse power to handle that... i doubt he can do this all in a nice speed. as i said earlier i am not sure how many enemies can be handled at once...

 

this is not gauntlet wth a lot of enemies on screen as we have a lot more stats to handle and to calculate each frame.

 

if we are just able to handle 4 enemies than we might handle each one separatly. but i like the list approach. but again its an 8bit cpu and unfortunatly we can just move 8bits per 2 cycles... ;)

The Atari clock is what? 1.7Mhz for 1.7 million clocks/sec? Subtract some cycles stolen for graphics or whatever and there should still be over 1.5 millions cycles/sec available. 1,500,000 / 60 (for NTSC) = 25,000 cycles / frame for NTSC and 30,000 for PAL. You have some room there if you use it wisely.

 

You are still prototyping in BASIC so you aren't seeing that speed. Compiled Basic is probably making a lot of ROM calls so it's nowhere near the speed of other compiled languages.

The biggest problem with BASIC is it's lack of ability to deal with structures and pointers. Something the method I'm suggesting would depend on.

cc65 would be better but generating code for the 6502 is tough so I'd use assembly for the innermost loops.

 

Scanning the short list is pretty quick really.

 

Can the current character move yet?

Yes, call the move routine which just sets the new location for the character. Reset the move counter.

No, decrement the counter.

Can the current character attack (distance less than min attack distanc) and (time between attacks counter <= 0)

if yes, reset counter, set up display to use attack and update character stats

No, decrement the counter

if character animation in progress and count between cells <= 0 then advance to next cell and reset counter

No, decrement counter

 

If you keep track of what characters change position then the draw routine only has to update those characters.

 

 

Stats should be the least of your problems. The scrolling and any memory moves for cell animation will probably occupy the majority of your clock cycles.

 

If you find the stats calculations are taking too many cycles then take a step back and look for another way.

Limit the number of calculations in the main loop by precalculating everything and simplify the calculations you have to do.

 

The beginning stats of each baddie are precalculated at the creation of the level and stored in it's data structure. This also contains precalculated vales related to player interaction.

 

Some games don't increase a player's stats until a kill takes place. You only get credit for a kill, not just fighting. This reduces the number of times you need to update most of the player's stats and when they are updated the info just comes from the data structure of the dead baddie and is just added.

 

The chance of hitting a character is determined with a formula involving player level, armor, baddie level, etc... but those are pre-calculated and stored with the baddies and only updated when the player stats change such as a kill, level up or weapon & armor changes.

Something like this:

(chance of player hitting me = (player level - my level) * level difference compensation - my special armor points + player special weapon points)

(chance of me hitting player = (my level - player level) * level difference compensation - player special armor points + my special weapon points)

 

The range for the random number generator is already calculated so when attacking a character you just generate the random number with that range and see if it matches what you want for a hit.

 

Do the random... if no match it's a miss and you're done.

 

If it's a match then it's a hit and you need to subtract the base hitpoints of the weapon from the character, then generate a random number based on the precalculated range associated with your weapon and subtract the result.

(If a 'Dark Sword of Death' causes 60-70 points damage it means 60 base and 10 random)

(monster hit points -= player weapon damage base + random(player weapon damage range) - monster armor compensation)

 

Since hit rate of characters should be regulated this doesn't take place more than 1 or 2 times per second, per character. That's probably less than 10 times / sec on average.

Link to comment
Share on other sites

thanks a lot for your long description.

 

sounds good and most you have described already implemented... ;) but on my list is optimising the stuff when all is working (precalculating stuff/unrolling loops, eliminating subroutine calls). otherwise maintaining the code is not possible... ;)

Link to comment
Share on other sites

thanks a lot for your long description.

 

sounds good and most you have described already implemented... ;) but on my list is optimising the stuff when all is working (precalculating stuff/unrolling loops, eliminating subroutine calls). otherwise maintaining the code is not possible... ;)

Understood and it sounds like you are on the right track. Work out the logic first and go from there.

 

BTW, by lists I just meant lists of pointers. If it were for a large machine or even a CPU that supported high level languages better I'd just use one and step through it until the current baddie was out of range instead of using a short list.

I figured the 2nd list would limit the number of moving characters and would fit in page zero to make for fast 6502 code. I could be wrong though... happens all the time! ;)

 

Looks cool!

Link to comment
Share on other sites

btw.... we had big discussions about gfx, inventory, controls etc... but one subengine is missing.

 

anybody any idea how a sill tree could be done? i mean how is the basic principles behind that? ok you are setting points etc which add or enable some specials... but how would i do this from coding point of view? esp. on 6502? arrays? lists?

 

any comments on that very much appreciated.

 

btw. expect tomorrow new build with some changes, f.e. line of sight...

Link to comment
Share on other sites

btw.... we had big discussions about gfx, inventory, controls etc... but one subengine is missing.

 

anybody any idea how a sill tree could be done? i mean how is the basic principles behind that? ok you are setting points etc which add or enable some specials... but how would i do this from coding point of view? esp. on 6502? arrays? lists?

 

any comments on that very much appreciated.

 

btw. expect tomorrow new build with some changes, f.e. line of sight...

I'm not familiar with the term 'sill tree' but I think I know what you mean.

Special Items?????

 

This is just a suggestion and it sounds complex at first but it should work. Keep in mind I haven't thought out all the details and can work without special functions or could be expanded easily without changing the core game logic. Some of my examples are just that and may be more complex than what is possible but they are just examples. You may want to finish a Rogue like game first and save this for a revamp once everything else works.

 

 

If you use the lists and call them object lists instead of character lists then it's easy to add.

All the short list does is let you step through the objects that need to update status regularly.

That could be move, attack or just a timer related to something on the level.

Objects don't need to be visible.

It could be a routine that makes a wall in the maze open for a few seconds every minute, closes a door within 10 seconds of you entering a room, randomly change walls of the maze or keep track of how fast you solve a level to give your character a melee bonus for finishing quickly.

You could create an object with a time limit. You must reach the item before the time expires. For example you design a shrine that must be reached within so many seconds of starting a level for it to give you a special sword that helps you kill a nasty baddie. This object is moved to the short list so it's updated regularly even though it's not visible at the start of the level. Once the timer expires the shrine gives you nothing or a lower level weapon and the baddie is much harder to kill.

It could even change the color palette to make lava look like it's glowing/moving or characters eyes pulse... a magic sword pulse with energy... whatever.

 

 

Each object starts with the address of several routines. What those routines are could be something like this:

UPDATE_OBJECT()

ATTACK_OBJECT()

INIT_OBJECT()

NEXT_OBJECT // pointer to the next object

DESTROY_OBJECT()

 

You can change this to suit your needs.

 

INIT_OBJECT is called for all objects when a level begins. Here is where any custom code for the object sets up it's internal structure. Duplicate objects can actually share code but the code just uses the base address for the structure to deternime where things are placed. The level init routine steps through the objects in the level calling these and then moving on to the NEXT_OBJECT. If you get around to loading levels this will come in handy. This routine also adds items to the short list that will need to be there from the start.

 

// call the setup routine for this level

init_level(level1_first_object);

 

//

// initialize all objects in a level

//

init_level(char *first_object) {

current object == first_object;

while(current_object != &H0000) {

*current_object->INIT_OBJECT(); //this may be wrong... haven't called a routine this way in a while

current_object = current_object->NEXT_OBJECT;

}

}

 

 

DESTROY_OBJECT is called when an object is destroyed so it can cleanup.

 

ATTACK_OBJECT is called if the player attacks it.

A baddie would update itself, if it dies update the player.

Special objects may do special things or nothing.

A pile of bones might fall apart, mark it's internal state as destroyed and tell you "you free the spirit of a warrior" and update player's stats.

An "Eternal Well of Mana" could update the player's mana.

If the well can only be used once it changes it's internal state to used and never adds mana to the player again.

If it gradually recharges itself it takes a timestamp of when last used and each update uses that and the current time to decide how much mana is in the well if the player goes back.

If the well is always full it always updates a player's mana.

 

 

UPDATE_OBJECT handles object related timers, moves an object, etc. This lets objects update themselves. Then can call a global move routine with a speed for that object and use the results to update itself. For some baddies you could create special behaviors. Use the default move until baddie is within 20 pixels. Then keep it's distance and try to circle behind you, wait for something else to attack before moving in... whatever. You could use this for a wolf for example. This keeps the core engine simple and capable of handling common stuff but custom items handle themselves and adds endless variety.

 

 

I know you are going to think it's too much but you can you do this on a 6502.

You have to keep the short list short and not do too much complex logic each pass.

For example, for a pack of wolves that circle the player, create an object with a counter and each wolf could be set to only do a complex update when the counter is equal to a certain value.

You may also need to reorganize the object structure to simplify the 6502 code for processing the lists but you get the basic idea.

 

It sounds more complicated than it is. To really implement cool stuff would require loading levels. That way you can load new objects with new behavior.

The worst part is the list handler stuff. After that you can add stuff as you think it up without messing with the main gameplay anymore and it can be as simple or as complex as you want to try.

Link to comment
Share on other sites

thanks again for your long reply but i just had a wrong typo...

 

i ment skill tree...

Ok. Gotcha.

 

*IF* I understand what you want...

 

 

It's pretty much a tree only on paper to the best of my knowledge.

 

The short version in C++ OOP speak...

Create a base class for each character class. (Any object I've mentioned could do the same so duplicate logic can be shared)

Add holders/variables for the character skills you want to store to it's object.

Add methods with the "business logic" for dealing with those skills.

Create some generic system routines these can call by setting parameters to keep things small.

 

To auto upgrade something call an update routine within the character and it's business logic does the rest.

If you manually upgrade skills this will be more methods to interact with the ugrade screen and the rest has to lie within the upgrade screen and variables stored in the character's object.

 

Summary...

The written tree just defines the 'business rules', data to store and items to store there..

Universal rules go into globally callable routines.

Character specific ones go into the base class for the character.

Data is stored in a character object.

A 'level up' screen acesses variables within the object and makes calls to routines within the object which can call the base class or deal with it on it's own.

 

So you are dealing with a base address for the character and accessing variables or methods with indexing.

 

Doing it this way lets you have any number of character classes. If you only allow one you just hardcode the business rules for one character and skip the addressing the 6502 might not like.

 

Execution speed isn't critical here if you are manually assigning skills so what you do just depends on how much work you want to put in.

 

I hope that's what you were asking about.

btw. your knowledge seems very deep...i assume have something to do with such a game in former life? ;)

To be honest, this design was actually just off the top of my head.

 

I'm not a game developer but I've been designing/writing commercial software since I was in high school (1981?) and used to be part owner/developer for a company that wrote software for the Amiga. I've also done embedded systems work and a lot of telcom/broadband stuff.

 

I've recently started getting back into 8 bit computers and have been looking into writing a few games myself.

Would you guys mind if I created a port of this for another machine?

I promise to share any cool stuff I come up with!

 

 

BTW, I just thought of another cool thing that could be implemented with custom objects.

 

Baddies could have grunts and commanders. The commander has smart logic telling the grunts simple coordinated orders and then when the grunt routines are called they follow the orders (go left, go right, attack but stored as numbers). If the cammander gets killed they stop taking orders and just continue with the last order, become confused and/or they don't work as a group.

 

You can see where there are endless varieties of options. On a fast machines you'd use a script to control characters in a similar manner (which you will see in ID games and many other PC games) but you'll load in machine language that is included with a level or randomly generate objects and call standard logic shared between them.

Link to comment
Share on other sites

What I have done is to use arrays of Fixed decimal values. Tie each 'skill' into an action, (such as using a sword raising the Edged Weapons Skill) and then every time the action is used they may gain a 'skill point' in the associated skill. Then take the skill reading into account when checking for game events like hitting, resisting, successfully sneaking, etc. You can also allow the purchase of skill points as well, either with gold or with experience points. Taking it much beyond a few battle-related skills probably will be too much for a game on this platform.

Edited by danwinslow
Link to comment
Share on other sites

What I have done is to use arrays of Fixed decimal values. Tie each 'skill' into an action, (such as using a sword raising the Edged Weapons Skill) and then every time the action is used they may gain a 'skill point' in the associated skill. Then take the skill reading into account when checking for game events like hitting, resisting, successfully sneaking, etc. You can also allow the purchase of skill points as well, either with gold or with experience points. Taking it much beyond a few battle-related skills probably will be too much for a game on this platform.

You can probably use integer math just as effectively in the final game and it's much faster on an 8 bit.

Link to comment
Share on other sites

It's also a good idea to have the skill advancement rate 'decay' as it approaches 100%...that is, it gets progressively harder ( ie., takes more usage ) the closer you get to max. Use the skills as scalers for the given actions...so if someone with 0 edged weapons skill picks up an edged weapon that takes a lot of skill to use, the chance of damage with that weapon actually goes way down until the person has skilled up a bit. Then provide choices of weapon in the game ( piercing, blunt, etc. ) and so you get people having to decide what skill sets to pursue. You can use the same idea for armor, and all sorts of other things, like magic success, different schools of magic, etc. The basic idea is that a given item, or spell, or action like hiding, would have a certain 'difficulty' modifier, that would be a large negative to the chance of success. So a person has to work hard to overcome that skill penalty and get back to even with the item, but that is usually balanced by there being more power available upon a success with that item. So, to use an edged example :

If a character finds a crappy edged weapon, say a bent sword, well that is very easy to use ( has a low skill penalty ), so a level 1 char can just pick it up and use it for its full effect. It's full effect, however, is pretty crappy...ok to kill easy things but impossible to really use against a mighty foe. But if he also finds a UberBlade of Serious Butt-Kicking, he can pick it up and try to use it, but that thing has a HUGE penalty for use, so he can barely swing it, and if he does manage to get a miraculous hit with it, it wont do much damage. BUT...if he bears down and uses the crappy sword for a while, and gains skill, perhaps also buying or finding skill points along the way ( you can have NPC 'teachers' ) then soon he will be able to use the UB of SBK in a fearsome manner indeed.

Link to comment
Share on other sites

I just checked out the latest and greatest.

Much more Diablo like. I would make the distance baddies detect you and start moving in a little further but it's definately the right idea.

 

You might want to set a flag if the player moves and not animate him if the flag isn't set. Or just make him stand there and look around.

While you are working out that logic it might be a good time to start calculating what sprite to display for what direction the player is walking.

For baddies you can use the change in x,y to determine what direction they face.

 

I would use something like this:

 

get userinput

if input != null

If left then base offset = left

else if right base offset = right

etc...

endif

move character flag = true

else

base offset = still

move character flag = false

endif

...

showsprite(base offest + sizeof(sprites) * spriteframe #)

if move character flag = true then spriteframe ++

 

 

 

if the sizeof a spriteframe = a multiple of 2 then you can just shift the bits for the multiply. 8 or 16 are the likely sizes. You don't have to use all the bytes if your character isn't 16 high but I'm sure it's over 8.

 

 

 

;table of sprites

;character sprites

;still

; frame 1

...

;

...

;left

; left frame 1

....

; left frame 2

...

etc...

;right

; right frame 1

...

; right frame 2

...

etc...

;North

 

;South

Edited by JamesD
Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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