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

Time in turn-based systems yet again

336 views
Skip to first unread message

Da-Breegster

unread,
Dec 17, 2005, 10:57:03 AM12/17/05
to

Hey. I know this topic has been brought up too many times before, but I just
don't get it in the way I'm thinking I should. I've already figured out how I'm
going to handle something like poisoning. Getting poisoned schedules a callback
to occur in the next turn, which depletes HP and schedules itself for the next
turn infinitely. (Thus making it viral.) A callback is scheduled to broadcast
an Unpoisoned event in about 6 turns. But what if a potion of healing is quaffed
between them? It will broadcast an Unpoisoned event as well. I'll implement a
dispatcher and watcher system and whatnot, and it will cancel those events.
(Yes, this isn't really time in the usual sense, but it's cool and it explains
the callback/event system.)

Something like delayed fireball, which takes one turn to chargeup and one to
execute, shouldn't be much harder. A callback to execute the attack itself is
scheduled in one turn and the current turn is spent "charging up", which pretty
much does nothing. The 'Hit' event for the actor can be broadcast to the
execute_fireball callback and interrupt it if that's how I decide to handle
that attack.

It gets tough in the case of picking up multiple items. Somebody suggested it
take 96 + (4 * x) ticks (with 100 being a turn) to pick up items. But in my
current system, there are no ticks. I don't want an overwhelming amount of
realism, but the possibility for it. What does 1.04 turns actually mean
practically? My first thought was to have it go towards which actor can go
first in a turn, thus making it a sort of priority queue. But the .04 wouldn't
really go away or change for most normal 1.00 turns until you do another action
with a remainder. Either way, this sort of realism and complexity isn't really
desirable. I was going to implement hasting/slowness by setting the amount of
actions that can be performed in a turn to a higher amount than usual. But then
how does that tie in with priority? Should the player be able to move twice in
a turn? Or should it move once, another monster do something, then another
move? How does the player know that's not a normal turn?

What I could do is have every action performed schedule itself to actually
occur in such and such time units. But that only seems to work for stuff like
a delayed magic attack. I just don't get how I should handle picking up
multiple items. I know there are different ways and I know I've asked this
before, but I still don't get it. Sorry. Can anybody help?

Da-Breegster

unread,
Dec 18, 2005, 5:31:36 PM12/18/05
to
On 2005-12-17, Da-Breegster <dabre...@gmail.com> wrote:
[snip original message]
I probably wasn't too clear earlier. My basic conflict was how to handle
partial turns, like getting 6 items taking 1.2 turns. I've figured it
out, I think. For actions costing more than 1 turn and less than 2, they
will be performed in that one turn instead of carrying over to the next.
This is done to preserve proper order for characters. But the fact that
they rushed to perform a certain action will temporarily decrease their
dodging stat or the general preparedness and defence. I think this
should work out OK. Still, though, any advice? It's a solution, but it
doesn't seem "clean."

Michal Brzozowski

unread,
Dec 19, 2005, 5:05:57 AM12/19/05
to

I don't see the problem. In my game I've got a priority queue, which
returns the creature earliest in time. Then every move has some
assigned duration, say 100 for walking, 50 for running, etc.
A faster creature may have a multiplier for this. So after every
move the creature is pushed back into the queue, with updated
time. There are no turns. You can say a turn is 100, but if your
PC moves in 80 units, you will get 5 moves in 4 turns.

nj...@hotmail.com

unread,
Dec 19, 2005, 8:57:34 AM12/19/05
to
You can take a look at XRogue 8.0 at http://roguelike.sourceforge.net
or Advance Rogue 7.7 (i think, but i don't have that version posted
yet) which handle this. I haven't quite followed it completely, and I
am not 100% sure I like it. In those versions of rogue there are 10
segments of each turn, every command generates an action which is
assigned delay (counted in segments) until completion (when the action
actually occurs). What I don't like about it is that you can send a
command to move into an empty space but by the time that command is
acted on a monster could move into that space and your action result
will be to strike the monster. The players speed is adjusted due to
effects (haste, slow, etc) and attacks can take up variable amounts of
time. Not too much is still based on the full turn, but a couple things
get triggered every 10 segments so I guess thats still the definition
of a turn.The player and each creature can have only one action
pending. So I guess they can't walk and chew gum at the same time. Not
saying it is the best or most clever solution (it is not even *my*
solution). But it is *A* solution. It of course requires something
anagolous to ticks which I guess you didn't want to have.

Gamer_2k4

unread,
Dec 19, 2005, 10:48:14 AM12/19/05
to
My method gives creatures a turn counter and a speed for each action.
The counter starts at 0. When the counter reaches 1000, the creature
can act again and 1000 is subtracted from the total. When the creature
acts, the speed for that action is stored temporarily. This happens
for each creature on that game turn. Then the next turn comes, and the
counter is checked. If it is less than 1000, the speed value of the
last action is added to the counter but the monster does not act.

Example:
Bat has a speed of 120.
Player has a speed of 100.
Turn: 1 2 3 4 5 6 7 8 9 10
Bat: 120 240 360 480 600 720 840 960 80 200
Player: 100 200 300 400 500 600 700 800 900 0

So we see that the bat moves again at turn 9, but the player can only
act at move 10 (because his speed is lower). Also, partial moves (for
example ones that take up 1.2 turns) are accounted for with the
carryover (1020 -> 20, not 0). You can give different values for
different actions too. This makes it fairly simple to have heavy
weapons take longer to attack with, and to allow for pack weight.
(Speed = Speed - (pack / Str)). If your speed was 100, your pack had
50 pounds in it, and your strength was 10, your speed would be reduced
by 5 (100 - (50 / 10)). You could say that your attack speed is (Speed
- weapon weight). This way you could attack very quickly with light
weapons (knives) or slowly with heavy weapons (hammer). Obviously
heavy weapons would do more damage. Attacking with hammer (weight 20)
would take 13 game turns, instead of the normal 10 for moving. I hope
this system helps.

NIm

unread,
Dec 19, 2005, 11:36:55 AM12/19/05
to

It seems like everyone is relying on ticks for thier game turns, or
discarding the excess. Is there any way of taking up 1.2 turns without
that? I personally prefer ticks, but if you don't want to go there you
could keep a tally of how much time you gave left over, and when it's a
whole turn, you get an extra turn. That's kind of like ticks though.
other than that I like the OP's current solution, which makes the pc
'hurry' to finish a move, and suffer a stat drain. I like this solution
because stats are basically there to make up for what you can't
simulate. you can't simulate. You can't simulate the partial turn
without a tick system, so use a stat equivalent of not having a full
turn.

Gamer_2k4

unread,
Dec 19, 2005, 1:44:37 PM12/19/05
to
Nlm wrote:
> You can't simulate the partial turn
> without a tick system, so use a stat equivalent of not having a full
> turn.

OTOH, it's not exactly fair to the player to penalize him for certain
actions. There could be a game option, though: Rush Actions. If it
was on, then all actions would take the same amount of time, but the
player would suffer stat penalties for slow actions (maybe bonuses for
quick ones?). If it was off, then the player would take longer to
finish actions, but would suffer no penalizations. This might be the
best way to implement this.

Da-Breegster

unread,
Dec 19, 2005, 6:37:23 PM12/19/05
to
The possibility of simply eliminating the traditional concept of turns
did cross my mind in fact. Or rather, keeping turns or a 100/1000-tick
system simply for purposes of recording action points. I'll consider
this again without the concept of turns hindering me.

A thought. Say the player just executed some action and they 0 action
points allocated. When should they be allowed to choose another move?
When their AP reaches some value like 1/100, depending on ratio? What if
they choose to do an action costing 1.5 turns and another character goes
between them? It'd look weird:

> Pick up the bread ration? y
> Pick up the great sword? n
> Pick up the really heavy troll corpse? y
- The goblin thumps you in the head.
You've picked up the items.

The problem isn't an enemy killing them during this delay, as events
sucha s On_hit can interrupt accordingly. It just seems weird. But
still, when should the player be asked for their next move? When the AP
reaches the standard value, i.e. the one that most turns take?

Da-Breegster

unread,
Dec 19, 2005, 6:40:43 PM12/19/05
to
On 2005-12-19, nj...@hotmail.com <nj...@hotmail.com> wrote:
> You can take a look at XRogue 8.0 at http://roguelike.sourceforge.net
> or Advance Rogue 7.7 (i think, but i don't have that version posted
> yet) which handle this. I haven't quite followed it completely, and I
> am not 100% sure I like it. In those versions of rogue there are 10
> segments of each turn, every command generates an action which is
> assigned delay (counted in segments) until completion (when the action
> actually occurs). What I don't like about it is that you can send a
> command to move into an empty space but by the time that command is
> acted on a monster could move into that space and your action result
> will be to strike the monster.
That'd be a problem, yeah. But for something like moving one adjacent
space, I think the player will already require 1 action point, or
whatever the required amount is, so it won't be a problem. As far as a
long-term travel thing, an event could interrupt it when an enemy
appears on the screen, like with crawl's nifty Travel patch.

> The players speed is adjusted due to effects (haste, slow, etc) and
> attacks can take up variable amounts of time. Not too much is still
> based on the full turn, but a couple things get triggered every 10
> segments so I guess thats still the definition of a turn.The player
> and each creature can have only one action pending. So I guess they
> can't walk and chew gum at the same time. Not saying it is the best
> or most clever solution (it is not even *my* solution). But it is
> *A* solution. It of course requires something anagolous to ticks
> which I guess you didn't want to have.
>

It sounds decent, but I think I won't use it. I probably will eventually
allow for walking and chewing gun simultaneously. Thanks for the idea
though.

Da-Breegster

unread,
Dec 19, 2005, 6:49:47 PM12/19/05
to
I think it's pretty similar to the idea starting to form in my head now.
The concept of turns exist only to give action points back to actors.
When actors reach a certain value for AP, they get to choose an action.
If it only costs the amount they've already got, it happens immediatly.
If not, they wait a bit until they've got enough points. The carryover
from a turn (where a certain amount of action points are recovered) is
simply kept.

Wait. What's the carryover used for? If you only gain back X amount each
turn and there are no concept of mini-turns (ticks?), then it only
factors in for speed.

I'm all confused again. Thanks though.

Da-Breegster

unread,
Dec 19, 2005, 6:58:32 PM12/19/05
to
You think it's a good idea? I like it myself now, because it's simple,
this preparedness factor can be very generic and can account for any
scenario (since I'm writing an engine that'll let me and others create
multiple games, more on this in a bit). Maybe preparedness could even be
thought of as luck, or a factor that acts similar to luck. The more you
rush, the less successful you are in what you do.

A question though. For actions costing 1.5 turns, .5 is the deduction
from the preparedness factor. (That's not the exact number, obviously.)
The same for 1.6, 1.73469 (though I may decide not to get THAT exact),
and 1.9. For something like 1.9, though, should I round up, call it 2
turns (thus forcing the player to lose a turn) and give them a bonus?

It seems like I can either have players lose a turn and get a
preparedness bonus or keep a turn but lose preparedness. It should
probably be a choice, shouldn't it? Keeping a turn sounds more
beneficial. Maybe if I made the preparedness factor equivalent in
fairness to the loss of a turn factor.... I dunno.

Oh yeah, clarification on my project. I'm planning to create several
roguelike games, starting with a stereotypical one to polish my engine,
then experiment more and more. My original idea back in July was to
create something like an Earthbound clone in ASCII art format. Seems
silly now, but I might incorporate more non-random factors into some of
my other games. Multi-parties, online games, and other such rarely-used
ideas might creep their way into my projects, thus the engine will
benefit.

Da-Breegster

unread,
Dec 19, 2005, 7:01:41 PM12/19/05
to
On 2005-12-19, Gamer_2k4 <game...@gmail.com> wrote:
Since I'm designing an engine (see my reply to the post above this
subtree), this might be the way to go. You can choose (in the game or by
the player) to lose a turn and get a preparedness bonus on the carryover
or keep a turn but lose preparedness. As long as preparedness was an
essential factor in everything favoring the player (or actually,
whichever actor is going), this will work out. All actions would never
take the same amount of time in either system. Actions taking 2 turns
take 2 turns in both systems. I was just talking about fractional parts.

bjorn.b...@jadestone.se

unread,
Dec 20, 2005, 2:45:30 AM12/20/05
to
All of this turn/tick/mini-turns talk twist my head. It seems
confusing. I prefer to handle the "who gets to act next" question using
a priority queue and think of how long different actions take to
perform measured in milliseconds. Consider this:

#######
#@....#
#...B.#
#.....#
#.T...#
#.....#
#######

You have the Player ('@') with speed 10
You have a Bat ('B') with speed 14
You have a Troll ('T') with speed 6

The average speed in your game is 10

Moving one mapcell takes 1000 milliseconds (1 second) for a creature
with average speed (ie. 10)

Attacking takes 300 milliseconds (0.3 seconds) for a creature with
average speed (ie. 10)

Then take a normal PQ and insert the Player, Bat and Troll, each with a
priority (time when they get to act next) of 0.

The PQ looks like this:

0 Player
0 Bat
0 Troll

Pop the creature with the lowest priority from the PQ, the Player.

The Player moves east. The time it takes to move one cell for the
Player is ((1000 * 10) / 10) = 1000 ms. Push the Player onto the PQ
again, now with a priority of 0 + 1000. PQ:

0 Bat
0 Troll
1000 Player

Pop the next creature, the Bat. The Bat moves one cell west which takes
((1000 * 10) / 14) = ~714 ms. Push the Bat onto the PQ again with a
priority of 0 + 714. PQ:

0 Troll
714 Bat
1000 Player

Pop the next creature, the Troll. The Troll moves north. This takes
((1000 * 10) / 6) = ~1667 ms. Push the Troll back onto the PQ with a
priority of 0 + 1667. PQ:

714 Bat
1000 Player
1667 Troll

#######
#.@...#
#..B..#
#.T...#
#.....#
#.....#
#######

Pop the next creature, the Bat. The Bat attacks the Player which takes
((300* 10) / 14) = ~214 ms. Push the Bat onto the PQ again with a
priority of 714 + 214. PQ:

928 Bat
1000 Player
1667 Troll

Pop the next creature, the Bat again! Due to it's speed it gets an
extra attack on the player, (((300* 10) / 14) = ~214 ms. Push the Bat
onto the PQ again with a priority of 928 + 214. PQ:

1000 Player
1142 Bat
1667 Troll

Next creature to act is the Player. The Player crushes the bat using a
normal attack, ((300 * 10) / 10) = 300 ms. The Bat dies and is removed
from the PQ. The Player is pushed back onto the PQ with a priority of
1000 + 300. PQ:

1300 Player
1667 Troll


Hope this was easy to follow. I think this is a neat way of solving
when different creatures get to act depending on speed and their
actions. Anything that should be scheduled to act can be put into the
PQ, not only creatures, but also poison effects, timed effects on the
map etc.

/Björn
(posted via Google Groups, *shrug*, any good NNTP servers that allows
posting and are free?)

Gamer_2k4

unread,
Dec 20, 2005, 1:53:32 PM12/20/05
to
The carryover lets the monster act sooner the next time. If it has 400
speed, then it takes 4 turns to move a second time (0 -> 400 -> 800 ->
1200), but only 3 turns to act a third time (200 -> 600 -> 1000).

Gamer_2k4

unread,
Dec 20, 2005, 2:00:48 PM12/20/05
to
That's a decent system, but if you want realistic healing and poison
effects (as well as other time based features) it is probably better to
use a turn system. In your example the Troll would probably only heal
on its turn, which would cause problems. Suppose the Troll had 10 HP
and two monsters hit him for 5 before he could act again? Conversely,
do you want a bat to heal more often merely because it is faster? It's
better to heal constantly, even when it's not the monster's turn. A
Troll has incredible regeneration no matter how fast it moves. You
would need to write seperate healing code using your method. With the
turn system, all you need to do is check if (TURN % (50 - Toughness))
== 0), and if it does, then heal. It seems fairer to have the Troll
slowly heal while in combat (10 -> 5 -> 6 -> 7 -> 2) This way the
Troll won't have a cheap death.

deric...@hotmail.com

unread,
Dec 20, 2005, 3:11:32 PM12/20/05
to
Da-Breegster wrote:
> I think it's pretty similar to the idea starting to form in my head now.
> The concept of turns exist only to give action points back to actors.
> When actors reach a certain value for AP, they get to choose an action.
> If it only costs the amount they've already got, it happens immediatly.
> If not, they wait a bit until they've got enough points. The carryover
> from a turn (where a certain amount of action points are recovered) is
> simply kept.
>

This is similar to the system I use, as well. There's a global turn
(basically, one time through the main game loop) where each actor is
given a certain amount of energy, which is based on their abilities,
items, etc. There are also two different types of energy - movement and
attack. Each action an actor can perform is classified as either
move-equivalent (basic movement, opening/closing doors) or
attack-equivalent (attacking, casting a spell, using an ability).
Currently, each action requires 1000 of the appropriate energy (but
that will probably change). When an actor attempts to do something, the
appropriate energy pool is checked to see if there's enough energy to
perform the action. Once both of the actor's energy pools drop below
the threshold for an action (1000), their turn has ended, and the next
actor begins their turn. Obviously, the actor can end their turn before
this happens, as well. If an actor does not have enough energy to
perform an action, their turn is simply skipped.

Now, if an actor is given 1500 movement energy on a turn (with an
initial pool of 0), they will be able to perform one move-equivalent
action. Their movement energy will then drop to 500. The next time
their turn comes around, they will have 2000 movement energy, and the
option of taking two move-equivalent actions. So, this actor will be
able to move twice every other turn.

Having everyone on the same turn is nice for the duration of effects,
as you can simply reduce the duration left for all effects by 1 each
turn. I like the separation of movement speed and attack speed, rather
than simply having a 'speed' value, as this opens up options for
different abilities. It also allows for creatures that can attack
quickly (like an actor with 6 arms) but moves slowly, and ones that can
move quickly, but attack at a normal rate. Actors also have the option
(with some restrictions) of using their attack energy for basic
movement. This will let them perform a 'double' move, and simulates the
actor focusing simply on moving.

Sam Skipsey

unread,
Dec 20, 2005, 3:38:10 PM12/20/05
to

In my queueing system, there are three separate event queues - one for
"metabolic" effects, one for "physical" effect and one for "intelligence"
effects.
So, a Troll has a fast metabolism, a normal response to physical stimuli,
and a very slow thought-process. We pop off the queues at the relevant
tick, which leads to a transparent ordering of people's turns (the
"intelligence" queing), separate from the ordinary physical and metabolic
effects in the game.

Sam

Da-Breegster

unread,
Dec 20, 2005, 4:02:44 PM12/20/05
to
I get it now. I've figured out how what I guess an energy/tick system
works. Every 10 ticks, or 1 turn, an actor gains back a certain amount
of energy. As soon as they can make a move, they'll go for it. I
understand now, thanks.

Da-Breegster

unread,
Dec 20, 2005, 4:09:27 PM12/20/05
to
On 2005-12-20, bjorn.b...@roguelikedevelopment.org
Hmm. I like this approach too. Actors don't really gain back energy
points or anything complex like that. But a question: the priority for
an actor simply keeps adding up. That's fine and all, because it
maintains order, but do you ever reset things back to 0? Perhaps when
the player is alone on their area of the map, the only actor?

The thing that's still not entirely clear is whether or not how much
time between two creatures acting matters. I know the bat moves first,
but does it matter that it moves 72 units prior the player? I think it'd
be nice if order was the only factor, but is it OK to disregard how much
the order contrasts specifically?

Da-Breegster

unread,
Dec 20, 2005, 4:11:43 PM12/20/05
to
On 2005-12-20, Gamer_2k4 <game...@gmail.com> wrote:
I see the problem. I haven't been thinking about healing at all. How
would this tie into an energy system without separating things into IQ,
physical, and metabolic tasks?

Narf the Mouse

unread,
Dec 21, 2005, 12:10:04 AM12/21/05
to

Da-Breegster wrote:

> Hey. I know this topic has been brought up too many times before, but I just
> don't get it in the way I'm thinking I should. I've already figured out how I'm
> going to handle something like poisoning. Getting poisoned schedules a callback
> to occur in the next turn, which depletes HP and schedules itself for the next
> turn infinitely. (Thus making it viral.) A callback is scheduled to broadcast
> an Unpoisoned event in about 6 turns. But what if a potion of healing is quaffed
> between them? It will broadcast an Unpoisoned event as well. I'll implement a
> dispatcher and watcher system and whatnot, and it will cancel those events.
> (Yes, this isn't really time in the usual sense, but it's cool and it explains
> the callback/event system.)
>

Without looking at the other posts in this rather large topic, here's
how I handled it in my proto-roguelike.

First, you have a turntimer float for each character (PC, NPC,
monster). Then, you set that to 100 / a number based on whatever you're
using for your characters speed.

Next, you run through all the turntimers, pick the lowest number, and
decrease all the turntimers by that number.

Then, all the characters with a zero'd turntimer move and get their
turntimers reset.

It's not truely turn-based, but it does the job.

bjorn.b...@jadestone.se

unread,
Dec 21, 2005, 1:45:45 AM12/21/05
to

Da-Breegster wrote:
> On 2005-12-20, bjorn.b...@roguelikedevelopment.org
> <bjorn.b...@jadestone.se> wrote:
> > All of this turn/tick/mini-turns talk twist my head. It seems
> > confusing. I prefer to handle the "who gets to act next" question using
> > a priority queue and think of how long different actions take to
> > perform measured in milliseconds. Consider this:
> >
[snip PQ example]

> >
> >
> > Hope this was easy to follow. I think this is a neat way of solving
> > when different creatures get to act depending on speed and their
> > actions. Anything that should be scheduled to act can be put into the
> > PQ, not only creatures, but also poison effects, timed effects on the
> > map etc.
> >
> > /Björn
> > (posted via Google Groups, *shrug*, any good NNTP servers that allows
> > posting and are free?)
> >
> Hmm. I like this approach too. Actors don't really gain back energy
> points or anything complex like that. But a question: the priority for
> an actor simply keeps adding up. That's fine and all, because it
> maintains order, but do you ever reset things back to 0? Perhaps when
> the player is alone on their area of the map, the only actor?

You could reset everything when the Player moves to a new map.

/Björn - roguelikedevelopment.org


> The thing that's still not entirely clear is whether or not how much
> time between two creatures acting matters. I know the bat moves first,
> but does it matter that it moves 72 units prior the player? I think it'd
> be nice if order was the only factor, but is it OK to disregard how much
> the order contrasts specifically?

I believe so yes. It should be enough.

/Björn

bjorn.b...@jadestone.se

unread,
Dec 21, 2005, 1:57:32 AM12/21/05
to

Hmm, yes, you have a point there. You could ofcourse wait with actually
removing the dead Troll until it was the Trolls turn to act again. This
way you could apply any regenerative effects first, then check if HP <=
0 and then remove the Troll if the amount of regeneration wasn't enough
to keep it alive. The message log might look a bit odd though:

The Troll is hit for 5 HP [first monster hits the Troll, HP = 5]
The Troll is hit for 5 HP [second monster hits the Troll, HP = 0]
The Troll crashes to the floor! It looks dead! [instant feedback from
HP reaching 0]
The Troll gets up on its feet again! [the Trolls' turn. Regeneration
kicks in]

or if the Troll actually doesn't regenerate enough HP:

The Troll is hit for 5 HP
The Troll is hit for 5 HP
The Troll crashes to the floor! It looks dead!
The Troll doesn't get up again

Handing out exp for a kill will become a bit more difficult with this
approach, but it's still a possible solution.

Another solution would be to have the Trolls regeneration trigger on
the "onDamage(5 HP) event" regenerating some HP for each damaging hit
the Troll receives.

/Björn - roguelikedevelopment.org

Da-Breegster

unread,
Dec 21, 2005, 2:06:59 PM12/21/05
to
I don't really see what the problem is. I've decided* to use a priority
queue with active and passive events. Active are decided by the actor
and passive are the 'metabolic' events. Healing, MP recovering, and
poison effects are handled in these passive events. The regeneration
rate determines how fast and how much HP/MP is recovered. So healing
isn't really done on an actor's turn, since their "turn" is considered
to be their active event.

* As much as one can decide. Two days ago, I was confident my stat
* drain/rushed actions system was perfect. Yesterday I was absolutely
* sure an energy/tick system would get the job down. And then today at
* school I realized a priority queue achieves the same effect as an
* energy system (ordering actors correctly) with much less complexity.
* So I don't really know what I'll do for sure yet.

Da-Breegster

unread,
Dec 21, 2005, 2:10:53 PM12/21/05
to
On 2005-12-21, Narf the Mouse <lrgm...@telus.net> wrote:
>
> Da-Breegster wrote:
>
>> Hey. I know this topic has been brought up too many times before, but I just
>> don't get it in the way I'm thinking I should. I've already figured out how I'm
>> going to handle something like poisoning. Getting poisoned schedules a callback
>> to occur in the next turn, which depletes HP and schedules itself for the next
>> turn infinitely. (Thus making it viral.) A callback is scheduled to broadcast
>> an Unpoisoned event in about 6 turns. But what if a potion of healing is quaffed
>> between them? It will broadcast an Unpoisoned event as well. I'll implement a
>> dispatcher and watcher system and whatnot, and it will cancel those events.
>> (Yes, this isn't really time in the usual sense, but it's cool and it explains
>> the callback/event system.)
>>
>
> Without looking at the other posts in this rather large topic, here's
> how I handled it in my proto-roguelike.
>
Well it's a complex subject, see.

> First, you have a turntimer float for each character (PC, NPC,
> monster). Then, you set that to 100 / a number based on whatever you're
> using for your characters speed.
>
> Next, you run through all the turntimers, pick the lowest number, and
> decrease all the turntimers by that number.
>
> Then, all the characters with a zero'd turntimer move and get their
> turntimers reset.
>
> It's not truely turn-based, but it does the job.
>
Kind of cool but weird. Sort of like a priority queue.

It is a priority queue I think. Everybody starts off with some priority
based on their speed and the smallest is popped off. Every actor's
priority is decreased by that number, ending one or more actors up with
0. They act at 0, then go back in the queue with their original speed
value. I really like this idea, as it prevents the priority from
building up.

How's this compare to the other priority queue idea where everybody
starts at 0, the cost of an action is added to priority each turn, and
the smallest acts again? It seems the same, but there could be
subtle differences.

Da-Breegster

unread,
Dec 21, 2005, 3:43:00 PM12/21/05
to
[snip]
I understand how it works now and I like it. I think I'll use it. If
anybody's interested, I "modelled" a simple scenario and described what
happens in detail.

Format = Actor: Priority - Action

M: 0.9 - Input
P: 1.0 - Input
N: 1.1 - Input

P: 0.1 - Input
N: 0.2 - Input
M: 1.0 - 1.0 Action

N: 0.1 - Input
M: 0.9 - 1.0 Action
P: 1.0 - 1.0 Action

M: 0.8 - 1.0 Action
P: 0.9 - 1.0 Action
N: 1.0 - 1.0 Action
(M performs 1.0 Action and is scheduled for input at 0.9)
P: 0.1 - 1.0 Action
N: 0.2 - 1.0 Action
M: 0.9 - Input

...Etc. The order is: M(I), P(I), N(I), M(A), P(A), N(A)

This system works beautifully. Let me model with 1.5 and 0.8 actions then with
stuff like poison and healing.

Actor: Priority - Action
M: 0.9 - Input
P: 1.0 - Input
N: 1.1 - Input

P: 0.1 - Input
N: 0.2 - Input
M: 1.0 - 1.0 Action

N: 0.1 - Input
M: 0.9 - 1.0 Action
P: 1.5 - 1.5 Action
(N after M because M faster)
M: 0.8 - 1.0 Action
N: 0.8 - 0.8 Action
P: 1.4 - 1.5 Action
(M performs 0.8 Action and is scheduled for input at 0.9)
N: 0.0 - 1.0 Action
P: 0.6 - 1.5 Action
M: 0.9 - Input
(Nothing subtracted since N is already at 0.)
(N performs 1.0 Action and is scheduled for input at 1.1)
P: 0.6 - 1.5 Action
M: 0.9 - Input
N: 1.1 - Input
(P performs 1.5 Action and is scheduled for input at 1.0)
M: 0.3 - Input
N: 0.5 - Input
P: 1.0 - Input

N: 0.2 - Input
P: 0.7 - Input
M: 1.0 - 1.0 Action

P: 0.5 - Input
M: 0.8 - 1.0 Action
N: 1.0 - 1.0 Action

M: 0.3 - 1.0 Action
N: 0.5 - 1.0 Action
P: 1.0 - 1.0 Action

But it seems like N will always be going before P until N does a slow move or P
does a fast move. But isn't this OK? Without turns, as long as the pattern is
somewhat OK, things are fine. It's simply reordered when the P does a slow move
and the N a fast one.

The order ends up being: M(I), P(I), N(I), M(A), N(A), P(A), M(I), N(I), P(I),
M(A), N(A), P(A).... M(A), N(A), P(A)

So the order of actual actions is: M, N, P, M, N, P, M, N, P

This works fine. Eventually it could end up changing to M, P, N.

Even a concept of 'turns' could be invented purely for the sake of the
player. The pattern is M, N, P. That's a turn. Or rather, more simply,
the number of actions the player has been performed is the number of
turns. Purely for the benefit of the player.

Thanks for all the help, guys. I see nothing wrong with this system.
Stuff like healing and poison and other metabolic events will simply be
scheduled as passive. The callbacks won't ask for input or perform an
action already selected, but instead do their job of adding/subtracting
HP or MP. I'm sure I can work it out so the order is fair and something
like a troll won't die unfairly.

Narf the Mouse

unread,
Dec 22, 2005, 3:24:37 AM12/22/05
to
Glad to help.

Ray Dillinger

unread,
Dec 23, 2005, 8:16:24 PM12/23/05
to
Gamer_2k4 wrote:

Here's what healing does: It checks the monster record to see
how long it's been since the monster last healed, and adds an
appropriate amount of hits for that interval. You heal the
monster on its turn (so that its AI has a reasonable idea of
its health in deciding what to do) and whenever it takes damage
(so you have an accurate idea of how damaged it has become and
whether it is really dead).

In other words, it's a simple rule. You apply healing, like
anything else, on the events where it might make a difference.

Bear

Brendan Guild

unread,
Dec 24, 2005, 4:22:35 PM12/24/05
to
deric...@hotmail.com wrote in
news:1135109492.8...@g49g2000cwa.googlegroups.com:
> This is similar to the system I use, as well. There's a global
> turn (basically, one time through the main game loop) where each
> actor is given a certain amount of energy, which is based on their
> abilities, items, etc. There are also two different types of
> energy - movement and attack. Each action an actor can perform is
> classified as either move-equivalent (basic movement,
> opening/closing doors) or attack-equivalent (attacking, casting a
> spell, using an ability). Currently, each action requires 1000 of
> the appropriate energy (but that will probably change). When an
> actor attempts to do something, the appropriate energy pool is
> checked to see if there's enough energy to perform the action.
> Once both of the actor's energy pools drop below the threshold for
> an action (1000), their turn has ended, and the next actor begins
> their turn. Obviously, the actor can end their turn before this
> happens, as well. If an actor does not have enough energy to
> perform an action, their turn is simply skipped.

Just to be clear, does this mean that nothing happens when the player
attempts to perform an action without enough energy? Would this
happen every turn as the player gets low on energy for that turn?
Having your keys sometimes perform actions and sometimes do nothing
is likely to seem frustrating and counter-intuitive, I think.

What happens when the player ends a turn before using up the energy?
Does the energy carry on to the next turn, growing larger and larger
until the actor chooses to use it? Probably not, because that would
seem to mean that the player can charge up the PC into a super-mode
by skipping a few turns, then suddenly perform a large number of
actions all within one turn. Taken to the extreme, I imagine the PC
locking himself in a closet and then holding down the 'skip' key for
a million turns to build up energy, then completing the entire game
in the next turn.

Brendan Guild

unread,
Dec 24, 2005, 5:20:18 PM12/24/05
to
Da-Breegster wrote in
news:slrndqjadp.4r...@localhost.localdomain:
> It is a priority queue I think. Everybody starts off with some
> priority based on their speed and the smallest is popped off.
> Every actor's priority is decreased by that number, ending one or
> more actors up with 0. They act at 0, then go back in the queue
> with their original speed value. I really like this idea, as it
> prevents the priority from building up.
>
> How's this compare to the other priority queue idea where
> everybody starts at 0, the cost of an action is added to priority
> each turn, and the smallest acts again? It seems the same, but
> there could be subtle differences.

The benefit of using a normal priority queue is that you don't have
to iterate over every monster for every turn. You can use a data
structure to increase efficiency. I'm not sure how serious a cost it
might be to scan the monsters and update the priority value, but what
cost is there with using fixed priority values?

The values will have to increase continuously throughout the game, so
we should probably store them in something more powerful than a
normal C++ variable, to allow larger values without limit. It can
also be used as a game-clock to report the length of the game to the
player. Aside from that, there is no cost. I like the idea of having
a very large number of monsters for the PC to face all at once, so
any cost-per-monster concerns me.

Ray Dillinger

unread,
Dec 25, 2005, 2:25:05 PM12/25/05
to
Brendan Guild wrote:

> The values will have to increase continuously throughout the game, so
> we should probably store them in something more powerful than a
> normal C++ variable, to allow larger values without limit. It can
> also be used as a game-clock to report the length of the game to the
> player. Aside from that, there is no cost. I like the idea of having
> a very large number of monsters for the PC to face all at once, so
> any cost-per-monster concerns me.

My friend, if I need anything bigger than a Long Double to store
game time, then there must be something very seriously wrong.
okay, maybe after playing a few quintillion turns (which would
take longer than the egyptian empire lasted, give or take) something
that's supposed to take place in a tenth of a turn starts taking place
in 13/128 of a turn instead due to roundoff error... I can live with
it.

Bear


Narf the Mouse

unread,
Dec 26, 2005, 1:04:37 PM12/26/05
to

Brendan Guild wrote:

Technically, a five-digit float would be enough for most games - Since
it works on addition and subtraction, the number in there would
probably never be higher than 200 - For slow monsters.

0 new messages