Jump to content
  • Advertisement
Sign in to follow this  
fyko chan

Speed formula in RPG game

This topic is 2142 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi

 

I'm trying to make a turn based rpg fighting system, but I'm trying to have it so if the speed is high enough, you will attack two times before the slower opponent has a chance to attack. (Making spells like quick and slow really smart spells)

 

Right now I use the speed, and how many times they already have attacked, to calculate a waiting time, and the one with the slowest waiting time gets to attack, But the problem with my formula is that everyone usually gets to attack twice before the next character.

 

Here is myformula:

wait = (100/speed)*(float)round;

Does anyone know of a better way of doing this?

Share this post


Link to post
Share on other sites
Advertisement

Right now I use the speed, and how many times they already have attacked, to calculate a waiting time, and the one with the slowest waiting time gets to attack

I'm not totally familiar with the vocabulary, but doesn't a "round" mean a cycle in fight in which every participant gets active at least once?

 

Perhaps an algorithm like the following will do what you expect:

 

1. All participants decide what their action in the current round would be. The actions are collected into a list. Store the count of activations per round within the action's list entry.

 

2. For each selected action its quickness (IMHO a better word than speed in this context) in dependence on the character's props, the action itself, and perhaps some buffs / de-buffs is computed. From each quickness the corresponding time lag will be computed and stored.

 

3. For each action in the list, its activation time will be set to its time lag value. This means that the particular first activation time is relative to the same virtual "start of round" moment in time for each action.

 

3. Sort the list by activation time.

 

4. Pick the action with the lowest activation time and apply it. Decrement its "counter of activations per round" and remove the action from the list if the counter has reached zero. Otherwise increase the activation time by the stored value of time lag, and re-insert the action in the list according to the sorting criteria of point 3.

 

5. Continue with point 4. until the list is empty.

 

Notice please that computing the time lag is independent on the round. With the quickness having a unit of a frequency ("1 over time" or "per time unit"), the time lag is just its inverse (perhaps scaled by a constant like the 100 you have used, if you want so; this just changes the time unit without any effect on the algorithm shown above).

Edited by haegarr

Share this post


Link to post
Share on other sites

I suggest a simpler priority queue, containing characters, sorted by the time of their next action, and initially sorted by some kind of "initiative rolls".

The first character in the queue acts, a delay dependent on stats, action type, equipment etc. is added, and the character is put back into the priority queue.

This allows multiple attacks to occur only occasionally: two fighters swinging at each other with delay 5 and 6 will attack at times 0,5,10,15, 20, 25, 30, 35... and 0, 6, 12, 18, 24, 30, 36... with the faster one attacking two times in a row (maybe, depending on initiative at time 0) at times 0 and 5, 25 and 30 or 30 and 35 depending on initiative, and every 30 ticks thereafter.

Share this post


Link to post
Share on other sites

I'm not totally familiar with the vocabulary, but doesn't a "round" mean a cycle in fight in which every participant gets active at least once?

 

Round is maybe not the best name for the variable, but it is the number of times the character has attacked, it's a variable each character has, not a global variable. I don't want a round in the way most rpg games have.

 

Lets say there are 3 characters fighting, and number 3 has a slow speed. Character 1 would attack, then character 2, then number 1 again, then number 2, then character 3. 

If character 3 has a really slow speed he might have to wait even twice as long.

 

I suggest a simpler priority queue, containing characters, sorted by the time of their next action, and initially sorted by some kind of "initiative rolls".

The first character in the queue acts, a delay dependent on stats, action type, equipment etc. is added, and the character is put back into the priority queue.

This allows multiple attacks to occur only occasionally: two fighters swinging at each other with delay 5 and 6 will attack at times 0,5,10,15, 20, 25, 30, 35... and 0, 6, 12, 18, 24, 30, 36... with the faster one attacking two times in a row (maybe, depending on initiative at time 0) at times 0 and 5, 25 and 30 or 30 and 35 depending on initiative, and every 30 ticks thereafter.

That is basically what I have. In that case, character 1 would have a wait of 5, and the second would have a wait of 6. What I want to know is what is the best way of calculating the wait "time"! 

 

What I'm doing now is dividing 100 by the speed, to "invert" the speed (higher speed=lower number) and multiplying this by the number of times the character has attacked 

Share this post


Link to post
Share on other sites


... In that case, character 1 would have a wait of 5, and the second would have a wait of 6. What I want to know is what is the best way of calculating the wait "time"! 
 
What I'm doing now is dividing 100 by the speed, to "invert" the speed (higher speed=lower number) and multiplying this by the number of times the character has attacked 

As written in my post above, there is no need to pre-compute all actions of a turn at once; to compute the next action of each participant is sufficient (and IMHO appropriate, because the players may rethink their selection after a turn has gone). So what is wrong with the inverse of quickness to compute the time to elapse until the next action happens?

Share this post


Link to post
Share on other sites

CAVEMAN works this way:

 

every attack has an attack time required (how long it takes).

 

every attacker has a is_attacking flag (Boolean). its set to true when an attack begins. 

 

every attacker has an attack counter (how far along they are in their current attack).

 

when an attack is made, is_attacking is set to true, and the attack counter begins incrementing once per turn.

 

when the attack counter reaches the attack time required, is_attacking is set to false,and the player can make their next attack.

 

its just uses simple counters to figure out when you can attack again. this will easily generate the correct timing for all attacks.

Share this post


Link to post
Share on other sites

Each actor has a 'readiness' variable.

 

Every tick, 'speed' is added to 'readiness'.

 

If no actor has a readiness at or above 100, move to next tick.

 

If any actor has a readiness at or above 100, the actor with the highest readiness score acts.

 

Upon acting, an actor's readiness is decreased by 100.

Share this post


Link to post
Share on other sites

CAVEMAN works this way:

 

every attack has an attack time required (how long it takes).

 

every attacker has a is_attacking flag (Boolean). its set to true when an attack begins. 

 

every attacker has an attack counter (how far along they are in their current attack).

 

when an attack is made, is_attacking is set to true, and the attack counter begins incrementing once per turn.

 

when the attack counter reaches the attack time required, is_attacking is set to false,and the player can make their next attack.

 

its just uses simple counters to figure out when you can attack again. this will easily generate the correct timing for all attacks.

 

You could get rid of the is attacking boolean and replace it with the timer. Set the timer to 0 to mean "is not attacking". When an attack starts, set it to the attack time. Subtract the frame time each frame (if the timer is > 0) and when it gets <= 0 set the timer back to 0 and the attack has finished.

 

It's usually much easier to count down...

Edited by Paradigm Shifter

Share this post


Link to post
Share on other sites

I have been working on a rules set for an RPG myself and you may want to take a look at how I handle the same issue.

 

For weapons attack frequency is handled by skill level with the weapons group and by a weapon speed modifier. For example a dagger is faster than an axe and an axe is faster than a flail.

 

when a player starts combat an initiative roll is done (1d20) to determine when they begin combat (in 1 of 20 slots). From here on out the number of times a player goes depends on the weapon, the skill with that weapon type and the attack being performed. it is possible for a low level character to go twice in the same round, but its not guaranteed.

 

My magic system is similar...any way maybe it will help.

 

www.redash.org

 

Share this post


Link to post
Share on other sites

As written in my post above, there is no need to pre-compute all actions of a turn at once; to compute the next action of each participant is sufficient

What do you mean by this? When a character attacks, I calculate when he will attack next. What am I pre-computing?


So what is wrong with the inverse of quickness to compute the time to elapse until the next action happens?

Nothing is wrong with it, but I was wondering if there was a better way to calculate it, something that would give you more control over the numbers. Right now you need almost no speed advantage to attack more often on low speeds, but on high speeds you need way bigger advantages. If I'm not mistaken?

Each actor has a 'readiness' variable.

 

Every tick, 'speed' is added to 'readiness'.

 

If no actor has a readiness at or above 100, move to next tick.

 

If any actor has a readiness at or above 100, the actor with the highest readiness score acts.

 

Upon acting, an actor's readiness is decreased by 100.

This would work, but it is more based on time, I want it based on a queue, meaning you don't have to stand around waiting for 2-3 seconds to see whos turn it is next. Also, I need a visual representation of the queue, so I need to know in what order they will attack.

 

I have all this, just the math doesn't seem right. I just believe it can be done better.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!