Skip to content

Repository files navigation

SeiunEngine Lua / HScript / Haxe

Completions, hover docs, signature help, per-version API filtering and syntax highlighting for SeiunEngine (Psych Engine 0.6.3 based) mod scripts.

Features

  • Completions — functions, global variables, callbacks and Haxe classes for both Lua and HScript files, filtered by the active engine version.
  • Hover documentation — signature, bilingual descriptions (following the VS Code UI language), category and per-version availability badges ([063] [073] [104] [SEIUN]); parameter names are highlighted inside signatures.
  • Signature help — parameter name, type, optional/default markers and parameter descriptions when the data provides them.
  • Version-aware API filtering — target Psych Engine 0.6.3 / 0.7.3 / 1.0.4 or SeiunEngine. APIs unavailable in the active version are greyed out and annotated (or hidden entirely).
  • require() / import() path completion — module names (lib.utils) and file paths (lib/utils.lua) following the engine's documented search order.
  • Code-block ergonomics — typing inside runHaxeCode(, runHaxeFunction( or runLuaCode( offers a [[ ... ]] long-bracket snippet, and the content inside the brackets is syntax-highlighted as HScript / Haxe or Lua instead of a plain string.
  • Hook skeletons with real parameters — the Insert hook / callback skeleton command (or the bundled snippets) inserts function goodNoteHit(note, direction, noteType, isSustainNote) ... end with the parameters extracted from the engine source, instead of an empty stub.
  • Object-tag completions — tags defined by makeLuaSprite('bg', ...) / makeLuaText('scoreTxt', ...) are completed inside tag-consuming calls like setProperty(", playAnim(" and setTextString(".
  • Target-version status bar — the active file's detected target version is shown in the status bar; click it to switch auto / 063 / 073 / 104 / seiun without opening settings.
  • Diagnostics — hints for calls that do not exist in the active target version; warnings for pack.json files that declare unsupported versions; errors for unbalanced Lua end / until blocks (missing or extra end, misplaced until).
  • Syntax highlighting without fighting vshaxe — Lua is contributed as a language with every engine API call highlighted in the engine's cyan-blue and hook/callback definitions (function onCreate(), onUpdate, …) in a dedicated pink. .hx files are fully left to the official Haxe extension (vshaxe): this extension only injects the Seiun API cyan and hook pink into source.hx and never ships or overrides a Haxe grammar. Standalone HScript files (.hscript / .hsc / .hxs — extensions vshaxe does not claim) keep the bundled lightweight HScript grammar (comments, $var / ${expr} interpolation, keywords, types, functions, operators) with the same two colors.
  • Localized UI — English and Simplified Chinese via package.nls.json / package.nls.zh-cn.json.

Requirements

  • Visual Studio Code 1.75.0 or newer.
  • The official Haxe extension (vshaxe, nadako.vshaxe) is recommended and declared as a dependency: .hx Haxe syntax coloring and the runHaxeCode([[ ... ]]) embedded-code highlighting rely on it (VS Code offers to install it automatically). Without it, Lua / HScript features and .hx completions, hover and signature help still work.

Installation

From the VSIX package

  1. Build the package (see Development) or download a pre-built vscode-seiun-lua-<version>.vsix.
  2. In VS Code, open the Extensions view (Ctrl+Shift+X), open the ... menu and choose Install from VSIX..., then select the file.

From source (F5)

cd tools/vscode-seiun-lua
npm install
npm run compile

Open the tools/vscode-seiun-lua folder in VS Code and press F5 to launch an Extension Development Host.

Quick start

  1. Open a mod folder in VS Code (one with a pack.json is all you need).
  2. In a .lua file, type setVar(, runHaxeCode( or require("; in a .hx file, type function onCreate() or setVar(. You get completions, signature help and hover documentation, and API calls are highlighted in teal so they stand out from your own code.
  3. Set seiunEngine.targetVersion to 063: changeDiscordPresence (0.7.3+) is now annotated as unavailable (or hidden with seiunEngine.showIncompatible: false). Switch to seiun to see LuaApi.addLuaFunction and import().
  4. After updating the API data file, run SeiunEngine: Reload API data from the command palette.

Extension settings

Setting Default Description
seiunEngine.targetVersion auto API filtering target: auto, 063, 073, 104 or seiun.
seiunEngine.showIncompatible true Show APIs unavailable in the active version (annotated) instead of hiding them.
seiunEngine.apiDataPath "" Absolute path to an api.js / JSON API data file.
seiunEngine.enableDiagnostics true Enable compatibility hints and pack.json warnings.

How version detection works (auto)

The extension walks up from the current file to the nearest pack.json (the mod-root marker) and applies the same semantics as source/backend/ModConfig.hx:

  • A textual engineVersion / psychEngineVersion field wins: 0.6.3063, 0.7.3073, 1.0.4104, seiunseiun.
  • Otherwise apiVersion / API_VERSION (integer) > 0 is treated as a SeiunEngine mod; 0 or missing means "legacy, assumed compatible" (no filtering).
  • If nothing can be detected, all APIs are suggested.

Note: Psych Engine 0.7.x uses a different apiVersion convention. For pure Psych mods without an engineVersion field, add "engineVersion" to pack.json or set seiunEngine.targetVersion explicitly.

Syntax highlighting

  • Lua is contributed as a language by this extension, so it shows up in the Extensions view and the language picker. The built-in Lua grammar stays active; on top of it:
    • every engine API function call — setVar(, makeLuaSprite(, import(, … — is highlighted in a soft cyan-blue (support.function.seiun.lua, #4FC3F7), echoing the engine's cyan-blue identity without being garish;
    • hook/callback definitions — function onCreate(), function onUpdate(elapsed), function goodNoteHit(note), … — are highlighted in the engine's pink accent (entity.name.function.hook.lua, #FD719B).
  • Haxe (.hx) is left to the official Haxe extension (vshaxe): its haxe language and source.hx grammar keep full control of classes, types, string interpolation, conditional compilation and everything else. This extension only injects two things:
    • engine API function calls (setVar(, getProperty(, …) get support.function.seiun.haxe (cyan-blue #4FC3F7 by default);
    • hook definitions (function onCreate(), function onUpdate(elapsed), …) get entity.name.function.hook.haxe (pink #FD719B by default) while the function keyword keeps vshaxe's own color.
  • HScript (.hscript / .hsc / .hxs — extensions vshaxe does not claim, so there is no conflict) is associated with the seiun-hscript language and uses the bundled TextMate grammar (source.hscript): comments, strings with $var / ${expr} interpolation, keywords, types, function definitions/calls and operators, with the same cyan-blue API calls and pink hooks.

Both lists are generated from the bundled data/api.js (311 API callables for Lua, 310 for HScript, 53 hooks including onCreate, which the engine calls but is missing from the data). They stay in sync automatically. require keeps its standard Lua built-in color and import keeps its HScript keyword color.

Code strings embedded with long brackets get their own treatment: runHaxeCode([[ ... ]]) and runHaxeFunction([[ ... ]]) tokenize the content with the official Haxe grammar (source.hx, active when vshaxe is installed) — keywords, types, strings and cyan-blue API calls included — and runLuaCode([[ ... ]]) applies a lightweight Lua highlight (comments, strings, numbers, keywords, API calls). A completion snippet inserts the brackets for you.

Wrapped forms such as runHaxeCode(string.format([[ ... ]], 600, 700)) are also recognized and the content is still highlighted as Haxe.

Commands

  • SeiunEngine: Insert hook / callback skeleton — pick a hook from the list (bilingual descriptions, version badges) and insert a complete skeleton with the engine's real parameters.
  • SeiunEngine: Switch target engine version — quick pick for auto / 063 / 073 / 104 / seiun; the status bar is the one-click entry point.
  • SeiunEngine: Reload API data — reload api.js after updating the data.
  • SeiunEngine: Open settings panel — a graphical configuration page (target version, toggles, colors, data source, quick actions); also reachable from the ⚙ status-bar button at the bottom.

Snippets

Bundled snippets cover the common hooks (onCreate, onUpdate, onStepHit, onSongStart, onTimerCompleted, goodNoteHit, noteMiss, onKeyPress, …), runHaxeCode([[ … ]]) / runLuaCode([[ … ]]) long-bracket calls, sprite/text creation, key-press blocks, tweens and a require-able module template.

The cyan-blue / pink colors are contributed as defaults through editor.tokenColorCustomizations, tuned for dark themes, and shared across Lua / HScript / Haxe files. To use different colors, add your own rules for the support.function.seiun.* and entity.name.function.hook.* scopes in your settings.

No manual language-mode switching is needed for .hx files: with vshaxe installed they are automatically Haxe. Even without vshaxe, completions / hover / signature help still work through the .hx filename fallback — only the runHaxeCode([[ ... ]]) embedded code loses its Haxe highlighting.

Data source

The extension ships its own copy of the engine API data (data/api.js, the four-engine-version API matrix) and never parses engine source or depends on the engine repository. Lookup order:

  1. seiunEngine.apiDataPath (absolute path);
  2. the copy bundled with the extension (data/api.js).

To refresh the bundled copy, replace data/api.js with the new API data file.

Development

npm run compile   # generate syntax assets + copy data + TypeScript build
npm test          # 80 unit/integration tests (node:test, no VS Code needed)
npm run package   # produce the .vsix

The test suite covers API data parsing and version matrices, signature parsing, call-context scanning, module path completion, version filtering, real TextMate tokenization (Lua injections, Haxe injections on top of a fixture of the official vshaxe source.hx grammar, and runHaxeCode embedding) and the release acceptance scenarios.

Known issues

  • Callbacks in the data have no parameter info, so signature help is not available for them (completion and hover still work).
  • Some parameter descriptions in the upstream data are missing or mismatched; the extension matches by name first and by position as a fallback.
  • require() / import() path completion only works when the call and the opening quote are on the same line.
  • Lua block comments (--[[ ... ]]) are not recognized by the completion/diagnostic scanners.
  • The Lua block-balance check is a heuristic: it understands strings, long strings/comments and -- line comments, but does not parse the full Lua grammar (for example, --[[ nesting is not handled).
  • Embedded code regions (runHaxeCode([[ ... ]])) close at the first ]]; nested [[ inside the embedded code is not supported. The runLuaCode embedding is a lightweight subset; runHaxeCode needs vshaxe installed for the embedded Haxe highlighting (otherwise the content stays a plain string); API calls inside the embedded code may carry the seiun.lua scope name (its default color is identical to seiun.haxe).
  • Object-tag completion only scans the current file; tags defined in other scripts are not suggested.
  • The version-incompatibility diagnostics are heuristic (regex-based with string/comment awareness).

Release notes

See CHANGELOG.md in the repository.

License

Released under the MIT License (see LICENSE).

About

SeiunEngine VS Code extension

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages