Utiliser Loreline avec Java
Loreline fournit une bibliothèque Java sous forme d'un seul JAR, compatible avec Java 8+ et tout langage JVM. Ce guide utilise Java pour ses exemples, mais la bibliothèque fonctionne tout aussi bien avec Kotlin ou tout autre langage tournant sur la JVM. Il montre comment configurer un projet, charger un script .lor, et gérer les dialogues, les choix et la fin du script.
Configurer votre projet
Téléchargez loreline-jvm.zip depuis la page des releases GitHub. L'archive contient :
loreline.jar: la bibliothèque Loreline (aucune dépendance externe)- Un projet d'exemple complet avec Swing, utilisable comme point de départ
Ajoutez loreline.jar à votre classpath. Pour compiler et exécuter un programme simple :
javac -cp loreline.jar MyStory.java
java -cp loreline.jar:. MyStory
Sous Windows, utilisez ; au lieu de : comme séparateur de classpath :
java -cp loreline.jar;. MyStory
Charger un script
Utilisez Loreline.parse() pour analyser une chaîne .lor. Les deuxième et troisième arguments gèrent les instructions import dans votre script :
import loreline.*;
import java.nio.file.*;
String content = Files.readString(Path.of("story/CoffeeShop.lor"));
Script script = Loreline.parse(content, "CoffeeShop.lor",
path -> Files.readString(Path.of("story/" + path)));
Loreline.play(script, this::onDialogue, this::onChoice, this::onFinish);
Si votre script n'a pas d'instructions import, vous pouvez omettre le callback de fichier :
Script script = Loreline.parse(content);
Gérer les dialogues
Le callback de dialogue reçoit l'interpréteur, un identifiant de personnage (ou null pour le texte narratif), le texte du dialogue, les tags éventuels et un Runnable pour faire avancer le script :
void onDialogue(Interpreter interpreter, String character, String text,
List<TextTag> tags, Runnable advance) {
if (character != null) {
// Résoudre le nom d'affichage depuis la définition du personnage
Object nameObj = interpreter.getCharacterField(character, "name");
String name = nameObj != null ? nameObj.toString() : character;
System.out.println(name + ": " + text);
} else {
// Texte narratif (pas de personnage)
System.out.println(text);
}
advance.run();
}
Gérer les choix
Le callback de choix reçoit une liste de ChoiceOption. Chaque option possède un champ text et un champ enabled. Appelez l'IntConsumer avec l'index du choix sélectionné :
void onChoice(Interpreter interpreter, List<ChoiceOption> options,
IntConsumer select) {
List<Integer> enabled = new ArrayList<>();
for (int i = 0; i < options.size(); i++) {
if (options.get(i).enabled) {
enabled.add(i);
System.out.println(" [" + enabled.size() + "] " + options.get(i).text);
}
}
// Lire la saisie du joueur
Scanner scanner = new Scanner(System.in);
System.out.print("> ");
int choice = scanner.nextInt();
select.accept(enabled.get(choice - 1));
}
Gérer la fin du script
Le callback de fin est appelé lorsque le script atteint sa conclusion :
void onFinish(Interpreter interpreter) {
System.out.println("--- Fin ---");
}
Démarrer depuis un beat spécifique
Par défaut, play() démarre depuis le début du script. Pour démarrer depuis un beat spécifique, passez son nom :
Engine.play(script, onDialogue, onChoice, onFinish, "MorningScene", null);
Options de l'interpréteur
Vous pouvez passer des options supplémentaires à play() pour enregistrer des fonctions personnalisées, appliquer des traductions ou activer l'accès strict aux variables :
InterpreterOptions options = new InterpreterOptions();
options.functions = new HashMap<>();
options.functions.put("roll", (interp, args) ->
(int)(Math.random() * ((Number)args[0]).intValue()) + 1);
options.translations = Engine.extractTranslations(script);
options.strictAccess = true;
Engine.play(script, onDialogue, onChoice, onFinish, null, options);
Exemple complet
Voici une application console complète qui charge et joue un script Loreline :
import loreline.*;
import java.io.IOException;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.function.IntConsumer;
public class MyStory {
static String storyDir = "story/";
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) throws IOException {
String content = Files.readString(Path.of(storyDir + "CoffeeShop.lor"));
Script script = Loreline.parse(content, "CoffeeShop.lor",
path -> readFile(storyDir + path));
if (script != null) {
Loreline.play(script, MyStory::onDialogue, MyStory::onChoice, MyStory::onFinish);
}
}
static String readFile(String path) {
try {
return Files.readString(Path.of(path));
} catch (IOException e) {
return null;
}
}
static void onDialogue(Interpreter interpreter, String character, String text,
List<TextTag> tags, Runnable advance) {
if (character != null) {
Object nameObj = interpreter.getCharacterField(character, "name");
String name = nameObj != null ? nameObj.toString() : character;
System.out.println(name + ": " + text);
} else {
System.out.println(text);
}
System.out.println();
advance.run();
}
static void onChoice(Interpreter interpreter, List<ChoiceOption> options,
IntConsumer select) {
List<Integer> enabled = new ArrayList<>();
for (int i = 0; i < options.size(); i++) {
if (options.get(i).enabled) {
enabled.add(i);
System.out.println(" [" + enabled.size() + "] " + options.get(i).text);
}
}
System.out.print("> ");
int choice = scanner.nextInt();
select.accept(enabled.get(choice - 1));
}
static void onFinish(Interpreter interpreter) {
System.out.println("--- Fin ---");
}
}
Aller plus loin
Pour un exemple de bureau soigné avec un rendu Swing, des animations et une sortie stylisée, consultez le projet d'exemple inclus dans loreline-jvm.zip depuis la page des releases GitHub.