Project1998 · builder's tool

NexusTK Map Editor

A visual editor for the world's maps. It renders with the real 5.33 client tile art — verified pixel-identical to the running game — and edits the 4.x .map files the server actually serves. It knows the content on the map (warps, spawns, NPCs, overrides as marker layers), can render exactly what players see, places new spawns/warps/NPCs and whole new maps, and turns edits into reviewable CSV rows — while never writing a game file itself: everything lands in its own saved\ folder for you to publish deliberately.

The editor showing Kugnae with the palette and tools visible

Installation

The easy way (no tools required)

  1. Grab the NexusTK-Map-Editor folder (the exe, a wwwroot folder, and a few runtime DLLs — keep the folder together).
  2. Put that folder anywhere inside your Project1998 checkout (for example Project1998\dist\NexusTK-Map-Editor\). The editor finds the maps by looking for a game-data\maps folder in the directories above it.
  3. Double-click NexusTK-Map-Editor.exe.

The editor opens as a single application window (a WebView2 shell — no console, no browser tab). It decodes the tileset for about a second on the way up, and closing the window shuts everything down. Window size and position are remembered.

Prefer your own browser? Run with --browser: the editor opens as a tab instead, and the server exits itself about 15 seconds after the last editor tab closes. (--no-browser starts the bare server for tooling; add --heartbeat if you want that to self-clean too.) Startup output goes to %TEMP%\nexustk-map-editor.log.

Tile.dat — the artwork

The editor needs the 5.33 client's Tile.dat. It looks, in order:

WhereNotes
P1998_CLIENT5environment variable pointing at the 5.33 client folder
next to the .exedrop a copy of Tile.dat beside the program
%LOCALAPPDATA%\Project1998\game\533\the standard Project1998 client install

If either the maps or Tile.dat can't be found, a message box says exactly what's missing and where it looked (the log has the same).

From source

dotnet run --project MapEditor

To build the standalone exe yourself:

dotnet publish MapEditor/MapEditor.csproj -c Release -r win-x64 --self-contained -p:PublishSingleFile=true -p:AssemblyName=NexusTK-Map-Editor -o dist/NexusTK-Map-Editor

A quick tour

Finding tiles

The palette has three modes:

Shift+click a second swatch to select a rectangular block of tiles — the brush then stamps the whole block, and the rectangle tool tiles it as a repeating pattern. Hover a swatch to see it magnified — objects preview as their full sprite. The eyedropper works the other way: click any cell and the palette jumps to that tile, brush ready.

On the Ground tab, Sheet 1 · walkable and Sheet 2 · blocking are the game's two ground-tile sheets. This is a real 4.x format rule, not an editor invention: a cell's sheet choice is its collision. Paint a wall tile and you've painted its collision too.

Navigating

Zoom from 10% to 500%: the top-bar − / + buttons, typing a percentage, Ctrl + mouse wheel, or the + / - keys. Pan with space + drag, middle-mouse drag, the mouse wheel (Shift for horizontal), or the arrow keys. The minimap floats bottom-right with the current view marked — click or drag on it to jump; it carries the marker layers' dots, so a city's warps and spawns are visible at a glance.

Whole-city overview at 10% zoom
A whole city at 10% zoom — marker glyphs become solid cell tints below 100%.

Editing

ToolWhat it does
Selectinspect a cell — the bottom bar shows its ground word, pass flag, object
Marqueedrag a box; the region is copied on release
Stampclick to paste the copied region, as many times as you like — all layers
Brushpaint the selected tile (click or drag); Ground/Objects/Pass tabs pick the layer
Fillflood-fill the contiguous region under the cursor on the active layer
Rectangledrag a box, fills it with the selected tile
Eyedropperpick the tile under the cursor into the palette
Eraserground → void, object → none, pass → walkable
No-entrytoggle a cell's passability (this flips its ground sheet — see above)

Ctrl+Z undoes stroke by stroke. The Passability overlay (Layers panel) tints every blocking cell red.

Saving — drafts, never the live maps

Nothing the editor generates goes into game-data. Everything lives with the tool under dist\NexusTK-Map-Editor\saved\:

Save never overwrites the shipped map. Loading a map prefers its draft, so your work is there next session; the status bar shows · draft, and Discard draft deletes the draft and reloads the shipped map. Getting an edit into the actual game is deliberate and manual — either copy saved\maps\TK<id>.map over game-data\maps\TK<id>.map yourself (then @reload on the server), or for small fixes use Corrections and append the rows to game-data\MapCells.csv.

Direct mode — the deliberate bypass. The Direct toggle in the top bar bypasses the saved folder — behind a confirmation box, and off on every start. While it's on (the button turns red), Save overwrites the shipped map (a new map's map_index.csv row is appended too), and the Corrections/spawn/warp/NPC exports append their rows straight into the live CSVs. The server still needs @reload, and git is the only undo — that trade is the point of the confirmation.

The test character

The walk tool drops a test character. Move with the arrow keys or the on-screen pad; blocked cells refuse the step, and walking behind trees, roofs and walls shows the same translucent ghost the real client draws. It always walks the base pass flags — the ones the server actually enforces — so it strolls through the default-open city gates even when the raw file draws them blocked. Remove it by clicking it, pressing Esc, or the ✕ on the pad.

Test character ghosting behind the Buya north gate
The test character ghosts behind the Buya north gate, exactly as the client draws it.

World markers

Read-only overlay layers (Layers panel) show the cells that server content points at, read fresh from the live game-data CSVs on every map load:

Warp diamonds, spawn dots and override squares over Arctic Village
Warp diamonds, spawn dots and override squares over Arctic Village.
Player view opens Kugnae's south gate
Player view opens Kugnae's south gate — the shipped file draws it closed.

Warps are usable, not just visible: with the select tool, clicking a warp diamond follows it — and the test character warps for real, including your pending placed warps, so you can walk into a brand-new map through its unpublished door before a single row is appended.

Checks

The run button in the Checks section scans the loaded map for suspicious cells: warp arrivals and spawn points on blocked ground, and walkable edges into void. Click a finding to jump to it. It judges the base (a cell an override already unblocks is not a finding), and blocked warp sources are deliberately not flagged — a doorway warp on a blocked cell is the game's normal idiom.

Exporting corrections

The server applies game-data/MapCells.csv rows as authored overrides on top of the shipped maps — "the shipped map is wrong here". The Corrections button diffs the editor's buffer against the shipped map and writes one CSV row per changed cell to saved\csvs\mapcells-TK<id>.csv, unchanged columns left blank so they inherit. A three-cell fix becomes three reviewable lines in git instead of a rewritten binary map.

Placing spawns, NPCs and warps

Placements are per-map, survive restarts, and export to saved\csvs\ — append the rows to the live CSVs by hand, then @reload.

Creating a new map

+ new (Maps panel) creates a brand-new map: an unused id (validated against both map_index.csv and the full RTK Maps.csv; the suggested id from 59000 up is free in both), a name, and dimensions (5–255 per axis). You get an all-void canvas — fence the playable area with blocking tiles the way the shipped maps do. Publishing is the usual manual step:

  1. append its row from saved\new-maps.csv to game-data\map_index.csv
  2. copy saved\maps\TK<id>.map into game-data\maps\
  3. @reload — the server's map registry is map_index.csv, so that's all it takes

Then wire it into the world with the warp tool — a pair in, a pair back out.

Import & export

Import accepts either. A .cmp carries its own dimensions; a headerless .map will ask for them (the editor suggests the likely pair from the file size).

Sharing a spot

The address bar carries state you can link to:

http://127.0.0.1:5959/?map=330&at=72,15&zoom=200

map (id), at (x,y to center on), zoom (percent), walk (x,y to drop the test character), and view=player (start in Player view) all work.

Troubleshooting