Skip to content

The shop editor ​

site/editors/shops.html — source site/editors/shp-editor.ts. Open http://localhost:5173/editors/shops.html.

Load a SHP shop — the props drawn on top of a room: HOUSE.SHP's 44 ship-wide props (including the 135-state door), INVEN.SHP's items, a puzzle's switches — and it comes apart into the three levels a shop has, group → state → frame.

Dust's props are .PRP, which is the same format under DreamFactory 1's name for it: readShpFile takes version 1 and 4 through one layout, so its fourteen open here like any other shop, and an export writes back the extension it read.

What it shows ​

PartWhat you can do with it
the shoprename it. This one is a label: scripts open a shop by filename (openshopfile("blkjack.shp")) and reach a prop by its group name, so nothing resolves through it
a proppick one, rename it — this is what sendtoprop/propvisible/propview address — and see its script and container
its statesevery named look, filterable (the ship-wide door has 135), each marked still, animation or selector — the distinction the format does not state outright and the runtime depends on: a selector's frames never play, propdeg() picks one of them by its stored degree
the previewthe 512×384 screen with the room view / UI band split drawn in. A prop draws at anchor − stored offset, and the anchor is what propxy moves — so the two anchor fields are that command, simulated: type 256,324 and the frame lands in the UI band where the watch does. ▶ Play state plays the frames in their stored play order at the game's 50 ms, once, holding the last one, exactly as a prop animation does
a frameits stored offset (Y before X, as everywhere), its propdeg degree, its packed size and its refScale; export it as a transparent PNG, or replace it
a view's soundDreamFactory 5 only: a state whose view names a sound shows its container, length and rate, and ♪ plays it. RedJack's shops have none; Villains Revenge's do. The link is measured from that game's file, not confirmed in an executable, so nothing says when the game plays it (DreamFactory 5's shop)
the scripts and palettethe shop main script and every prop's, decompiled on demand (read-only), and the file's own 256 colours

Two things the page is built to show ​

A stored offset belongs to the frame container, so changing it moves that art in every state that references it — a shop reuses frames heavily.

A degree belongs to the state's slot, not to the art: the same frame container reached through two states carries a degree in each, independently.

Replacing art ​

Replacing art takes any image the browser can decode, matches its pixels to the shop's palette (nearest RGB) and treats alpha < 128 as transparent — the mask matters twice over, because a prop is a cut-out and its clicks are hit-tested pixel-accurately against that mask. The frame's stored offset is kept, so a replacement of a different size sits differently against its anchor; the page says so when that happens.

Exporting ​

Export .shp repacks the container file and downloads it. Every edit that is not frame art is a copy-on-write patch on a single container (patchShopRefName, patchGroupName, patchStateIdentifier, patchFrameDegree, patchFrameAnchor in engine/src/df/shp.ts), so everything you did not touch is the byte it was (see taoot/tests/auto/shp-editor.ts).

That suite also pins the one case where the bytes and the view can disagree: a state whose play-order table reverses its frames, where an edit made through the reordered view has to land on the record that frame came from.

See also ​

Docs licensed GPL-3.0 (the decoder is ported from DFET). Game data © CyberFlix — not included.