lua-users home
lua-l archive

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


> 
> Also, on a completely different note; whilst I would *never ever* use
> gotos
> in C++ or even C for that matter, there is an argument for having them
in
> a
> *multi-threaded* scripting language. (note the emphasis on
multi-threaded)

Shouldn't the emphasis be on "pre-emptive multi-threaded" scripting
language? Lua is cooperative hence you have to think about control flow
and suspend/yield points. You don't have to think about this in
pre-emptive environments. Gotos are nice where you are constantly
changing state and would otherwise meet a stack overflow by calling
functions - the lazy mans function call ;-)


> With multi-threaded scripting languages, especially those for games,
it is
> necessary to implement state machines, or more simply put, areas of
code
> you
> can *jump* to, to get a character to go into a particular state.
> 
> I understand why lua doesn't have this right now, the "co-routines"
are a
> far call from multi-threading and require the user to write a whole
> multi-threading kernel in order to use them.  However, once this is
> written
> you begin wanting to write code like this:  (believe me, you really
*do*)
> (pseudo code)
> 
> Thread AlienMonster
> init:
>     initialise_state()        // initialise function for this monster
> 
> check:
>     nearest_player = check_for_nearest_player();
>     if ( nearest_player )
>     {
>         jump_to_state( attack );
>     }
> 
> idle:
>     play( "scratch_arse" );        // animation (takes time to
complete)
>     wait( 5 )
>     play( "look_around_aimlessly" );
>     jump_to_state( check );
> 
> attack:
>     play( "monster_roar" );
>     while ( nearest_player == check_for_nearest_player() )
>     {
>         if ( turn_to_player() )        // facing player?
>         {
>             play( "chase_1_step" );        // step towards the player
> (takes
> time for animation to complete)
>         }
>         wait( 1 )     // wait 1 frame (or nth of a second)
>     }
>     jump_to_state( check );
> EndThread


You could possibly do this in Lua with the following completely seat of
the pants untested code:


-- Thread AlienMonster

function init()
    initialise_state()        // initialise function for this monster
    jump_to_state(check)
end

function check()
    nearest_player = check_for_nearest_player()
    if nearest_player then
        jump_to_state( attack )
    else
        jump_to_state(idle)
    end
end
 
function idle()
     play( "scratch_arse" );        // animation (takes time to
complete)
     wait( 5 )
     play( "look_around_aimlessly" );
     jump_to_state( check );
end

function attack()
     play( "monster_roar" );
     while ( nearest_player == check_for_nearest_player() )
     {
         if ( turn_to_player() )        // facing player?
         {
             play( "chase_1_step" );        // step towards the player
 (takes
 time for animation to complete)
         }
         wait( 1 )     // wait 1 frame (or nth of a second)
     }
     jump_to_state( check );
end

-- EndThread

state = init

function wait(t)
    while timer < t do
        coroutine.yield()
    end
end

function jump_to_state(newtstate)
    state = newstate
    coroutine.yield()
end

co = coroutine.create(function() state() end)
while couroutine.resume(co) do
end



> Of course I can make "attack", "idle" and "check" functions and then
have
> some kind of table which is run through in order, but then there are
no
> *conditions*, and quite frankly, setting up the table is just as much
a
> pain
> in the arse as writing the above using while/dos and lots of local
"state"
> variables, which is definitely *not* the way to write that kind of
code.
> Importantly, the above is *simple to understand*.

You can do some nice things with first class objects in Lua.



Nick