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.
Install and enable
Section titled “Install and enable”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.
- 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.
- Press Ctrl+Shift+P, run Extensions: Install from VSIX…, and select
eclipse-modding-0.1.0.vsix. Reload when prompted. - Open the folder containing your
mod.toml. - Run Eclipse Modding: Enable in This Folder.
- 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.
Create a new mod
Section titled “Create a new mod”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.
Your mod’s files and text
Section titled “Your mod’s files and text”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.
Core content
Section titled “Core content”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(", typecore:to see the IDs that lookup accepts, with each entry’s English name. The same works for fields such astemplate,locationandfights.patch { target = … }. - Fields that take a plain name, such as
tactic,subtype,avatarandskeleton, suggest the game’s names directly.subtypeonly 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.
Write behaviors
Section titled “Write behaviors”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.
Understand warnings
Section titled “Understand warnings”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.
Snippets and settings
Section titled “Snippets and settings”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.
What the editor can’t check
Section titled “What the editor can’t check”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.
Check patches against vanilla moves
Section titled “Check patches against vanilla moves”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 = "ortarget = ", 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 forinterval_start,interval_endandremove_interval, its sound names forsound_frame, its currenthit,inputandanimationvalues, and native template names forcore_templates. - The game rejects a patch whose
expectedvalue 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.
Edit moveset files
Section titled “Edit moveset files”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.
See what your mod changes
Section titled “See what your mod changes”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:
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.
Find conflicts with other mods
Section titled “Find conflicts with other mods”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.