DreamShaderLang
Plugin referenceTools

Workspace and editor extensions

Workspace and editor extensions

Workspace and editor extensions

DreamShader » Tools » Workspace and editor extensions

A generated VSCode workspace file that maps the six DreamShaderLang file extensions onto the language ids of the VS Code extension, and the editor command that writes it and launches an external editor on it.

Kindeditor command + generated file
Writes<SourceDirectory>/DreamShader.code-workspace
CommandTools ▸ DreamShader ▸ Open Dream Shader Workspace (VSCode), and the toolbar button of the same name
PlatformWindows only — discovery uses Windows environment variables, ;-separated PATH, cmd.exe and notepad.exe
Since1.2.1

Synopsis

<SourceDirectory>/DreamShader.code-workspace

<SourceDirectory> is the Source Directory project setting, default <Project>/DShader. The directory is created if it does not exist. The file is written UTF-8 without a BOM, pretty-printed by Unreal's JSON writer (tab indentation):

{
	"folders": [
		{
			"name": "DreamShader Source",
			"path": "."
		},
		{
			"name": "Plugin: MoonToon",
			"path": "../Plugins/MoonToon/DShader"
		}
	],
	"settings": {
		"files.associations": {
			"*.dss": "dreamshader-dss",
			"*.dsi": "dreamshader-dss",
			"*.dsp": "dreamshader-dsp",
			"*.dsm": "dreamshaderlang",
			"*.dsh": "dreamshaderlang",
			"*.dsf": "dreamshaderlang"
		}
	}
}

One folders entry per source root: the project root is always first and always "." (the workspace file lives in it), then one entry per plugin that ships a DShader folder, named Plugin: <Name> and pointed at a path relative to the workspace file. A root that has no relative form — an engine plugin on a different drive — gets its absolute path instead. See Source files.

Contents

Every key the writer emits. There are no others; only the number of folders entries varies.

KeyValuePurpose
folders[0].nameDreamShader SourceDisplay name of the project root's folder.
folders[0].path.The folder containing the workspace file, i.e. <SourceDirectory> itself.
folders[n].name, folders[n].pathPlugin: <Name>, a path relative to the workspace file (absolute when there is none)One per plugin source root, in root order.
settings["files.associations"]["*.dss"]dreamshader-dssLanguage id for 2.0 compilation units (since 2.1.0).
settings["files.associations"]["*.dsi"]dreamshader-dssLanguage id for material instance sources (since 2.1.0).
settings["files.associations"]["*.dsp"]dreamshader-dspLanguage id for Custom Pass pipelines (since 2.1.0). Without it a .dsp is claimed by whatever else knows the extension -- the Faust language and old Visual C++ projects use it too.
settings["files.associations"]["*.dsm"]dreamshaderlangLanguage id for material sources.
settings["files.associations"]["*.dsh"]dreamshaderlangLanguage id for headers.
settings["files.associations"]["*.dsf"]dreamshaderlangLanguage id for function sources (since 1.3.5).

Three language ids, the ones the extension registers: dreamshaderlang for the 1.x sources and headers, dreamshader-dss for 2.0 sources, dreamshader-dsp for pipelines (extension 2.1.0 and later). A workspace association overrides the extension's own mapping of an extension to a language, so the two have to agree: with dreamshaderlang for a .dss, VS Code would give it the 1.x grammar and language server. Settings scoped to a language -- "[dreamshader-dss]": { ... } -- use the same ids.

[!WARNING] The file is rewritten from scratch on every invocation of Open Dream Shader Workspace. The writer serializes a fixed object; it never reads, merges or preserves the existing file. Any launch, tasks, extensions or extra settings entries added by hand are destroyed the next time the command runs. Keep per-user workspace configuration in a different .code-workspace file or in <SourceDirectory>/.vscode/settings.json, neither of which this command touches.

Open behaviour

The command performs five steps, in this order:

StepActionOn failure
1Re-export material-expressions.jsonlogged, command continues
2Re-export settings.json, and pass-keys.json right after it (since 2.1.0)logged, command continues
3Re-export substrate-builtins.jsonlogged, command continues
4Write DreamShader.code-workspacetoast + warning, command aborts
5Launch an editor on the workspace file (fallback chain below)toast + warning

Steps 1–3 are the same three manifests the bridge writes at editor startup; opening the workspace refreshes them so an extension that has just been installed sees current data without an editor restart.

Launch fallback chain

The first mechanism that succeeds wins; the rest are not attempted.

OrderMechanismDetail
1VSCodeThe first discovered executable that yields a valid process handle. .cmd / .bat candidates are run through %ComSpec% (falling back to C:/Windows/System32/cmd.exe) with /C, hidden; .exe candidates are spawned directly.
2Shell default applicationFPlatformProcess::LaunchFileInDefaultExternalApplication with the Edit verb — whatever is registered for .code-workspace.
3Notepad%SystemRoot%\System32\notepad.exe if it exists, otherwise bare notepad.exe.
—(none)Failure toast and a warning in the log.

VSCode executable discovery

Probed in this exact order. Only paths that exist as files are kept, and duplicates are dropped.

OrderCandidate
1%LOCALAPPDATA%\Programs\Microsoft VS Code\Code.exe
2%LOCALAPPDATA%\Programs\Microsoft VS Code\bin\code.cmd
3%LOCALAPPDATA%\Programs\Microsoft VS Code Insiders\Code - Insiders.exe
4%LOCALAPPDATA%\Programs\Microsoft VS Code Insiders\bin\code-insiders.cmd
5%ProgramFiles%\Microsoft VS Code\Code.exe
6%ProgramFiles%\Microsoft VS Code\bin\code.cmd
7%ProgramFiles(x86)%\Microsoft VS Code\Code.exe
8%ProgramFiles(x86)%\Microsoft VS Code\bin\code.cmd
9For each ;-separated PATH entry, in PATH order: code.cmd, code.exe, Code.exe, code-insiders.cmd, Code - Insiders.exe

There is no setting that names a VSCode executable. A non-standard install is reachable only by putting it on PATH.

The reuse-window setting

SettingOpen In New Window — bOpenInNewWindow, category Editor
Defaulttrue
EffectWhen false, --reuse-window is appended to the VSCode command line. When true, no flag is passed and VSCode applies its own default.

[!NOTE] bOpenInNewWindow is consulted by the workspace launcher only. Every other DreamShader action that opens a file in VSCode uses a separate launcher that always passes --reuse-window -g "<path>:<line>:<column>", regardless of the setting. Turning Open In New Window on does not make Open source, OpenVirtualFunction or the post-export open use a new window.

ActionLauncherWindow behaviour
Open Dream Shader Workspace (VSCode) (menu and toolbar)workspace launcherhonours bOpenInNewWindow
Open source (Material Content Browser)file launcheralways --reuse-window
OpenVirtualFunction (asset context menu)file launcheralways --reuse-window, positioned at the declaration's line and column
Export .dss / .dsi / Legacy .dsm / Legacy .dsf post-export openpreferred-editor chainalways --reuse-window when VSCode is used

The file launcher clamps line and column to 1 or greater. Its own fallback chain is VSCode → shell default application (Edit verb) → Notepad, the same shape as the workspace chain.

Diagnostics

Runtime substitutions are shown as {Placeholder}. Toast text and log text differ; both are listed.

ToastLogCause
DreamShader failed to create workspace: {Error}Warning — Failed to create DreamShader workspace: {Error}the workspace file could not be written; {Error} is one of the three writer errors below
Opened DreamShader workspace in VSCode: {Path}Display — same texta VSCode candidate launched
Opened DreamShader workspace: {Path}Display — Opened DreamShader workspace with the default editor: {Path}the shell default application launched
Opened DreamShader workspace in Notepad: {Path}Display — same textNotepad launched
DreamShader could not open workspace: {Path}Warning — Failed to open DreamShader workspace: {Path}every mechanism in the chain failed; the file was still written

Writer errors, substituted into {Error} above:

MessageCause
DreamShader source directory is empty.the resolved source directory normalized to an empty string
Failed to create DreamShader source directory '{Path}'.the source directory did not exist and could not be created
Failed to write DreamShader workspace file '{Path}'.the file could not be saved (read-only, locked, out of space)

All logging goes to the LogDreamShader category.

Editor extensions

The language tooling lives in two repositories, neither of which ships inside this plugin. The plugin contributes the workspace file, the file associations and the bridge artifacts; everything below — grammars, completion, navigation, package commands — is implemented by the extension.

EditorRepositoryProvides
VSCodehttps://github.com/TypeDreamMoon/dreamshader-language-supportSyntax highlighting, snippets, completion, Go to Definition, Find References, Hover, Signature Help, local diagnostics, Unreal bridge diagnostics, package commands, quick templates.
JetBrains Riderhttps://github.com/tsdaer/dreamshader-language-support.dsm / .dsf / .dsh file types, grammar and PSI parsing, highlighting, completion, navigation, diagnostics, Unreal Bridge integration, semantic tokens, inlay hints, package tools.

Extension-side settings (for example a project-root override, a preview frame rate, or package store index URLs) are declared by the extension, not by UDreamShaderSettings, and are documented in the extension's own repository. The release workflow attaches the latest VSCode extension assets to each plugin GitHub release; see Release.

What an extension consumes

Every artifact an extension reads or writes lives under <Project>/Saved/DreamShader/Bridge/, plus the loopback WebSocket endpoint. The full schemas are on Editor bridge.

ArtifactDirectionContents
Requests/*.jsonextension → editorRecompile, clean and one-shot preview commands; see request files.
diagnostics.jsoneditor → extensionAll current diagnostics, grouped by source file.
diagnostics/index.json + diagnostics/<md5>.jsoneditor → extensionThe same data sharded per file, for incremental reads.
bridge.dbeditor → extensionSQLite mirror of the diagnostics and the three manifests.
material-expressions.jsoneditor → extensionReflected UMaterialExpression catalogue for UE.Expression completion (since 1.2.10).
settings.jsoneditor → extensionShadingModel / BlendMode / MaterialDomain alias tables.
substrate-builtins.jsoneditor → extensionSubstrate.* builtin catalogue with snippets; supported: false below UE 5.4.
pass-keys.jsoneditor → extensionWhat a .dsp may say, for completion; supported: false below UE 5.8 — below (since 2.1.0).
preview.json + Preview/*.pngeditor → extensionResult manifest and image for a one-shot preview.
ws://127.0.0.1:17864bidirectionalStreaming preview with orbit control; see WebSocket protocol.

pass-keys.json

(since 2.1.0) The vocabulary of a .dsp, for an editor's completion: <Project>/Saved/DreamShader/Bridge/pass-keys.json, schema DreamShader.PassKeys, version 1, with a generatedAt timestamp. It is written with settings.json — at bridge startup and on Open Dream Shader Workspace — because the layer names it ends with are a project setting. It has no bridge.db table.

KeyContents
supportedtrue on UE 5.8 and later. Below, false with unsupportedReason: Custom Pass pipelines run on Unreal Engine 5.8 and later. — a .dsp still parses and binds there, and nothing runs it
injectionPointsevery injection point in the order a frame reaches it: name, order, postProcess, and resolution (Render or Output)
pipelineKeysthe #pragma pipeline keys: Order, Injection, Views, Requires, Enabled
bufferFormats · bufferKeys · bufferResolutionsR8 … Depth32; Scale, Size, Resolution, Clear, Mips, History, Export; Render, Output
passKindsfullscreen, compute, mesh, clear, copy, each with its own keys and a detail
commonPassKeysInjection and Enabled, which every kind takes
bindingStatementsread, write, param
filterKindsStencil, Layer, List, each with the snippet an editor inserts (Stencil(${1:1}))
meshModes · depthModes · cullModes · blendModes · nanitePolicies · meshUsages · viewFlags · requirementFlags · parameterTypesthe spellings each of those values takes
builtinBuffersSceneColor, SceneDepth, CustomDepth, CustomStencil, GBufferA … GBufferF, Velocity, Translucency
weightParameterDreamPassWeight
layerNamesthe project's pass layers, in bit order — the names Layer(...) takes

Every key entry is name, value (the kind of value, which names the list it is completed from — injection for injectionPoints, …), default (what leaving the key out means), required (true when there is no default) and detail.

Example

Running Tools ▸ DreamShader ▸ Open Dream Shader Workspace (VSCode) on a default project touches:

<Project>/DShader/DreamShader.code-workspace                    rewritten
<Project>/Saved/DreamShader/Bridge/material-expressions.json    rewritten
<Project>/Saved/DreamShader/Bridge/settings.json                rewritten
<Project>/Saved/DreamShader/Bridge/pass-keys.json               rewritten (since 2.1.0)
<Project>/Saved/DreamShader/Bridge/substrate-builtins.json      rewritten
<Project>/Saved/DreamShader/Bridge/bridge.db                    tables replaced

and then launches, for a code.cmd candidate with Open In New Window left at its default:

%ComSpec% /C ""C:/Users/<user>/AppData/Local/Programs/Microsoft VS Code/bin/code.cmd"  "C:/Projects/MyGame/DShader/DreamShader.code-workspace""

With Open In New Window turned off, the same line carries the extra flag:

%ComSpec% /C ""C:/Users/<user>/AppData/Local/Programs/Microsoft VS Code/bin/code.cmd" --reuse-window "C:/Projects/MyGame/DShader/DreamShader.code-workspace""

See also

On this page