Lingara Lingara Dokumentasi Panduan API Pustaka Aplikasi Buat Sematkan Aplikasi web
Bahasa: Bahasa Indonesia

Dialog NPC

Halaman ini diterjemahkan dari bahasa Inggris. Jika keduanya berbeda, halaman bahasa Inggris yang benar. Baca halaman bahasa Inggris

Karakter di game Anda dapat bercakap dengan pemain dalam bahasa yang sedang mereka pelajari, disesuaikan dengan tingkat mereka. Setiap kalimat yang diucapkan pemain adalah satu giliran: kit pemain mengirimkannya, dan balasan karakter mengalir kembali sepotong demi sepotong.

Isi sebuah giliran

Setiap giliran mengirim semua yang dibutuhkan karakter, karena Lingara tidak menyimpan percakapan di antara giliran:

  • npc: siapa yang berbicara. Nilai name miliknya 1 sampai 32 karakter, dan persona opsionalnya adalah satu baris deskripsi, 1 sampai 120 karakter, seperti “penjual pangsit”.
  • scene: opsional, tempat percakapan berlangsung, 1 sampai 160 karakter.
  • source_lang dan target_lang: bahasa pemain sendiri dan bahasa yang sedang mereka pelajari. Keduanya harus berbeda, dan karakter hanya berbicara dalam target_lang.
  • level: tingkat pemain, dari 1 sampai 9. Panduan Lingara “Arti sebuah tingkat” menjelaskan skalanya.
  • line: apa yang baru saja diucapkan pemain, 1 sampai 500 karakter.
  • history: percakapan sejauh ini, yang terlama lebih dulu, paling banyak 12 baris. Setiap baris memiliki speaker, yaitu player atau npc, dan text baris itu, 1 sampai 500 karakter.

Setiap teks adalah satu baris. Game Anda yang menyimpan percakapan: kit pemain memegang jendela untuk setiap dialog yang Anda buka, menambahkan setiap giliran yang selesai ke dalamnya, memotong setiap balasan menjadi 500 karakter pertamanya, dan membuang baris terlama setelah 12.

Lingara memperlakukan persona dan scene sebagai teks tidak tepercaya dari game Anda. Keduanya membentuk cara karakter berbicara, tidak pernah apa yang boleh dilakukannya.

Cara balasan tiba

Balasan mengalir sebagai potongan teks, yang ditambahkan game Anda begitu tiba. Sebuah pemberitahuan dapat muncul di antaranya, misalnya yang menyatakan bahwa balasan terpotong. Giliran berakhir dengan done saat balasan lengkap, atau dengan error saat gagal. Giliran tidak dapat dilanjutkan: jika koneksi terputus, pemain mengucapkan kalimatnya lagi.

Ucapkan satu kalimat setiap kali kepada setiap karakter. Kalimat yang diucapkan saat karakter masih membalas akan ditolak alih-alih dimasukkan ke antrean, karena setiap giliran ditagih.

Siapa yang membayar

Hanya pemain dari klien berbasis meter yang dapat bercakap dengan karakter, dan setiap giliran ditagihkan ke klien itu. Token pemain membutuhkan embed:play.

Bahasa contoh kode

Bevy

fn spawn_seller(mut commands: Commands) {
    let mei = NpcDialogue::new("Mei", "zh", 2)
        .and_then(|npc| npc.with_persona("a dumpling seller"))
        .and_then(|npc| npc.with_scene("the night market"))
        .expect("within Lingara's bounds");
    commands.spawn(mei);
    commands.spawn(Player);
}

/// One turn at a time: a line said while the NPC is replying is a `Busy` error.
fn talk(keys: Res<ButtonInput<KeyCode>>, npcs: Query<Entity, With<NpcDialogue>>, mut say: MessageWriter<NpcSay>) {
    if keys.just_pressed(KeyCode::Digit1) {
        for entity in &npcs {
            say.write(NpcSay { entity, line: "饺子多少钱?".into() });
        }
    }
}

/// `streaming` grows as the reply arrives; `turns` holds the finished ones.
fn show_reply(transcripts: Query<&NpcTranscript, Changed<NpcTranscript>>) {
    for transcript in &transcripts {
        if let Some(partial) = &transcript.streaming {
            info!("…{partial}");
        }
    }
}

Unity

public DialogueId OpenDialogue(string npc, string sourceLang, string targetLang, byte level) =>
    Client.DialogueOpen(new DialogueConfig { Npc = new Npc { Name = npc }, SourceLang = sourceLang, TargetLang = targetLang, Level = level });

// The reply streams back as NpcTurn events: append each Fragment's text to your label.
public RequestId Say(DialogueId dialogue, string line) => Client.DialogueSay(dialogue, line);

Godot C#

public long OpenDialogue(string npc, string sourceLang, string targetLang, byte level) =>
    Client.DialogueOpen(new DialogueConfig { Npc = new Npc { Name = npc }, SourceLang = sourceLang, TargetLang = targetLang, Level = level }).Value;

// The reply streams back as NpcTurnFragment signals, then one NpcTurnFinished.
public long Say(long dialogue, string line) => Client.DialogueSay(new DialogueId(dialogue), line).Value;

GDScript

# A LingaraNpc child per character: npc_name, target_lang and level in the
# inspector. say() returns false while a turn is in flight (turns are never
# queued, because each one is billed).
func talk_to_mei(line: String) -> void:
	if mei.say(line):
		bubble.text = "…"


func _on_mei_replied(text: String) -> void:
	bubble.text = text

Unreal C++

void ALingaraEmbedSnippetActor::Say(const FString& Line)
{
	ELingaraCallResult Result;
	FLingaraEmbedError Error;
	if (Dialogue == 0)
	{
		FLingaraDialogueConfig Config;
		Config.Npc.Name = TEXT("Mei");
		Config.Npc.Persona = TEXT("a tea seller at the night market");
		Config.SourceLang = TEXT("en");
		Config.TargetLang = TEXT("zh");
		Config.Level = 2;
		Dialogue = Lingara()->DialogueOpen(Config, Result, Error);
	}
	Reply.Reset();
	Lingara()->DialogueSay(Dialogue, Line, Result, Error);
}

// The reply streams back as npc_turn events: append each fragment.
void ALingaraEmbedSnippetActor::HandleNpcTurn(const FLingaraNpcTurn& Turn)
{
	if (Turn.Dialogue == Dialogue && Turn.Update.Type == ELingaraNpcTurnUpdateType::Fragment)
	{
		Reply += Turn.Update.Text;
	}
}

Kotlin

fun talkToMei(line: String) {
    val dialogue = npc ?: lingara.dialogueOpen(DialogueConfig(Npc("Mei", "a tea seller"), "the tea house", "en", "zh", 2, emptyList()))
    npc = dialogue
    lingara.dialogueSay(dialogue, line)
}

private fun onNpcTurn(update: NpcTurnUpdate) {
    when (update) {
        is NpcTurnUpdate.Opened -> bubble = ""
        is NpcTurnUpdate.Fragment -> bubble += update.text
        is NpcTurnUpdate.Finished -> bubble = update.text
        else -> Unit
    }
}

Java

void talkToMei(String line) {
  if (npc < 0) {
    Npc mei = new Npc("Mei", "a tea seller");
    npc =
        lingara.dialogueOpen(new DialogueConfig(mei, "the tea house", "en", "zh", 2, List.of()));
  }
  lingara.dialogueSay(npc, line);
}

void onNpcTurn(EmbedEvent.NpcTurn turn) {
  if (turn.getUpdate() instanceof NpcTurnUpdate.Fragment fragment) {
    bubble.append(fragment.getText());
  } else if (turn.getUpdate() instanceof NpcTurnUpdate.Finished finished) {
    bubble.setLength(0);
    bubble.append(finished.getText());
  }
}

Lihat juga