Skip to content

Add scoped NPC voice session lane#270

Merged
JOY (JOY) merged 1 commit into
devfrom
feat/npc-voice-session-lane
May 26, 2026
Merged

Add scoped NPC voice session lane#270
JOY (JOY) merged 1 commit into
devfrom
feat/npc-voice-session-lane

Conversation

@JOY
Copy link
Copy Markdown
Contributor

Summary

  • Add secondspawn_voice_session_request as the scoped Nakama boundary for future NPC voice playback material.
  • Keep voice sessions disabled by default, return structured text fallback reasons, and mint only short-lived api.dos.ai session material when explicitly configured.
  • Wire the Unity gateway and prototype NPC chat hotkey to request voice sessions through Nakama only, plus document the Convai/TTS decision lane.

Safety and Authority

  • Unity never receives provider API keys and never calls voice/model providers directly.
  • Voice session responses are presentation-only and cannot mutate memory, relationship, quest, TIME, SECOND, inventory, combat, or body lifecycle state.
  • Convai remains an isolated phase 1 spike option for one boss or hub NPC, not a blocker for text-first focused dialogue.

Verification

  • npm.cmd run build in backend/nakama - passed.
  • npm.cmd test in backend/nakama - passed.
  • git diff --check - passed.
  • Local code-review fallback - approved with one known environment gap: Unity compile could not complete because package resolution fails before scripts load.
  • Unity MCP - no active Unity session was available.
  • Unity batchmode with 6000.5.0b9 - blocked by existing Package Manager error: The "path" argument must be of type string. Received undefined. No packages loaded. Log: Unity/Logs/npc-voice-session-batchmode.log.

Refs #262

@JOY JOY (JOY) merged commit dc5e602 into dev May 26, 2026
2 checks passed
@JOY JOY (JOY) deleted the feat/npc-voice-session-lane branch May 26, 2026 04:56
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 14f16c9c0d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment on lines +1300 to +1304
var voiceTarget = resolveVoiceSessionTarget(ctx, nk, userId, request);
var ttlSeconds = voiceSessionTtlSeconds(ctx, request);
var expiresAtMs = new Date().getTime() + ttlSeconds * 1000;
var sessionDescriptor = buildVoiceSessionDescriptor(nk, voiceTarget, request, ttlSeconds, expiresAtMs);
var disabledResponse = voiceSessionDisabledResponse(ctx, voiceTarget, sessionDescriptor);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Gate voice-session RPC before any profile writes

rpcVoiceSessionRequest resolves the actor target before checking whether voice sessions are disabled, and resolveVoiceSessionTarget calls getOrCreateWorldNpcProfileState for NPC targets. That helper performs storage writes on first access, so even with DOS_AI_VOICE_SESSIONS_ENABLED=false this supposedly presentation-only RPC mutates persistent actor state and can create per-user NPC records unexpectedly. This is reproducible by calling secondspawn_voice_session_request for a permanent NPC on a fresh account.

Useful? React with 👍 / 👎.

yield return _gateway.GetVoiceSession(response =>
yield return _gateway.GetVoiceSession(new VoiceSessionRequestDto
{
actor_id = _npcId,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fallback invalid NPC id before requesting voice session

The voice-session request now sends actor_id = _npcId directly, but existing serialized scene data still uses legacy values like prototype-guide (for example Unity/Assets/_SecondSpawn/Scenes/ZoneTest_Hub.unity). The new Nakama RPC rejects non-permanent NPC ids, so enabling prototype hotkeys in that scene and pressing the voice key now fails with an RPC error instead of returning the structured fallback response.

Useful? React with 👍 / 👎.

userId;
return {
owner_id: userId,
actor_id: trimString(player.player_id) || userId,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return reusable actor_id for current-body voice responses

When actor_id is omitted, the RPC returns actor_id as the player id, but later validates provided actor_id values as permanent NPC ids only. This makes the response self-inconsistent: if a client reuses the returned actor_id on the next secondspawn_voice_session_request, the call is rejected with voice session actor must be a permanent NPC or omitted for the current body. Returning the current body source actor id (or omitting actor_id) avoids this contract break.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant