GameMaker Toolkit is a VS Code extension for GameMaker Language (.gml) projects. It includes a
formatter, parser-backed safety checks, a language server, project indexing, diagnostics,
completions, hovers, signatures, navigation, rename support, generated GameMaker API knowledge,
room-aware project reports, optional project-pattern analysis, and beginner-friendly cleanup tools.
Install
The preferred install method is the VS Code Marketplace:
Install GameMaker Toolkit from the VS Code Marketplace
You can also install it from inside VS Code:
- Open the Extensions view.
- Search for
GameMaker Toolkit. - Install the extension published by
alexdotpink.
Alternative install options:
- Open VSX: alexdotpink.gamemaker-toolkit
- GitHub Release VSIX: latest release
To install a downloaded VSIX manually:
code --install-extension path/to/gamemaker-toolkit-0.10.1.vsix --force
Features
- Registers
.gmlas thegmllanguage in VS Code. - Provides a document formatter for Format Document and
editor.formatOnSave. - Uses
@bscotch/gml-parserto parse GML before formatting, then prints from the parser CST with token-range expression rendering. - Skips formatting when the GML parser reports syntax errors, when formatted output fails to reparse, or when the safety gate detects a formatter AST/trivia mismatch.
- Builds a formatter-owned AST for safety checks and debug output.
- Indents nested brace blocks and
switch/casebodies while ignoring braces inside strings and comments. - Normalizes
//comments to include a following space. - Adds spaces around common operators and after commas.
- Removes redundant outer parentheses from expression output when safe for the printed range.
- Splits long function calls, arrays, and structs using
gmlFormatter.printWidth. - Enforces braces around single-statement
if/elsebodies. - Adds missing semicolons to ordinary statements.
- Supports document formatting, range formatting, formatter debug info, setup diagnosis, formatted diffs, skipped-format explanations, workspace dry runs, and a default-formatter setup command.
- Includes formatter preview, safe cleanup preview/apply, and a readability workflow that groups safe fixes separately from refactor suggestions.
- Indexes GameMaker projects from
.yyp,.yy, and.gmlfiles for resource completions, built-in hovers, signature help, definitions, references, rename, workspace symbols, typo suggestions, inferred resource/value types, and unresolved-resource diagnostics. - Builds a project graph with room instances, resource usage, unused-resource hints, and resource type-mismatch checks.
- Includes corpus scanning, fixture approval, check/write, project snapshots, generated fuzzing, debug-format, and local playground CLI tools.
- Includes a VS Code formatter playground webview with AST, comments, parser, and safety output.
- Adds a bundled language server for diagnostics, document symbols, workspace symbols, semantic tokens, completions, hovers, signatures, definitions, references, and rename.
- Uses generated GameMaker API data for built-in completions, hover docs, signatures, argument diagnostics, resource argument hints, and event-aware warnings.
- Adds smart expression tools, state-machine analysis, a scene-flow view, cutscene timeline notes, state enum previews, scene-note generation, Project Doctor, and a GameMaker project map.
- Adds object-event maps, maybe-uninitialized instance-variable hints, globals reports, and resource rename previews.
- Keeps dialogue/localization checks as optional project-pattern analysis instead of treating project-specific systems as first-party GameMaker features.
- Adds inline code lenses for scene states, branch-heavy conditions, and repeated expressions.
- Adds
Explain This File,Installation Doctor, andReport Formatter Bugcommands. - Includes syntax highlighting, semantic tokens, snippets, folding, bracket matching, comment
toggling, and indentation rules for
.gml. - Offers one-click onboarding when a
.gmlfile opens and this extension is not the default formatter. - Preserves preprocessor lines such as
#macroand#region. - Supports spaces or tabs, configurable indent size, trailing whitespace trimming, and blank-line limits.
Settings
{
"gmlFormatter.indentSize": 4,
"gmlFormatter.useTabs": false,
"gmlFormatter.printWidth": 100,
"gmlFormatter.trailingCommas": false,
"gmlFormatter.multilineFunctionCalls": "auto",
"gmlFormatter.style": "readable",
"gmlFormatter.safety": "ast-and-trivia",
"gmlFormatter.smartSimplify": "suggest",
"gmlFormatter.projectRules": {
"enableProjectPatternAnalysis": false,
"stateVariables": ["fase", "phase", "state"],
"languageVariables": [],
"requiredLanguages": [],
"dialogueObjects": []
},
"gmlFormatter.mode": "file",
"gmlFormatter.trimTrailingWhitespace": true,
"gmlFormatter.maxBlankLines": 2,
"gmlFormatter.readableSpacing": true,
"gmlFormatter.onboarding.enabled": true
}
Style presets:
readable: beginner-friendly default with braces, semicolons, normalized comments, operator spacing, readable blank-line separators, and multiline layout.compact: keeps the same safety expectations while using fewer blank-line separators.strict: readable formatting with the strictest trivia safety mode by default.repair: parse-only safety for damaged snippets and manual recovery work.opinionated: compatibility alias for the readable preset.minimal: lower-churn formatting with fewer automatic rewrites.preserve: keeps more whitespace choices intact.gameMakerStudio: a wider, GameMaker-like preset.
Project pattern rules:
stateVariablescontrols generic switch/state-machine detection.enableProjectPatternAnalysisturns on optional project-specific checks such as dialogue/localization patterns.languageVariables,requiredLanguages, anddialogueObjectsare empty by default because those systems are project conventions, not standard GameMaker APIs.
Safety modes:
ast-and-trivia: reparse formatted output, compare the formatter-owned AST, and verify comment/string preservation.ast-equivalence: reparse formatted output and compare the formatter-owned AST.trivia-strict: AST/trivia safety plus stricter comment anchor checks.parse-only: require only parser success before and after formatting.off: skip the post-format safety gate.
Development
Requirements:
- VS Code 1.90 or newer
- Node.js 20 or newer
- pnpm 9 or newer
Install dependencies:
corepack enable
pnpm install
Build and test:
pnpm test
Regenerate the bundled GameMaker API knowledge after editing data/gml-builtins.seed.json or after
importing a fuller JSON data source:
pnpm generate:gml-knowledge
The official GameMaker manual publishes the GML reference as documentation pages. This repository keeps the extension data as importable JSON so the knowledge pack can be expanded without wiring every built-in manually in TypeScript.
Format the repository's TypeScript, JSON, Markdown, and scripts:
pnpm format
pnpm format:check
Package a local VSIX and install it into VS Code:
pnpm package
code --install-extension gamemaker-toolkit-0.10.1.vsix --force
On Windows, run the same commands from PowerShell, Command Prompt, or Git Bash after installing Node.js and VS Code. The package scripts use Node-based runners, so they do not require Unix shell syntax.
GitHub Releases
Tagged releases create a VSIX automatically through GitHub Actions:
git tag v0.10.1
git push origin v0.10.1
The release workflow runs the same pnpm package:check gate before attaching the .vsix file to
the GitHub release.
If the repository has VSCE_PAT and OVSX_PAT secrets configured, the release workflow also
publishes the same VSIX to the VS Code Marketplace and Open VSX.
Continuous Integration
CI runs on Ubuntu, Windows, and macOS with Node.js 20 and 22. It checks formatting, tests, fixtures, public fixtures, fuzzing, and VSIX packaging.
A separate extension-host smoke test runs the extension inside VS Code on the public fixture corpus on Linux and Windows:
pnpm test:extension-host
Commands
GML: Format DocumentGML: Format With Lexical FallbackGML: Show Formatter Debug InfoGML: Make This The Default FormatterGML: Diagnose Formatter SetupGML: Explain Why This File Was Not FormattedGML: Explain ProblemGML: Format and Show DiffGML: Preview Format ChangesGML: Format Workspace Dry RunGML: Open Formatter PlaygroundGML: Analyze Current FileGML: Project DoctorGML: Explain Expression Under CursorGML: Simplify Selected ExpressionGML: Generate Scene NotesGML: Analyze State MachineGML: Open Scene Flow ViewGML: Open Project MapGML: Rebuild Project IndexGML: Go To ResourceGML: Export Dialogue CSVGML: Preview Safe Cleanup FixesGML: Apply Safe Cleanup FixesGML: Make This Code Easier To ReadGML: Explain This FileGML: Report Formatter BugGML: Installation DoctorGML: Open Object Event MapGML: Open Cutscene TimelineGML: Preview State EnumGML: Preview Resource RenameGML: Open Globals ReportGML: Minimize Formatter Bug
Quality Gates
The test suite includes inline regression tests, golden fixtures in test/fixtures, parser-error
refusal checks, and idempotency checks.
Useful local checks:
pnpm fixtures:test
pnpm fixtures:update
pnpm corpus /path/to/GameMaker/project
pnpm corpus /path/to/GameMaker/project --safety ast-equivalence
pnpm check /path/to/GameMaker/project
pnpm write /path/to/GameMaker/project
pnpm fuzz
pnpm analyze /path/to/file-or-project
pnpm project-index /path/to/GameMaker/project
pnpm dialogue-export /path/to/file-or-project
pnpm simplify-expression "ready == true"
pnpm snapshot:create /path/to/GameMaker/project chessworld
pnpm snapshot:test chessworld
pnpm snapshot:update chessworld
pnpm debug-format /path/to/file.gml
pnpm playground
pnpm public-fixtures:test
pnpm test:extension-host
pnpm check is the CI-style dry run. It exits non-zero if files would change or if parsing, safety,
or idempotency checks fail.
pnpm write formats files in place. Use it only when you intend to update the project.
pnpm corpus is stricter than a simple dry run: it formats every .gml file, reparses the result,
formats again, and verifies idempotency. By default it uses the same AST-plus-trivia safety as VS
Code. Use --safety ast-equivalence when you want to measure the structural formatter pass while
still allowing files with known comment-trivia issues to be skipped by normal Format Document.
pnpm snapshot:create writes ignored project snapshots under test/corpus-snapshots/<name>.
snapshot:test compares the current formatter output against that snapshot, and snapshot:update
refreshes it.
pnpm fuzz runs fixed and generated snippets through parse, format, reparse, AST safety, and
idempotency checks.
pnpm analyze runs the smart analyzer over one file or a folder and reports confidence, findings,
state machines, dialogue cases, magic numbers, suspicious names, and repeated expressions.
pnpm project-index reads .yyp, .yy, and .gml files and reports resources, symbols, rooms,
resource references, inferred types, resource usage, type mismatches, and unresolved resource
references.
pnpm dialogue-export writes dialogue analysis as CSV.
pnpm simplify-expression runs the same expression simplifier used by the VS Code command/code
action.
pnpm public-fixtures:test runs corpus, analyzer, and project-index checks against the public
fixtures in public-fixtures/, including a tiny room/object/sprite project with an intentional
resource typo.
Smart Analysis
The analyzer is intentionally separate from Format Document. Formatting remains conservative and behavior-preserving; smart rewrites are exposed as commands or code actions.
Current analysis features:
- formatter confidence with parser, AST, comment, and string preservation checks
- comment preservation audit
- string literal preservation audit
- magic-number detection
- constant arithmetic detection for tuning values such as
(46 / 2025) - file metrics for branch/condition score, nesting, function count, code lines, and comment lines
- per-line branch contributors so reports can show which exact condition or case caused the score
- TODO/FIXME/BUG/HACK/NOTE comment detection
- asset-reference extraction for common sprite, sound, object, room, path, font, and timeline usages
- suspicious-name detection such as
chioces->choices - duplicate-case and unreachable-flow warnings
- empty branch detection
- repeated-expression detection
- state-machine analysis for variables such as
fase,phase, andstate - Mermaid state-machine graph generation
- dialogue checks for
LEN,text,face,choices,WN, missing language branches, and empty language branches - scene notes generated from switch-case comments
- beginner-friendly explanations for warnings, including what happened, why it matters, and what to do next
- GameMaker resource index from
.yyand.yypfiles
Project Intelligence
The extension builds a lightweight project index from workspace files. It powers:
- resource-name completions
- built-in function/constant completions
- function, macro, enum, and resource workspace symbols
- hover docs for common GameMaker built-ins
- go-to-definition for indexed resources and symbols
- find-references for resource usage in common calls
- unresolved-resource diagnostics
- likely-resource suggestions for unresolved resource names
- a project-map webview with resource/reference counts
- Project Doctor for formatting confidence, missing resources, branchy lines, and beginner-friendly next steps
- dialogue CSV export for translation review
Smart expression tools can:
- remove comparisons to
true/false - remove arithmetic identities such as
+ 0,* 1,/ 1 - simplify double negation
- convert
x - -1intox + 1 - detect repeated factors and suggest
sqr(...)or local extraction - explain expression shape, detected patterns, plain-English meaning, and a fully parenthesized form
Marketplace Checklist
For Marketplace releases, the preferred public story is:
- safe formatting through parser, AST, comment, and string checks
- beginner-friendly diagnostics with quick fixes and explanations
- GameMaker project awareness for
.yyp,.yy, resources, scripts, and events - scene-flow tooling for
switch (state)/switch (fase)cutscene code - public fixtures and extension-host smoke tests for clone-and-run confidence
Library API
The formatter core exports source-level helpers from src/formatter.ts:
parseGml(source);
formatGml(source, options);
formatGmlDocument(source, options);
checkGml(source, options);
getGmlFormatterDebugInfo(source);
analyzeGmlSource(source, options);
simplifyExpressionText(source);
analyzeExpressionAtText(source);
The CLI and VS Code extension are wrappers around the same engine.
Troubleshooting
If normal Format Document does not run this extension:
- Open a
.gmlfile. - Run
GML: Diagnose Formatter Setup. - Check the language ID and default formatter line in the
GameMaker Toolkitoutput channel. - Run
GML: Make This The Default Formatter. - Reload the VS Code window if an older VSIX was already active.
If a file is skipped:
- Run
GML: Explain Why This File Was Not Formatted. - Fix parser errors first.
- If the safety gate refuses the file, inspect the semantic mismatch before lowering
gmlFormatter.safety.
Notes
The formatter is intentionally opinionated. It uses the parser CST for statement structure, preserves comments as trivia, reparses the formatted output, and compares a formatter-owned AST before returning edits in the default safety mode.