M2-GamaGora
int´egration d’un langage de script: Lua
J.C. Iehl
December 11, 2009
J.C. Iehl M2-GamaGora
r´ esum´ e des ´ episodes pr´ ec´ edents
boucle principale :
I
d´ eplacements,
I
collisions,
I
r´ eaction aux collisions,
I
comportements,
I
interactions : r´ eaction ` a des ev` enements.
r´ esum´ e des ´ episodes pr´ ec´ edents
pour chaque ´ etat :
en fonction de l’ev` enement re¸ cu : r´ eagir,
I
envoyer de nouveaux ev` enements,
I
attendre un ev` enement particulier, etc.
I
(gestion des transitions vers les autres ´ etats) comportement, ev` enements :
I
assez p´ enible ` a ´ ecrire,
I
encore plus p´ enible ` a modifier.
programmeur n´ ecessaire pour construire l’interaction du ”monde”
et du joueur.
J.C. Iehl M2-GamaGora
scripter le comportement du ”monde”
pourquoi ?
I
simplifier l’´ ecriture du comportement de chaque classe d’entit´ e,
I
aide pour le programmeur,
I
mais surtout :
exposer simplement la ”logique” du comportement,
I
et cacher la programmation ”bas niveau” associ´ ee,
permettre aux LD de d´ ecrire les interactions / comportements.
int´ egrer un langage de script
pourquoi ?
I
s´ eparer le ”code” et les ”donn´ ees”,
I
le comportement d’une entit´ e est une donn´ ee pour le jeu,
I
ne pas recompiler l’application ` a chaque test,
I
change le cycle de mise au point du jeu.
classique :
coder, compiler, ex´ ecuter, reproduire les conditions permettant de tester la modification, tester ...
data driven (comportement == donn´ ee) :
ex´ ecuter, charger le script, tester, modifier le script, continuer ` a tester ...
J.C. Iehl M2-GamaGora
int´ egrer un langage de script ”visuel”
autre solution pour les LD :
utiliser une repr´ esentation visuelle plutot que du script.
exemple : kismet du udk3.
quel langage ?
I
python,
I
lua,
I
angelscript,
I
javascript,
I
...
J.C. Iehl M2-GamaGora
pr´ esentation Lua
pourquoi Lua ?
I
l’interpr´ eteur est une librairie C,
I
facile ` a inclure dans une application,
I
rapide, + machine virtuelle JIT (x86),
I
gestion m´ emoire automatique (garbage collector),
I
multi-thread´ e (coop´ eratif) + co-routines,
I
interactions entre code C/C++ et code lua interpr´ et´ e :
I
variables globales,
I
appel de fonctions C/C++ depuis lua,
I
appel de fonctions lua depuis C/C++.
pr´ esentation de Lua
- d e f i n e a f u n c t i o n f u n c t i o n E r u p t ()
C a m e r a . S e t M o d e ( O R B I T ) ;
C a m e r a . S e t O r b i t R a t e ( P I O V E R 2 ) ; e n t i t y = E n t i t y . f i n d ( " V o l c a n o " ) ; C a m e r a . S e t T a r g e t E n t i t y ( e n t i t y ) ; end
- d e f i n e a m a i n w h i l e (1)
S c r i p t . W a i t S e c o n d s ( 1 0 ) ; E r u p t ()
end
J.C. Iehl M2-GamaGora
int´ egration Lua
I
Lua et son ”hote” communiquent ` a travers une pile.
I
lua State repr´ esente le contexte d’ex´ ecution de la fonction (pile, etc.).
les param` etres sont empil´ es dans l’ordre, 1, 2, 3, etc.
I
lua est typ´ e dynamiquement, une variable peut changer de type !
I
donc, il faut v´ erifier le type des param` etres empil´ es.
int´ egration Lua
s c r i p t lua :
C a m e r a . S e t T a r g e t P o s (100.0 , 40.0 , 2 3 0 . 0 ) ; c o d e C :
int L u a S e t T a r g e t P o s ( l u a _ S t a t e * s t a t e ) {
f l o a t x , y , z ;
x = ( f l o a t ) l u a _ t o n u m b e r ( state , 1) ; y = ( f l o a t ) l u a _ t o n u m b e r ( state , 2) ; z = ( f l o a t ) l u a _ t o n u m b e r ( state , 3) ; C a m e r a S e t T a r g e t P o s ( x , y , z ) ;
r e t u r n 0;
}
J.C. Iehl M2-GamaGora
int´ egration Lua
int L u a S e t T a r g e t P o s ( l u a _ S t a t e * s t a t e ) {
f l o a t x , y , z ;
if ( l u a _ i s n u m b e r ( state , 1)
&& l u a _ i s n u m b e r ( state , 2)
&& l u a _ i s n u m b e r ( state , 3) ) {
x = ( f l o a t ) l u a _ t o n u m b e r ( state , 1) ; y = ( f l o a t ) l u a _ t o n u m b e r ( state , 2) ; z = ( f l o a t ) l u a _ t o n u m b e r ( state , 3) ; C a m e r a S e t T a r g e t P o s ( x , y , z ) ;
}
r e t u r n 0;
int´ egration Lua
une fonction C peut aussi renvoyer une valeur ` a Lua :
s c r i p t lua :if G a m e . G e t P l a y e r S c o r e () > 9 t h e n T r i g g e r E n d O f L E v e l () ;
end c o d e C :
int L u a G e t P l a y e r S c o r e ( l u a _ S t a t e * s t a t e ) {
l u a _ p u s h n u m b e r ( state , game - > p l a y e r S c o r e ) ; r e t u r n 1;
}
J.C. Iehl M2-GamaGora
int´ egration Lua
d´ eclarer des fonctions C/C++ ` a l’interpr´ eteur Lua :
c o n s t l u a L _ r e g C a m e r a L i b []={
{ " S e t M o d e " , L u a S e t M o d e } , { " G e t M o d e " , L u a G e t M o d e } ,
{ " S e t T a r g e t P o s " , L u a S e t T a r g e t P o s } ,
{ " S e t T a r g e t E n t i t y " , L u a S e t T a r g e t E n t i t y } , ...
{ NULL , N U L L } };
l u a L _ o p e n l i b ( state , " C a m e r a " , C a m e r a L i b , 0) ;
int´ egration Lua
ex´ ecuter du code Lua depuis du C/C++ : cr´ eer un contexte d’ex´ ecution, lua State.
lua_State *state= lua_open();
lua_dofile(state, "script.lua");
lua_dostring(state, "a= 1; b= 4;");
lua_close(state);
J.C. Iehl M2-GamaGora
int´ egration Lua
charger un script, ex´ ecuter une fonction :
charger le script, empiler les param` etres, appeler la fonction.
lua_State *state= lua_open();
lua_loadfile(state, "script.lua");
lua_getglobal(state, "function")
;
lua_pushnumber(state, 1.0)lua_call(state, 1, 0);
lua_close(state);