Lingara Lingara Dokumentasie Gidse API Biblioteke Apps Bou Inbed Webtoepassing
Taal: Afrikaans

Godot

Hierdie bladsy is uit Engels vertaal. As die twee verskil, is die Engelse bladsy korrek. Lees die Engelse bladsy

Godot bied twee tale, en Lingara het ‘n kit vir elkeen. ‘n GDScript-speletjie gebruik die Lingara-byvoeging. ‘n Godot C#-speletjie gebruik Lingara.Embed, dieselfde pakket wat ‘n Unity-speletjie gebruik. Gebruik die een of die ander in ‘n projek, nooit albei nie. Die oortjies hieronder wys elkeen.

Installeer

GDScript. Installeer die Lingara-byvoeging uit die Godot Asset Library, en aktiveer dit dan onder Project Settings, Plugins. Om dit te aktiveer voeg ‘n autoload genaamd Lingara by, wat elke toneel by /root/Lingara bereik.

C#. Voeg Lingara.Embed as ‘n pakketverwysing by jou projek. Die voorbeeldnodus hieronder, LingaraEmbedNode, is nie deel van die pakket nie: voeg sy bronkode by jou projek en sit dit in ‘n toneel.

Kry tokens van jou bediener

Nie een van die twee kits hou ‘n geheim nie. Wanneer die kern ‘n token nodig het, vra dit jou eie bediener, wat een met ‘n bedienerkit uitreik en met die token en sy vervaltyd antwoord.

Met die byvoeging stel jy jou bediener se tokenroete onder Project Settings, en Lingara roep dit op sy eie draad aan. As die roete die speler se sessie nodig het, stel dit eerder tydens looptyd, want projekinstellings word binne jou uitvoer saamgestuur. Of koppel token_needed en beantwoord elke versoek self. Met C# stuur die voorbeeldnodus ‘n POST na jou tokenroete wanneer die kliënt ‘n token vra. Rapporteer in albei gevalle ‘n mislukking met token_unavailable of TokenUnavailable, sodat die wagtende oproepe dadelik misluk.

Verwerk gebeurtenisse elke raam

Die kern voer sy netwerk-I/O op sy eie draad uit. Die byvoeging se autoload maak dit een keer per raam leeg en stuur een sein per gebeurtenis uit, so jy koppel die seine wat jou speletjie nodig het en maak self nooit iets leeg nie. Die C#-nodus maak leeg in _process, hoogstens 256 gebeurtenisse per raam, en stuur elkeen weer as ‘n Godot-sein uit.

Dieselfde seine dra gestroomde NPC-antwoorde (sien NPC-dialoog) en oefenopdaterings (sien oefenresultate).

<PackageReference Include="Lingara.Embed" Version="0.1.0-alpha.6" />
Taal van die kodevoorbeeld

Godot C#

// Your own server mints the token: never put a client secret in a game. The
// continuation may run off the main thread, which the client allows.
private async Task FetchToken()
{
    try
    {
        using var response = await Http.PostAsync(TokenUrl, new StringContent("{}"));
        response.EnsureSuccessStatusCode();
        using var body = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
        Client?.ProvideToken(body.RootElement.GetProperty("token").GetString(), body.RootElement.GetProperty("expires_at").GetString());
    }
    catch (Exception e) when (e is HttpRequestException || e is JsonException || e is KeyNotFoundException)
    {
        Client?.TokenUnavailable(e.Message); // fail the waiting calls now
    }
}

GDScript

# The common case: set Project Settings > lingara/token_url to your server's
# token route, which answers exactly {"token", "expires_at"}. Lingara POSTs to
# it on its own thread whenever it needs a token. If the route needs the
# player's session, set it at run time instead (never in ProjectSettings,
# which ships inside the export):
func use_my_session(session_cookie: String) -> void:
	lingara.set_token_endpoint("https://game.example.com/lingara-token", {"cookie": session_cookie})


# Or answer each token_needed yourself, with whatever login your game has.
func _on_token_needed(_request: int, _reason: String) -> void:
	var http := HTTPRequest.new()
	add_child(http)
	http.request("https://game.example.com/lingara-token", [], HTTPClient.METHOD_POST, "{}")
	var reply: Array = await http.request_completed
	http.queue_free()
	var body: Variant = JSON.parse_string((reply[3] as PackedByteArray).get_string_from_utf8())
	if reply[1] == 200 and body is Dictionary:
		lingara.provide_token(body["token"], body["expires_at"])
	else:
		lingara.token_unavailable("the token route answered %d" % reply[1])
Taal van die kodevoorbeeld

Godot C#

public override void _Process(double delta)
{
    if (Client == null) return;
    events.Clear();
    Client.Drain(events); // at most 256 a frame; the rest wait for the next
    foreach (var e in events)
    {
        switch (e)
        {
            case EmbedEvent.TokenNeeded _: _ = FetchToken(); break;
            case EmbedEvent.NpcTurn { Update: NpcTurnUpdate.Fragment f } t:
                EmitSignal(SignalName.NpcTurnFragment, t.Dialogue.Value, t.Request.Value, f.Text); break;
            case EmbedEvent.NpcTurn { Update: NpcTurnUpdate.Finished f } t:
                EmitSignal(SignalName.NpcTurnFinished, t.Dialogue.Value, t.Request.Value, f.Text); break;
            case EmbedEvent.Practice p: EmitSignal(SignalName.PracticeChanged, p.Session.Value, p.Snapshot.Phase.ToString()); break;
            case EmbedEvent.Failed f: EmitSignal(SignalName.Failed, f.Error.KindName, f.Error.Message, f.Error.Request?.Value ?? 0); break;
            case EmbedEvent.Log log: GD.Print($"[lingara] {log.Level} {log.Target}: {log.Message}"); break;
        }
    }
}

GDScript

# The Lingara autoload the plugin adds, reached by path and typed, so every
# call and signal below is checked against LingaraEmbed.
@onready var lingara: LingaraEmbed = get_node("/root/Lingara")

# Enable the plugin (Project > Project Settings > Plugins): it adds the
# Lingara autoload, which drains the core once per frame and emits one signal
# per event. Connect the signals your game needs; you never call drain.
func _ready() -> void:
	lingara.token_needed.connect(_on_token_needed)
	lingara.event_received.connect(_on_event)
	lingara.error_raised.connect(func(error: Dictionary) -> void: push_warning(error.message))
	lingara.practice_changed.connect(_on_practice_changed)
	lingara.practice_finished.connect(_on_practice_finished)
	mei.replied.connect(_on_mei_replied)


func _on_event(_id: String, event_type: String, _created_at: String, data: Dictionary) -> void:
	if event_type == "lesson_plan.ready":
		print("a plan is ready: ", data.get("plan_id"))