LUA-NAR VSCode Extension
A full-featured Visual Studio Code extension for writing LUA-NAR scripts — the Lua scripting mod for Kerbal Space Program.
Includes syntax highlighting, autocomplete with docs, live diagnostics, snippets, and a one-click deploy to your KSP install.
Features
Syntax Highlighting
Each API category is coloured differently so you can spot what your script is doing at a glance:
| Colour |
Category |
Examples |
| Teal |
Navigation |
getLatitude, addManeuverNode, getTimeToApo |
| Yellow |
Flight Control |
setSAS, setThrottle, activateStage |
| Purple |
Autopilot |
apStartAscent, apAbort, apGetState |
| Green |
Vessel State |
getFuelPercent, isLanded, getOrbitApoapsis |
| Orange |
UI |
guiCreate, guiButton, guiLabel |
| Red |
Core Hooks |
onTick, setTickRate, logToFile |
Autocomplete
Start typing any LUA-NAR function and IntelliSense fills it in with tab-stop snippets. Complex functions like setSASMode auto-offer valid string values; setWarp offers levels 0–7.
Hover Documentation
Hover over any LUA-NAR function to see its full signature, return type, parameter descriptions, and usage notes — without leaving your editor.
Live Diagnostics
The extension warns you about common mistakes as you type:
- Using
flightPathAngle (removed from KSP) → suggests getAngleToHorizon()
setThrottle() value outside 0.0–1.0
setWarp() level outside 0–7
actionGroup() index outside 1–10
Snippets
Type nar- to get full script templates:
| Prefix |
What it generates |
nar-tick |
Basic onTick loop |
nar-ascent |
Full ascent-to-orbit autopilot script |
nar-hud |
Live telemetry GUI overlay |
nar-stage |
Auto-staging monitor |
nar-maneuver |
Maneuver node setup |
nar-gui |
GUI window with buttons |
nar-warp |
Time-warp until apoapsis |
nar-report |
Print full orbital parameter report |
Deploy to KSP
Right-click any .lua file → LUA-NAR: Deploy Script to KSP — copies it straight to your GameData/LUA-NAR/Scripts folder. Set the path once in Settings.
Status Bar
A 🚀 LUA-NAR button appears in the status bar whenever you edit a .lua file. Click it for a searchable API picker that inserts any function at your cursor.
Installation (from .vsix file)
If you downloaded the .vsix directly:
- Open VS Code
- Press
Ctrl+Shift+X to open the Extensions panel
- Click the
··· menu (top right of the Extensions panel)
- Select Install from VSIX...
- Pick the
lua-nar-1.0.0.vsix file
- Reload VS Code when prompted
Or from the terminal:
code --install-extension lua-nar-1.0.0.vsix
Publishing to the VS Code Marketplace
Follow these steps to put the extension on the public Marketplace so anyone can install it by searching.
Step 1 — Microsoft Account + Azure DevOps
Go to https://dev.azure.com and sign in with your Microsoft account (or create one free). If you don't have an organisation, create one — the name doesn't matter.
Step 2 — Create a Personal Access Token (PAT)
- In Azure DevOps, click your profile picture (top right) → Personal access tokens
- Click New Token
- Give it a name (e.g.
vsce-publish)
- Set Organization to All accessible organizations
- Set expiry to whatever you like (up to 1 year)
- Under Scopes → Custom defined → scroll to Marketplace → tick Manage
- Click Create
- Copy the token now — you cannot see it again after closing the dialog
Step 3 — Create a Publisher
Go to https://marketplace.visualstudio.com/manage and click Create Publisher.
Pick a publisher ID — this is permanent and becomes part of your extension's unique ID (e.g. if your ID is suddo, the extension becomes suddo.lua-nar). Use something like your username.
Step 4 — Update package.json
Open package.json and set two fields:
"publisher": "your-publisher-id-here",
"repository": {
"type": "git",
"url": "https://github.com/yourusername/lua-nar-vscode"
}
The repository field is optional but the Marketplace listing looks much better with it. If you don't have a GitHub repo yet, just push the folder there — it's free.
Step 5 — Install vsce
npm install -g @vscode/vsce
Step 6 — Login
vsce login your-publisher-id-here
It will ask for the PAT you copied in Step 2. Paste it in.
Step 7 — Publish
From inside the extension folder (where package.json lives):
vsce publish
The extension usually appears on the Marketplace within a few minutes and becomes searchable within about 15 minutes.
Updating Later
Bump the version and republish:
vsce publish patch # 1.0.0 → 1.0.1
vsce publish minor # 1.0.0 → 1.1.0
vsce publish major # 1.0.0 → 2.0.0
Extension Settings
| Setting |
Default |
Description |
luanar.enableDiagnostics |
true |
Turn on/off live error checking |
luanar.scriptsFolder |
"" |
Path to your GameData/LUA-NAR/Scripts folder for one-click deploy |
To set the scripts folder: Ctrl+, → search luanar → paste your KSP scripts path, e.g.:
C:\KSP\GameData\LUA-NAR\Scripts
Full API Reference
Navigation
| Function |
Returns |
Description |
getLatitude() |
number |
Latitude in degrees |
getLongitude() |
number |
Longitude in degrees |
getHeading() |
number |
Compass heading 0–360 |
getPitchAngle() |
number |
Pitch relative to horizon |
getRollAngle() |
number |
Roll angle in degrees |
getOrbVelocity() |
number |
Orbital speed m/s |
getSurfVelocity() |
number |
Surface-relative speed m/s |
getOrbPeriod() |
number |
Orbital period in seconds |
getTimeToApo() |
number |
Seconds to apoapsis |
getTimeToPe() |
number |
Seconds to periapsis |
getSOI() |
number |
Sphere of influence radius m |
getBodyRadius() |
number |
Body equatorial radius m |
getBodyGravity() |
number |
Gravitational parameter μ |
getBodyAtmHeight() |
number |
Atmosphere top altitude m |
hasAtmosphere() |
boolean |
Body has atmosphere |
getAngleToHorizon() |
number |
Flight path angle γ in degrees |
getOrbitEcc() |
number |
Orbital eccentricity |
getSemiMajorAxis() |
number |
Semi-major axis in metres |
addManeuverNode(ut, pro, nrm, rad) |
void |
Add maneuver node |
clearManeuverNodes() |
void |
Remove all maneuver nodes |
getUniversalTime() |
number |
Universal time in seconds |
Vessel State
| Function |
Returns |
Description |
getOrbitApoapsis() |
number |
Apoapsis altitude m |
getOrbitPeriapsis() |
number |
Periapsis altitude m |
getOrbitInclination() |
number |
Orbital inclination degrees |
getFuelPercent() |
number |
Liquid fuel remaining % |
getElectricPercent() |
number |
Electric charge remaining % |
isInAtmosphere() |
boolean |
Inside atmosphere |
isLanded() |
boolean |
Landed or splashed |
getAlt() |
number |
Altitude above sea level m |
getSpeed() |
number |
Surface speed m/s |
getVertSpeed() |
number |
Vertical speed m/s |
getMET() |
number |
Mission elapsed time s |
getMach() |
number |
Mach number |
getGForce() |
number |
G-force |
getDynPressure() |
number |
Dynamic pressure Pa |
getBodyName() |
string |
Current body name |
Flight Control
| Function |
Returns |
Description |
setSAS(bool) |
void |
Enable/disable SAS |
setRCS(bool) |
void |
Enable/disable RCS |
setGear(bool) |
void |
Deploy/retract gear |
setBrakes(bool) |
void |
Apply/release brakes |
setLights(bool) |
void |
Lights on/off |
activateStage() |
void |
Fire next stage |
setThrottle(0–1) |
void |
Set main throttle |
getThrottle() |
number |
Current throttle 0–1 |
setPitch(-1–1) |
void |
Set pitch input |
setYaw(-1–1) |
void |
Set yaw input |
setRoll(-1–1) |
void |
Set roll input |
setPitchYawRoll(p,y,r) |
void |
Set all three at once |
clearControls() |
void |
Zero pitch/yaw/roll |
setWarp(0–7) |
void |
Set time warp level |
getSASMode() |
string |
Current SAS mode |
setSASMode(string) |
void |
Set SAS hold mode |
getStage() |
number |
Current stage number |
isEngineFlame() |
boolean |
Any engine producing thrust |
getMaxThrust() |
number |
Max vacuum thrust kN |
getCurrentThrust() |
number |
Current thrust kN |
getTWR() |
number |
Thrust-to-weight ratio |
getMass() |
number |
Total mass tonnes |
actionGroup(1–10, bool) |
void |
Toggle action group |
Autopilot
| Function |
Returns |
Description |
apStartAscent(altM) |
void |
Start ascent to altitude |
apAbort() |
void |
Abort autopilot, cut throttle |
apGetState() |
string |
Current AP state |
apGetStatus() |
string |
Human-readable status |
apIsRunning() |
boolean |
AP actively running |
apCircularise() |
void |
Start circularisation burn |
apSetTargetAlt(altM) |
void |
Set target altitude |
apGetTargetAlt() |
number |
Get target altitude |
UI
| Function |
Returns |
Description |
showGUI(text) |
void |
Show simple popup |
hideGUI() |
void |
Hide simple popup |
guiCreate(id,title,x,y,w,h) |
void |
Create named window |
guiShow(id) |
void |
Show named window |
guiHide(id) |
void |
Hide named window |
guiSetTitle(id, title) |
void |
Change window title |
guiClear(id) |
void |
Remove all widgets |
guiLabel(id, text) |
void |
Add text label |
guiButton(id, label, fn) |
void |
Add button with callback |
guiSpace(id, px) |
void |
Add vertical space |
guiSeparator(id) |
void |
Add horizontal line |
guiMove(id, x, y) |
void |
Move window on screen |
Core
| Function |
Returns |
Description |
onTick() |
— |
Main callback (define this) |
setTickRate(seconds) |
void |
How often onTick fires |
logToFile(msg) |
void |
Write to LUA-NAR log file |
print(msg) |
void |
Print to KSP console |
Building from Source
If you want to modify the extension:
# Install dependencies
npm install
# Compile TypeScript
npm run compile
# Watch mode (recompiles on save)
npm run watch
# Package into .vsix
npx vsce package --no-yarn
Requirements: Node.js 18+, npm
Project Structure
lua-nar-vscode/
├── src/
│ └── extension.ts # All extension logic (autocomplete, hover, diagnostics)
├── syntaxes/
│ └── lua-nar.tmLanguage.json # TextMate grammar for syntax highlighting
├── snippets/
│ └── lua-nar.json # Code snippet templates
├── out/ # Compiled JS (generated by tsc)
├── package.json # Extension manifest
├── tsconfig.json # TypeScript config
└── language-configuration.json # Bracket matching, comments