Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>Pixel KnightsNew to Visual Studio Code? Get it now.
Pixel Knights

Pixel Knights

Do Minh Quan Ho

|
13 installs
| (0) | Free
A garrisoned pixel island in your sidebar. Errors land raiders on the shore; fix them and the knights cut them down.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Pixel Knights

TypeScript esbuild Canvas Tiny Swords

A small pixel island in your sidebar, with a castle, a village, and the units that hold them. It reads out your code. Errors land raiders on the shore, and fixing them lets the garrison cut them down. Warnings, uncommitted work, and your build and test tasks show up on the island too. The whole thing is one canvas in a webview. No accounts, no tracking, and nothing leaves your machine.

The island at rest

Features

  • An island of stacked elevations, drawn from the Tiny Swords tileset. From the top: a monastery with its Monk, a row of hillside houses, an archery range, the castle, the barracks, and a village on the ground. Every elevation of the fort has a tower on its corner
  • A garrison that lives where it is posted. Archers on the walls, Lancers guarding the monastery, Warriors at the barracks. No unit in armour starts on the shore, because the ground belongs to the Pawn
  • Grass stairs cut into each cliff, on opposite sides, so the elevations zigzag. The units walk them. Soldiers come down from the upper elevations, garrison figures leave their posts to walk the village, and the Pawn carries wood up the stairs to repair the buildings
  • Raids driven by your errors. One red raider per error, up to three. Every Archer on the island opens fire at once, and a Warrior and a Lancer come down the stairs to meet them
  • More of your code on the island. Warnings are Red Pawn thieves who carry gold out of the village houses and pile it on the shore. Fix one, and the village Pawn throws a thief into the sea and takes the gold home. Uncommitted files bring out Pawns to haul work up to the castle, and a commit delivers it. Commits you have not pushed wait at the castle gate, and merge conflicts set the castle on fire. A running build task sets the Pawns hammering, a failing test task sets a roof on fire, and a passing one has the Monk heal the knight
  • Your debugger too. A debug session brings the rubber duck into the shallows, and a breakpoint stops the knight in its guard
  • The island remembers. It counts raiders slain, commits delivered and days on the island. The count stays on your machine, in VS Code's own storage, and shows in the status bar tooltip
  • Day and night. The island grows darker in the evening by your local clock, and lighter again in the morning
  • The island scrolls. It is about 1,100px tall, taller than most sidebars, so the pane shows part of it and scrolls. It opens on the shore, and if raiders land while you are scrolled up to the castle, it scrolls back down to them
  • The layout is worked out from the width of the pane, so the scene rebuilds when you make the sidebar wider or narrower instead of getting cut off
  • Four colours, blue, black, purple and yellow, changed live from settings. The units and every building change together
  • A status bar entry opens the view, and Pixel Knights: Focus Companion View does the same from the command palette
  • Pixel Knights: Stage a Practice Raid lands three raiders that fall one by one, so you can watch a raid without breaking your code. Pixel Knights: Copy Island Record copies the island's count to the clipboard

Install

Search Pixel Knights in the Extensions view, or:

code --install-extension nauqh.pixel-knights

How the island reacts

The extension sends the state of your code to the island. That is every error, with its file and line. It is also the number of warnings, uncommitted files, files in conflict and commits not pushed, whether a build task is running, whether the last test task failed, and whether a debug session is running or stopped. Everything below is the island's reading of that. It responds to whatever produces your diagnostics, such as a language server, a linter or a compile task, and not to any particular editor event.

Error count What happens
Rises above zero One red raider per error wades in from the right shore, up to three, and they line up on the beach. Every Archer on the island opens fire from where it already stands, so the island answers before anything has moved
Stays above zero The garrison turns out. The knight, which is one of the barracks Warriors, comes down and repeats two attacks and a guard. One of the two Lancers leaves the monastery and runs down every stair on the island to attack from the second row. Both start where they are posted, so the knight arrives in about 5 seconds and the Lancer, starting from the top, in about 16 to 26, longer the wider the pane. Everything else holds its post, and the Pawn and the Sheep get out of the way
An error is fixed A raider dies in a puff of dust, always the one nearest the fight. Errors are followed one by one rather than counted, so fixing one error while another appears kills a raider and lands a new one
Reaches zero The raid ends and both units walk back up the stairs to their own elevation

Raiders on the shore as errors come and go

The rest of your code shows up like this:

Your code What happens
Warnings One Red Pawn thief comes ashore, however many warnings there are. It goes into a house in the village and carries a load of gold to the bottom shore, and keeps making trips until there is one load per warning, up to six. The gold is one pile that grows with every load, using the pack's six gold stones from smallest to largest. Nobody fights it while the warnings stand, because warnings are known about, not urgent. When a warning is fixed and others remain, the village Pawn comes down and carries one load of gold back to the house, one trip per fixed warning. When the last one is fixed, the Pawn first hits the thief with its hammer, which throws the thief spinning through the air and into the sea with a splash, then carries all the gold home. A thief still wading in, or caught with gold in its arms, just runs off. While the thief is ashore, the button at the top says Thief ashore instead of Island at peace
Uncommitted files A Pawn comes out to haul work up to the castle, and a second one at 10 files or more. A pile of work grows at the castle gate, from one load up to three at 15 files. The village Pawn works more often too
A commit The chronicle calls the quest complete and counts the files in the commit. The haulers go home, and the pile goes with the count. A checkout or a rebase moves HEAD as well, but is not counted as a commit
A build task running Every Pawn stops where it is and hammers until the build ends, then carries on with what it was doing. Watch tasks, which never end, are left out
A test task failing A village roof catches fire and keeps burning until a test task passes
A test task passing The Monk heals the knight, as soon as the knight is out of doors
Commits not pushed One load of stores per commit waits on the right of the castle gate, up to three. The uncommitted pile is on the left, so a commit moves the work across the gate. A push ships the stores. A branch with no upstream shows none, and a reset that drops the commits reads as a push
Merge conflicts The castle catches fire on both decks and at the gate, and burns until the conflicts are resolved. On a narrow pane the tower that stands in for the castle burns instead
A debug session The rubber duck leaves its corner of the sea and paddles into the shallows under the shore until the session ends
Stopped at a breakpoint or a step The knight stops where it is and holds its guard until the program runs on. A raid still comes first

Tests here means a task in the Test group, such as npm test. Results shown in the Test Explorer are not visible to other extensions, so they do not reach the island. The git readouts need VS Code's built in git extension. Without it the village is simply never busy.

The record counts an error as a raider slain when it goes away, even when it went because its file was closed. It is kept in VS Code's global storage, so it is the same in every workspace, and it never leaves your machine. The practice raid is not counted.

Diagnostics are debounced by 300ms, and a state identical to the last one is dropped rather than posted, so a busy language server does not wake the render loop.

The garrison

Every soldier is posted at a building. It stands either on the deck on top of that building or on the ground in front of it. Archers go on top, because an Archer is only worth having where it can see. The rest stand at the gate.

Building Where Who
Castle Deck 1 Archer
Tower Deck 1 Archer. There is one tower on each elevation of the fort: the archery range, the castle and the barracks
Barracks Ground 2 Warriors. One of them is the knight
Monastery Ground 2 Lancers, who walk the open grass on the right of the monastery rather than standing on a spot, each in its own half. The one in the half nearer the stair is the one that goes out to fight. The Monk stands in front of the door, now and then walks down the island and back, and stays out of raids

The guard is deliberately small. A castle elevation is about 190px of ledge at a normal sidebar and the castle itself covers 156 of it, so a bigger guard fills the whole ledge and reads as a queue rather than as a garrison.

Each elevation has its stair at one end, and the two tiles of ground beside that stair reach one row further down than the rest. The tower stands on the front edge of that step, level with the top of the stair beside it. The two elevations above the fort are not walled, so a tree stands there instead. The stairs alternate sides, counted up from the barracks, whose stair is always on the right. That is the beach side, which keeps the knight's run down to a raid short. It also means the tower never competes with the castle for space, so every tower appears at every pane size.

The castle and the barracks do need room, so what else you get depends on the pane.

Sidebar What the island posts
About 300px wide or more Everything. 4 Archers, 2 Lancers, 2 Warriors and the Monk
About 250 to 300px wide Every elevation, but too narrow for the castle, so a tower stands in its place. The Lancers guard the monastery, so they are still there
Under about 250px wide Too narrow for stairs on both sides, so only the castle elevation, with a tower in place of the castle. You get 2 Archers and the knight

Greenery on the upper levels

Bushes, rocks and the two short trees are scattered on the elevations as well as on the ground, following what Pixel Frog does in the pack's own promo art, where scrub grows along the lip of every cliff.

Two rules decide where it goes, and both come from the size of the ledge:

  1. It sits on the lip, not spread over the whole elevation. An elevation is three tiles of grass and its building stands taller than all three, so anything placed behind a building is not partly hidden, it is completely hidden.
  2. If there is no room beside the building, it grows at the foot of the wall instead, at the building's outer corners, drawn over the base stonework. Never across the gate, and never where a guard is standing.

That second rule is what makes it work at sidebar width. The castle elevation is 160px of ledge at a 300px pane and the castle covers 156 of it, so there is nothing to plant beside. The gap does not reach the 56px a bush needs until the sidebar is about 420px wide.

The monastery and the hillside houses are the exception. Their buildings are short enough to leave the back of the elevation showing, so trees also grow along the back of those two, clear of the buildings, the way the pack's own banner crowds its hills.

Only Tree3 and Tree4 are used up here. Tree1 and Tree2 stand 120px, taller than the elevation they would be standing on. The trees up here are scenery and are never cut, so the woodland the Pawn works stays on the ground, a walk from his yard rather than a climb.

When nothing is wrong

Which is most of the time, so the island is built to be worth leaving open. Every elevation can be walked on, and the stairs are the only way between them.

Who What they get up to
The knight Walks up and down the barracks elevation it is posted on. Every few minutes it takes a longer walk, down into the village or up to the castle, then comes back
The Pawn Wood is the island's only resource. The Pawn takes an axe to a tree, fells it, sets the axe down by the stump, carries the log home and stacks it on the woodpile beside his house, then goes back for the axe. From the woodpile he splits a log at the chopping stump in his yard and carries the firewood indoors, or takes a log to a building anywhere on the island and hammers at it to repair it. The woodpile holds three logs. He fells while it has room, and splits or repairs while it has logs
Trees and stumps A felled tree leaves its own stump, a pine's for a pine and a birch's for a birch, for a minute or two, and then grows back. The last standing tree is never cut
The Lancers Wander the grass on the right of the monastery, walking to a spot, standing a while, then picking another. When raiders land they stop where they are, apart from the one who goes down to fight
The garrison A Lancer or a Warrior leaves its post now and then and walks the island. Only one at a time, so an elevation is never left empty. The Archers never leave at all, because they are the wall
Going indoors Buildings are solid, so a unit on a deck has to use the door. It steps inside at the foot of the building, comes out on top, and does the reverse on the way back. A unit posted on the ground just walks
Everyone Steps inside a building for a while and comes back out
The Monk Stands at the monastery. Every few minutes he walks down to another elevation and climbs back
The Sheep Grass

None of it runs to a fixed script. Each unit picks its own jobs, and the long ones have a wait between them, so the island is quiet more often than it is busy. The moment a raid lands it all stops. Anything above the ground walks back down the stairs, anything indoors comes out, and the line forms.

Nothing is remembered between sessions yet. See plan.md.

The chronicle

The button at the top right of the view shows the pack's shield icon while the island is at peace and its sword once there are errors, with the pack's arrow pointing down, or up while the panel is open. It opens a panel with two parts. Live activity says what each unit is doing right now. The chronicle is a log of what has happened, written like the chat log of an old strategy game: a time, then who did what, with names and items in brackets.

Line When it is written
The garrison stands watch. The view opens
Raiders sighted off the eastern shore! The first error appears
A [Red Raider] wades ashore. (app.ts:12, 2 errors) Each raider lands, up to three, with the file and line of its error
[Knight] rallies the garrison! The raid starts
More raiders gather offshore. (util.ts:40, 5 errors) or A raider offshore turns back. An error past the third appears or is fixed, where the beach cannot show it
[Knight] slays a [Red Raider]! (app.ts:12, 1 error left) A raider dies because an error was fixed. If the Knight has not reached the fight yet, the Lancer or the Archers get the credit
Victory! The shore is clear. The last error is fixed
[Pawn] fells a tree. A tree comes down
[Pawn] receives loot: [Wood]. A load is picked up. Items show the pack's own icon
[Pawn] stacks [Wood] on the woodpile. A log reaches the woodpile
[Pawn] splits a log into firewood. A log is split at the chopping stump
[Pawn] repairs the Barracks with [Wood]. A log is used to repair a building
[Monk] heads down to the Archery Range. A unit sets out for another elevation
A [Red Pawn] sneaks ashore. (2 warnings) A thief comes ashore for a warning
A [Red Pawn] steals [Gold] from the House. (2 gold on the shore) The thief puts a load of gold on the shore
[Pawn] kicks the [Red Pawn] into the sea! (0 warnings) The last warning is fixed and the village Pawn throws the thief out. A thief still on its way slinks back out to sea instead
[Pawn] brings the [Gold] back to the House. A warning is fixed and the village Pawn carries a load home. After the thief is kicked out it can be brings 3 loads of [Gold]
[Pawn] brings the [Gold] back to the House. The stolen gold is home
A [Pawn] comes out to haul. (7 uncommitted files) A hauler comes out
Work piles up at the Castle. (7 uncommitted files) The pile of uncommitted work grows
Quest complete: 7 files delivered. You commit
The builders down tools. The build is done. A build task ends, or The build failed.
Fire in the village! The tests failed. A test task fails
[Monk] heals the [Knight]. The tests pass. A test task passes, starting with The fire is out. if the last one failed

Each line is written at the moment the thing happens, so a Pawn carrying wood for ten seconds is one line, not ten. The panel is framed in the pack's own SpecialPaper art and keeps the last 40 lines. If you scroll up to read older lines, new ones do not pull you back down.

A file and line in brackets is a link. Click it, or press Enter on it, to open the file at that line. It only opens files the extension has reported an error in.

The island

Tiny Swords is drawn at 1x on a 64px world grid, which is far too big for a sidebar, so the scene is not simply scaled down with CSS. Two rules keep the pixels straight:

  1. Resize the art once, and only once. Each sheet is drawn one time into an offscreen canvas at half size, with smoothing off. Every draw after that reads from that cache at 1:1. When the pane is wide enough to be worth it, the whole viewport is scaled up by an integer factor, never a fraction.
  2. Integer positions. No sprite ever lands on half a pixel, so nothing shimmers as it moves.

Units are not resized to a common body height. Each one stands on the ground contact point drawn into its own shadow, which is why the Lancer, whose frame is mostly spear, comes out the right size next to the Warrior. Draw order sorts on that same contact point, so whoever is further down the screen is drawn last.

The terrain is built from the pack's tilemap rather than from pre-cut images. It uses a nine slice for the water edge, another for each elevation, and a stone wall row that stands on grass. The stairs are the pack's diagonal grass ramp, two tiles tall, and each elevation's edge drops a row where the ramp meets it. Without that drop the ramp looks like a mound instead of a way down.

Configuration

Setting Default Does
pixelKnight.colour colour1 Unit and building colour. colour1 is blue, colour2 is black. It applies to every unit and building at once. Raiders stay red either way

Colour changes are sent to the open view straight away, with no reload.

Development

npm install
npm run build

Then press F5. That launches an Extension Development Host with Pixel Knights loaded. Open it from the activity bar or from the status bar. npm run package builds a .vsix you can install locally with code --install-extension. It bumps the patch version in package.json first, so to rebuild the same version run npx vsce package instead.

If you also have the Marketplace build installed, both use the same icon in the activity bar. The launch config passes --disable-extension=nauqh.pixel-knights so that only the workspace copy loads. It does not pass --disable-extensions, which would switch off the language servers too, and with no diagnostics there is nothing to raid you. The copy that does load says which one it is. The view header reads Pixel Knights [DEV] with the version next to it, and the status bar entry ends in [dev].

src/extension.ts     startup, diagnostics, git and task watchers, webview host
src/world.ts         what the host tells the island, shaped from plain data
src/sprites.ts       the asset list: every sheet, and where it lives
media/companion.js   the whole renderer: layout, tilemap, animation, sprites
media/tiny-swords/   the copy of the asset pack
docs/plan.md         where this is going

npm run watch rebuilds src/ on save. The renderer is plain browser JavaScript with no build step of its own, so editing media/companion.js only needs a reload of the Extension Development Host.

One thing has to match across the two sides. The sprite keys in COLOUR_FILES, SCENE_FILES and UI_FILES in src/sprites.ts build the list of URIs, and they must match the keys the renderer looks up in the SPR and NATIVE tables in media/companion.js. Adding a sprite means editing both files. One says where the art is, the other says how big it is and where it stands on the ground.

If the sprite comes from a part of the pack that is currently excluded, you also have to relax .vscodeignore, which keeps the unused teams out of the .vsix.

Credits

All artwork is from the Tiny Swords pack by Pixel Frog, used under its license terms. The code is MIT, the artwork is not. See LICENSE and THIRD_PARTY_NOTICES.md. Purchase the pack from Pixel Frog.

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