Hi everyone,
After more than 10 years since the original SMDecoder (PHP/Node.js, 2015), I've done a complete rewrite of the project as a modern TypeScript SDK.
The new project is called StarMade-Decoder and supersedes this one entirely.
What changed
Supported formats (new)
Quick example
Links
Feedback and contributions welcome.
After more than 10 years since the original SMDecoder (PHP/Node.js, 2015), I've done a complete rewrite of the project as a modern TypeScript SDK.
The new project is called StarMade-Decoder and supersedes this one entirely.
What changed
| Old SMDecoder (PHP/Node.js) | New StarMade-Decoder (TypeScript) |
|---|---|
| PHP class + early Node.js port | Pure TypeScript, ESM, Node.js ≥ 20 |
| .smd2 format (pre-release era) | .smd3 + .smd2 retrocompat |
| Partial: .smbpm broken | All formats fully implemented |
| No write support | Full read and write / round-trip |
| No typed API | Complete typed domain objects |
| No tests | 525 passing tests, 99% coverage |
| Format | Read | Write |
|---|---|---|
| .ent (Ship, Station, Player, Shop, Asteroid) | ||
| .fac (Factions) | ||
| .cat (Catalog) | ||
| .tag (Trading, Chat, NPC) | ||
| .sim (Simulation state) | ||
| .smd3 (Block segments) | ||
| .sment (Blueprint archive) | — | |
| .smtpl (Template) | ||
| .smbpl (Logic/control links) | ||
| .smbpm (Metadata) | — | |
| .smbmm (Mod mappings) | — | |
| .smbph (Blueprint header) | ||
| BlockConfig.xml | ||
| server.cfg | ||
| blockBehaviorConfig.xml | ||
| FactionConfig.xml |
JavaScript:
import { registerAllFactories, Ship, FactionManager, Catalog, writeTo } from 'starmade-decoder';
import fs from 'node:fs';
registerAllFactories();
// Read a ship
const ship = Ship.fromBuffer(fs.readFileSync('ENTITY_SHIP_MyShip.ent'));
console.log(ship.uniqueId, ship.realName, ship.sectorPosition.toString());
// Rename it and write back
const renamed = ship.withRealName('Explorer MkII');
fs.writeFileSync('ENTITY_SHIP_MyShip.ent', writeTo(renamed.toTag()));
// Read factions
const factions = FactionManager.fromBuffer(fs.readFileSync('FACTIONS.fac'));
for (const f of factions.playerFactions) {
console.log(`[${f.id}] ${f.name} — ${f.memberCount} members`);
}
- GitHub: GitHub - blackcancer/StarMade-Decoder: TypeScript SDK to read/write StarMade save files — faithful port of the Java Tag format
- Getting Started Guide: StarMade-Decoder/docs/GUIDE.md at main · blackcancer/StarMade-Decoder
- API Reference: StarMade-Decoder/docs/API.md at main · blackcancer/StarMade-Decoder
- Examples: StarMade-Decoder/docs/EXAMPLES.md at main · blackcancer/StarMade-Decoder
- Release v1.0.0: Release v1.0.0 — Initial release · blackcancer/StarMade-Decoder
Feedback and contributions welcome.
Last edited: