Jean-Pierre Deschamps Who am I ?

Personal Project – NPCScript

head

Comme dans la plupart des jeux de rôle en ligne, Caldeira contient des personnages non joueurs communément appelés PNJ ou NPC en anglais. Afin de déterminer leurs paroles, actions et comportements. Deux possibilités sont envisageables pour notre cas de figure :

  1. compilé à même le code source
  2. dans des fichiers de scripts non compilés

La première idée n'étant pas possible à maintenir correctement, la seconde solution s'impose d'elle-même. C'est ainsi que le langage NPCScript est né. En voici un court exemple :

{*} Default Text
    IF (target.flag(ADDON_READY) = 1)
        SayText(Je le savais, vous êtes un barbare !)
        SetPlayerFlag(EXPECTED_SENTENCE, 1)
        BreakConversation
    ELSE
        SayText(...)
    END
    
{*} Initial Text
    IF (target.flag(FLOOR4_ACCESS) = 1)
        SayText(Bonjour, souhaitez vous aller au dernier étage maintenant ?)
    ELSE IF (target.flag(ADDON_READY) = 1)
        SayText(Alors avez-vous trouvé la signification de la première phrase ?)
    ELSE
        SayText(Ne comptez pas aller plus loin vous êtes un barbare ! Si vous voulez ne serait-ce penser à accéder à l'étage supérieur, vous devez compléter le "rite de passage".)
    END

{*} Rite de passage
    IF (target.flag(ADDON_READY) = 0)
        SayText("Dos vaneslae navidal", "Kadrim lok ungrim dok", "Somalina oundi inesora", "Tharrgra nethdrovar". Si vous pouvez me dire ce que cela signifie, non seulement je vous concéderai l’accès au dernier étage, mais je serai en plus gentil avec vous. Voici un indice: vous serez incapable de résoudre cette énigme si vous n’allez pas visiter le sous-sol de la Librairie.)
        SetPlayerFlag(ADDON_READY, 1)
        BreakConversation
    ELSE IF (target.flag(EXPECTED_SENTENCE) != 0)
        SayText(Je le savais, vous êtes un barbare !)
        SetPlayerFlag(EXPECTED_SENTENCE, 1)
        BreakConversation
    ELSE
        SayText(...)
    END

Les scripts sont rédigés dans un simple éditeur de texte. Ils sont divisés en noeuds. Chaque noeud contient deux éléments principaux soit les mots-clefs et les instructions. Le PNJ exécutera donc les instructions une à une lorsqu'un des mots-clefs est reçu de la part d'un joueur. Les instructions sont soient des fonctions (par exemple SayText), soit des structures plus complexes (par exemple IF (1 < 2))

Afin de pouvoir aisément exécuter tous les scripts, il fallait pouvoir les transformer aisément en objet du code source de l'émulateur. C'est de là que la création d'un petit compilateur à passe unique a commencé. Le principe est bien simple. On fait une lecture de chaque ligne, on la traduit en objet, et on ajoute cet objet au code source... Cependant, c'est un poil plus complexe. Il faut prévoir beaucoup de cas de figure, d'élément syntaxique invalide, d'erreur d'écriture qui rendrait l'exécution d'un noeud impossible, la duplication de mots-clefs dans plusieurs noeuds.

Poussons encore plus loin les besoins. Ajoutons la possibilité au script de s'interrompre et reprendre plus tard, gérer plusieurs ensembles de fonctions (QuestScript, NPCScript, TeleportScript...), fusionner des scripts sans conflits, informer avec des messages d'erreurs verbeux les différentes erreurs rencontrées... C'est là tout mon travail des premiers mois sur l'équipe Caldeira.