Skip to content

VS Code IntelliSense

Eclipse Modding is a VS Code extension for writing mods. As you type, it suggests API functions, table fields, your mod’s files and the game’s own content. It also flags mistakes such as a missing permission or a misspelled ID before you start the game.

The extension is installed from a .vsix package, not the Marketplace. Get it from a successful Modding editor workflow artifact, or build it using the source README.

  1. Install Lua by sumneko in VS Code. 3.19.1 is the currently tested version; choose it with the gear menu > Install Another Version if needed.
  2. Press Ctrl+Shift+P, run Extensions: Install from VSIX…, and select eclipse-modding-0.1.0.vsix. Reload when prompted.
  3. Open the folder containing your mod.toml.
  4. Run Eclipse Modding: Enable in This Folder.
  5. Begin your Lua script with:
local sf2 = require("sf2")

Type sf2. and press Ctrl+Space. Choose a module, such as items, and type another dot to see its functions. Hover a function for its requirements and a link to its reference page. Inside a call, Ctrl+Shift+Space opens parameter hints.

Run Eclipse Modding: Create Mod. Enter a unique lowercase mod ID, display name and author name, then choose a parent folder. The command creates a new subfolder and opens it in another VS Code window. Existing folders are never overwritten.

The new mod contains a complete Training Blade: manifest, Lua script, translation, texture, sprite descriptor and editor settings. Follow Your first weapon to understand each file and try it in Eclipse. To rename the weapon, edit weapon.training_blade in localizations/eng.toml.

For larger, working examples, see Working examples.

Inside a lookup string, press Ctrl+Space to choose a matching file from your mod:

local icon = sf2.assets.sprite("sprites/weapon")
local name = sf2.localization.key("weapon.training_blade")

Press F12 on the string to open the file. Hover a translation key to read its translations. Suggestions also work through local aliases such as local assets = sf2.assets.

The extension knows every ID in the core catalog: the game’s items, perks, fights, warriors, arenas, sounds, models and icons.

  • Inside a lookup such as sf2.items.get(", type core: to see the IDs that lookup accepts, with each entry’s English name. The same works for fields such as template, location and fights.patch { target = … }.
  • Fields that take a plain name, such as tactic, subtype, avatar and skeleton, suggest the game’s names directly. subtype only offers subtypes that fit the item you are registering.
  • Hover a core ID to see what it is.
  • An ID that doesn’t exist is underlined, with the closest real IDs in the message. A core ID written without its core: prefix is flagged too; press Ctrl+. to add it.

Icons inside atlases are only partly known to the catalog, so an icon name inside a known atlas is never flagged.

Type eclipse-behavior or eclipse-stateful and accept a snippet. Callback arguments are typed: fighter: suggests what a fighter can do, and event. suggests the event’s fields. A stateful behavior’s self.state completes the state fields you declared.

Attach the returned behavior handle to a perk, enchantment or rule to use it in a fight. The extension warns when an operation is used in a callback that can’t run it, for example scaling damage outside on_damage_resolving. See combat callbacks for which callback to use.

Open View > Problems. The Lua language server checks names, argument types, required fields and handle kinds. Eclipse Modding adds checks for:

  • Missing files, wrong asset kinds and undeclared dependencies.
  • Core IDs that don’t exist or lack their core: prefix.
  • Missing permissions (capabilities) for the API calls and fighter methods you use.
  • Invalid literal prices, and operations in a callback that can’t run them.
  • Manifest fields, duplicate IDs, missing entrypoints, sprite textures, unsupported audio formats and malformed translation files.

For a missing capability, press Ctrl+. and choose Declare … in mod.toml. Save the manifest before running the game.

Eclipse Modding: Validate Open Mod rechecks the open Lua files with their mod’s manifest, assets and translations, then opens Problems. A syntax error pauses these checks until the file parses again.

Type eclipse- and press Ctrl+Space for weapon, behavior, stateful behavior, damage modifier, saved state, perk, sprite, localization and import snippets. Replace the placeholders, add any files they name, and declare the capabilities they need.

Enabling the extension keeps your other Lua libraries and updates an existing .luarc.json or .luarc.jsonc without losing comments. Select Lua 5.2 as the Lua runtime; Create Mod sets it for you. Disable in This Folder removes the extension’s library and turns off its checks.

If suggestions disappear after an update, run Enable in This Folder again. Check Output > Eclipse Modding for indexing errors and Output > Lua for language server errors.

The extension reads your source; it doesn’t run it. It can’t follow IDs or references built at runtime (for example "WaspFly_" .. suffix), decode images, models or sounds, or tell how a fight will play out. A clean Problems panel means the mod is well formed, not that it works: always try it in Eclipse.

sf2.moves.patch, sf2.moves.replace, sf2.moves.extend_item_lock, sf2.moves.remove_perk_lock and sf2.moves.extend_perk_lock name an existing native move: one of the base game’s moves, spelled exactly, with matching case. The extension ships the base game’s move data so it can help with those names.

  • Inside move = " or target = ", press Ctrl+Space to choose from every native move. Hover a name to see its animation file, priority, templates, input keys, intervals and scheduled sounds.
  • Once the target is known, completion also offers its expected_file, the interval names for interval_start, interval_end and remove_interval, its sound names for sound_frame, its current hit, input and animation values, and native template names for core_templates.
  • The game rejects a patch whose expected value does not match the native move. The extension compares literal values with the same base data and warns first:
sf2.moves.patch {
move = "HighKick",
-- Warning: Vanilla "HighKick" has priority 110, not 100; the runtime rejects this patch.
priority = { expected = 100, value = 90 },
}

Guards are checked for interval bounds, the hit reaction, sound frames, the input key, priority, the animation file, interval removal and addition, the replacement expected_file, playback_rate limits, every intervals selector and every attacks field (id, frames, damage, damage terms, edges, impulse and hit). A misspelled move name is reported as unknown. Hovering a move shows each interval as Type/Name start..end, with open for an interval that runs to the end of the move, which is the same notation intervals selectors use.

These checks read literal strings and numbers only, so a name built at runtime (for example "WaspFly_" .. suffix) is not checked. They model the base game: if another enabled mod replaces the same move with sf2.moves.replace, the game checks your guards against that replacement instead. The game remains the authority.

Moveset files (movesets/*.json) get completion and hover descriptions for every field from a JSON Schema, plus the same checks as Lua: unknown fields, wrong value types, duplicate fields, vanilla guard mismatches and missing content.patch or core dependencies appear in Problems with their line. Forks are checked against the source move’s weapon lock: forking a subtype the move is not locked to, or the only subtype of its lock, is reported before you launch.

Run Eclipse Modding: Show Move Changes from a file in your mod. A report opens with one section per native move your mod touches:

  • for sf2.moves.patch, a table of each field’s vanilla value beside the value after your patch, followed by any guard problem;
  • for sf2.moves.replace, the vanilla animation, priority, templates, intervals, key conditions and sounds, with every field your replacement omits marked omitted — not inherited. A replacement keeps nothing from the original move, so this list shows exactly what you must define again;
  • item and perk lock changes, and the exclusive claims described below.

The same report is available without VS Code. From the repository root:

Terminal window
node Tools/ModdingEditor/scripts/report.cjs path/to/my.mod --mods path/to/Mods

--mods is optional and may repeat. The command exits with status 1 when it finds an unknown move, a guard mismatch or a conflict, so a mod repository can run it in CI.

Some changes can have only one owner. If two enabled mods claim the same one, the mod that registers second fails to load as a whole (see Combine mods). The extension compares these literal claims across every mod in your workspace:

Claim One owner per
sf2.moves.patch native move
sf2.moves.replace native target
sf2.assets.replace target asset (case-insensitive path)
sf2.localization.patch target and language pair
sf2.battles.patch target battle position

A conflict appears as a warning on your claim, naming the other mod and its file. Claiming the same thing twice inside one mod is reported too. Two mod folders with the same ID in one parent folder are flagged on mod.toml; the game rejects duplicate IDs in one mods folder. Copies of the same mod in different folders, such as a backup, are not treated as conflicting with each other.

To include mods that live outside your workspace, set Eclipse Modding: Mods Root (eclipseModding.modsRoot) to the game’s Mods folder, either absolute or relative to your workspace folder. Those mods are read, never changed.

The extension cannot know which mods a player enables, so it treats every indexed mod as enabled. Claims built from computed values, item setters that take an item handle, and fight rule patches are not compared; the game still enforces their rules.