# VM templates

One folder per emulated machine. Each is the "fresh PC" a player starts from: `template.json` is the PCjs machine
state a new player boots with, `manifest.json` describes it (machine id prefix, PCjs state key, the disks, notes).
Served at `http://78.110.173.123/VM/templates/<name>/` (deploy: copy the folder to `/var/www/afx/VM/templates/`).

How a player relates to a template:

- The disk images listed in the manifest are read-only masters shared by everyone. PCjs never writes to them; a
  player's changes are the modified sectors kept inside their own state file, so a player costs a few MB, not a copy
  of the disks.
- `afx-api` (`server/afx-api.js`) provisions a player from the template: `req=new&user=U&machine=<prefix>` copies
  `template.json` to `/var/www/afx/VM/states/U/<key>.json` (skipped if the player already has one),
  `req=reset&user=U&machine=<prefix>` throws the player's saves for that machine away and provisions again.
  `req=latest&mode=disk` always answers with the template merged with the player's disk changes, so a machine
  boots exactly like the template plus whatever the player has saved on its drives.
- The page embeds (`index.html` of each mirror) boot from the same `template.json`, so a player who has never saved
  and a freshly reset player see the same thing.

To change what a fresh player gets (pre-installed software, files on D:, a different D: size): boot the template in
a browser, make the changes, click the hidden Save control (or let Unity autosave), fetch that player's state with
`req=load`, and replace `template.json` with it (for Windows 95 keep a real-mode boot-start state: patch the stock
state's disk controller section rather than saving a running Windows, PCjs cannot restore a protected-mode snapshot).
`tools/bda.py` prints the BIOS data area of a state, `tools/pcjstest.js` boots a page headless and can click Save.

Disk images were made on the server with `sfdisk` + `mkfs.fat` (FAT16, the right CHS geometry) and converted with
PCjs's `tools/diskimage/diskimage.js <img> --output=<json> --drivetype=C:H:S` (sparse clone of jeffpar/pcjs, `npm i glob@7`).
