Lingara Lingara Mwongozo Miongozo API Maktaba Programu Unda Pachika Programu ya wavuti
Lugha: Kiswahili

Godot

Ukurasa huu umetafsiriwa kutoka Kiingereza. Ikiwa hizi mbili zinatofautiana, ukurasa wa Kiingereza ndio sahihi. Soma ukurasa wa Kiingereza

Godot hutoa lugha mbili, na Lingara ina kifurushi kwa kila moja. Mchezo wa GDScript hutumia addon ya Lingara. Mchezo wa Godot C# hutumia Lingara.Embed, kifurushi kilekile ambacho mchezo wa Unity hutumia. Tumia kimoja au kingine katika mradi, kamwe si vyote viwili. Vichupo vilivyo hapa chini vinaonyesha kila kimoja.

Sakinisha

GDScript. Sakinisha addon ya Lingara kutoka Godot Asset Library, kisha iwezeshe chini ya Project Settings, Plugins. Kuiwezesha huongeza autoload inayoitwa Lingara, ambayo kila scene huifikia kwenye /root/Lingara.

C#. Ongeza Lingara.Embed kwenye mradi wako kama package reference. Node ya mfano iliyo hapa chini, LingaraEmbedNode, si sehemu ya kifurushi: ongeza msimbo wake chanzo kwenye mradi wako na uiweke katika scene.

Pata tokeni kutoka kwa seva yako

Hakuna kifurushi kinachoshikilia siri. Kiini kinapohitaji tokeni, huiomba seva yako mwenyewe, ambayo hutengeneza tokeni kwa kifurushi cha seva na kujibu kwa tokeni na muda wake wa kuisha.

Ukitumia addon, weka njia ya tokeni (token route) ya seva yako chini ya Project Settings na Lingara huiita kwenye thread yake yenyewe. Ikiwa njia hiyo inahitaji kipindi cha mchezaji, iweke wakati wa kuendesha badala yake, kwa sababu mipangilio ya mradi husafirishwa ndani ya export yako. Au unganisha token_needed na ujibu kila ombi mwenyewe. Ukitumia C#, node ya mfano hutuma kwa njia yako ya tokeni kila mteja anapoomba tokeni. Kwa njia yoyote ile, ripoti kushindwa kwa token_unavailable au TokenUnavailable, ili miito inayosubiri ishindwe mara moja.

Shughulikia matukio kila fremu

Kiini huendesha I/O yake ya mtandao kwenye thread yake yenyewe. Autoload ya addon huimaliza mara moja kwa kila fremu na hutoa signal moja kwa kila tukio, kwa hivyo unaunganisha signals ambazo mchezo wako unahitaji na humalizi chochote mwenyewe kamwe. Node ya C# humaliza ndani ya _process, hadi matukio 256 kwa fremu, na hutoa tena kila moja kama signal ya Godot.

Signals hizo hizo hubeba majibu ya NPC yanayotiririshwa (tazama mazungumzo ya NPC) na masasisho ya mazoezi (tazama matokeo ya mazoezi).

<PackageReference Include="Lingara.Embed" Version="0.1.0-alpha.6" />
Lugha ya mfano wa msimbo

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])
Lugha ya mfano wa msimbo

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