00:00 / 00:00

Persona

外掛 API

Persona 會執行一個本機 WebSocket 伺服器,供其他應用程式驅動:切換場景、新增並擺放圖層、開關表情、播放動作、播放帶口型的語音、讀取追蹤狀態,以及直接寫入模型參數

它預設關閉。在 設定 → 外掛 API 中開啟,建立一把金鑰,再把權杖貼進你的外掛

開啟

控制項作用
啟用 API啟動伺服器。沒有金鑰就連不上
連接埠預設 25034
允許區域網路存取綁定到本機回送位址之外,讓手機或另一台電腦也能連上

開啟區域網路存取後,Persona 會顯示本機對外回應的位址,讓你知道該把瀏覽器指向哪裡

如果連接埠已被佔用,這一節會直接顯示錯誤,而不是默默失敗

API 金鑰

金鑰是必要的——未經認證的連線會被拒絕。建立金鑰 會讓你為金鑰命名,並把它的權杖完整顯示一次;該列上的複製按鈕隨時可以再次取出完整權杖

動作作用
複製權杖把完整權杖複製到剪貼簿
重新命名金鑰原地改名
撤銷金鑰刪除它。正在使用它的工作階段會被關閉,並被告知不要重連

每個金鑰列還會顯示已連線從未使用,或者以相對時間顯示最近使用於…。用戶端表明身分後,該列會記住最近一次的名稱與版本,因此沒有用戶端連線時也認得出這把金鑰

權杖保存在作業系統的安全儲存區裡。在沒有安全儲存區的電腦上,建立金鑰會失敗並給出說明,而不是把權杖寫進明文檔案

外掛資料夾

外掛可以請求 Persona 註冊一個模型或素材檔案,之後再載入它。這只對位於你在 外掛資料夾 中新增過的資料夾內的檔案有效——其他任何路徑都會以 forbidden-path 拒絕

已連線的用戶端

伺服器執行期間,每個開啟中的工作階段都會列出來,顯示它宣告的名稱、版本、開發者、用的是哪把金鑰,以及從哪裡連入。瀏覽器用戶端會顯示自己的頁面來源

從不表明身分的用戶端會列為 未識別的用戶端,功能完全一樣。該列上的中斷按鈕會關閉那個工作階段,並告訴它不要重連

每接受一次連線,還會跳一則靜音的系統通知,寫明是哪個用戶端、用的哪把金鑰、從哪裡連入——金鑰落到別人手裡,一被使用就會露出來。系統拒發通知時——沒簽章的開發版、權限被關掉——同一則訊息會在控制面板開啟期間以提示訊息的形式出現。它從不落到舞台上,那裡的東西會被擷取畫面帶走

Web 控制台

persona-console.laplace.live 是基於這套 API 實作的瀏覽器控制台。作為第一方的「外掛」,你可以用它檢查連線,也可以在直播時透過手機或平板控制 Persona

填入主機、連接埠與金鑰後,就能控制場景、圖層、表情、動作、特效、相機、燈光、自動化、追蹤與設定。版面與桌面端的 控制面板 一致:左側是圖層清單,下方固定顯示舞台追蹤自動化設定;寬度足夠時,選取項目的詳細內容會顯示在右側。每個部分都有獨立網址,可以加入書籤。選取模型後可調整它的表情、動作與參數綁定,選取場景效果下的特效後可調整其參數;選取的模型或 3D 物件還帶有自己的圖層效果。目前實例不支援的控制項會停用

圖層清單底部的新增到場景按鈕會開啟 素材庫,內容透過 API 從 Persona 的登錄表讀取。在控制台註冊檔案時,需要輸入檔案在桌面端電腦上的路徑,且檔案必須位於已設定的 外掛資料夾

場景素材 中,環境貼圖LUT 各有獨立的分頁。點選素材即可套用到目前場景,隨後會顯示確認提示。動畫沒有獨立分頁,因為 API 不支援直接播放動畫片段。請在全部分頁的類型選擇器中註冊動畫,再透過選擇…按鈕將其設為某個圖層的待機動畫

選取場景後,燈光分區會列出 3D 物件與環境自帶的 烘焙燈光,和桌面端一樣可以開關、調整強度。已載入素材的尺寸與 glTF 擴充資訊也在這裡顯示

金鑰可以未加密的形式儲存在瀏覽器中,也可以僅在本次工作階段中保留。控制請求直接傳送到本機或區域網路中的 Persona

沒有 API 介面的功能都留在桌面應用程式裡:更新程式、API 金鑰、系統匣圖示、視窗邊界、原生檔案選擇器、舞台控制點與快速鍵錄製。自動化 也只能在桌面端編輯:控制台的自動化頁會列出並執行它們,主模型的快速鍵則放在下方可摺疊的虛擬形象快速鍵區塊裡。在桌面端暫停的自動化會標為已暫停,無法執行

Stream Deck

Stream Deck 外掛 是同一套 API 的另一個第一方用戶端,把切換模型與場景、觸發快速鍵、表情與動作,以及移動、縮放形象放到實體按鍵上

MCP 伺服器

@laplace.live/persona-mcp 是第三個:一個 Model Context Protocol 伺服器,把這套 API 交給 AI 助理——Claude、Cursor、Codex——封成二十來個按任務劃分的工具,其餘的走 call_api,還有 stage.capture 讓助理看得見自己改出來的結果

SDK

@laplace.live/persona-sdk 是配套的具型別用戶端——在 Node、Bun、瀏覽器與 OBS 瀏覽器來源之間同構

import { PersonaClient } from "@laplace.live/persona-sdk";

const persona = new PersonaClient({ token: "sk-lp-v1-…" });
await persona.connect();

await persona.call("expression.toggle", { name: "Smile" });
persona.on("motion.started", (m) => console.log("playing", m.group));

每個方法都由同一份共享的型別表描述,因此一次呼叫的請求與回應形狀由方法名稱決定。SDK 參考 涵蓋安裝、用戶端選項、認證、參數租約與每一個匯出的型別

事件

工作階段只會收到已訂閱的事件。SDK 會在重新連線後自動恢復訂閱

事件觸發時機
scene.changed任何場景變更:建立、刪除、重新命名、啟用或編輯
scene.loading場景套用或渲染管線預熱的開始與結束
settings.changed應用程式設定變更
instance.loaded一個模型實例在舞台上載入完成
selection.changed編輯選取項變動,來源不限
expression.changed目前生效的表情組合變更
expression.persistence某個模型的「記住表情」開關被切換
motion.started一段動作開始播放;帶 motion-stop 的主機還會附上 oneShot
motion.ended一段動作播放結束
speech.started一段 speech.play 的語音開始播放
speech.ended該段語音結束——播完、被停止或被頂替都算
hotkey.state快速鍵設定變更
automation.state自動化的清單、名稱、觸發條件種類、啟用狀態或系統註冊狀態發生變化
tracking.status臉部或姿勢追蹤狀態變更,或任一來源自身的狀態變更——包括攝影機的臉部、手部與身體追蹤
registry.changed有模型或素材被註冊——需要重新讀取對應的清單

方法一覽

以模型為作用域的方法接受可選的 instanceId,預設作用於場景的 主模型

分組方法
scene.*list get activate create duplicate rename delete patch inspect setLightFollowCamera
instance.*list get add setModel remove setVisible setEffects setTrackingSources reorder setPrimary setPlacement attach setMToon setIdle setControllerMovement setLipSync info
binding.*get preview set release inputs override
controller.*state rename setDeadZone remove assign
selection.*get set
object.*add addMany rename setContent setSpace setPlacement attach setLightOverrides anchors
expression.*list active toggle getPersistence setPersistence
motion.*list play playing stop
speech.*play stop
hotkey.*list set trigger
automation.*list run
model.* / asset.*各自的 listregister,外加 registry.thumbnail
settings.*get patch
tracking.* / pose.*tracking.addSource tracking.updateSource tracking.removeSourcesetEnabledsetSource,外加 pose.setPorttracking.status
lipSync.*state configure restart calibrate
stage.*resetTransform resetCamera spawn clearSpawned capture
app.* / session.*app.info app.localAddresses app.stats,以及 session.identify
storage.*get set delete list
param.*inject release

scene.create 追加一個空場景並啟用它,和在應用程式裡新建一個場景一樣,所以回傳裡的 activeSceneId 就是新場景——新場景的 id 從這裡讀,而不是去比對前後兩份場景清單,因為中間可能夾進別的工作階段建立的場景

scene.patch 編輯目前場景的背景、相機、燈光、環境與 轉場;場景項目則透過 instance.*object.* 修改。enabledfalse 的燈光會連同陰影一起熄滅,其餘設定都會保留。該欄位預設為 true,不支援關閉燈光的建置不會帶這個欄位

vrmCamera 整體取代:orbitfov(1 – 179°)、roll(繞視線軸旋轉的弧度)、projectionperspectiveorthographic)與 clipAssetId。舊版建置不帶 rollprojection——視為 0 與 perspective——所以提供這兩項控制項之前,先看回傳的相機裡有沒有。環繞的角度可以取任意弧度,distance 也可以是負數,滑鼠導覽則保留自己較窄的範圍。正交視圖的寬度是 abs(distance)fov 保留但不起作用,distance 為負時兩個軸都會翻轉。stage.resetCamera 也會重設滾轉與投影

object.add 可以帶 place2dplace3d,物件在同一次編輯裡就落在該位置,不會先在預設位置畫出一個影格;取值依 object.setPlacement 的規則修正。object.addMany { objects } 把最多 100 筆同樣的項目作為一次場景編輯加入——只儲存一次,復原也只算一步——並依請求順序回傳 instanceIds。只要有一個素材無法解析,就一個也不加入

instance.attach { instanceId, attach } 把一個 Live2D 實例作為 物品 釘選到另一個 Live2D 模型上,attachobject.attach 的相同;傳 null 則原地解除。attach.depth{ kind: 'front' }{ kind: 'behind' }{ kind: 'artMesh', id },最後一種把物品插在父模型那個 ArtMesh 的正上方——父模型沒有的 ID 視為前方。attach.split{ itemArtMesh, depth },在物品自己的某個 ArtMesh 處切開,把它下面的部分送到第二個深度。object.anchors 的每一列帶有 order,即取得清單時該 ArtMesh 的繪製順序,深度控制項就是依它排列各格的。會形成循環的釘選回傳 invalid-params,對 VRM 實例呼叫則回傳 unsupported-for-format。對物件而言,目前只有 front 生效

stage.capture 需要 stage-capture 能力,回傳 { dataUrl, width, height }:舞台視窗此刻顯示的樣子,一張帶透明通道的 PNG,最長邊縮到不超過 maxEdge(64 – 2048,預設 1024),且從不放大。看不見螢幕的用戶端——比如經由 MCP 伺服器 的 AI 助理——就是靠它確認自己的改動。每擷取一張,算繪都要停下一幀,所以按需取用,不要輪詢。renderer-unavailable 表示當時沒有舞台視窗,或者沒有可複製的影格;舞台當掉後直到重新載入畫出第一幀為止都會回傳它,所以該重試而不是放棄

能力

應用程式層級與實例層級的能力清單說明目前版本支援哪些功能。請以能力清單為準,不要透過比較版本號碼來判斷

應用程式層級的那份由 helloapp.info 回報——目前是 storagespeechautomationslayer-effectsscene-transitionsarea-lightsspot-lightscamera-follow-lightsshadow-filtersenvironment-map-modelspawntracking-lostmotion-stopstage-capturecontrollersmodel-editingasset-inspection。每個實例自己的那份在 instance.listcapabilities 裡,能力表涵蓋不到的方法會以 unsupported-for-format 拒絕

後三項各自開啟一批共享編輯器的方法:controllerscontroller.*(讀取已連接的裝置與已儲存的設定檔,改名、設死區、移除、發起指派),以及用 settings.patchcontroller.enabled 這個總開關——裝置指的是接在桌面端上的,不是瀏覽器所在那台電腦上的;model-editingbinding.*(讀取、預覽、寫回與釋放某個模型的參數綁定,並做短時的輸入覆寫)連同 instance.setBreath,其中 binding.inputs 回傳 { inputs, outputs }inputs 是即時的追蹤輸入,outputs 依輸出 id 給出每個被綁定的參數此刻在模型上的讀數——已經算完動作、表情與物理演算之後的值,讀不回來的輸出不列出;asset-inspectionscene.inspectregistry.thumbnail

instance.setControllerMovement 合併某個實例的 控制器移動 設定:enabledslot(已儲存的設定檔編號)、moveSpeedturnSpeedsmoothing,VRM 上還有 walkEnabledwalkClipwalkSpeedfaceMovement。越界的值會被修正到預設值或邊界上;對物件呼叫會傳回 unsupported-for-formatwalkClip 接受和 instance.setIdle 一樣的引用

動作與待機

motion.list 列出模型的動作群組。Live2D 模型還會把模型資料夾裡每一個 .model3.json 沒有宣告的 .motion3.json 一併列出,各自成為一個以檔案名稱命名的群組——在桌面端動作分區裡 錄下來的動作 因此無需重新載入就會出現

motion.stop(應用程式能力 motion-stop)把正在播放的動作淡出,讓待機接回去。只有待機在播時它什麼都不做,回傳 { stopped: false }motion.playingoneShotmotion.started 上也有)說明回報的這段動作是不是蓋在待機之上的那一種,也就是 stop 會結束的那一種;舊版建置不帶這個欄位

instance.setIdle 合併某個實例的待機設定:

欄位說明
idleAnimation待機總開關。false 會停下 VRM 的片段,Live2D 上則停下每一段待機動作,包括模型自己的 Idle 群組
idleClip僅 VRM。待機片段的參照
idleMotion僅 Live2D,需實例能力 idle-motionsmotion.list 裡的一個動作檔案,在其他所有動作之下循環;null 表示隨機播放模型的 Idle 群組。模型不再列出的檔案按 null 處理
trackingLostBehaviortracking-losthold 保持最後追蹤到的姿態,idle 用約 0.3 秒回到待機、臉回來時再回去
trackingLostMotiontracking-lost,僅 Live2D。臉消失夠久之後頂替待機的那個動作,null 表示不換
trackingLostDelaytracking-lost。「夠久」是多少秒,0 – 60

instance.get 會把這幾項一併回報

燈光

area-lights 能力的建置接受類型為 areaSceneLight:一塊位於 x/y/z 的矩形,以 azimuth/elevation(度)指向,以 roll(−180 – 180°,預設 0)在自身平面內旋轉,尺寸由 widthheight 決定(各 0.01 – 20 場景單位,預設 1)。它照亮 PBR 材質與 MToon 虛擬形象——MToon 在自己的卡通著色裡用四個光照取樣來近似這塊矩形——但不影響 Live2D,也不投射陰影。它的 range 與陰影設定會保留,以便之後切換類型

spot-lights 能力的建置接受類型 spot,它使用 x/y/zazimuth/elevationrange(0.1 – 20 場景單位)。方位角與仰角都為 0 時光束指向 −Z,仰角為正時朝下。angle 是光錐的半角(1 – 89°,預設 30),penumbra 柔化光錐邊緣(0 – 1,預設 0.3)。強度範圍 0 – 20,與點光源相同。聚光燈照亮 PBR 與 MToon 材質,支援一般的陰影等級與半徑,也能點亮體積光照的霧氣。面光源與聚光燈——無論是新增還是切換類型——只在帶對應能力的建置上提供

shadowFilter 為每盞平行光、點光源或聚光燈單獨選擇 pcf(預設)或 pcss,兩者可以在同一個場景裡並存。shadowQuality 仍然決定貼圖解析度,off 仍然關閉投射。PCF 依 shadowRadius(陰影貼圖紋素)柔化。PCSS 會搜尋遮擋物,陰影離投射物越遠,半影越寬,寬度取決於 shadowSourceSize:光源直徑,平行光以度計,點光源與聚光燈以公尺計(0 – 10,預設 0.1),為 0 時是硬光源。PCSS 不會改動已儲存的 shadowRadius,舊場景載入後是 PCF。過濾方式的選擇要依 shadow-filters 能力判斷——本機新增的燈即使在不支援的建置上也可能帶著 shadowFilter

camera-follow-lights 能力的建置接受燈光上的 followCamera,環境光會忽略它。它預設是 false;為 true 時,x/y/z 與各個角度都相對相機計算,於是燈光會隨手動編輯相機、也隨相機運動播放一起移動。followCameraOptions 選擇跟隨哪些部分,各項預設 trueposition 跟隨相機的注視目標與平移,rotation 跟隨它在世界空間中含滾轉在內的旋轉,distance 跟隨帶正負號的環繞距離。只改 fov 永遠不會移動燈光。關掉的部分改用 followCameraReference——targetXtargetYtargetZdistance 與世界空間的 rotation 四元數——即關掉那一刻定格的值;缺少參考時依目標為零、單位旋轉、距離為零處理

scene.setLightFollowCamera { lightId, followCamera, options? } 為目前場景的一盞燈切換跟隨,或把 options 合併進它的選擇,同時不移動它、也不改變它的朝向:桌面端依畫面上的相機(包括正在播放的相機運動)換算這盞燈的座標,回傳換算後的 { light },燈已不存在時為 light: nullscene.patch 與已儲存的場景則依寫入的值原樣使用,不做這種換算。這些欄位與這個方法都要依 camera-follow-lights 判斷

SceneLight.volumetric 為單盞點光源、聚光燈或面光源開啟受光照亮的霧氣。它預設是 false,其他類型會忽略它。舊版建置不帶這個欄位,而是整個場景共用一個開關,所以提供這項控制項之前先檢查欄位是否存在;開啟那個開關儲存的場景,載入後每盞能點亮霧氣的燈都會開啟 volumetric

SceneEnvironment 新增了兩個可選欄位 volumetricLightingclusteredLighting。舊版建置不帶它們,所以提供這兩項控制項之前先檢查欄位是否存在。volumetricLighting 決定整個場景裡霧氣的樣子,本身沒有開關——沒有哪盞亮著的燈開啟霧氣時,就沒有霧氣。目前的版本會回傳完整的霧氣設定,並把 clusteredLighting 修正為關閉;修改它們走 scene.patch 的環境

volumetricLighting 欄位取值預設值
density0 – 101
intensity0 – 101
range距相機 1 – 100 場景單位20
qualitylowmediumhighmedium
speed0 – 5;為 0 時霧氣靜止0.2

霧氣圍繞開啟了它的燈發光,會被深度遮擋,未被照亮處保持透明;只要有一盞亮著的場景光源開啟了它,3D 物件與環境模型自帶的點光源、聚光燈與面光源也會加入。它需要透視相機:正交投影下設定保留,但不渲染霧氣。平行光與環境光不參與,Live2D 也不會遮擋它。clusteredLighting: true 會在 WebGPU 透視相機下,為 1 – 64 盞範圍有限、不投射陰影的點光源加速表面光照。有點光源沒有範圍上限、數量超出,或渲染器、相機不受支援時,照舊使用一般光照。它不會降低陰影的渲染開銷,也不會改變霧氣所用的光源

environment-map-model 能力的建置上,SceneEnvironment 可以同時帶 iblAssetIdmodelAssetId。此時 bakeFromModel 選擇從模型產生光照,貼圖作為它的輸入;為 false 時直接用貼圖照明,沒有貼圖時退回模型自帶的天空。showSkybox 只管顯示,無論由誰照明,畫的都是貼圖或那片天空。清除其中一項會保留另一項,SDK 的 environmentClearPatch() 可以產生這種修改。舊版建置同一時間只能有一項環境素材,在那裡設定其中一項時要清掉另一項

還有三個可選欄位透過 scene.patch 調整全景圖:skyboxBlur(0 – 1,預設 0)與 skyboxIntensity(0 – 2,預設 1)只影響看得見的天空盒,iblRotation(弧度,預設 0,可以超過一整圈)讓全景圖與它的光照一起轉動,模型產生光照所用的天空也一樣。舊版建置不帶這些欄位,所以欄位存在時才提供對應控制項

物理模擬

SceneEnvironment.physics 就是場景的 物理模擬 開關:3D 物件會落到舞台地面上,也會落在 VRM 虛擬形象身上。它預設是 false,舊版建置不帶這個欄位。模擬出的姿態從不儲存,讀回的物件擺放始終是寫入的值,把 physics 關掉,每個物件都會回到原位

spawn 能力的建置還接受 stage.spawn,它把已註冊的 prop 素材複製成一批受物理驅動的物體,投放到舞台上。這些副本只存在於渲染器裡——沒有場景項目,沒有圖層列,不能復原,也不會儲存——同一個檔案的所有副本共用幾何體、紋理與繪製呼叫,所以數量上百也依然輕量。目前場景的 physics 關閉時,呼叫回傳 invalid-state;素材不是已註冊的 prop 時回傳 not-found;否則回傳 { spawned, alive },其中 alive 統計所有素材的物體

欄位意義
assetId已註冊的 prop 素材
count1 – 200,預設 1。舞台上的物體超過 500 個時,最早的會讓出位置
origin散佈立方體的中心,{ x, y, z },以公尺為單位。預設 { x: 0, y: 3, z: 0 },在虛擬形象站立處的上方
spread散佈立方體的邊長,0 – 20 公尺,預設 1
velocity所有物體共用的初速度,{ x, y, z },以公尺每秒為單位,每個軸在 ±50 以內。預設靜止
scale0.01 – 100,預設 1
ttlMs每個物體存在多久,0 – 600000 毫秒,預設 30000。0 表示一直保留到被清除
transition{ style, inMs, outMs }:只為這批物體另選 顯示與隱藏 樣式,出現與消失各用 0 – 5000 毫秒。省略的欄位沿用場景的設定

超出範圍的數值會被修正到邊界上。物體會在 ttlMs 到期、切換到其他場景或關閉 physics 時離開,也可以用 stage.clearSpawned {} 清除——它回傳 { cleared },還會取消仍在載入素材的投放

場景轉場

scene.activate 會等目標場景載入完成並接管舞台——這段期間原場景照常運作、可以編輯——但不會等轉場把它完全揭開。較新的切換會頂替尚未完成的那次,所以回應裡回報的是實際生效的場景,不一定是你請求的那個。SDK 給切換場景保留 120 秒,設定了 requestTimeoutMs 時以它為準

scene-transitions 能力的建置會在 Scene.transition 裡帶上每個場景的 轉場,也就是進入該場景時播放的效果。scene.patch { transition } 會整個取代它,但不會播放:

欄位意義
typecutfadewipecircleimagevideo
durationMs100 – 10000 毫秒
color淡入、擦除或圓形展開的遮罩顏色,十六進位
assetId已註冊的圖片或影片,或 null
switchPoint影片中切換場景的位置,0.05 – 0.95。請選一個完全蓋住舞台的影格
autoFade讓影片淡入淡出。預設關閉
fadeInMs / fadeOutMs各為 0 – 10000 毫秒的播放時間,預設 300,分別以切換點之前與之後的時間為上限。0 關閉該淡變

所有切換場景的方式都使用目標場景的轉場。除了直接切換,轉場都會立即開始,並一直遮住舞台直到目標場景就緒,載入較慢時會超出 durationMs 自動延長。影片靜音播放,速度隨時長調整,等待期間停在切換影格上

顯示與隱藏

SceneEnvironment.itemTransition { style, durationMs } 就是場景的 顯示與隱藏 設定:場景裡的模型、物件與生成物體如何出現與消失。舊版建置不帶這個欄位。styleglitch(帶撕裂與灼燒的抖動溶解,預設)、dither(不帶額外效果的抖動溶解)、pop(縮放出現與消失)或 cutdurationMs 取值 0 – 5000,預設 300。cut 無論 durationMs 是多少都不會漸變,0 也等同於 cut。修改它走 scene.patch 的環境

圖層特效

layer-effects 能力的建置允許單個模型或物件帶上自己的 特效,在它併入場景之前生效。每個場景項目都有自己的 effectseffectLayers,結構與場景的一致,由 instance.setEffects { instanceId, effects, effectLayers? } 編輯:

  • effects 接受 colorlevelscolorWheelscolorShiftselectColorsgradientblurbloomdiffusionrimoutlinedropShadow 的部分設定,沒寫到的保持原值
  • effectLayers 傳入時會取代已新增特效的清單。已啟用的特效始終在清單裡

回應是修正後的結果:數值被限制在範圍內,未知的鍵被捨棄。格式有誤的特效會讓整個呼叫在任何變更生效之前失敗

圖層特效作用於模型和位於 3D 空間的物件。2D 物件會回傳 unsupported-for-format;它們已儲存的設定會保留,等空間改變後再生效

追蹤來源

Persona 可以同時執行多個已設定的追蹤來源。settings.tracking.sources 列出它們,tracking.addSourcetracking.updateSourcetracking.removeSource 管理這份清單。instance.setTrackingSources 依來源 id 將實例的臉部、姿勢與手部通道(faceSourceIdposeSourceIdhandSourceId)綁定到對應來源。設為 null 會停止該通道的追蹤,不存在的 id 也視同 null。新實例預設綁定各通道的預設來源;同一個來源可以同時驅動多個實例

instance.setTrackingSources 還接受 handTrackingModearms 讓追蹤到的手同時帶動 VRM 的手臂、手腕與手指,fingers 只動手指,手臂留給 VMC 或 mocopi 的身體追蹤

臉部追蹤來源可以是 persona-iosifacialmocapvts-ios,也可以用選填的 phoneIp 固定一部傳送裝置。姿勢追蹤來源使用 vmcmocopiport 屬於 vmcmocopiifacialmocap——若該連接埠已被其他來源佔用,請求會被拒絕,只有幾個 ifacialmocap 來源之間共用一個 socket;persona-iosvts-ios 的連接埠由協定本身固定。已淘汰的 vts-ios-native 會在協定層被拒絕

mediapipe攝影機 追蹤來源,最多只能有一個,沒有 portphoneIp。它的 mediapipe 選項開關三項任務——facehandsbody,分別對應三個通道——並設定 deviceId'' 表示預設攝影機)、mirrordelegateCPUGPU)。預設開啟鏡像、在 CPU 上執行,追蹤臉部與手部而不追蹤身體。tracking.addSourcetracking.updateSource 接受部分選項,沒寫到的保持原樣。追蹤到的手還會驅動 注入 一節列出的手部輸入

tracking.status 回傳網路臉部來源與姿勢來源的彙總狀態,以及 sources 對應表中每個已設定來源的獨立狀態,攝影機也在其中;tracking.status 事件帶有相同的結構,只有單一來源的狀態變更時也會觸發

舊的單一來源方法仍然作用於對應通道的第一個網路來源:tracking.setSource 修改其種類,pose.setSource 在需要時建立 VMC 來源並回傳它的連接埠,pose.setPort 則修改該連接埠。tracking.setEnabledpose.setEnabled 仍是網路臉部來源與姿勢來源的總開關。攝影機只聽它自己的 enabled,透過 tracking.updateSource 設定,任務選擇與模型指派都會保留

麥克風口型同步

口型同步 用桌面端的麥克風驅動口型。麥克風與輸入裝置清單都是桌面端的,不是瀏覽器所在那台電腦上的;音訊與校正資料都不會經過 API。分析結果還會驅動 注入 一節列出的聲音輸入

方法作用
lipSync.state讀取設定、擷取狀態(offstartinglisteningerror)、桌面端的輸入裝置、即時音量與母音取樣,以及進行中的校正
lipSync.configure合併一份部分設定——enableddeviceIdgain(0 – 30 dB)、noiseGate(−60 – 0 dBFS)、smoothing(0 – 0.3 秒)——並回傳儲存後的結果
lipSync.restart在下一個影格重新啟動擷取。它既不會開啟已關閉的麥克風,也不會等擷取完成,請輪詢 lipSync.state
lipSync.calibrate執行一步校正並回傳新狀態

同一份設定也以 settings.lipSync 出現,settings.patch 同樣接受。校正使用桌面端選取的麥克風,並與桌面面板共用:start 開始一份草稿,record 搭配 phonemeAIUEO,或代表背景噪音的 S)把該聲音錄兩秒,六個都錄完後用 preview 套用草稿,最後 savecancel 結束。reset 讓目前的麥克風回到內建設定檔。錄製會立即回傳,進度請輪詢 lipSync.state:其中的 calibration 會回報目前階段 phasereadyrecordingverifying)、正在錄製的聲音與已錄完的聲音。不符合目前階段的步驟會得到 invalid-state

instance.setLipSync { instanceId?, mode } 設定麥克風是否驅動某個模型:always(預設)、when-untracked(僅在它的臉部沒被追蹤時)或 off。對物件呼叫會回傳 unsupported-for-format

語音

speech.play 播放一段音訊,並用它的響度驅動口型。它只作用於能力表裡帶 speech 的實例——目前是已載入的 Live2D 模型。判斷依據始終是實例的執行階段能力而不是格式:0.53 及更早的版本在已移除的舊版 WebGL 引擎下不回報它

參數說明
urlhttps:http:(本機 TTS 橋接)或內嵌的 data:audio/* 負載
volume選填,0..1
instanceId選填,預設場景的主模型

一個模型同一時刻只有一段語音,新的播放會頂替正在播的那段。呼叫回傳即表示播放已經開始,沒能開始則是 invalid-statespeech.startedspeech.ended 成對包住這段語音,speech.stop 提前結束它

自動化

automations 能力的建置可以列出並執行應用程式的 自動化——由快速鍵、事件或請求觸發的一串舞台改動

方法作用
automation.list列出全部自動化
automation.run依 id 執行其中一條

操作內容、觸發條件設定與編輯都留在應用程式一側。清單裡給出的是 idtitleacceleratorregisteredenabled,以及 actionKindstriggerKinds 兩份陣列——足夠畫出一列按鈕,不必知道每條操作具體做什麼。titlenull 時用 actionKinds 拼一個標籤出來,SDK 的 automationLabel 做的就是這件事。actionSceneIdsactionKinds 一一對應,記錄每個 switch-scene 的目標場景(其他種類為 null),標籤因此可以寫出場景名稱——不過那個場景可能已經被刪除了

每條自動化都是一條時間軸,它的時間和其他內容一樣留在桌面應用程式裡,所以 actionKinds 的順序並不代表執行的先後。操作種類包括在時間軸開始前作為準備步驟執行的 switch-sceneload-model;暫時效果 effect-clipplay-camera-motionstop-camera-motionplay-audioaudio-control;以及作用於虛擬形象的 toggle-expressionplay-motionremove-all-expressionsload-modelmodel-positiondelay 已經移除——時間軸上的空白就是等待。音訊沒有自己的方法:檔案、播放與輸出裝置都留在桌面端,用戶端要播放聲音,就執行一條自動化。triggerKinds 列出這條自動化在快速鍵之外還有哪些種類的事件觸發條件——目前有 scenemodel-loadedmotionface-trackingmicrophoneparameter

沒有指派鍵盤或控制器快速鍵時 acceleratornull——automation.run 照樣能執行它。暫停的自動化 enabledfalse,會忽略所有觸發,包括 automation.runautomation.run 在派送後立即回傳,不等操作執行完。清單、名稱、觸發條件種類、啟用狀態或系統註冊狀態一有變化,automation.state 就會送來完整的新清單

外掛儲存空間

storage.* 為外掛提供持久化鍵值儲存空間,按 API 金鑰劃分命名空間。使用同一把金鑰的所有工作階段共用資料,撤銷金鑰也會刪除對應資料。值可以是任意 JSON

方法作用
storage.get讀一個鍵。從沒寫過的鍵回傳 value: null
storage.set寫一個鍵
storage.delete刪一個鍵。鍵本來就不存在也算成功
storage.list列出所有鍵,已排序

上限是鍵名 128 個字元、單一值序列化後 64 KB、每把金鑰 256 個鍵。會突破鍵數上限的 storage.set 得到的是 invalid-state

錯誤

persona.call 會擲出帶字串 codePersonaApiError

代碼意義
parse-error這個訊框不是合法的 JSON
invalid-request訊息封裝格式有誤
unknown-method這個建置沒有這個方法
invalid-params參數未通過驗證
not-found引用的 id 找不到對應物件
unsupported-for-format該實例的格式做不到這件事——例如對 Live2D 模型設定 MToon
conflict參數租約被另一個工作階段持有
renderer-unavailable舞台無法回應——沒有視窗,或渲染行程正在重新載入
forbidden-path路徑不在任何已設定的外掛資料夾內
invalid-state目前不允許,例如刪除最後一個場景、儲存超額、音訊沒能開始
internal其餘所有情況

這套代碼是協定的一部分:用戶端會丟棄帶未知代碼的錯誤訊框,所以新增代碼只隨協定版本一起到來,新出現的失敗沿用現有這些

連線中斷

用戶端會在連線意外中斷後自動重新連線。以下關閉碼會停止自動重新連線,以遵循金鑰撤銷或使用者手動中斷連線的操作:

代碼常數原因
4001CLOSE_KEY_REVOKED金鑰已被撤銷
4002CLOSE_FORCE_DISCONNECTED使用者中斷了該工作階段

兩者都會讓用戶端最終停在 closed 狀態。傳入了 onClose 時,終止性關閉會交給它,並略過 onWarning;沒有 onClose 時則回退到 onWarning1001 不在此列——它表示伺服器正在停止,等它回來重連即可

撤銷金鑰會立即捨棄待傳送的訊框,並以 4001 關閉使用該金鑰的連線。仍在等待舞台回應的請求不會繼續寫入。已傳送給舞台的操作可能完成,但其回應會被捨棄

版本不一致

協定自帶版本號,與所連接的建置不符時 SDK 會發出警告。訂閱一個舊版 Persona 不認識的事件並非致命錯誤——SDK 會退回到逐個訂閱,保留能用的,並逐一報出其餘事件的名稱

目前的協定版本是 4。此前的每次升級都從協定中移除了一些內容,所以針對舊協定撰寫的用戶端或外掛需要更新:

協定變化
2Scene.behavior(視線跟隨游標)已移除,場景資料與 scene.patch 裡都沒有了
3stage.shockwave 已移除,呼叫它會得到 unknown-method
4shortcut.listshortcut.triggershortcut.state 改為 automation.listautomation.runautomation.stateshortcuts 能力改名為 automations,負載裡改用 automationIdautomations

最後更新於 2026年9月20日

Tech otakus destroy the world