A browser-based archive explorer and asset viewer for Terminal Reality POD files.
JSPod opens POD, EPD, and ZIP archives without uploading their contents to a server. It presents the archive as a searchable file tree, previews common game assets, and can extract one file or repack the complete archive as ZIP.
Live application: Open JSPod on GitHub Pages
- Local or remote archives — open files from disk, a URL, or an autoload query parameter.
- Private client-side processing — indexing, decoding, and preview generation happen in the browser.
- Archive navigation — search and browse a collapsible directory tree with entry metadata.
- Asset previews — inspect textures, palettes, 3D models, text, audio, and common web images.
- Modern MTM2 (Community Patch 3) support — read extended POD1 directories, long BIN texture names, material records, PNG/TGA textures, and tangent-space normal maps.
- Extraction — download a selected entry or export the archive contents as a ZIP.
| Format | Description | Support |
|---|---|---|
| POD1 | Original Terminal Reality POD layout | Read |
| POD2 | POD2 archive layout | Read |
| EPD | Enhanced POD layout | Read |
| ZIP | Loads the first POD contained in the ZIP | Read |
POD1 has exactly one directory layout: 40-byte entries of char name[32], int32 size, int32 offset, holding paths of up to 31 characters. A directory table that does not validate as 40-byte records is a malformed archive and is refused. See POD1 format.
| File types | Preview |
|---|---|
.BIN, .LWO |
Interactive Three.js model viewer with orbit controls. An animated BIN opens on frame 1 with a bar naming every frame and where it resolves from; Play or the A key steps through them |
.SMF |
4x4 Evolution 1 and 2 models, in the same viewer |
.RAW |
Paletted or grayscale texture with automatic dimension detection and ACT palette selection |
.ACT |
256-color palette grid |
.TIF |
4x4 Evolution 2 palette-indexed TIFF, drawn over a checkerboard when it carries an opacity sample |
.PNG, .TGA, .BMP, .JPG, .JPEG, .GIF, .WEBP |
Image preview |
.TXT, .INI, .TRK, .SIT, .SI2, .SIX, .SIY, .TRX, .TXV, .LVL, .DEF, .VEG, .WAT, and other text formats |
Text preview |
.WAV |
Audio player |
CommPatch tracks and the disabled forms of tracks and trucks are described and
previewed alongside the originals: .SI2 is a track only newer engines see, .TXV
is the plain-text record asserting what the pod around it contains, and .SIX,
.SIY and .TRX are .SIT, .SI2 and .TRK renamed to something the game passes
over. Art files name the map they are: a _N, _AO, _DTL or _MASK suffix on a
.RAW, .PNG or .TGA stem is reported as a normal map, ambient occlusion,
terrain detail normal or terrain detail mask.
The BIN viewer understands classic and modern MTM2 records, including long texture names, material assignments, reflection and color blocks, and material parameters. For diffuse textures it resolves .PNG, then .TGA, then .RAW; _N normal maps use DirectX/green-down tangent space. Their RGB channels are decoded as X/Y/Z, alpha is ignored, and the engine has no roughness texture channel.
For early POD1 archives, JSPod also reads the hidden .ACT palette name stored after a .RAW path in the fixed-width directory field.
Palettes are ranked the same way in the RAW preview and the BIN texture fallback: the entry's own same-name .ACT and the name recorded in the directory field first, then the archive's own METALCR2.ACT, then its VGA.ACT, then the bundled palettes, greyscale, and every differently-named .ACT last. The archive's own METALCR2 outranks the bundled copy because METALCR2 is not one palette - CPR ships a different one from MTM1 and MTM2 - and a VGA.ACT in the pod means a flight game whose exact title cannot be told apart from here, so the pod's copy is the only safe pick. A differently-named .ACT is offered but never chosen automatically. The BIN selector supplies the fallback for textures that have no same-name .ACT, so same-name palettes belonging to other textures are listed there but never lead.
.SMF is 4x4 Evolution's static model format, a text C3DModel covering versions 2 to 4 including Evo 2's v1 bump materials. It opens in the same viewer, and is detected by its magic rather than its extension so a renamed entry still opens. Evo is Y-up where .BIN is Z-up, and Evo's texture V runs top-down where .BIN's does not, so the decoder converts both into the .BIN convention as it reads and the viewer then treats every model alike. That conversion negates Evo's Z on the way to the screen; leaving it out renders the model as its own mirror image, which reads as the texture being mirrored because a mirrored mesh still carries its own UVs. Diffuse textures resolve .PNG, .TGA, .TIF, then .RAW; an Evo .RAW also picks up its same-stem .OPA opacity plane, which is a real gradient rather than a mask and so is merged into the alpha channel instead of being reduced to the MTM colour key. Reduced-detail LOD groups are hidden when a model carries its full-detail pair.
In the interactive BIN preview, use the Left and Right Arrow keys to strafe the camera.
- A modern browser with JavaScript modules, Web Workers, WebGL, and Origin Private File System support
- An HTTP or HTTPS origin; browsers do not provide the required features when opened through
file:// - Network access to the Three.js and fflate CDN modules
- Open JSPod on GitHub Pages.
- Choose Open POD / EPD / ZIP, or paste an archive URL and choose Open from URL.
- Select an entry in the file tree to preview or download it.
Note
Remote archives must be served over HTTP or HTTPS. Cross-origin servers must also allow the browser request through CORS.
Clone the repository and serve its root directory with any static HTTP server:
git clone https://github.com/juanputrerasm/JSPod.git
cd JSPod
python3 -m http.server 8080Then open http://localhost:8080/. There is no build step and no package installation.
JSPod can automatically load an archive supplied through either url or file:
https://juanputrerasm.github.io/JSPod/?url=https%3A%2F%2Fexample.com%2Fgame.pod
https://juanputrerasm.github.io/JSPod/?file=%2Fdownloads%2Fgame.zip
Relative archive paths are resolved against the viewer page. When both parameters are present, url takes precedence.
| Component | Role |
|---|---|
| ES modules | Application, preview, and user-interface code |
| Module Web Worker | POD indexing, entry reads, and asset decoding off the main thread |
| OPFS | Temporary per-session archive storage |
| Three.js r169 | BIN/LWO rendering and camera controls |
| fflate 0.8.2 | ZIP import and export |
src/
├── pod-app.js Application controller
├── preview/ File-type preview modules
├── shared/ Shared OPFS helpers
├── ui/ File tree and dialog components
├── worker/ Archive, BIN, SMF, texture, and image decoders
├── file-type-info.js Extension metadata and preview routing
└── zip-utils.js ZIP archive handling
- JSPod is an archive viewer and extractor; it does not edit or rebuild POD files.
- ZIP input opens the first POD member rather than merging multiple archives.
- Browser image decoding availability depends on the browser's worker APIs.
- Rendering approximates the updated MTM2 material behavior in Three.js; it is not an exact copy of the game renderer.
- 4x4 Evolution
.SMFanimation frames past the first are read but not played, and Evo 2's bump, gloss and cubic reflection material stages are not reproduced.
- JSTruckViewer — assembles and displays complete MTM2 trucks from TRK and POD data.
- KPodman — desktop POD archive manager.
Developed by Juan Pablo Utreras for the Monster Truck Madness Guild.
Released under the Apache License 2.0.
Monster Truck Madness and Terminal Reality are trademarks of their respective owners. This project is an independent community tool and is not affiliated with or endorsed by them.
