Metastar AI NPC SDK
Add a talking AI character to your own Babylon.js or three.js web world with a few lines of script. Visitors can talk to it by voice or text; it answers aloud with lip sync. You don't need your own LLM, speech, or voice API keys — they stay on Metastar's servers.
내 Babylon.js 또는 three.js 웹 월드에 스크립트 몇 줄로 말하는 AI 캐릭터를 넣을 수 있습니다. 방문자가 음성이나 글로 말을 걸면 NPC 가 입 모양에 맞춰 소리로 답합니다. LLM·음성 인식·음성 합성 API 키를 직접 준비할 필요가 없습니다. 키는 모두 메타스타 서버에만 있습니다.
Quick start (about 5 minutes)빠른 시작 (약 5분)
- Open the dashboard, sign in with a Metastar (Google) account and press Register as operator — it is approved instantly. Then register your site: enter the domain(s) your world is served from (for example
https://example.com, orhttp://localhost:8080while developing). You get a public key (pk_live_…). - Create an NPC: name, avatar, voice, a short persona, and one or more greeting lines.
- Copy the embed code from the dashboard and for your engine — Babylon.js or three.js — and paste it into your page after your scene is created.
- 대시보드를 열고 메타스타(구글) 계정으로 로그인한 뒤 운영자 등록을 누릅니다(바로 승인됩니다). 이어서 사이트를 등록합니다. 월드가 열리는 도메인을 입력하면(예:
https://example.com, 개발 중에는http://localhost:8080) 공개 키(pk_live_…)가 나옵니다. - NPC 를 만듭니다: 이름, 아바타, 목소리, 짧은 페르소나, 인사말 한 줄 이상.
- 대시보드의 삽입 코드를 쓰는 엔진(Babylon.js 또는 three.js)에 맞게 복사해, 씬을 만든 다음 위치에 붙여 넣습니다.
Babylon.js
For a Babylon.js world use npc.js. Load Babylon.js and its glTF loader first, then the SDK.
Babylon.js 월드에서는 npc.js 를 씁니다. Babylon.js 와 glTF 로더를 먼저 불러온 다음 SDK 를 불러옵니다.
Embed code (Babylon.js)삽입 코드 (Babylon.js)
<script src="https://metastar.world/static/sdk/v0/npc.js"></script>
<script>
MetastarNPC.init({
publicKey: "pk_live_xxxxxxxx", // from the dashboard
scene: scene, // your BABYLON.Scene
npcId: "npc_xxxxxxxx", // from the dashboard
position: { x: 0, y: 0, z: 3 }, // where the NPC stands (feet)
rotationY: Math.PI, // 0 faces +Z, Math.PI faces -Z
getPlayerPosition: function () { return scene.activeCamera.position; }
});
</script>
Complete minimal page (Babylon.js)전체 최소 예제 (Babylon.js)
Save this as index.html, replace the two IDs, and serve it from a domain you registered (for example python -m http.server 8080 → http://localhost:8080).
아래를 index.html 로 저장하고 두 ID 만 바꾼 뒤, 등록한 도메인에서 여세요(예: python -m http.server 8080 → http://localhost:8080).
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>html, body, canvas { margin: 0; width: 100%; height: 100%; display: block; }</style>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
<script src="https://metastar.world/static/sdk/v0/npc.js"></script>
</head>
<body>
<canvas id="c"></canvas>
<script>
var canvas = document.getElementById("c");
var engine = new BABYLON.Engine(canvas, true);
var scene = new BABYLON.Scene(engine);
var camera = new BABYLON.UniversalCamera("cam", new BABYLON.Vector3(0, 1.6, -2), scene);
camera.setTarget(new BABYLON.Vector3(0, 1.4, 3));
camera.attachControl(canvas, true);
new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
BABYLON.MeshBuilder.CreateGround("ground", { width: 20, height: 20 }, scene);
engine.runRenderLoop(function () { scene.render(); });
window.addEventListener("resize", function () { engine.resize(); });
MetastarNPC.init({
publicKey: "pk_live_xxxxxxxx",
scene: scene,
npcId: "npc_xxxxxxxx",
position: { x: 0, y: 0, z: 3 },
rotationY: Math.PI,
getPlayerPosition: function () { return camera.position; },
onError: function (e) { console.error("NPC failed:", e.code, e.message); }
});
</script>
</body>
</html>
three.js
For a three.js world use npc.three.js. It is an ES module, and you hand it the three you already use, so three is not loaded twice. Everything else — dashboard, API, events, limits, accounts — is the same as the Babylon.js version.
three.js 월드에서는 npc.three.js 를 씁니다. ES 모듈이며, 이미 쓰고 있는 three 를 넘겨받아 쓰므로 three 가 두 번 실리지 않습니다. 그 밖의 것(대시보드, API, 이벤트, 한도, 계정)은 Babylon.js 판과 같습니다.
Embed code (three.js)삽입 코드 (three.js)
<script type="module">
import * as THREE from "three";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
import { MetastarNPC } from "https://metastar.world/static/sdk/v0/npc.three.js";
MetastarNPC.init({
publicKey: "pk_live_xxxxxxxx", // from the dashboard
npcId: "npc_xxxxxxxx", // from the dashboard
THREE, GLTFLoader, // the same three your scene uses
scene, camera, renderer, // your THREE.Scene, camera, WebGLRenderer
position: { x: 0, y: 0, z: 3 }, // where the NPC stands (feet)
rotationY: Math.PI, // 0 faces +Z, Math.PI faces -Z
getPlayerPosition: () => camera.position
});
</script>
| option | Description (three.js only)설명 (three.js 전용) |
|---|---|
THREE * | The three module your scene uses (import * as THREE from "three"). r150 or later.씬에서 쓰는 three 모듈(import * as THREE from "three"). r150 이상. |
GLTFLoader * | The GLTFLoader class from three's addons. You can pass a ready loader instance as gltfLoader instead.three 애드온의 GLTFLoader 클래스. 대신 이미 만든 로더를 gltfLoader 로 넘겨도 됩니다. |
scene * | Your THREE.Scene.사용 중인 THREE.Scene. |
camera | The camera you render with. Needed for opening the chat by tapping the avatar, and used as the visitor position when getPlayerPosition is not given.렌더링에 쓰는 카메라. 아바타를 눌러 대화창을 여는 데 필요하고, getPlayerPosition 이 없으면 방문자 위치로 씁니다. |
renderer | Your WebGLRenderer (or pass its canvas as domElement). The SDK only listens for taps on the canvas; it never renders or resizes. Without it the Talk button still works.사용 중인 WebGLRenderer (또는 캔버스를 domElement 로). SDK 는 캔버스의 누름만 듣고, 렌더링이나 크기 변경은 하지 않습니다. 없어도 대화하기 버튼은 동작합니다. |
- Import map or bundler: in a plain page, map
threeandthree/addons/with an import map as in the example below. With a bundler (Vite, webpack) keep the SDK out of the bundle:const { MetastarNPC } = await import(/* @vite-ignore */ /* webpackIgnore: true */ "https://metastar.world/static/sdk/v0/npc.three.js"). - Nothing to call per frame: the SDK animates the mouth, blinking and turning on its own. Your render loop stays as it is.
- Tapping the avatar is tested against the avatar only, so an NPC behind a wall can still be tapped. Give
getPlayerPositionto hide the Talk button and close the chat when the visitor is far away. - Cleanup:
npc.destroy()removes the avatar from the scene and frees its geometries, materials and textures. - Not checked yet: immersive WebXR sessions and
WebGPURenderer.
- 임포트 맵 또는 번들러: 일반 페이지에서는 아래 예제처럼 임포트 맵으로
three와three/addons/주소를 정합니다. 번들러(Vite, webpack)를 쓴다면 SDK 는 번들에 넣지 말고 이렇게 불러옵니다:const { MetastarNPC } = await import(/* @vite-ignore */ /* webpackIgnore: true */ "https://metastar.world/static/sdk/v0/npc.three.js"). - 매 프레임 부를 것이 없습니다: 입 모양·눈 깜빡임·돌아보기는 SDK 가 알아서 움직입니다. 렌더 루프는 그대로 두세요.
- 아바타 누르기는 아바타에만 판정합니다. 그래서 벽 뒤의 NPC 도 눌릴 수 있습니다.
getPlayerPosition을 주면 방문자가 멀 때 대화하기 버튼을 숨기고 대화창을 닫습니다. - 정리:
npc.destroy()는 아바타를 씬에서 빼고 지오메트리·재질·텍스처를 해제합니다. - 아직 확인하지 않은 것: 몰입형 WebXR 세션,
WebGPURenderer.
Complete minimal page (three.js)전체 최소 예제 (three.js)
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>html, body, canvas { margin: 0; width: 100%; height: 100%; display: block; }</style>
<script type="importmap">
{ "imports": { "three": "https://cdn.jsdelivr.net/npm/three@0.187.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.187.0/examples/jsm/" } }
</script>
</head>
<body>
<canvas id="c"></canvas>
<script type="module">
import * as THREE from "three";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
import { MetastarNPC } from "https://metastar.world/static/sdk/v0/npc.three.js";
const canvas = document.getElementById("c");
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x9ebde0);
const camera = new THREE.PerspectiveCamera(60, 1, 0.05, 200);
camera.position.set(0, 1.6, -2);
camera.lookAt(0, 1.4, 3);
scene.add(new THREE.HemisphereLight(0xffffff, 0x556655, 2.5));
const ground = new THREE.Mesh(new THREE.PlaneGeometry(20, 20), new THREE.MeshStandardMaterial({ color: 0x73806f }));
ground.rotation.x = -Math.PI / 2;
scene.add(ground);
function resize() {
renderer.setSize(innerWidth, innerHeight, false);
camera.aspect = innerWidth / innerHeight; camera.updateProjectionMatrix();
}
addEventListener("resize", resize); resize();
renderer.setAnimationLoop(() => renderer.render(scene, camera));
MetastarNPC.init({
publicKey: "pk_live_xxxxxxxx",
npcId: "npc_xxxxxxxx",
THREE, GLTFLoader, scene, camera, renderer,
position: { x: 0, y: 0, z: 3 },
rotationY: Math.PI,
getPlayerPosition: () => camera.position,
onError: (e) => console.error("NPC failed:", e.code, e.message)
});
</script>
</body>
</html>
What visitors see방문자에게 보이는 것
- The avatar with a name tag and an AI badge.
- When they come within about 3 m, the NPC greets them once (at most every 5 minutes) using a pre-made voice line.
- Within about 4 m a Talk button appears; clicking the avatar also opens the chat panel.
- In the panel they can type, or hold the microphone button to speak. The microphone is requested only when they press that button, after a short notice.
- 이름표와 AI 표시가 달린 아바타.
- 3m 안으로 다가오면 미리 만든 음성으로 한 번 인사합니다(같은 방문자에게 5분에 1번까지).
- 4m 안에서는 대화하기 버튼이 나타나고, 아바타를 눌러도 대화창이 열립니다.
- 대화창에서 글을 입력하거나 마이크 버튼을 누른 채 말할 수 있습니다. 마이크 권한은 그 버튼을 눌렀을 때만, 짧은 안내 뒤에 요청합니다.
Options옵션 — MetastarNPC.init(options)
| option | Description설명 |
|---|---|
publicKey * | Your site's public key. It only works on the domains you registered.사이트의 공개 키. 등록한 도메인에서만 동작합니다. |
scene * | Your BABYLON.Scene (with npc.three.js: your THREE.Scene). The SDK does not bundle the engine and does not touch your camera, lights, render loop or input.사용 중인 BABYLON.Scene (npc.three.js 에서는 THREE.Scene). SDK 는 엔진을 포함하지 않으며 카메라·조명·렌더 루프·입력을 바꾸지 않습니다. |
npcId * | The NPC to place.배치할 NPC. |
position | {x, y, z} of the feet. Default origin.발 위치 {x, y, z}. 기본값 원점. |
rotationY | Facing in radians. 0 faces +Z, Math.PI faces −Z. The NPC turns toward the visitor while talking.바라보는 방향(라디안). 0 은 +Z, Math.PI 는 −Z. 대화 중에는 방문자 쪽으로 돌아봅니다. |
scale | Avatar scale (default 1 = about 1.75 m tall). Use it if your world's unit is not metres; distances scale with it.아바타 크기(기본 1 = 키 약 1.75m). 월드 단위가 미터가 아니면 조정하세요. 감지 거리도 같이 바뀝니다. |
getPlayerPosition | Function returning the visitor's {x, y, z}. Used for the greeting and the Talk button. Without it the active camera (three.js: the camera you passed) is used and the Talk button is always shown.방문자 위치 {x, y, z} 를 돌려주는 함수. 인사와 대화하기 버튼에 씁니다. 없으면 활성 카메라(three.js 는 넘겨준 camera) 위치를 쓰고 대화하기 버튼이 항상 보입니다. |
greet | false turns off the proximity greeting.false 면 먼저 인사하지 않습니다. |
ui | false hides the built-in panel so you can build your own UI with sendText() and events.false 면 기본 대화창을 만들지 않습니다. sendText() 와 이벤트로 직접 UI 를 만들 때 씁니다. |
onError | Called with {code, message} if initialisation fails. init() never throws and never breaks your page.초기화에 실패하면 {code, message} 로 불립니다. init() 은 예외를 던지지 않으며 페이지를 멈추지 않습니다. |
* required. You can call init() several times to place several NPCs; they share one session and only one speaks at a time.
* 필수. init() 을 여러 번 불러 NPC 를 여러 명 둘 수 있습니다. 세션은 하나를 같이 쓰고, 한 번에 한 명만 말합니다.
API
const npc = await MetastarNPC.init({ ... });
if (!npc.ready) return; // see onError
npc.on("reply", function (e) { console.log(e.text); });
npc.sendText("What are your opening hours?"); // ask as the visitor (LLM)
npc.say("We close at six today."); // fixed line, no LLM
npc.openChat(); npc.closeChat();
npc.setPosition({ x: 2, y: 0, z: 5 });
npc.login(); npc.logout(); npc.user; // Metastar account: { nickname, paid } or null
npc.destroy(); // removes everything the SDK added
| Method메서드 | |
|---|---|
sendText(text) | Sends a visitor message (up to 300 characters). Resolves with {text} once the reply arrives; the voice then plays.방문자 메시지를 보냅니다(300자 이하). 답이 오면 {text} 로 완료되고 음성이 재생됩니다. |
say(text) | Speaks a fixed line (up to 120 characters) without the LLM. The voice is generated once and then cached; each NPC can hold up to 40 cached lines.정해 둔 대사(120자 이하)를 LLM 없이 말합니다. 음성은 한 번만 만들어 저장하며, NPC 한 명당 40개까지 저장됩니다. |
openChat() / closeChat() | Opens or closes the built-in panel.기본 대화창을 열거나 닫습니다. |
setPosition({x,y,z}) | Moves the NPC.NPC 를 옮깁니다. |
destroy() | Removes the avatar, panel, observers and audio use. Everything the SDK adds to your scene is named metastar_….아바타·대화창·옵저버·오디오 사용을 모두 정리합니다. SDK 가 씬에 만드는 것은 전부 이름이 metastar_… 로 시작합니다. |
login() / logout() / user | Opens the Metastar sign-in window (call it from a click), signs out, or reads the signed-in visitor {nickname, paid}. The built-in panel already shows a sign-in button when it is needed, so you only need these with ui: false.메타스타 로그인 창을 열거나(클릭 안에서 호출), 로그아웃하거나, 로그인한 방문자 {nickname, paid} 를 읽습니다. 기본 대화창은 필요할 때 로그인 버튼을 스스로 보여 주므로 ui: false 일 때만 직접 쓰면 됩니다. |
on(event, fn) / off | Subscribe to events below.아래 이벤트를 받습니다. |
| Event이벤트 | |
|---|---|
ready | Avatar loaded.아바타 로딩 완료. |
greeting | The NPC greeted a nearby visitor. {text}다가온 방문자에게 인사함. {text} |
listening | Microphone recording started.마이크 녹음 시작. |
thinking | A message was sent; waiting for the reply.메시지를 보냈고 답을 기다리는 중. |
reply | {text, userText} — userText is what was heard, for voice input.{text, userText} — 음성 입력이면 userText 가 알아들은 문장. |
speaking / speakend | Voice playback started / ended.음성 재생 시작 / 끝. |
quota_exceeded | Your usage limit is reached. The NPC says a "taking a break" line instead of answering; your page keeps working.사용 한도에 도달함. NPC 가 답 대신 "쉬는 중" 대사를 말하며, 페이지는 그대로 동작합니다. |
login_required | The visitor has used the free turns, or tried voice chat without signing in. {reason: "text" | "voice"}방문자가 무료 턴을 다 썼거나, 로그인 없이 음성 대화를 시도함. {reason: "text" | "voice"} |
login / logout | The visitor signed in with a Metastar account {nickname, paid} / signed out.방문자가 메타스타 계정으로 로그인함 {nickname, paid} / 로그아웃함. |
limit | A signed-in visitor reached today's turns. {code: "text_limit" | "voice_limit", paid, upgradeUrl}로그인한 방문자가 오늘의 턴을 다 씀. {code: "text_limit" | "voice_limit", paid, upgradeUrl} |
error | {code, message} — see troubleshooting.{code, message} — 문제 해결 참고. |
Requirements, limits and privacy요구 사항 · 한도 · 개인정보
- Engine: Babylon.js 6 or later (tested on 9.x) with the glTF loader (
babylonjs.loaders) loaded before the SDK; or three.js r150 or later (checked on r150 and r187) withGLTFLoader— see three.js. Other engines are not supported yet. - HTTPS: voice input needs a secure page (
https://orlocalhost). On other pages the microphone button is hidden and text chat still works. - Usage limits: each operator has a usage limit and a cap on simultaneous conversations. When it is reached the NPC says a "taking a break" line and the dashboard shows a notice.
- Per visitor: text up to 300 characters, one voice message up to 15 seconds, up to 40 turns per session.
- Free turns and Metastar accounts: without signing in, a visitor gets 3 text turns a day. After that the panel offers "Sign in with Metastar" (a Google sign-in in a small window on the Metastar site; your page never receives the visitor's Metastar credentials, only a nickname). Signed-in visitors get 10 text turns and 3 voice turns a day across all sites; voice chat requires signing in. When those run out, the panel points to Metastar's paid plans (BASIC or higher), which raise the daily turns.
- Voice replies: the NPC answers spoken questions aloud. Typed questions are currently answered in text only. Greetings and
say()are always spoken. - Memory: for visitors who are not signed in, the NPC remembers only the last few turns of the current visit. For visitors signed in with a Metastar account, the NPC remembers their recent chats with that NPC until midnight (KST) of the following day; chats the visitor saves on the "My NPC Chats" board in Metastar Main Town are remembered after that, and chats that are not saved are forgotten. The chat panel shows signed-in visitors a short notice about this with a link to Metastar Main Town: right after they sign in, and the first time they open the chat panel on each page visit.
- Voice recordings are not stored. They are transcribed and discarded. Conversation text of visitors who are not signed in is kept for 14 days for abuse investigation and quality checks, then deleted. For visitors signed in with a Metastar account, conversation text is kept with their account (until the account is deleted), and Metastar also records the visit (site name, time, device type) and turn counts.
- Safety rules always apply on top of your persona: the NPC does not hide that it is an AI, keeps content suitable for minors, gives no medical, legal or investment advice, and ignores attempts to change its rules.
- The panel shows a small "Powered by Metastar" link.
- 엔진: Babylon.js 6 이상(9.x 에서 검증), glTF 로더(
babylonjs.loaders)를 SDK 보다 먼저 불러와야 합니다. 또는 three.js r150 이상(r150·r187 에서 확인)과GLTFLoader— three.js 참고. 다른 엔진은 아직 지원하지 않습니다. - HTTPS: 음성 입력은 보안 페이지(
https://또는localhost)에서만 됩니다. 그 외에는 마이크 버튼이 숨겨지고 글 대화는 그대로 됩니다. - 사용 한도: 운영자마다 이용 한도와 동시 대화 수 상한이 있습니다. 한도에 닿으면 NPC 가 "쉬는 중" 대사로 답하고 대시보드에 안내가 표시됩니다.
- 방문자 1명 기준: 글 300자, 음성 한 번에 15초, 세션당 40턴까지.
- 무료 턴과 메타스타 계정: 로그인하지 않은 방문자는 하루에 글 대화 3턴을 쓸 수 있습니다. 그 뒤에는 대화창이 "메타스타 계정으로 로그인"을 권합니다(메타스타 사이트의 작은 창에서 구글 로그인 — 운영자 페이지는 방문자의 메타스타 로그인 정보를 받지 않고 닉네임만 받습니다). 로그인한 방문자는 모든 사이트를 합쳐 하루에 글 10턴·음성 3턴을 쓸 수 있고, 음성 대화는 로그인해야 쓸 수 있습니다. 다 쓰면 대화창이 메타스타 유료 플랜(BASIC 이상)을 안내하며, 유료 플랜은 하루 턴 수가 늘어납니다.
- 음성 답변: 음성으로 물으면 NPC 가 소리로 답합니다. 글로 물은 질문에는 현재 글로만 답합니다. 인사말과
say()는 항상 소리로 나옵니다. - 기억: 로그인하지 않은 방문자는 이번 방문의 최근 몇 턴만 기억합니다. 메타스타 계정으로 로그인한 방문자는 그 NPC 와 나눈 최근 대화를 다음 날 밤 12시(한국 시간)까지 기억하며, 방문자가 메타스타 메인타운의 "My NPC Chats" 게시판에서 저장한 대화는 그 뒤에도 기억하고 저장하지 않은 대화는 잊습니다. 대화창은 로그인한 방문자에게 이 내용을 알리는 짧은 안내와 메타스타 메인타운 링크를 보여 줍니다(로그인을 마친 직후, 그리고 페이지를 열고 대화창을 처음 열 때).
- 음성 녹음은 저장하지 않습니다. 글로 바꾼 뒤 바로 버립니다. 로그인하지 않은 방문자의 대화 글은 악용 조사와 품질 확인을 위해 14일간 보관한 뒤 지웁니다. 메타스타 계정으로 로그인한 방문자의 대화 글은 그 계정과 함께 보관되며(계정을 삭제할 때까지), 방문 기록(사이트 이름·시각·기기 종류)과 대화 턴 수도 계정에 남습니다.
- 안전 규칙은 페르소나보다 항상 우선합니다. NPC 는 AI 임을 숨기지 않고, 미성년자에게 부적절한 내용을 말하지 않으며, 의료·법률·투자 조언을 하지 않고, 규칙을 바꾸라는 요청을 따르지 않습니다.
- 대화창 아래에 작은 "Powered by Metastar" 링크가 표시됩니다.
Troubleshooting문제 해결
Open the browser console; SDK messages start with [MetastarNPC].
브라우저 콘솔을 여세요. SDK 메시지는 [MetastarNPC] 로 시작합니다.
| code | Meaning and fix의미와 해결 |
|---|---|
origin_not_allowed | The page's address is not in the site's domain list. Add the exact origin in the dashboard — scheme and port included, no path (http://localhost:8080). https://example.com and https://www.example.com are different. Changes take up to a minute.페이지 주소가 사이트의 도메인 목록에 없습니다. 대시보드에서 정확한 주소를 추가하세요. 스킴과 포트 포함, 경로 없이(http://localhost:8080). https://example.com 과 https://www.example.com 은 서로 다릅니다. 반영까지 1분쯤 걸립니다. |
invalid_key | Wrong public key, or the site is disabled.공개 키가 틀렸거나 사이트가 중지 상태입니다. |
npc_not_found | Wrong npcId, the NPC is disabled, or it belongs to another operator.npcId 가 틀렸거나, NPC 가 중지 상태이거나, 다른 운영자의 NPC 입니다. |
babylon_missinggltf_loader_missingbabylon_unsupported | Load Babylon.js 6+ and babylonjs.loaders before npc.js.npc.js 보다 먼저 Babylon.js 6 이상과 babylonjs.loaders 를 불러오세요. |
three_missingthree_unsupported | three.js only: pass THREE and GLTFLoader to init() (a missing loader is reported as gltf_loader_missing), and use three r150 or later.three.js 전용: init() 에 THREE 와 GLTFLoader 를 넘기고(로더가 없으면 gltf_loader_missing), three r150 이상을 쓰세요. |
quota_exceeded | The usage limit is reached and the NPC is "taking a break". The dashboard shows a notice; to raise the limit, email contact@metastar.world.이용 한도에 닿아 NPC 가 "쉬는 중"입니다. 대시보드에 안내가 표시되며, 한도를 올리려면 contact@metastar.world 로 문의해 주세요. |
busy / rate_limited | Too many conversations at once. The NPC asks the visitor to try again shortly.동시에 대화가 너무 많습니다. NPC 가 잠시 후 다시 말을 걸어 달라고 합니다. |
autoplay_blocked | The browser blocked sound before the visitor's first tap or click. The text is still shown; sound works after any interaction.방문자가 화면을 한 번 누르기 전이라 브라우저가 소리를 막았습니다. 글은 표시되며, 화면을 한 번 누른 뒤에는 소리가 납니다. |
mic_denied / no_speech | Microphone permission was refused, or nothing was heard. Text input keeps working.마이크 권한이 거절됐거나 알아들은 말이 없습니다. 글 입력은 계속 됩니다. |
The avatar is too big, too small, or underground: set scale and position.y. It faces the wrong way: set rotationY.
아바타가 너무 크거나 작거나 땅에 묻힘: scale 과 position.y 를 조정하세요. 방향이 반대: rotationY 를 바꾸세요.