Interprêter son propre code

La création de jeux indépendants/amateurs (tuto, entraide, questions...) sous les moteurs de la série RPG Maker.
nuki
Koruldia Warrior
Messages : 238
Localisation : Bruxelles
Contact :

Interprêter son propre code

Message non lu par nuki » dim. mai 01, 2011 11:15 pm

Ce tutoriel sera principalement théorique et portera sur interprétation de son propre langage.
Vous vous demanderez peut être quel est le but? Et bien il permet, par exemple d'offrir une manière plus abordable (pour les event makers par exemple) d'utiliser des composantes scriptées. Un des exemple le plus connu dans la communauté francophone est par exemple, l'Event Language développé par Avygeil et Roys qui admet sa propre syntaxe.
Pour mon module de QuickSave, il existe une syntaxe alternative. Par exemple, au lieu de faire Appeler Script> Quicksave::save(1) qui sauvegardera la partie sur le slot 1, il est possibel de faire Appeler Script> Save in 1, bien que la différence est minime, elle permet de faire une petite abstraction de la couche script au profit d'une syntaxe plus verbeuse.
Mais comment mettre ce genre de petit raccourci en oeuvre? Nous allons nous intéresser a la première méthode.

De la méta-programmation
Concrètement la méta programmation nous permet de décrire un comportement ou un autre langage durant cet explication, nous ne ferons que de la méta programmation. Une des fonction qui devrait venir aux scripteurs en premier lieu, lorsqu'ils pensent à méta programmation est la fonction Eval qui permet d'interpréter une chaine de texte comme du code ruby. Par exemple, cette commande:

Code : Tout sélectionner

eval("print LOL")
affichera une alerte avec le contenu de la constante LOL. Les plus perspicaces auront compris que c'est cette commande qui sera appelé lorsqu'on fait appel à une commande "Appeler Script" ou par exemple a une condition Si_Script.

Modifier notre commande événement
Une des solutions les plus primaire vise à parler de commandes et non de langage défini par une syntaxe précise. Pour effectuer des "customs commande", il va falloir modifier notre commande "Appeler script".
Pour ce faire, nous allons analyser son comportement:
def command_355
script = @list[@index].parameters[0] + "\n"
loop do
if @list[@index+1].code == 655 # Second line of script and after
script += @list[@index+1].parameters[0] + "\n"
else
break
end
@index += 1
end
eval(script)
return true
end
La commande Appeler script correspond à la commande_355, elle se trouve dans game Interpreter. Nous voyosn que, a la fin de la méthode, on évalue une variable script qui correspond donc à une chaine de texte. A ce stade, il suffirait donc de remplacer le eval(script) par un custom_eval(script).
C'est donc ce que nous allons faire.
Nous allons créer une méthode:

Code : Tout sélectionner

def custom_eval(script)
	if(commande_1)
		#Executer la commande 1
	else
		eval(script)
	end
end
Dans notre if, nous allons donc mettre une commande. Je me permet de rebondir sur mon script de Quicksave (ou Quicksave::save(x)) sera l'exemple.
Nous allons établir une syntaxe pour que Save in X sauve dans le slot X.
Pour cela, nous allons utiliser un regex. rappellons que l'opérateur de test d'un regex sera =~.
(le cours ne portant pas sur les regex's, je ne m'attarderai pas sur sa construction)

Code : Tout sélectionner

def custom_eval(script)
	if(script =~ /^Save in [0-9]$/ )
		evaluation = script.split(" in ")
		Quicksave::save(evaluation[1].to_i)
	else
		eval(script)
	end
end
Et voila, notre méthode peut interpréter le cas ou on lui demande une sauvegarde. Le role du split est de faire une découpe de la chaine. Complétons cette méthode en modifiant les autres méthodes du module Quicksave:

Code : Tout sélectionner

def custom_eval(script)
	if(script =~ /^Save in [0-9]$/ )
		evaluation = script.split(" in ")
		Quicksave::save(evaluation[1].to_i)
        elsif(script =~ /^Load from [0-9]$/ )
		evaluation = script.split(" from ")
		Quicksave::load(evaluation[1].to_i)
	else
		eval(script)
	end
end
etc.
Comme vous pouvez le voir, cet interpréteur rapide est facile a mettre en place et il suffit de remplacer, dans la commande_355 le eval(script) par custom_eval(script).
Pour pousser le vice plus loin, il est aussi possible de modifier les conditions pour qu'elles fassent référence a notre interpréteur en modifiant la ligne 638 de note Game_Interpreter.

Pistes de recherches pour la suite
Cette publication était relativement courte et facile a mettre en place, cependant, il serait intéressant de réfléchir a un vrai langage au sein de Rm respectant sa propre syntaxe.
Pour aller plus loin, il serait amusant de s'intéresser aux automates non déterministes nous permettant, pourquoi pas, d'interpréter, au sein de notre commande Appeller un script, un langage respectant la logique Ruby mais à la syntaxte abordable à n'importe quel Event Maker, ayant de l'urticaire à la prononciation du mot RGSS.

Merci de m'avoir lu. Bien à vous, NUKI.

Raytwo-x
Koruldia Master
Messages : 2041

Message non lu par Raytwo-x » lun. mai 02, 2011 12:51 am

Grand merci à toi, exactement ce qu'il me fallait ! Ça va simplifier un peu les choses ! :p

Giro Noden
Koruldia Divinity
Messages : 4619
Localisation : Lyon
Contact :

Message non lu par Giro Noden » lun. mai 02, 2011 1:13 am

Merci d'avoir fait ce commentaire, je me voyais pas commencer alors que je n'y comprend rien...
Bref, je trouve que c'est super que tu fasses des tutos, je vais voir pour épingler tous les tutoriels, ça serra peut-être plus lisible :) !
Giro

nuki
Koruldia Warrior
Messages : 238
Localisation : Bruxelles
Contact :

Message non lu par nuki » lun. mai 02, 2011 9:34 am

Merci pour vos commentaires.
Ce tutoriel est, pour qui comprend les chaines de textes et la logique de l'interpreter de RM assez facile à aborder et il s'agit surtout d'une astuce pour produire des systèmes complexes accessible à n'importe quel event maker allergique au mot script.
Car produire au cas par cas pour chacun des scripts est un peu dommage car il faudrait demander au maker au mise a jours constante du produit.

Avatar de l’utilisateur
Lufia Lula
Koruldia Hunter
Messages : 86

Message non lu par Lufia Lula » sam. mai 07, 2011 8:30 am

Pareil pour moi, et ça risque d’être utile à pas mal ici, déjà mon frère qui vient sans s’inscrire qui m’a filé le lien. Bon boulot bien propre. J’aime cette façon de faire aussi.
:bravo:
~o~ Lufia Lula ~o~

nuki
Koruldia Warrior
Messages : 238
Localisation : Bruxelles
Contact :

Message non lu par nuki » lun. mai 09, 2011 5:54 am

Merci. Si vous avez des questions précises n'hésitez pas.
Image

Giro Noden
Koruldia Divinity
Messages : 4619
Localisation : Lyon
Contact :

Message non lu par Giro Noden » lun. mai 09, 2011 5:20 pm

Aucune question pour ma part, mais sérieux, elle a vraiment la classe ta signature !
Ça ne vaut peut-être pas la peine de faire un message complet pour ça, mais je suis fan !
Giro

nuki
Koruldia Warrior
Messages : 238
Localisation : Bruxelles
Contact :

Message non lu par nuki » mer. mai 11, 2011 12:34 pm

Merci je l'ai faite pour un concours duel (ou j'ai perdu :(). Je trouvais ça assez rigolo de masquer un sexe dedans :)
Image