Lingara Lingara Docs Guides API Libraries Apps Build Embed Web app
Language: English

JVM and Android

The Kotlin player kit runs on the JVM, on the desktop and on Android. Java games use the same kit through its Java facade. The samples follow a libGDX game, whose render loop is a natural place to drain events, and the same calls fit any game loop.

Add the kit and its natives

The kit and its native libraries are separate artifacts on Maven Central, so add both. A desktop game adds lingara-embed-natives-desktop, which carries the libraries for Windows, macOS and Linux. An Android module adds lingara-embed-natives-android, an AAR, instead. In a libGDX project, the desktop natives go in the desktop module and the Android natives in the Android module.

A Kotlin game depends on lingara-embed-kotlin; a Java game on lingara-embed-java, the facade.

Get tokens from your server

The kit never holds a secret. Give it your own server’s token route and the header that carries the player’s session, and the kit posts to it whenever it needs a token. Your server mints with a server kit and answers with the token and its expiry.

Drain events in your render loop

The core runs its network I/O on its own thread and never calls into your code. In your render loop, on the game thread, drain what has arrived, at most 256 events at a time, and handle each one: a practice update, a streamed NPC reply, an error. In Java, each event goes to the matching method of your visitor. Close the kit in your game’s dispose step, which stops the core and frees it.

See NPC dialogue and practice results for what those events carry.

Code sample language

Kotlin

// The kit, and the natives for the platform: natives-desktop in a libGDX lwjgl3 module, natives-android in its android module.
implementation("com.getlingara:lingara-embed-kotlin:0.1.0-alpha.6")
implementation("com.getlingara:lingara-embed-natives-desktop:0.1.0-alpha.6")

Java

<!-- The kit, and the natives for the platform (lingara-embed-natives-android in an Android module). -->
<dependency>
  <groupId>com.getlingara</groupId>
  <artifactId>lingara-embed-java</artifactId>
  <version>0.1.0-alpha.6</version>
</dependency>
<dependency>
  <groupId>com.getlingara</groupId>
  <artifactId>lingara-embed-natives-desktop</artifactId>
  <version>0.1.0-alpha.6</version>
</dependency>
Code sample language

Kotlin

// Your server mints the embed token; the kit POSTs {} here whenever it needs one.
private val lingara =
    LingaraEmbed.start(
        EmbedConfig(
            tokenSource =
                TokenSourceConfig.Http(
                    url = "https://my-game.example/lingara/token",
                    headers = listOf(Header("Authorization", Secret("Bearer $session"))),
                ),
            userAgentSuffix = "my-game/1.4",
        ),
    )

Java

// Your server mints the embed token; the kit POSTs {} here whenever it needs one.
lingara =
    LingaraEmbedJava.builder()
        .httpTokenSource(
            "https://my-game.example/lingara/token",
            Map.of("Authorization", "Bearer " + session))
        .userAgentSuffix("my-game/1.4")
        .build();
Code sample language

Kotlin

// In render(), on the game thread: one crossing, at most 256 events.
fun render() {
    lingara.drain(256) { event ->
        when (event) {
            is EmbedEvent.Practice -> showPractice(event.snapshot.question?.prompt)
            is EmbedEvent.NpcTurn -> onNpcTurn(event.update)
            is EmbedEvent.Error -> println("Lingara error: ${event.error.message}")
            else -> Unit
        }
    }
}

// In dispose(): stops the core and frees it.
fun dispose() {
    lingara.close()
}

Java

// In render(), on the game thread: one crossing, at most 256 events, each to its visitor method.
void render() {
  lingara.drain(256, event -> LingaraEmbedJava.visit(event, visitor));
}

// In dispose(), or let try-with-resources do it.
@Override
public void close() {
  lingara.close();
}