Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>Alamo Engine Tools - Empire at War EditNew to Visual Studio Code? Get it now.
Alamo Engine Tools - Empire at War Edit

Alamo Engine Tools - Empire at War Edit

Preview

Alamo Engine Tools

|
36 installs
| (0) | Free
Editor intelligence for Star Wars: Empire at War and Forces of Corruption mod development - XML completions, diagnostics, hover, go-to-definition, rename, and Lua support.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Alamo Engine Tools - Empire at War Edit

Editor support for Star Wars: Empire at War and Forces of Corruption mod development.

  • XML and Lua: completions, hover documentation, cross-file diagnostics, navigation, rename
  • Story tooling: campaign navigator, story graph, cross-language symbols
  • Localisation editor
  • Model preview
  • Lua debugger

Preview release. Not every feature is complete; behaviour may change between versions. Report problems on the issue tracker.


Requirements

  • Visual Studio Code 1.107 or later
  • Windows 11 (x64); Windows 10 is unsupported (end of mainstream support October 2025)
  • The PG.StarWarsGame.LSP server binary, self-contained; no .NET runtime needed

Getting started

1. Download the server

From the Releases page:

  • aet-eaw-edit-x.x.x.vsix - the extension, for manual installs
  • PG.StarWarsGame.LSP.Server-x.x.x-win-x64.zip - the language server; extract to a permanent folder, e.g. C:\tools\aet-lsp\

2. Configure the extension

Setting Value
aet-eaw-edit.lsp.executable Full path to PG.StarWarsGame.LSP.Server.exe
aet-eaw-edit.lsp.enabled true

Activation: an open XML or Lua file, or a .pgproj in the workspace. A missing or mismatched server binary is reported with a link to the matching release.

3. Create a mod project file

.pgproj at the root of the mod workspace:

{
  "_type": "aetswg.ModProject",
  "_typeVersion": "aetswg-1.0.0",
  "name": "My Mod",
  "directories": {
    "xml":     ["data/xml"],
    "scripts": ["data/scripts"],
    "art":     ["data/art"],
    "audio":   ["data/audio"]
  },
  "localisation": {
    "type": "CSV",
    "directory": "data/text"
  },
  "projectReferences": []
}
  • _type and _typeVersion - the file's format, written and maintained by the extension. A file without them loads as format 1.0.0; a newer format than the extension understands is refused.
  • Paths are relative to the .pgproj.
  • projectReferences - other .pgproj files whose symbols the mod inherits, e.g. a base game project.
  • localisation.type - CSV, DAT, XML or NLS.
  • icons (optional) - megaTexture (atlas pair without extension, e.g. data/art/textures/mt_commandbar) and sourceRoots (loose icon folders). Omitted: engine convention.

Upgrading from 0.1.x

Required .pgproj change. Localisation moved from directories to its own node:

   "directories": {
     "xml": ["data/xml"],
     "scripts": ["data/scripts"],
     "art": ["data/art"],
-    "audio": ["data/audio"],
-    "text": ["data/text"],
-    "textResourceType": "Csv"
+    "audio": ["data/audio"]
   },
+  "localisation": {
+    "type": "CSV",
+    "directory": "data/text"
+  },
   "projectReferences": []

A .pgproj in the old shape fails to load with a notification naming this fix.

One .pgproj per workspace. More than one fails to start with a notification listing them all; remove the extras or open the subfolder holding the one you want.

Clear cached indexes. Delete .aetswg next to every .pgproj and %USERPROFILE%\.aetswg\, then run EaWEdit: Restart LSP Server. Both are rebuilt automatically.


XML features

Indexes the full EaW/FoC object graph across the workspace.

  • Completions - enum values and named objects from the whole workspace
  • Hover - type, description and valid values for tags, enum values and references
  • Diagnostics
    • Unknown references
    • Unknown or misspelled tags, with a suggestion
    • Unnamed objects, missing required tags
    • Type mismatches, malformed values, deprecated fields
    • Duplicate declarations
  • Engine rules - about 150 checks taken from the game's parser and error messages
    • Numeric ranges
    • Tags required or forbidden together
    • Comparisons between tags of one object
    • Variant-inheritance rules
  • Go to definition - F12 / Ctrl+Click, across files
  • Find all references - Shift+F12
  • Rename - F2, workspace-wide
  • Code actions - quick fixes, including creating a missing localisation key
  • Code lens - reference counts above every named object
  • Auto-close tags - on > (needs editor.formatOnType)
  • Linked editing - opening and closing tag renamed together (needs editor.linkedEditing)
  • Variant inheritance - Show Effective Object opens the merged XML of a Variant_Of_Existing_Type object

Lua features

Scripts under the declared scripts directories are indexed and checked.

  • Completion
  • Go to definition
  • Rename, including XML objects referenced from Lua
  • Code lenses, inlay hints, quick fixes
  • Hover and diagnostics (work in progress)

Lua debugger

Work in progress, off by default. Flag: aet-eaw-edit.features.lua.debugger. Requires a debug build of the game with its Lua debug server running; retail builds have none.

With thanks to EvilBobTheBob (@andrewfullard), of Phoenix Rising and EaWX, whose eaw-lua-debugger documented the game's Lua debug server protocol. This debugger was built against that description.

Debug type Empire at War Lua in Run and Debug:

  • Breakpoints in Lua files under the project's script directories
  • Attach to a running game, or launch it with the mod chain
  • Call stack, locals in the Variables view, watches and hovers on plain names
  • Debug Console running Lua in the selected or stopped script
  • Lua Scripts view: every running script instance with its coroutine threads; break in a script or a thread (the game cannot start a script on request)

F5 in a Lua file attaches with the settings below. launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "eaw-lua",
      "request": "attach",
      "name": "Attach to Empire at War (Lua)"
    },
    {
      "type": "eaw-lua",
      "request": "launch",
      "name": "Launch Empire at War (Lua)",
      "program": "${config:aet-eaw-edit.game.executable}"
    }
  ]
}
Attribute Request Default Description
host both aet-eaw-edit.game.luaDebugHost Machine running the game
port both aet-eaw-edit.game.luaDebugPort The game's Lua debug UDP port
sourceRoots both every project layer's script directories Directories the game's script paths map onto, mod first
clientName both AetLuaDebugger:<pid> Client name the game logs
unsafeTableExpansion both aet-eaw-edit.game.unsafeTableExpansion Expand tables in the Variables view
dropDuplicateOutermostFrame both true Drop a duplicated outermost call-stack entry
program launch aet-eaw-edit.game.executable Debug game executable
args launch [] Extra arguments, after the mod chain
cwd launch executable's directory Working directory
modPaths launch built from the project layers MODPATH= entries, leaf first; replaces the chain from the .pgproj
attachTimeoutSeconds launch 60 Attach retry window after launch

Launch and the mod chain

  • One MODPATH= per project layer: mod first, dependencies after
  • The game reads a mod folder as-is, so each layer needs:
    • Its declared directories under its Data/ folder
    • No space in its path
  • A layer that does not comply is refused with the reason
  • modPaths overrides the chain
  • A build step for other layouts is planned (#144)

Lua Scripts view

  • Refresh reloads the list
  • Expanding a script fetches its threads
  • Break actions are greyed out, with the reason in the tooltip, while a script is stopped or a break is already waiting

Limits of the game's debug server, reported rather than hidden:

  • Breakpoint conditions, hit counts and log messages are never evaluated; such breakpoints are reported as not set
  • The whole game freezes while a script is stopped
  • Pause takes effect at the next Lua line of the selected script, or of any attached script
  • Locals are the names found in scope at the stopped line
    • Upvalues resolve to the global of the same name
    • Numbers are reported as integers
  • Tables show as table: 0x... without children unless aet-eaw-edit.game.unsafeTableExpansion is on
    • The game is reported to crash on member text of 255 bytes or more

Suppressing diagnostics

Every diagnostic carries a stable id aetswg-<group>-<number> (e.g. aetswg-004-0001), shown in the Problems panel's Code column.

Quick fixes

Ctrl+. on a problem offers four scopes, narrowest first, none preselected:

  • Suppress ... for this line
  • Suppress ... for this <Unit> / function / chapter - only with an enclosing declaration
  • Suppress ... in this file
  • Suppress ... across the project

Writing directives by hand

Language Comment form
XML <!-- aetswg:suppress aetswg-004-0001 -->
Lua -- aetswg:suppress aetswg-004-0001
Story dialog (.txt) # aetswg:suppress aetswg-004-0001
Keyword Covers
aetswg:suppress the next element (XML), statement (Lua), or command line (dialog)
aetswg:suppress-object the enclosing object element, function, or [CHAPTER n] section
aetswg:suppress-file the whole file

A directive may share a longer comment. A scope with no target (an -object directive outside any object, a trailing directive) covers its own line only.

Project-wide suppressions live in .aetswg/suppressions.json, written by the across the project quick fix. Commit that file.

Lists, wildcards, and reasons

Several ids per directive, comma-separated; a note after reason:::

<!-- aetswg:suppress aetswg-010-0002, aetswg-010-0003 reason:: deliberate shadow, cleared with the art team -->

* in place of the number silences a group, e.g. aetswg-004-* for every asset-file check:

Group Covers
aetswg-001-* References that do not resolve
aetswg-002-* Enum values
aetswg-003-* Value format: numbers, booleans, tuples, arity
aetswg-004-* Asset files: models, textures, audio, maps
aetswg-005-* Localisation keys
aetswg-006-* Document structure
aetswg-007-* Cross-tag rules within one object
aetswg-008-* Variant inheritance
aetswg-009-* Story and campaigns
aetswg-010-* Symbols and layers: duplicates, shadowing
aetswg-011-* Engine constraints
aetswg-012-* Syntax errors
aetswg-013-* Suppression comments themselves

Groups classify the problem, not the language: aetswg-001-* covers XML and Lua alike.

When a directive is wrong

  • aetswg-013-0001 - an entry that is not an id or wildcard (typo, or missing leading zeros: aetswg-4-1 for aetswg-004-0001)
  • aetswg-013-0002 - a directive naming no diagnostic

Only the bad entry is rejected; the rest of the list applies. Silence these with aetswg-013-*.

<Override> is not a suppression

<!-- <Override Name="..."/> --> declares intended shadowing of a lower layer, a claim the server checks. Unaffected by suppression.

Dialog quick fixes require aet-eaw-edit.features.dialog.codeActions; the rest of suppression is always on.


Story mode

Campaigns are followed from CampaignFiles.xml through plot manifests to the Story_*.xml thread files and understood as one graph. Opt-in and in development; see the story flags under feature flags.

  • Campaign Editor view
    • Campaigns, factions, galactic plot threads, the faction's battles in play order with their own plot files and the script their manifest attaches beneath them, and the faction's attached Lua scripts
    • Suspended threads marked
    • Click opens the file; a battle opens its graph
  • Story graph - one panel per campaign faction at the galactic level, and one per battle
    • Auto-laid-out event flow with AND/OR junctions and cross-file portals
    • Battles as sub-graphs: the galactic graph shows each tactical mission as one portal that opens the battle's own panel; the battle graph shows the galactic events that link it in and listen for its outcome as portals back, each opening the galactic panel on that event. In Simulation a pick on the portal selects the battle's decision beside the dock instead - fight, auto-resolve, won or lost - and the portal's arrow opens the battle's graph into Simulation. The command palette lists the battles after their faction
    • Node colour by lifecycle: inactive, waiting, armed, fired, disabled
    • Unreachable events dimmed; schema-untested types dashed
    • Filters: name, branch, lifecycle, plot state, the incoming or outgoing chain of one event - inside the panel's scope; the chain runs through a battle's portal
    • Engine links (dash-dot): the links the game makes that no prerequisite writes - a speech or movie to the listener that waits for it to end, a tutorial dialog to the listener for its Continue button, a battle to the galactic listeners for its outcome and for the summary dialog closing. Drawn so a sequence the game plays in order reads in order; never a prerequisite
    • Thread lanes on the galactic graph (Empire at War's acts); disabled inside a battle, which is one plot
  • Params by name - every event and reward slot carries a label from the schema ("Planets", "Flash id", "Required result"); the description with its legend and ranges is the tooltip, and a missing-param warning quotes the same name after the slot
  • Colour key - flyout keying node, border and edge styles, including per-branch hues on zoomed-out nodes
  • Editing (Edit mode)
    • Drag a prerequisite between events
    • Drop event and reward types from the palette
    • Edit names, params, branch, perpetual and dialog in place
    • Staged and applied on save as one workspace/applyEdit; minimal edits; inserted tags in the engine's order
  • Simulation (Simulation mode, flag tools.storySimulator)
    • The campaign runs forward in 1 s ticks by the engine's own event rules: push-based arming, campaign-wide trigger rewards, resets, disables, timers from arming, flag comparisons with the engine's defaults, speech and movie completions owed to the next tick
    • The world is a fact table seeded from the campaign XML - planets and owners, units, tech, credits - written only by rewards and by the author; nothing moves, builds or fights on its own
    • Every trigger the game would decide is a decision for the author: capture a planet, build or destroy a unit, win or lose a battle, send a script event, or assume the trigger met; pickers list what fits the facts first and accept any name
    • Battles run as their own session, as the game plays them: the galactic simulation arms the galactic listeners only. Entering a battle - from its portal, its row in the dock, or the decision that waits on it - opens its panel into Simulation on its own clock, seeded with the galaxy's flags and world, and the galaxy stands still until it resolves. Won or lost, from either panel: the battle's own listeners fire, the flags it wrote cross into the galaxy, and the galactic outcome listeners fire. A rewind replays the outcome as one step without replaying the battle
    • A Continue_Tutorial listener is a decision only while a tutorial dialog shows: the dialog's Continue button is what raises it, a TUTORIAL_DIALOG reward puts the dialog up and continuing closes it. A flag poll that already holds is the clock's work, not a wait: the story is not waiting for input while a chain behind a flag write is still landing
    • Rule out: a decision the author knows will not come in this run (the defeat listener of a battle to be won, say) leaves the list from its flyout. The listener stays armed, as in the game; the Ruled out group at the end of the decisions reverses the call, and the listener firing after all clears it
    • A linked battle waits for its choice, as the game's pending-battle panel does: a LINK_TACTICAL reward makes the battle pending and holds gameplay time - the story keeps running (pushes, flag polls, scripts, generic and GUI events), only STORY_ELAPSED timers stand still. The decision sits on the battle's portal: Fight opens the battle's panel straight into its session, Auto-resolve leaves won or lost and the flag picks to you. A FORCE_CLICK_GUI on the left choice button fights by itself, as the tutorial does, and on the right one auto-resolves. The battle_end_closed listener is the battle's to raise, not a decision, while one is pending or running; a loss that links the same mission again is a new attempt
    • Campaign scripts run as their PGStateMachine: a fired event enters the state, its OnEnter thread sleeps and sends Story_Event ids back into the graph, drawn as state nodes and links
    • Dock header: the tick and what stopped the clock; content: decisions, world, flags, scripts, each row opening beside the dock; foot: the transport - restart, one tick back, play, one tick, run until the story reaches a new decision, a breakpoint or nothing more can happen - with a pace of pulse, step or a custom rate. The clock is never held back by open decisions: a real campaign has hundreds of armed listeners from tick 0
    • Canvas: the flow along the edges, fire counts, gate meters on armed timers and flag checks, breakpoint marks; lenses for the path taken, the flow tints and the script states
    • Trace panel: every transition with its tick, node, cause and source; filter by text or t12 for one tick; copy
    • Breakpoints on any event and on every clock or flag gate; rewind to any tick replays the same answers
  • Large campaigns - lightweight overview when zoomed out, real nodes only for the visible part; 1000+ events stay responsive
  • Campaign diagnostics
    • Dangling or cyclic prerequisites
    • Duplicate event names
    • Prerequisites, reset and disable targets the engine cannot see because they live in another plot file
    • Two events of one name in one plot file
    • Events that can never fire
    • Suspended plots nothing activates
    • Problems bar can follow the branch filter; jumping to a hidden problem lifts it
  • Cross-language symbols
    • Event names, flags and AI-notification ids indexed across XML and Lua
    • Go to definition from Prereq tokens and STORY_AI_NOTIFICATION ids to the Lua Story_Event("...") call
    • F2 renames across threads and scripts
  • Dialog scripts (.txt scripts declared in the .pgproj)
    • Diagnostics
    • Inlay hints with the localisation text of TEXT and TITLE lines
    • Go to definition on speech, movie and sound arguments

Dependency and base-game files are read-only. Node positions, events and junctions, portals and script states alike, persist per campaign faction in .aetswg/story-layout.json.


Model preview

Flag: aet-eaw-edit.features.tools.modelPreview (on by default).

  • Alamo Model Preview editor for .alo models and .ala animations; the file only, no XML
  • Preview Assembled Unit (command and GameObject code lens) - the unit as the game builds it
    • Hardpoints on their attachment bones
    • Movable turrets
    • Firing arcs
    • Team colour
  • Model lens
    • Model tree with per-part visibility
    • LOD and ALT levels
    • Skeleton, cameras, info inspector
    • Scene and light settings
  • Animation lens
    • Clip library by family, action and take
    • The game's loop rule: idle repeats, death does not
    • Transport, playback speed
  • Gameplay lens
    • Attacker weapons and abilities against the unit
    • Shields and hardpoint health
    • Destroy and repair hardpoints, with damage smoke and death clone
    • Damage log naming the armour type per hit
  • Particles - effects, groups and emitters of a particle system
  • Saved shots - captures kept in a set
  • Handoff - Open in AloViewer and Open in Particle Editor via aet-eaw-edit.tools.aloViewerExecutable and aet-eaw-edit.tools.particleEditorExecutable
  • Shaders - Set Up Base Shader Sources fetches Petroglyph's published shader sources into aet-eaw-edit.shaders.directory; never redistributed
  • Game models - require aet-eaw-edit.lsp.source.baseGameDirectory and, for Forces of Corruption, expansionDirectory
  • Energy pool - behind aet-eaw-edit.features.preview.energyPool, off on purpose: the engine implements it, the shipped game disables it
  • Not covered - sounds and animation SFX maps; AloViewer remains the tool for those

Encyclopedia preview

Flag: aet-eaw-edit.features.tools.encyclopedia (on by default). Read-only.

  • Preview Encyclopedia Popup (command and GameObject code lens) - the in-game tooltip card
    • Icon, name, class line
    • Encyclopedia_Text wrapped as the game wraps it
    • Ship names from the game's tables
    • Faction switch
  • Language - aet-eaw-edit.lsp.localisation.language (the game's language, not the extension's)
  • Icons - from the mega texture
    • Game icons baked into the baseline
    • A project's own mt_commandbar (.pgproj icons) replaces them wholesale
    • Missing everywhere: error
    • In sources but not in the mega texture: warning to rebuild

Localisation editor

Flag: aet-eaw-edit.features.tools.localisation. Localisation Editor activity bar view, files grouped into Text files and Credits files; one grid tab per file, splittable side by side.

  • Editing - staged edits, count on Save, one all-or-nothing write; refused if the file changed on disk
  • Validate - without writing; duplicate and empty keys are errors in text files, expected in credits files
  • Rows - right-click menu: add and delete; reorder on credits files
  • Add language - from the game's language list, for formats that hold more than one
  • Fill language - from another language or from the game's own translations
  • Inherited rows - hidden by default, Inherited toggle shows them; Reset to inherited value on overridden rows
  • Filter - plain text, wildcard (*, ?) or regex; scoped to keys, one language or everything
  • Columns - language columns chosen from the header gear; empty languages hidden at first
  • Export to DAT and Convert to another format - from the file's context menu; conversion keeps the original
  • New project - initialise from the EaW + FoC baseline, or import existing files

Saves rewrite changed rows only; untouched rows keep quoting, comments and line endings.

Credits files

Ordered lists that may repeat a key. Rows are addressed by position, so duplicates, spacer rows and order survive editing.

  • Line kinds, offered as tiles to drag into the table:
    • HEADER - label
    • CENTER - name
    • [TBL] - blank spacer
  • Open Credits Preview to the Side and Play Credits Crawl Full Screen play the staged rows as the game does

Detection: engine naming (credits*), or in the .pgproj:

"localisation": {
  "type": "CSV",
  "directory": "data/text",
  "credits": {
    // "convention" (default), "explicit" (only the files listed), or "none"
    "detection": "convention",
    "files": ["rolls.csv"]
  }
}

One format per project: a CSV project's credits file is a .csv. "type": "DAT" projects edit compiled .dat files directly (language from the file name, sort order preserved). Set Localisation Project Format changes the format from the editor.


Commands

Command Palette (Ctrl+Shift+P). Commands of a flagged feature are greyed out until the flag is on.

Command Description Flag
EaWEdit: New Mod Project Creates a .pgproj and initial directories -
EaWEdit: Reload Mod Project Re-reads the .pgproj, re-indexes -
EaWEdit: Re-validate Workspace Re-runs diagnostics in every language -
EaWEdit: Restart LSP Server Restarts the language server -
EaWEdit: Force LSP Startup Runs the startup scan again when a session came up without one -
EaWEdit: Show Effective Object (Variant Inheritance) Merged XML of a variant object tools.variants
EaWEdit: Preview Model Opens a model by file name, without XML tools.modelPreview
EaWEdit: Preview Assembled Unit Opens the GameObject under the cursor, assembled from the XML tools.modelPreview
EaWEdit: Set Up Base Shader Sources Fetches the shader sources into aet-eaw-edit.shaders.directory tools.modelPreview
EaWEdit: Preview Encyclopedia Popup The encyclopedia card of the GameObject under the cursor tools.encyclopedia
EaWEdit: Open Story Graph A faction's story graph tools.storyEditor, story.discovery
EaWEdit: Refresh Story Navigator Rebuilds the campaign tree tools.storyEditor, story.discovery
EaWEdit: New Localisation Project Initialise from baseline, or import tools.localisation
EaWEdit: Initialise Localisation Project from Baseline Starter file from the game baseline tools.localisation
EaWEdit: Import Existing Localisation Files Adopts CSV, XML, Properties or DAT files tools.localisation
EaWEdit: Set Localisation Project Format Writes localisation.type tools.localisation
EaWEdit: Open Localisation Editor Grid tab for a file tools.localisation
EaWEdit: Open Localisation File as Text Plain text editor for a file tools.localisation
EaWEdit: Refresh Localisation Files Re-reads the project's files tools.localisation
EaWEdit: Convert Localisation File to Another Format CSV, XML, Properties or DAT tools.localisation
EaWEdit: Export Localisation to DAT Compiled .dat for a file tools.localisation
EaWEdit: Open Credits Preview to the Side Credits crawl beside the editor tools.localisation
EaWEdit: Play Credits Crawl Full Screen Credits crawl over the editor tools.localisation
EaWEdit: Refresh Lua Scripts Reloads the Lua Scripts view from the game lua.debugger, active session
EaWEdit: Refresh Script Threads Reloads one script's threads (inline) lua.debugger, active session
EaWEdit: Break in Script Break at the script's next Lua line (inline) lua.debugger, game running
EaWEdit: Break in Thread Break at the thread's next Lua line (inline) lua.debugger, game running

Flag column: the feature-flag id without its common prefix.


Settings reference

Language server

Setting Default Description
aet-eaw-edit.lsp.enabled false Enable the language server
aet-eaw-edit.lsp.executable (empty) Path to PG.StarWarsGame.LSP.Server.exe
aet-eaw-edit.lsp.locale en Language of hover text and diagnostics (en, de, fr, es, it, pl, ru)
aet-eaw-edit.lsp.localisation.language ENGLISH Game language for displayed localisation text (hovers, inlay hints, encyclopedia card)
aet-eaw-edit.lsp.debug.traceServer off messages or verbose: LSP traffic in the EaWEdit output channel
aet-eaw-edit.lsp.debug.logLevel Information Detail in the server's own log file; Debug records whether a document reached a sync handler

Game installation and external tools

Never searched for; used only once set.

Setting Default Description
aet-eaw-edit.lsp.source.baseGameDirectory (empty) Empire at War install; models, textures and string table that ship with the game
aet-eaw-edit.lsp.source.expansionDirectory (empty) Forces of Corruption install, searched alongside the base game
aet-eaw-edit.tools.aloViewerExecutable (empty) AloViewer.exe, for Open in AloViewer
aet-eaw-edit.tools.particleEditorExecutable (empty) ParticleEditor.exe, for Open in Particle Editor
aet-eaw-edit.shaders.directory (empty) Base game shader sources (.fx) for the preview; filled by Set Up Base Shader Sources or your own copy
aet-eaw-edit.shaders.sourceUrl (empty) Download location for Set Up Base Shader Sources; empty = Petroglyph's published download
aet-eaw-edit.modVerify.enabled false ModVerify integration
aet-eaw-edit.modVerify.executable (empty) ModVerify executable

Schema

The EaW/FoC XML schema: the newest compatible release, resolved on server start and cached per release; a local copy for offline or pinned use.

Setting Default Description
aet-eaw-edit.lsp.schema.source http http (GitHub) or local
aet-eaw-edit.lsp.schema.localPath (empty) Local schema/eaw/ directory (source local)
aet-eaw-edit.lsp.schema.url (empty) Custom schema index URL (source http)

Baseline

Snapshot of all vanilla EaW and FoC objects and localisation keys, downloaded once to %USERPROFILE%\.pg-swg-lsp\baselines\ and refreshed on new versions. Powers reference validation and the Inherited toggle.

Setting Default Description
aet-eaw-edit.lsp.source.baseline.type http http, local or none
aet-eaw-edit.lsp.source.baseline.localPath (empty) Local baseline file (type local)
aet-eaw-edit.lsp.source.baseline.url (empty) Custom baseline URL (type http)

Development

Setting Default Description
aet-eaw-edit.lsp.devMode.enabled false Start the server from source with dotnet run --project
aet-eaw-edit.lsp.devMode.projectPath (empty) PG.StarWarsGame.LSP.Server.csproj for dev mode
aet-eaw-edit.lsp.debug.waitForDebugger false Start the server with --wait-for-debugger

Localisation editor

Setting Default Description
aet-eaw-edit.localisation.format format-dat Default format for new localisation projects (format-dat, format-csv, format-xml)

Lua debugger

Read only with aet-eaw-edit.features.lua.debugger on; a launch.json attribute overrides the setting of the same meaning.

Setting Default Description
aet-eaw-edit.game.executable (empty) Debug StarWarsI.exe for launch; retail builds have no debug server
aet-eaw-edit.game.arguments [] Extra game arguments, before the mod chain
aet-eaw-edit.game.luaDebugHost 127.0.0.1 Machine running the game (UDP)
aet-eaw-edit.game.luaDebugPort 1234 Lua debug UDP port; the game takes the first free port from 1234 upward
aet-eaw-edit.game.unsafeTableExpansion false Expand tables in the Variables view; the game is reported to crash on member text of 255 bytes or more

Diagnostics

Setting Default Meaning
aet-eaw-edit.diagnostics.workspaceOnStartup false Diagnose every indexed file once the scan finishes, instead of only the files that are opened. Expensive - on the base game, 580 files, that is 18,281 diagnostics and 21.8 MiB the editor holds. Turn it on only when a session has started with no diagnostics at all

Encyclopedia preview

The game sizes the popup's glyphs from the display it runs on, and wraps its body text by character count rather than by measured width - so the card's proportions follow the screen it is drawn for.

Setting Default Meaning
aet-eaw-edit.encyclopedia.screenWidth 1920 Screen width, in pixels, the card is drawn for
aet-eaw-edit.encyclopedia.screenHeight 1080 Screen height, in pixels; this is what sets the glyph size

Story simulation

Setting Default Meaning
aet-eaw-edit.storySimulator.assumeMediaCompletes true A speech or movie a reward starts completes on the next tick, so its STORY_SPEECH_DONE or STORY_MOVIE_DONE listener fires on its own. Off, each is a decision until answered; the game never ends one on a timer. Either way a new speech ends the one still playing and a battle's end ends every speech, as the game does. Takes effect when a simulation starts
aet-eaw-edit.storySimulator.autoResume true When play paused itself for a decision, answering it resumes play

Feature flags

Every feature has a flag. Work-in-progress features default to off. A flag the language server reads restarts it on change; editor-side flags apply at once.

XML:

Setting Default Description
aet-eaw-edit.features.xml.completion true Code completion
aet-eaw-edit.features.xml.hover true Hover tooltips
aet-eaw-edit.features.xml.diagnostics true Diagnostics
aet-eaw-edit.features.xml.goToDefinition true Go to definition
aet-eaw-edit.features.xml.findReferences true Find all references
aet-eaw-edit.features.xml.rename true Symbol rename
aet-eaw-edit.features.xml.codeLens true Code lenses (reference counts, variant links)
aet-eaw-edit.features.xml.inlayHints true Inlay hints
aet-eaw-edit.features.xml.codeActions true Code actions (quick fixes)
aet-eaw-edit.features.xml.linkedEditing true Linked editing of tag pairs (needs editor.linkedEditing)
aet-eaw-edit.features.xml.autoCloseTag true Auto-close tag on > (needs editor.formatOnType)

Lua:

Setting Default Description
aet-eaw-edit.features.lua.completion true Code completion
aet-eaw-edit.features.lua.hover false Hover tooltips (work in progress)
aet-eaw-edit.features.lua.diagnostics false Diagnostics (work in progress)
aet-eaw-edit.features.lua.goToDefinition true Go to definition
aet-eaw-edit.features.lua.rename true Symbol rename, including XML objects referenced from Lua
aet-eaw-edit.features.lua.codeLens true Code lenses
aet-eaw-edit.features.lua.inlayHints true Inlay hints
aet-eaw-edit.features.lua.codeActions true Code actions (quick fixes)
aet-eaw-edit.features.lua.debugger false Lua debugger: debug type, Lua Scripts view, aet-eaw-edit.game.* (work in progress)

Story mode:

Setting Default Description
aet-eaw-edit.features.story.discovery false Follows the campaign story chain and types its files; base of every other story flag (work in progress)
aet-eaw-edit.features.story.graphDiagnostics false Whole-campaign analysis: dangling and cyclic prerequisites, duplicate event names, targets outside their plot file, unreachable events, orphaned suspended plots, tag order, over-long flag names, STORY_GENERIC listeners for a name the game never raises (work in progress)
aet-eaw-edit.features.story.symbols false Story event names, flags and AI-notification ids indexed across XML and Lua (work in progress)
aet-eaw-edit.features.story.rename false Cross-language rename of story symbols; builds on story symbols (work in progress)

Story dialog (.txt files under directories.storyDialog only):

Setting Default Description
aet-eaw-edit.features.dialog.diagnostics false Unknown commands, argument errors, untested commands, reference checks (work in progress)
aet-eaw-edit.features.dialog.inlayHints false Localisation text after TEXT and TITLE lines (work in progress)
aet-eaw-edit.features.dialog.goToDefinition false From DIALOG, MOVIE/MOVIE_ONCE and SFX arguments to the XML object (work in progress)
aet-eaw-edit.features.dialog.codeActions false Suppression quick fixes in dialog scripts (work in progress)

Tools:

Setting Default Description
aet-eaw-edit.features.tools.localisation false Localisation editor, initialise and import commands, create-key code action (work in progress)
aet-eaw-edit.features.tools.storyEditor false Campaign Editor view and story graph in View mode; builds on story.discovery (work in progress)
aet-eaw-edit.features.tools.storyEditing false Edit mode in the story graph; builds on tools.storyEditor (work in progress)
aet-eaw-edit.features.tools.storySimulator false Simulation mode in the story graph; builds on tools.storyEditor
aet-eaw-edit.features.tools.variants true Show Effective Object and its code lens
aet-eaw-edit.features.tools.modelPreview true Model preview; game models need aet-eaw-edit.lsp.source.baseGameDirectory
aet-eaw-edit.features.tools.encyclopedia true Encyclopedia popup preview and its code lens
aet-eaw-edit.features.preview.energyPool false Energy pool in the preview (editor-side, no restart). Off on purpose: the shipped game disables the mechanic

What this extension downloads

Three data sources; nothing else is sent or received. No telemetry.

What Where When How to disable
XML schema GitHub - newest compatible schema release On server start; nothing when the release is already cached; default branch when no release exists aet-eaw-edit.lsp.schema.source = local
Game baseline Configured URL (default: GitHub releases) Once; cached in %USERPROFILE%\.pg-swg-lsp\baselines\; refreshed on new versions aet-eaw-edit.lsp.source.baseline.type = local or none
Shader sources Petroglyph's published download, or aet-eaw-edit.shaders.sourceUrl Only on Set Up Base Shader Sources Do not run the command; set aet-eaw-edit.shaders.directory to your own copy

Troubleshooting

No diagnostics. aet-eaw-edit.lsp.enabled must be true and aet-eaw-edit.lsp.executable must point to PG.StarWarsGame.LSP.Server.exe; then EaWEdit: Restart LSP Server.

"LSP server failed to start". Windows may have blocked the downloaded executable: Properties > Unblock on PG.StarWarsGame.LSP.Server.exe, then restart the server. Otherwise Show Output in the notification.

Version mismatch. Server and extension must match; download the matching server from the releases page.

Features work in some files only. Only directories listed in the .pgproj are indexed; add the paths to directories.xml or directories.scripts.

"Found multiple .pgproj files under ...". One .pgproj per workspace root: remove the extras or open the subfolder, then restart the server.

"'directories.text'/'directories.textResourceType' were removed". Pre-0.2.0 .pgproj; see Upgrading from 0.1.x.

Localisation views missing. aet-eaw-edit.features.tools.localisation = true; the server restarts on the change.

A command or code action is missing. Its feature flag is off; see the Flag column of the commands table.

"The Lua debugger is disabled". aet-eaw-edit.features.lua.debugger = true. The debug type is always registered so launch.json validates; sessions start only with the flag on.

"The game did not answer on 127.0.0.1:1234 within 60 s". Debug build with luadebug run in its console required; retail builds never answer. A second game instance listens on 1235: set aet-eaw-edit.game.luaDebugPort or port. Remote machine: allow UDP to that port.

Breakpoint: "The file is under none of the configured script roots". The file is outside every project layer's script directories; move it, or add its root to sourceRoots.

Launch refused: layer not runnable. Declared directories under Data/ and no space in the path, or pass the folders via modPaths. See Lua debugger.

Raw server output. aet-eaw-edit.lsp.debug.traceServer = messages; EaWEdit output channel.

No diagnostics at all, for any file. aet-eaw-edit.lsp.debug.logLevel = Debug, then restart the server and read aetswg-*.log in the workspace root: it records whether XML document sync was registered and whether each didOpen reached the handler. At the default level neither line is written.


Acknowledgements

EvilBobTheBob (@andrewfullard), of Phoenix Rising and EaWX, for eaw-lua-debugger - the Python client that documented the game's Lua debug server protocol. The Lua debugger here was built against that description.


Issues

AlamoEngine-Tools/pg-starwarsgame-lsp/issues

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft