Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Speed and motion

9 views
Skip to first unread message

Bongo Bill

unread,
Dec 1, 2006, 7:38:52 PM12/1/06
to
In your Roguelikes, to the extent that the player and every monster all
have their own speed stat, how do you choose to translate this number
into more or less frequent actions? How, in addition, do you account
for the amount of time certain behaviors take (if at all)? This could
be either from a design or a programming perspective.

My own thoughts lead me to suggest that the following is a good method:
every actor has a speed stat between 0 and 100, and every action has a
time cost (visible or otherwise), also between 0 and 100. When the
player enters a room, dungeon level, region, or however the geography
of the game is divided, the game makes a Movement Index number, and
initializes it with a random value between 1 and 1000. Every actor has
a number called Delay, which is represented by (200 (ballpark) - Speed)
+ (time cost of most recent action). The Movement Index is incremented
until it is evenly divisible by any actor's Delay, at which point the
actor takes its next move, and depending on what that was and how it
affected its Speed stat, its Delay is set to a new value. If two actors
get their move at the same time, an arbitrary tie-breaker is used. This
repeats until there is only one actor in the area, or until the player
leaves the area.

But that's just my hare-brained opinion. What other methods are out
there?

Simon Richard Clarkstone

unread,
Dec 1, 2006, 8:16:47 PM12/1/06
to
Bongo Bill wrote:
> My own thoughts lead me to suggest that the following is a good method:
> every actor has a speed stat between 0 and 100, and every action has a
> time cost (visible or otherwise), also between 0 and 100. When the
> player enters a room, dungeon level, region, or however the geography
> of the game is divided, the game makes a Movement Index number, and
> initializes it with a random value between 1 and 1000. Every actor has
> a number called Delay, which is represented by (200 (ballpark) - Speed)
> + (time cost of most recent action). The Movement Index is incremented
> until it is evenly divisible by any actor's Delay, at which point the
> actor takes its next move, and depending on what that was and how it
> affected its Speed stat, its Delay is set to a new value. If two actors
> get their move at the same time, an arbitrary tie-breaker is used. This
> repeats until there is only one actor in the area, or until the player
> leaves the area.
That will spend a lot of time just incrementing and testing the movement
indices of various monsters. I recommend keeping an eye out for that
in profiling if your game becomes slow.

> But that's just my hare-brained opinion. What other methods are out
> there?

I have a priority queue of events. Initially, each monster has an event
on the queue to say when it will next move. I repeatedly take the
earliest event off the queue and act on it. If that event is a monster
becoming able to move, the sense data is acquired and passed to the AI,
which decides what to do, then the game performs the decided action and
puts a new event on the queue to say when the monster moves next. Any
other timed effects are also handled by the queue.

--
Simon Richard Clarkstone: s.r.cl?rkst?n?@durham.ac.uk/s?m?n.cl?rkst?n?@
hotmail.com ### "I have a spelling chequer / it came with my PC /
it plainly marks for my revue / Mistake's I cannot sea" ...
by: John Brophy (at: http://www.cfwf.ca/farmj/fjjun96/)

Gamer_2k4

unread,
Dec 1, 2006, 11:46:42 PM12/1/06
to
> But that's just my hare-brained opinion. What other methods are out
> there?

Each monster has there own speed stat, and action time is based on the
base speed and the action. For example, an attack with a whip is going
to take less time than an attack with a greatsword. Pushing a boulder
is going to take more time than just moving. Weight is a major factor
here.

Gamer_2k4

eri...@gmail.com

unread,
Dec 2, 2006, 1:50:37 AM12/2/06
to

Each mob has a move speed rating, and each attack has a speed rating,
too. I have a function that translates speed into delay (a higher
speed will result in less delay--delay represents the actual amount of
time the action consumes). Haste or slow effects are just a multiplier
to the speed rating. Moving or attacking (or opening a door, etc) adds
an amount of delay to the mob.

I have a priority queue like Simon described. Every time through the
dungeon level's update loop, I pull the mob with the lowest delay out
of the queue, call its update method, then stick it back into the
queue. The update method might not even alter the mob's delay--if
that's the case, then the mob will immediately get updated again, since
it'll still be top of queue. Sometimes that makes for easier code.

pol

unread,
Dec 2, 2006, 2:24:05 AM12/2/06
to
As long as you set up the numbers and the math in an efficient manner or
scale them correctly and not have to go through 999 increments before player
can go again. Besides that, it seems pretty interesting.


In mine i have speeds from -6 to ~26 which dictate 11 percentages for an
actor
every tic it checks which actors can act that turn. If allowed to act, they
do whatever they do.After 11 tics on the world clock, the 'turn' resets back
to 0 and goes through the 11 percentages again.

I also have different actions that take less than one turn like looking
around or dropping something from your hand or whatever. They usually take
1/3 of a turn, 2/3 of a turn of no time at all.

Some things take more. Like resting, and dentistry.

Radomir 'The Sheep' Dopieralski

unread,
Dec 2, 2006, 3:26:38 AM12/2/06
to
At 1 Dec 2006 16:38:52 -0800,
Bongo Bill wrote:

> But that's just my hare-brained opinion. What other methods are out
> there?

http://roguebasin.roguelikedevelopment.org/index.php?title=Time_Systems

--
Radomir `The Sheep' Dopieralski

Je n'ai fait celle-ci plus longue que parceque
je n'ai pas eu le loisir de la faire plus courte.

Jude H

unread,
Dec 2, 2006, 7:39:52 AM12/2/06
to
Bongo Bill <Bong...@gmail.com> wrote:
> The Movement Index is incremented
> until it is evenly divisible by any actor's Delay, at which point the
> actor takes its next move,

A priority queue will be much more efficient; each action in the queue
has a time index at which it's set to occur, and each "turn" you process
the action with the lowest index, setting the gametime to that time
index as you go.

Each action, on its conclusion, adds a new action_request to the queue
with the appropriately delayed time index (assuming the actor didn't die
during the action). The requested action will occur at the same time
index as the action_request which initated it.

> If two actors
> get their move at the same time, an arbitrary tie-breaker is used.

I advise against making it arbitrary; give the PC priority in all cases,
or you will sometimes get odd sequences like:

You hit the monster.
The monster hits you.
The monster hits you.
You hit the monster.
You hit the monster.
The monster hits you.

In cases where the actions happen simultaneously, it's better to
alternate in a consistent fashion.

--
--j hungerford.

Bongo Bill

unread,
Dec 2, 2006, 1:40:01 PM12/2/06
to
On Dec 2, 12:24 am, "pol" <p...@pol.net> wrote:
> As long as you set up the numbers and the math in an efficient manner or
> scale them correctly and not have to go through 999 increments before player
> can go again. Besides that, it seems pretty interesting.

Well, yes, I did fail to mention optimization. I tend to initially
program things first for being easy to follow and test, and *then*
optimize the living hell out of it.

Of course, it now occurs to me that, properly optimized, my system *is*
basically a priority queue, masquerading as a representation of
real-time. Eh.

Bongo Bill

unread,
Dec 2, 2006, 1:43:49 PM12/2/06
to
> > If two actors
> > get their move at the same time, an arbitrary tie-breaker is used.I advise against making it arbitrary; give the PC priority in all cases,

> or you will sometimes get odd sequences like:
>
> You hit the monster.
> The monster hits you.
> The monster hits you.
> You hit the monster.
> You hit the monster.
> The monster hits you.
>
> In cases where the actions happen simultaneously, it's better to
> alternate in a consistent fashion.

By "arbitrary" I meant it doesn't matter what method is chosen - not
that it would be decided arbitrarily.

Jude H

unread,
Dec 3, 2006, 5:52:56 AM12/3/06
to
Bongo Bill <Bong...@gmail.com> wrote:
> By "arbitrary" I meant it doesn't matter what method is chosen - not
> that it would be decided arbitrarily.

My misunderstanding, sorry. I mention it because the effect I describe
is what I ended up with when I first implemented my action priority queue.

--
--j hungerford.
Another Roguelike In Development:
http://arid.sourceforge.net

Ray Dillinger

unread,
Dec 4, 2006, 11:28:10 AM12/4/06
to
Bongo Bill wrote:
> In your Roguelikes, to the extent that the player and every monster all
> have their own speed stat, how do you choose to translate this number
> into more or less frequent actions? How, in addition, do you account
> for the amount of time certain behaviors take (if at all)? This could
> be either from a design or a programming perspective.

speed rating depends on strength, dex, and bulk. If all stats are
(human) average, speed starts out at 1.00.

Various races and monster species have their own distributions for
speed, dex, and bulk; these make average speed for each species
slightly different. And of course, individuals within various species
vary as to these stats, and therefore as to their speeds.

Bear

Jude H

unread,
Dec 5, 2006, 9:34:11 AM12/5/06
to
Ray Dillinger <be...@sonic.net> wrote:
> speed rating depends on strength, dex, and bulk. If all stats are
> (human) average, speed starts out at 1.00.
>
> Various races and monster species have their own distributions for
> speed, dex, and bulk;

Does this mean that there is a very fine gradation between different
monster speeds, and you may get some monsters which move 51 spaces for
every 50 of yours?

If so, does this feel confusing and unpredictable?

I ask because currently I am artificially simplifying my speed system
such that the gradation is very coarse (if you move 8 spaces and the
monster moves 8 spaces, you can be pretty sure that you can move another
100 without the monster getting an extra turn). The simulationist in me
wants the fine grade, but I have been concerned that this might damage
enjoyability.

Bongo Bill

unread,
Dec 5, 2006, 10:05:17 AM12/5/06
to

On Dec 5, 7:34 am, j...@nonexistant.invalid (Jude H) wrote:


> Ray Dillinger <b...@sonic.net> wrote:
> > speed rating depends on strength, dex, and bulk. If all stats are
> > (human) average, speed starts out at 1.00.
>
> > Various races and monster species have their own distributions for
> > speed, dex, and bulk;
>Does this mean that there is a very fine gradation between different
> monster speeds, and you may get some monsters which move 51 spaces for
> every 50 of yours?
>
> If so, does this feel confusing and unpredictable?
>
> I ask because currently I am artificially simplifying my speed system
> such that the gradation is very coarse (if you move 8 spaces and the
> monster moves 8 spaces, you can be pretty sure that you can move another
> 100 without the monster getting an extra turn). The simulationist in me
> wants the fine grade, but I have been concerned that this might damage
> enjoyability.

It seems to me that as long as various actions take different amounts
of time to act, then the timescale will shift due to fast or slow
actions sooner than it shifts due to fine differences in speed. But,
there's no reason a coarser scale couldn't hurt. Or an artificially
coarse scale, say, it can stretch from 0 to 100, but natural speeds can
only be in multiples of five.

Jeff Lait

unread,
Dec 5, 2006, 12:13:12 PM12/5/06
to
Bongo Bill wrote:
> On Dec 5, 7:34 am, j...@nonexistant.invalid (Jude H) wrote:
> > Ray Dillinger <b...@sonic.net> wrote:
> > > speed rating depends on strength, dex, and bulk. If all stats are
> > > (human) average, speed starts out at 1.00.
> >
> > > Various races and monster species have their own distributions for
> > > speed, dex, and bulk;
> >Does this mean that there is a very fine gradation between different
> > monster speeds, and you may get some monsters which move 51 spaces for
> > every 50 of yours?
> >
> > If so, does this feel confusing and unpredictable?
> >
> > I ask because currently I am artificially simplifying my speed system
> > such that the gradation is very coarse (if you move 8 spaces and the
> > monster moves 8 spaces, you can be pretty sure that you can move another
> > 100 without the monster getting an extra turn). The simulationist in me
> > wants the fine grade, but I have been concerned that this might damage
> > enjoyability.
>
> It seems to me that as long as various actions take different amounts
> of time to act, then the timescale will shift due to fast or slow
> actions sooner than it shifts due to fine differences in speed.

I think you are drawing the wrong conclusion from that lesson. That
tells you that having various actions take different amount of times is
*worse* than merely having fine graduation of monster speeds. At
least, worst in the sense of being confusing and unpredictable.

The speed thing is the most overrated aspect of Roguelike design. You
can only plan ahead the number of moves you can reliably predict. The
more random crap you throw into the simulation, the less the player can
plan ahead.

If the pattern of double-attacks for monsters is sufficiently random,
the player will not be able to safely rely on the monster only getting
one attack. This forces the player to be even more conservative.
Instead of wondering: "Can I survive to the next turn?" it becomes "Can
I survive for two turns?", a much harder and more conservative
estimate.

The fundamental flaw with the attempts to make ultra-realistic speed
models is that roguelikes are very, very, turn-centric. Damage is
usually resolved entirely in the instant of the turn. Movement occurs
instantly when the creature gets a turn. You can try and change these
things - apply damage over time for all attacks, track sub-grid
movement, etc.

Having said that, I'll point out there are two things a speed system
must do:
1) Track dungeon time. This is used for how long it takes effects to
wear off, when damage-over-time effects like poison proc, etc.
2) Determine turn order. A simple function that determines the next
mob to act.

Please note that it is important to make #1 independent of the player
and mob speeds.

My own suggestion for speed systems (which you can see in POWDER, You
Only Live Once, and Letter Hunt, the latter two providing source code)
is modelled off how I thought Nethack used to work. (Nethack as since
moved to the sort of overengineered speed systems I dislike). It is
built on the premise of making it as completely simple as absolutely
possible.

We divide creatures into 4 classes of speeds. Slow, Normal, Fast, and
Fast & Quick. In terms of effective speed, Slow is 66%, Normal 100%,
Fast 133%, and Fast & Quick 166%. This gives both a wide range of
speeds and also ensures each speed is significantly different from the
other speed levels. The latter point is one of my design principles -
I try to avoid continuous scales where one improves by 1% at a time -
that doesn't register on the players "Cool, new ability!" meter.

Anyways, implementation is straightforward. Track the current phase
which goes through the pattern FAST, NORMAL, SLOW, QUICK, NORMAL.

Then your time loop is...
while (1)
{
increment_phase();
for all mobs
{
if (phase is NORMAL or SLOW)
{
// Apply time to the mob.
mob->heartbeat();
}
if (mob->actsThisPhase(phase))
{
mob->getsTurn();
}
}
}

A mob which is marked as SLOW will not act in the SLOW phase. A mob
which is marked as QUICK will act in the QUICK phase. And a mob which
is marked as FAST will act in the FAST phase. All mobs will act in the
NORMAL phase.

Note that you can have both SLOW and FAST and end up with 100% of the
phases, albeit in a different order.

The heartbeat method is the constant in dungeon-time callback to do all
the maintaince, such as regeneration, hunger, poison, etc, that should
be independent of the creatures actual speed.

One thing to note about this system is that it is simple enough for the
player to figure out. When you are FAST facing a NORMAL monster, you
can easily pick up the pattern of double moves and thereby know if this
move will be a "free" move or not. This lets you perform, say, a two
turn action knowing you can complete it before the monster can react.
Of course, this also implies that you *know* that the actions only take
two turns. Having variable timed actions throws this out the window -
even if I know zapping a wand is faster than attacking, I don't know
how many fractional time units are left until the monster attacks next,
so can't determine if I can zap twice or attack once.

Many people seem to think this sort of knowledge is a bad thing.
They'd rather the player know as little as possible. This, however,
turns every battle into an FPS twitch fest. One can only act on the
immediate information at hand as any forward planning is guaranteed to
be disrupted by the RNG. Roguelikes, IMHO, occupy a neat place between
twitch-immediacy and long-term strategy. This tactical layer is
facilitated by being able to look a bit forward, but not too far
forward.

Note that the deterministic timing may allow more precise back & hack,
but any speed system allows the faster player to back & fire. The
limit placed in roguelikes is usually stumbling into other enemies, or
having other enemies stumble into you, while you prance about trying to
wear down the too powerful enemy.

Martin Read's Dungeon Bash uses a similar system to this, except with
four phases:

SLOW,NORMAL,SLOW,FAST

In his system, a mob gets a turn on any phase <= to its speed. SLOW
monsters act on SLOW turns, NORMAL on SLOW and NORMAL, and FAST on all
turns.

He's got an out of date comment, however:
/* Player is always speed 1, for now. */
if (action_speed <= u.speed)
I think u.speed isn't always 1 any more - there are ways to gain both a
malus and a bonus.

So, in summary, I'd be more concerned about creating enough good
content for a roguelike than worrying about the speed system. Not only
is it not necessary, it may even be harmful to your game.
--
Jeff Lait
(POWDER: http://www.zincland.com/powder)

eri...@gmail.com

unread,
Dec 5, 2006, 12:30:23 PM12/5/06
to
On Dec 5, 11:13 am, "Jeff Lait" <torespondisfut...@hotmail.com> wrote:
> So, in summary, I'd be more concerned about creating enough good
> content for a roguelike than worrying about the speed system. Not only
> is it not necessary, it may even be harmful to your game.

That was a very interesting read! Pyro currently implements a
continuously-variable timing system, but your argument about
predictability has convinced me to replace it with something much
simpler. I recently re-did my @ stats system so that a +1 to any stat
actually *means* something, for simplicity's sake, and this sort of
timing fits right in with that.

Timofei Shatrov

unread,
Dec 5, 2006, 1:34:19 PM12/5/06
to
On 5 Dec 2006 09:30:23 -0800, eri...@gmail.com tried to confuse everyone with
this message:

No-o-o! Predictability sucks! 4 monster speeds is just not enough. In my games
speed can be any rational number greater than 0. Various modifiers are also
possible - for example one item multiplies player's speed by 19/20. You'd think
it's barely noticeable? Well, it's not - it gives you the edge over monsters
which are as fast as you, but not so unbalanced that you can run away from any
monster. Large speed variations create imbalance, so fine speed gradations are
necessary. Consider Crawl, or ADOM or any other roguelike that allows a player
to become two times faster than normal monster. A character with such speed is
practically unkillable, so Haste spell in Crawl or seven league boots in ADOM
are basically game-winners. Even 33% speed boost is too much, IMHO.

--
|Don't believe this - you're not worthless ,gr---------.ru
|It's us against millions and we can't take them all... | ue il |
|But we can take them on! | @ma |
| (A Wilhelm Scream - The Rip) |______________|

Ray Dillinger

unread,
Dec 5, 2006, 3:28:25 PM12/5/06
to
Jude H wrote:

> Does this mean that there is a very fine gradation between different
> monster speeds, and you may get some monsters which move 51 spaces for
> every 50 of yours?

Yep. The average goblin, for example, is a little quicker
than the average human - by about 5%. But there are
differences among goblins, and some of them will be slower
than you, others as much as 12% faster. And yes, there'll
be a few that are 0.42125 % faster or slower...

> If so, does this feel confusing and unpredictable?

Yes, and that's the way I like it.

> I ask because currently I am artificially simplifying my speed system
> such that the gradation is very coarse (if you move 8 spaces and the
> monster moves 8 spaces, you can be pretty sure that you can move another
> 100 without the monster getting an extra turn). The simulationist in me
> wants the fine grade, but I have been concerned that this might damage
> enjoyability.

I don't think so, obviously. To me this is combat,
not chess. You *shouldn't* be able to predict, on a
fine scale, exactly when and how your opponent is
moving. Judging your enemy's speed and what you can
get away with is a very fine point of the game, and
I don't want the answers clear-cut down to the last
movement; I want them general and "iffy."

Bear


Tarindel

unread,
Dec 5, 2006, 6:39:36 PM12/5/06
to
Incidentally, I think it should be noted that you can avoid the
double-attack phenomena (where a monster gets 2 attacks in a row)
simply by making a round of combat take equal to or more time than any
other normal action in the game. That way, no matter what you do, you
can always guarantee that a monster will get no more than 1 attack per
standard action of yours.

Ray Dillinger

unread,
Dec 5, 2006, 10:34:52 PM12/5/06
to

True. And consistent with the way I have action balanced,
for that matter. Firing a bow takes three times as long as
moving orthogonally, and swinging a sword about twice as
long. Even daggers are slower than an orthogonal move, at
about the same speed as a diagonal move.

Eventually I want to add "move combo" abilities, where a
fighter gets a speed bonus on his next action if it's part
of a combination. So for example, a fighter might get the
"parry-riposte" combo at third level, and thereafter get a
speed (and possibly hit) bonus on attacks if they come right
after defending against an opponent's swing. And at fourth
level a "lunge and thrust" combo, which gives a speed bonus
on attacks following a movement toward an opponent who's not
moving away from you. Etc. As move combos accumulate, the
difference between a low-level and high-level fighter becomes
a lot more pronounced... Which I want to do because the hit
point differences that most games use aren't nearly as
pronounced in mine and I think that, as a result, high-level
fighters need some buffing.

Bear

Martin Read

unread,
Dec 6, 2006, 2:16:48 PM12/6/06
to
gr...@mail.ru (Timofei Shatrov) wrote:
>No-o-o! Predictability sucks!

In your opinion - which is a perfectly fair opinion to have. However,
*some* predictability is essential; we are not (in general) attempting
to write Dada: The Roguelike.

>4 monster speeds is just not enough.

I think it's plenty.

Hell, *one* monster speed is enough.

>In my games
>speed can be any rational number greater than 0.

Good.

>Various modifiers are also
>possible - for example one item multiplies player's speed by 19/20.

Good.

>You'd think
>it's barely noticeable?

No, because I used to play ADOM.

>Well, it's not - it gives you the edge over monsters
>which are as fast as you, but not so unbalanced that you can run away from any
>monster. Large speed variations create imbalance, so fine speed gradations are
>necessary.

All excessive game imbalance arises out of poor game design.

Besides, there's always the option of making sure there is at least one
monster the player cannot possibly outrun. You can't outrun an air
elemental in Nethack or a quickling king in ADOM.

>Consider Crawl, or ADOM or any other roguelike that allows a player
>to become two times faster than normal monster.

Many roguelikes that allow players to become twice as fast as a normal
monster have monsters that are three or more times as fast as a normal
player. In some cases, they're really quite *nasty* monsters. In
Angband, Morgoth is speed +30, making him about 3.5 times as fast as an
unhastened player.

>A character with such speed is
>practically unkillable, so Haste spell in Crawl or seven league boots in ADOM
>are basically game-winners.

ADOM's seven-league boots are nice, but I don't think I've ever actually
won the game wearing them. They don't increase overall speed; they just
reduce the energy cost of movement.

Crawl's Haste spell is nice, but you can't (safely) use it all the time
because of the magic contamination factor.

>Even 33% speed boost is too much, IMHO.

Only if you haven't designed with it in mind.

Fine-grained speed systems are good if the designer is competent.
Coarse-grained speed systems are good if the designer is competent.
If the designer isn't competent, the resolution of the speed system is
irrelevant. A game designed by an incompetent designer will only ever
be any good by serendipity.
--
Martin Read - my opinions are my own. share them if you wish.
\_\/_/ http://www.chiark.greenend.org.uk/~mpread/dungeonbash/
\ / "the lights shine clear through the sodium haze the night draws near
\/ and the daylight fades" -- Sisters of Mercy, "Lights"

0 new messages