8.3 KiB
Config Knobs — load-bearing settings
YAML configs live in overwrite/SKSE/Plugins/SkyrimNet/config/ (with active edits) and mods/SkyrimNet/SKSE/Plugins/SkyrimNet/config/ (shipped baselines). 38 YAML files total, plus defaults_manifest.json.
This document focuses on the load-bearing settings — ones we've discovered have outsized effects on behavior. Full enumeration would be brittle and date-sensitive; the goal here is to capture the gotchas.
SkyrimNet.yaml — the central config
[verified] Direct observations from this install + log/trace correlation.
| Setting | This install | What it controls | Gotcha |
|---|---|---|---|
dialogue.embedActionsInDialogue |
true |
Lets the Dialogue model emit ACTION: lines inline after speech. |
When true, the native_action_selector may be bypassed — and bug #2 (malformed markers) surfaces. When false, actions are strictly post-hoc via native selector. |
dialogue.eligibilityCheckTimeoutMs |
2500 |
Bounds the wait_eligibility_results span. |
Slow Papyrus eligibility callbacks (>2.5s) get dropped from the available action list for that turn. |
dialogue.interruptDialogueOnVoiceStart |
true |
Player STT triggers a barge-in on the NPC. | Distinct from TTS-side interrupts; affects whose voice cuts off whom. |
dialogue.maxSegmentWords (tts.maxSegmentWords) |
4 |
TTS chunk size for streaming. | Was raised by us as part of the first-sentence-drop fix. Small chunks can amplify chunker race conditions; suspected innocent in NPC-NPC restatement. |
gamemaster.enabled |
true |
Master switch for the GM. | — |
gamemaster.agentEnabled |
true |
[unknown] Distinct from enabled? Both default true; toggling untested. |
See open-questions.md. |
gamemaster.continuousSceneCooldownSeconds |
30 |
Minimum gap between GM polling ticks in continuous mode. | Lower = more LLM cost, more "alive" feel. Higher = cheaper, quieter scenes. |
gamemaster.actionCooldownSeconds |
180 |
Per-NPC action cooldown. | Prevents the same NPC from being action-targeted repeatedly. |
gamemaster.nearbyActorRadius |
600 |
Radius around player the GM considers. | Skyrim units (~10cm each, so ~60m). |
gamemaster.recentEventsCount |
25 |
How much event history goes into the GM prompt. | Higher = more context, more tokens, more cost. |
gamemaster.requestTimeoutSeconds |
30 |
Per-call LLM timeout for the GM. | — |
gamemaster.continuousSceneCooldownSeconds |
30 |
(duplicate row — see above) | — |
interaction.maxDistance |
250 |
Default interaction distance. | Affects who hears what. |
interaction.normalMaxDistance |
250 |
Normal speech audibility. | — |
interaction.whisperMaxDistance |
100 |
Whisper audibility. | — |
events.preloadCount |
1000 |
Events warmed at startup. | Affects load time + initial memory query corpus. |
narration.enabled |
false |
Suppresses asterisk-style narration globally. | Referenced by is_narration_enabled() decorator in many prompts; toggling changes prompt content materially. |
subtitles.enableNPCSubtitles |
true |
Whether NPC subtitles render. | — |
dbvo.enabled |
true |
Dialogue Background Voice Over — routes TTS through vanilla Skyrim dialogue topics. | The "first-sentence-dropped" bug we hit was traced to this. Disabling skips lip-sync and topic-coupling. |
shouldSilenceActors |
true |
Silences actors before TTS plays (prevents vanilla audio overlap). | Can race the first audio chunk and silence it. |
[verified] enableNPCNodeUpdates: true and dbvo.fixSubtitleDuringTTS: true were the toggles that fixed the user's "first sentence not played" issue (see bugs-and-fixes.md historical context).
Agents.yaml
Defines per-agent variant assignments and behavior. Each agent has:
variant— which OpenRouter variant to use (cross-referencesOpenRouter.yaml)enabled— master toggle for the agent- Possibly
cooldown,timeout, model-specific overrides
[hypothesis] Editing Agents.yaml is how a user changes which model handles which agent (e.g., "use Claude for dialogue too, not just GM"). Confirm by inspection.
OpenRouter.yaml
Variant → model + endpoint + per-call defaults. See agent-pipelines.md for the full table extracted from this install.
Key sections:
default_paramsper variant —max_tokens,temperature,top_p, etc.endpoint— the URL the OpenRouter routing layer sends to. In this install, mostly local IPs (10.0.30.x) plus a Claude proxy on127.0.0.1:8000.model— the OpenRouter alias or local model ID.
Actions.yaml
[hypothesis] Defines global action-system policies: which categories are enabled, default priorities, eligibility-check defaults. Doesn't define individual actions — those come from config/actions/*.yaml in contributing mods' folders (see action-system.md).
Events.yaml
~40 event types, each with toggles:
enabled— does SkyrimNet listen for this event at allpersistent— does the event get stored in the long-term logshortLivedEnabled— short-lived event variantallowNPCReaction— can NPCs react to this event via the GMnpcReactionCooldown— per-NPC cooldown for reactinginterrupt— does this event interrupt ongoing dialogue
Currently disabled in user's config [verified] from the user's install:
quest_stagecell_attach_detachquest_objective_statescene*(multiple scene_* event types)
These were likely disabled to cut event noise. Re-enabling would feed more triggers to the GM and increase LLM call frequency.
Memory.yaml
Controls the vector memory system (semantic embeddings via all-MiniLM-L6-v2):
- Embedding model selection
- Memory retention windows
- Number of memories retrieved per query
- Memory generation thresholds
[hypothesis] These tune the RAG-for-NPCs behavior. Defaults probably reasonable for most users.
OmniSight.yaml
Vision-agent settings — when to capture screenshots, how often, scene description verbosity.
MCP.yaml
[hypothesis] Model Context Protocol integration? Not yet inspected. Could be relevant if SkyrimNet exposes MCP servers/clients for external tool integration.
Per-TTS provider configs
One YAML per supported TTS backend:
XTTS.yaml,Zonos.yaml,Chatterbox.yaml,Piper.yaml,PocketTTS.yaml,ElevenLabs.yaml,Inworld.yaml,VastAI.yaml
Active backend selected by tts.engine in SkyrimNet.yaml. This install uses pocket_tts.
Streaming params worth knowing (in PocketTTS.yaml):
streaming.max_words_to_process: 32— max chunk sizestreaming.min_words_to_process_initial: 16— first-chunk minimum (was a suspect for the first-sentence-drop bug)streaming.process_on_sentence_boundary: truestreaming.process_on_word_count: truestreaming.max_buffers_per_actor: 4
STT.yaml
Speech-to-text settings (whisper.cpp local). VAD thresholds, language, sample rate, voice activity gate.
defaults_manifest.json
[hypothesis] JSON dump of every config key with its default value, structured by section name. Looks like the schema the DLL seeds first-run config from — when a YAML doesn't exist, the DLL writes one populated from this manifest.
Sections present (28 total): ActorFilter, Agents, BardSinging, ChatUI, Chatterbox, DialogueFilter, Diary, DynamicBio, ElevenLabs, Entity, Events, Hotkey, Inworld, Memory, MemoryFilter, OmniSight, OpenRouter, Piper, PlayerDialogue, PocketTTS, STT, UniversalTranslator, VastAI, VirtualEntities, VoiceSamples, WebServer, XTTS, Zonos.
Each section name matches a YAML file. Verify role by deleting a YAML and watching what regenerates.
Plugins subtree
config/plugins/IntelEngine/ — the IntelEngine sibling plugin keeps its config under SkyrimNet's config root. Notable files: factions.yaml, settings.yaml. [unknown] exact contents.
Editing safety
- Always edit
overwrite/.../config/, nevermods/.../config/directly. The overwrite layer is what the game reads. - Most settings hot-reload. Restart only needed for backend swaps (TTS engine, STT) or fundamental architecture changes.
- Backup before changes:
cp foo.yaml foo.yaml.backupis the pattern we've used. - The in-game MCM (Mod Configuration Menu) writes back to these YAMLs — UI tweaks persist as YAML edits, which is convenient but means the UI is yet another writer to be aware of.