palito-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[palito-dev] on simultaneous orders


From: Gabriel Blum
Subject: [palito-dev] on simultaneous orders
Date: Tue, 21 Jan 2003 13:18:46 -0200

Cool... the server sketch looks fine; It's simple because the select()
synchronizes the
processing into frames/time slots;

Tough the network code is the tricky one, cause it's asynchronous.

I see problems in the game loop;
First issue) It isn't fair neither correct to process all commands from
player i before processing commands from player i+i; You should process one
command per player, in a round-robin fashion until there is no more commands
from any player OR until your time for that frame is over; This way is the
correct way when server resources are limited; You should save the last
round robin position for the next tick/game loop; It's a scheduling
system... when you have extra time, anything works. But when you haven't,
you must ensure fairness;

Seconde issue) It is also important to note that player orders may generate
conflicts if the processing is linear; Or may even generate paradoxes;. I
take this from my Diplomacy experience, because it's a game that all orders
run simultaneous;

I mean that the loop
> void game_tick() {
> foreach player
> foreach unit

has problems;

Player 0 orders
- Unit A: attack unit B

Player 1 orders
- Unit B, with very little health: < some order>

Correct "adjudication" is that BOTH unit orders should be execute, because
they were issued simultaneously;
Problem: the actual game loop causes unit B do die, so he won't execute his
orders;

Paradox

Player 0 order
- Unit A attack unit B
Player 1 order
- Unit B attack unit A

If both units are with almost zero health, both units should fire and both
should die; Your game loop causes B to die first and A to live; The paradox:
if both shoot and both kill each other instantaneously, both are
instantaneously dead and couldn't shoot the other in first place! This
paradox is a 2-way, but it can be n-way;
The same applies to movement!

I know this is more complicated because attacks aren't instantaneous, but
anyway the problem persist: you shouldn't process the world information for
player 0 before you do for player 1; It should be done for all players
simultaneously -- which is not only correct and fair, it's also cheaper;

The solution to the paradox involves finding conflict orders and circular
references orders first and making special processing for them ( that is,
applying rules ); After that, you can proccess the rest in any way;

Ending this email with an interesting question: Is it possible in TOTALA to
create a circular movement with 4 units?
Imagine 4 units adjacent
AB
DC

Can we make the circular move A move to B's position, B move to C, C->D->A
??

[]'s
Gabriel

----- Original Message -----
From: <address@hidden>
To: <address@hidden>
Sent: Friday, January 17, 2003 11:36 PM
Subject: [palito-dev] server sketch


>
//--------------------------------------------------------------------------
-
> int main(int argc, char *argv[])
> {
> print_welcome();
> network_init();
>
> while() {
> tv = wait_period;
> do {
> fd_set(rin, fileno(stdin));
> foreach fd_set(rin, player[i]->fd);
> start_select = get_ticks;
> if(select rin, tv) {
> foreach player
> if fd_isset(pl[i]->fd)
> process_command(i);
> if fd_isset(rin 0)
> process_command(0);
> }
> spent_on_select = get_ticks - start_select;
> tv -= spent_on_select;
> } while (tv>0);
>
> start_gameloop = get_ticks;
> game_tick();
> spent_on_gameloop = get_ticks - start_gameloop;
> wait_period = frame_period - spent_on_gameloop;
> }
>
> return 0;
> }
>
//--------------------------------------------------------------------------
-
> void process_command(Client *client, char *cmd)
> {
> char *tok = *cmd;
> switch(tok) {
> map;
> server settings;
> join {
> if(id = next_token)
> join as player id;
> else
> return new_player->id;
> }
> status {
> playerlist
> maplist
> orderlist [player] [unit]
> }
> client != NULL && command {
> unit = next_token(&tok);
> if(append|prepend|insert|delete) {
> if(insert|delete)
> order_idx = next_token;
> order_type = next_token(&tok);
> if(move|build|attack)
> target = next_token;
> else if(kill)
> kill();
> }
> else if(group) {
> group_id = next_token;
> group_op = next_token;
> units = next_tokens;
> }
> }
> }
> }
>
//--------------------------------------------------------------------------
-
> void game_tick()
> {
> // allocate unit slots with orders
> foreach player
> foreach unit
> use_slots = 0
>
> // decide what to do
> foreach order // inherit group?
> req_slots = 0
> "move"
> if too_far
> req_slots |= 1<<MOVE
> else
> accomplished = 1
> "attack"
> if target dead
> accomplished = 1
> break
>
> foreach weapon
> if used_slot & 1<<weapon_slot_id
> if (target_fly && weapon->is_air)
> || (!target_fly && !weapon->is_air)
> req_slots |= 1<<weapon
> range = weapon_range
> //FIXME move even if one
> // weapon already reaching?
>
>
> "build"
> if target_built
> accomplished =1
>
> req_slots |= 1<<NANO
> range = nano_range
>
>
> "follow"
> "guard"
> ...
>
> if dist_to_target > range
> req_slots |= 1<<MOVE
>
> if accomplished
> pop_order
> continue
>
> if req_slots & use_slots
> continue
>
> use_slots |= req_slots;
>
> foreach slot
> MOVE
> unit->slot[MOVE]
> target = order->target - range
> path//finding
>
> WEAPON1
> WEAPON2
> WEAPON3
> WEAPON4
> unit->slot[1<<weapon]
> target = order->target
> //allocate resources
> NANO
> unit->slot[MOVE]
> target = order->target - range
> path//finding
> //allocate resources
>
> end //foreach order
>
> // alocate unused slots on automatic tasks
> foreach slot
> MOVE
> wander around
> WEAPON1
> WEAPON2
> WEAPON3
> WEAPON4
> //shoot someone!
> //plane, trains and automobiles
>
> //allocate resources
> NANO
> //nanolate something!
> //patrol! get wreckage!
> //do something utile of your life!
> //FIXME make nano like a specialized weapon
> //  nano shoots friends and building stuff
>
> //allocate resources
>
> end //foreach slot
>
> if once_in_a_while
> //check communication with commander
>
> if once_in_a_while
> //add visual area on visualization map
>
> //FIXME visualization map is like
> //the commander communication check
> //(but to the enemy commander?)
>
> end //foreach unit
> end //foreach player
>
> foreach player
> foreach unit
> // finally do the physics and other shit
> foreach slot
> MOVE
> //change angle/speed
> WEAPON
> //spend energy/metal
> //aim
> //spawn shot
>
> if in_communication_with_commander
> send player unit
>
> foreach other_player
> if in visualization_map
> send other_player unit
>
> //FIXME visualization map is like
> //the commander communication check
> //(but to the enemy commander?)
>
> end //foreach unit
> end //foreach player
> }
>
//--------------------------------------------------------------------------
-
>
>
>
> _______________________________________________
> palito-dev mailing list
> address@hidden
> http://mail.nongnu.org/mailman/listinfo/palito-dev
>
>
> Esta mensagem foi verificada pelo E-mail Protegido Terra.
> Scan engine: VirusScan / Atualizado em 15/01/2003 / Versão: 1.3.13
> Proteja o seu e-mail Terra: http://www.emailprotegido.terra.com.br/
>





reply via email to

[Prev in Thread] Current Thread [Next in Thread]