Lingara Lingara Dokumentasyon Mga gabay API Mga library Mga app Gumawa Embed Web app
Wika: Filipino

Godot

Isinalin mula sa Ingles ang pahinang ito. Kung magkaiba ang dalawa, ang pahinang Ingles ang tama. Basahin ang pahinang Ingles

Dalawang wika ang iniaalok ng Godot, at may kit ang Lingara para sa bawat isa. Ginagamit ng isang GDScript na laro ang Lingara addon. Ginagamit ng isang Godot C# na laro ang Lingara.Embed, ang parehong package na ginagamit ng isang Unity na laro. Gamitin ang isa o ang isa pa sa isang project, hindi kailanman ang dalawa. Ipinapakita ng mga tab sa ibaba ang bawat isa.

I-install

GDScript. I-install ang Lingara addon mula sa Godot Asset Library, saka i-enable ito sa ilalim ng Project Settings, Plugins. Kapag na-enable ito, nagdadagdag ito ng autoload na pinangalanang Lingara, na naaabot ng bawat scene sa /root/Lingara.

C#. Idagdag ang Lingara.Embed sa iyong project bilang package reference. Ang sample node sa ibaba, ang LingaraEmbedNode, ay hindi bahagi ng package: idagdag ang source nito sa iyong project at ilagay ito sa isang scene.

Kumuha ng mga token mula sa iyong server

Walang kit na humahawak ng secret. Kapag kailangan ng core ng token, humihingi ito sa sarili mong server, na nagmi-mint ng isa gamit ang isang server kit at sumasagot gamit ang token at ang expiry nito.

Gamit ang addon, itakda ang token route ng iyong server sa ilalim ng Project Settings at tatawagin ito ng Lingara sa sarili nitong thread. Kung kailangan ng route ang session ng player, itakda ito sa run time sa halip, dahil kasama ang mga project setting sa loob ng iyong export. O ikonekta ang token_needed at sagutin mo mismo ang bawat request. Gamit ang C#, nagpo-post ang sample node sa iyong token route tuwing humihingi ng token ang client. Alinman ang paraan, iulat ang pagkabigo gamit ang token_unavailable o TokenUnavailable, para agad na mabigo ang mga naghihintay na tawag.

Iproseso ang mga event bawat frame

Pinapatakbo ng core ang network I/O nito sa sarili nitong thread. Inuubos ito ng autoload ng addon nang isang beses bawat frame at naglalabas ng isang signal bawat event, kaya ikinokonekta mo ang mga signal na kailangan ng iyong laro at hindi ka kailanman mismong umuubos ng anuman. Umuubos ang C# node sa _process, hanggang 256 na event bawat frame, at muling inilalabas ang bawat isa bilang isang Godot signal.

Ang parehong mga signal ang nagdadala ng mga naka-stream na sagot ng NPC (tingnan ang usapan ng NPC) at mga update ng pagsasanay (tingnan ang mga resulta ng pagsasanay).

<PackageReference Include="Lingara.Embed" Version="0.1.0-alpha.6" />
Wika ng halimbawang code

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])
Wika ng halimbawang code

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"))