Amiga Doors
Amiga Doors via vAmiga
Section titled “Amiga Doors via vAmiga”ENiGMA½ can run Amiga BBS doors written for AmiExpress (the “/X” family) in an Amiga emulator that is built in: the vAmiga core, compiled to WebAssembly and shipped in the enigma-vamiga npm package. There is no external emulator to install, and no Kickstart ROM or Workbench is needed: the package bundles the AROS ROM. The amiga_door module runs the emulator in a worker thread and bridges the caller to it.
ENiGMA½ also runs CLI doors: ordinary AmigaDOS programs that read the keyboard and write the screen through their standard input and output, the way many Amiga BBS games were written. See CLI Doors. It runs ARexx doors, the /X scripts marked TYPE=AIM, on an image that carries ARexx from your own Workbench 3.1; see ARexx Doors. It runs Paragon doors, written for Paragon, StarNet and MAX’s BBS (and run by /X as TYPE=TIM); see Paragon Doors. And it runs C-Net ARexx doors, the ARexx “pfiles” of C-Net Amiga, again with ARexx from your Workbench 3.1; see C-Net ARexx Doors.
How It Works
Section titled “How It Works”- A caller picks the menu entry. ENiGMA½ checks
nodeMax, that no other session is using the door’s image (for a door that saves its changes), and the caller’s time left. - The first session for a door image boots the emulator (at warp speed, about 0.4 seconds), waits for the shim to say it is ready, and keeps a snapshot of the booted machine in memory. Later sessions restore that snapshot in about 50 ms.
- ENiGMA½ hands the shim the user block (name, location, security level, time left, terminal size, and so on) and the door to run. This takes the place of a drop file.
- The door runs. Its output goes to the caller, and the caller’s keys go to the door. The emulator’s hard disk is the image file itself: the emulator reads it as the door asks and writes the door’s changes into it as the door makes them.
- When the door ends, the shim reports how it ended, and ENiGMA½ makes sure the image holds everything the door wrote.
Each caller gets an emulator of their own, so one caller per emulator. A door that saves its changes has its image to itself while it runs; see Persistence for what that means for a door with shared state.
Prerequisites
Section titled “Prerequisites”- The
enigma-vamigapackage. It is a dependency of ENiGMA½ and is installed with the rest. - A door image. A small hard-disk image holding the shim, a startup sequence and the door. See Building a Door Image.
- Optionally, a Kickstart ROM. The bundled AROS ROM runs most /X doors. If a door needs the real thing, supply your own Kickstart 3.1 ROM with
rom. ENiGMA½ does not ship Kickstart; see Licensing.
ROMs and Workbench
Section titled “ROMs and Workbench”No ROM is needed. The enigma-vamiga package bundles the AROS replacement Kickstart, published under the AROS Public License 1.1, and every door type runs on it (ARexx doors too, once the ARexx files from a Workbench disk are on the image). The bundled pair is the AROS build of 2026-08-20:
| File | Size | CRC32 |
|---|---|---|
aros-rom.bin | 524,288 bytes | CDB1F414 |
aros-ext.bin | 524,288 bytes | 6F9A4AD2 |
This aros-rom.bin carries a fix to AROS’s FFS bitmap handling (enigma-vamiga 0.1.2 and later), which is why its CRC32 differs from the stock AROS build, 7AE94477; the package’s roms/README.md explains the fix. With the bundled ROM an image of any size is safe to write to. An AROS ROM built before AROS#1720 was merged (the fix is upstream: aros-development-team/AROS#1720, commit 9ebf8cb390), supplied through the rom option, corrupts an FFS volume of more than one bitmap block (2032 KB) when a door writes to it, so ENiGMA½ logs a warning at startup when rom is set and the image is bigger than that; keep the image at 2032 KB or less with such a ROM.
Kickstart 3.1, optional. If you own a Kickstart ROM you may use it instead with the rom option: a plain, unencrypted, 524,288-byte image whose file name ends in .rom or .bin (the emulator refuses other extensions before looking at the contents). Kickstart 3.1 is the tested release; the shim needs Kickstart 2.0 or newer. Known-good dumps, by CRC32:
| Revision | Machine | CRC32 |
|---|---|---|
| 40.63 | A500 / A600 / A2000 | FC24AE0D or 88136CA9 (the emulator’s two known dumps); FC8A3FD2 is also widely listed |
| 40.68 | A1200 | 1483A091 |
| 40.69 | A1200 | 1D9AA278 |
| 40.68 | A3000 | EFB239CC |
| 40.68 | A4000 | D6BAE334 |
The A1200 and A500-family builds are the right ones for the machine ENiGMA½ emulates; the A3000 and A4000 builds also boot but carry drivers for hardware the emulator lacks. A ROM the emulator does not recognise still loads, as “Unknown ROM”. To check a file:
python3 -c "import zlib,sys;print('%08X'%zlib.crc32(open(sys.argv[1],'rb').read()))" kick40068-a1200.romxxd -l 4 kick40068-a1200.rom # 1114 4ef9 for a plain Kickstart 2.0+ imageAmiga Forever ships its ROMs encrypted: the file is 524,299 bytes and starts with the text AMIROMTYPE1. Decrypt it once with the rom.key from the same folder, since the emulator refuses encrypted files:
python3 misc/amiga_door/tools/decrypt_af_rom.py amiga-os-310-a1200.rom rom.key kick40068-a1200.romKickstart and Workbench are copyrighted (Amiga Corporation; Cloanto’s Amiga Forever is the usual legitimate source). Their licences cover personal systems and say nothing about public servers, which is one more reason the bundled AROS ROM is the default.
Workbench 3.1, needed only for ARexx doors. The AROS ROM has no ARexx, so oputil.js amiga-door create --workbench (or make_image.sh -w) reads RexxMast, rexxsyslib.library, rexxsupport.library, the IEEE math libraries, Rexxc/ and a few C: commands from your own Workbench3.1.adf. A Workbench 3.1 set is six ADF images of 901,120 bytes each: Workbench3.1, Extras3.1, Fonts, Install3.1, Locale and Storage3.1; only the first is read. Amiga Forever ships them unencrypted. For reference, one clean set of dumps has these CRC32 values; other dumps differ in date stamps, and the image builder checks contents rather than checksums:
| Disk | CRC32 |
|---|---|
| Workbench3.1 | D233484C |
| Extras3.1 | 32F55078 |
| Fonts | 63470DE4 |
| Install3.1 | B631F796 |
| Locale | E0E5DE81 |
| Storage3.1 | 4BD38EF4 |
An image that contains Workbench files is licensed material: keep it on your server and out of any public repository.
Building a Door Image
Section titled “Building a Door Image”A door image is a bare FFS partition (no RDB), named BBS, 2000 KB (create’s default) unless the door needs more, in a file whose name ends in .hdf (the emulator recognises a hard-disk image by that extension). A session reads only the parts of the image the door uses, so a large image costs no more memory than a small one. It holds:
C/axshim the host shimLibs/AEDoor.library the library most doors openS/Startup-Sequence boots straight into the shimDoors/<name>/... the door, its data files, icons and configurationBuild one with oputil.js amiga-door create. It needs nothing but ENiGMA½: no Python, no amitools, no running board.
./oputil.js amiga-door create ~/amiga/dreamsweeper.hdf ~/doors/dreamsweeperIt takes the image to create and one or more door directories (listed after the image, or with --doors DIR...). Each directory is copied, layout kept, to Doors/<directory name>/ in the image, so the door above ends up at BBS:Doors/dreamsweeper/.... Empty files and empty directories are kept, and files keep their modification times. Give several directories to put several doors on one image. Options:
| Option | |
|---|---|
--size SIZE | Image size, default 2000K: bytes, or with K, M or G. Rounded up to a multiple of 8 KB. At most 2032K unless --allow-large is given. |
--allow-large | Allow a --size over 2032 KB (up to 2097144K, 8 KB short of 2 GB). Only for an image used with the bundled ROM, Kickstart 3.1 or another ROM that carries the FFS fix. |
--name NAME | Volume name, default BBS. |
--workbench ADF | Add ARexx from your own Workbench 3.1 disk, for ARexx doors; see ARexx Doors. |
--force | Replace the image if it exists. |
The limit is there because an AROS ROM built before AROS#1720 was merged (2026-10-19) corrupts an FFS volume of more than 4066 blocks (2033 KB, the most one bitmap block covers) as soon as a door writes to it; 2032 KB is the largest multiple of 8 KB within it. The ROM bundled with ENiGMA½ (enigma-vamiga 0.1.2 and later) carries the fix, as do Kickstart 3.1 and AROS builds that include AROS#1720, but an image kept at 2032 KB or less also works with an older AROS ROM given through rom, so create refuses a larger one unless you pass --allow-large.
When it finishes it lists the image so you can check it. Nothing is written unless the whole image can be built: a door that does not fit (give a larger --size), a file name AmigaDOS cannot hold (longer than 30 characters, or with a :), or two file names that differ only in case (AmigaDOS ignores case) stop it with a message saying which.
A door directory or file name that the module would refuse in a door path (a quote, an asterisk, a backtick or one of $ ; < > |, a control character, or text outside Latin-1) does not stop the build: create warns that the module will refuse a door: path through it, so rename it before you point a menu entry at it.
The script make_image.sh (for a machine with amitools but not ENiGMA½) takes the same image and door directories with -s, -n, -x PATH (the xdftool), -w ADF, -p DIR and -c FILE (see C-Net ARexx Doors) and -f; its default size is 2000K too.
The door setting names the door’s path inside the image, written with BBS:, for example BBS:Doors/dreamsweeper/dreamsweeper.xim.
To look at or change an image later:
| Command | |
|---|---|
amiga-door add IMAGE SRC [DST] | Copy a local file or directory into the image. DST is its path in the image (default: the root). A DST ending in /, or an existing directory when SRC is a file, puts SRC inside it. A file of the same name is replaced. |
amiga-door ls IMAGE [DIR] | List the image, or a directory in it, with sizes, protection bits and dates. |
amiga-door extract IMAGE SRC DST | Copy a file or directory out of the image; DST of - writes a file to standard output. |
amiga-door info IMAGE | Volume name, file system, size and free space, and a check of the image’s structure. |
./oputil.js amiga-door add ~/amiga/cli-doors.hdf ~/amiga/libs/mathieeedoubbas.library Libs/./oputil.js amiga-door ls ~/amiga/doors.hdf Doors/dreamsweeper./oputil.js amiga-door extract ~/amiga/doors.hdf Doors/wallhall ~/backup/wallhallChange an image only while none of its doors is in use: a running door writes into the file, and its emulator holds parts of the file system in memory that a change underneath would contradict. The next session after a change boots the image afresh, since the snapshot of the booted machine belongs to the old file.
These commands read and write any plain OFS or FFS image, floppy .adf files included (handy for taking a door off its distribution disk with extract). They do not handle partitioned hard-disk images (with a Rigid Disk Block) or other file systems such as PFS and SFS.
Test-driving a door
Section titled “Test-driving a door”amiga-door console plays a door on your own terminal, with no running ENiGMA½ and no menu entry: it boots the image in-process, starts the door as a caller would, and wires your keyboard to it.
./oputil.js amiga-door console ~/amiga/doors.hdf --door BBS:Doors/XIMTest/XIMTest./oputil.js amiga-door console ~/amiga/cli.hdf --door BBS:Doors/spac/space --type cli \ --args '"{name}" DOORS:spac/' --user Hero --no-persist--door is required; --type is xim (the default), cli or aim, or another door type the shim on the image supports (tim for Paragon doors and cnetrexx for C-Net ARexx doors, once that door support is installed; a shim without it ends the session with error=unknown door type). --user sets the caller’s name, and --args, --console-mode, --mainline, --encoding (try cp437 for doors drawn for a PC terminal), --rom and --rows/--cols mirror the module’s settings. The door’s output is shown as UTF-8 with the Amiga console’s control codes translated and the shim’s control frames removed. When the door ends, the shim’s summary (status, the commands it used, the files it changed) is printed, then what became of the image (written as the door went: 8 writes, 40 KB, synced, or not changed). As in a real session the image is the emulator’s disk: whatever the door writes goes into it as the door runs, however the session ends; --no-persist keeps every write in the emulator and leaves the image exactly as it was. Press Ctrl+] to hang up and quit; that ends the session with status carrier, and what the door wrote until then stays in the image. Try a door on a copy of an image, and never on one a running board is using.
What a door may need
Section titled “What a door may need”Copy these from the door’s archive, keeping its layout under BBS::
- Data and configuration files the door reads. Some doors will not create their data file and need an empty one to exist;
amiga-door createandaddkeep empty files. - Icons with tooltypes (
<door>.info). /X doors often read their settings from their icon. - Screens and bulletins the door displays.
Doors that read files straight from an /X install’s own data (BBS:user.data, BBS:Node<n>/...) are not supported; they may not work.
Finding doors
Section titled “Finding doors”/X doors are on Aminet under comm/amiex, and many are still distributed by the AmiExpress community; the Up Rough door repository collects thousands of Amiga BBS door archives. Read the AEDoor 2.8 documentation that comes with the door developer kits if a door’s own notes are thin. ENiGMA½ supports XIM doors, which are the ones that talk to a node through AEDoor.library, /X ARexx doors, CLI doors and Paragon doors (below); Paragon and MAX’s BBS doors are on Aminet under comm/maxs, and C-Net’s ARexx pfiles under comm/cnet. It does not run C-Net’s C pfiles, which read C-Net’s own memory structures.
Configuration
Section titled “Configuration”Add an amiga_door module entry to a menu in menu.hjson. name, image and door are required.
| Item | Required | Description |
|---|---|---|
name | Yes | Door name. Used as a key for tracking concurrent sessions. |
image | Yes | Path to the door’s .hdf image. |
door | Yes | Amiga path of the door executable inside the image, such as BBS:Doors/DreamSweeper/dreamsweeper.xim. For an ARexx or C-Net ARexx door, the script’s full path (BBS:Doors/Kickboxing/KickBox.Rexx, PFILES:Badlibs/badlibs), with no blanks, quotes or shell characters. XIM, Paragon and CLI door paths may have blanks but none of the shell characters " * ` $ ; < > |. At most 199 characters, Latin-1, no control characters. |
doorType | No | xim for an AmiExpress XIM door, aim for an /X ARexx door, tim for a Paragon door (Paragon, StarNet, MAX’s BBS; /X’s TYPE=TIM), cnetrexx for a C-Net ARexx door, cli for a CLI door. Default: xim. |
consoleMode | No | CLI doors only: cooked (line input with echo, like an Amiga Shell window) or raw (each key as typed) until the door picks a mode itself. Default: cooked. |
doorDir | No | The door’s current directory. Default: the door’s own directory. |
doorArgs | No | XIM and ARexx doors: extra arguments after the node number; Paragon doors: after the line number. C-Net ARexx doors: the script’s arguments (C-Net gave pfiles none). CLI doors: the door’s whole argument line. {name}, {node}, {level} and {timeleft} are filled in; see CLI Doors. The arguments may be at most 199 characters and the whole command line (door path, node number, arguments) 299, with placeholders counted at their widest; a longer setting is refused. |
doorStack | No | Door stack size in bytes, 4096 to 1048576. Default: 32768. |
assigns | No | Assigns the door’s installation asks for, as { NAME: 'PATH' } (for example { MSE: 'BBS:Doors/MSE' }), made for each session before the door’s path is checked. Names are 1 to 30 letters, digits, _, . or -; paths are Amiga paths on the image, without ;. A path that is not on the image ends the session with an error. Any door type. |
env | No | Environment variables the door reads from ENV:, as { NAME: 'value' } (an empty value is allowed), set for each session; ENV: is made in RAM: when the image has none. Any door type. assigns and env each take at most 199 characters in all (NAME=value pairs joined with ;). |
mainline | No | The /X command line the caller “typed”. Some doors parse it. Default: empty. |
rom | No | Path to a Kickstart ROM. Default: the bundled AROS ROM. |
extRom | No | Path to an extension ROM. Default: the bundled AROS extension with the bundled ROM, none with your own rom. |
cpu | No | 68000, 68010 or 68EC020. Default: 68EC020. |
chipKb | No | Chip RAM: 256, 512, 1024 or 2048. Default: 512. |
slowKb | No | Slow RAM, 0 to 1536 in steps of 256. Default: 512. |
fastKb | No | Fast RAM, 0 to 8192 in steps of 64. Default: 8192. The core supports at most 8 MB. |
overclock | No | CPU speed multiplier, 1 to 16. Default: 1. |
baud | No | The serial line’s rate for the session: 9600, 19200, 38400, 57600, 115200 or 230400. Default: 115200. See Serial Line for the rate to pick. Needs an image built with axshim 1.5 or later; an older shim keeps its own rate, and ENiGMA½ logs a warning. |
nodeMax | No | Maximum concurrent sessions. 0 is unlimited. Default: 0, or 1 when sharedState is true and nodeMax is not set. |
sharedState | No | The door writes state all callers share (high scores, a wall): sets nodeMax to 1 when nodeMax is not set. A door that persists already runs one caller at a time per image. Default: false. See Persistence. |
tooManyArt | No | Art spec shown when nodeMax is reached or the door’s image is in use by another session. |
minTimeLeftMinutes | No | Refuse to start if the caller has less time than this left today. |
notEnoughTimeArt | No | Art spec shown when minTimeLeftMinutes refuses. |
encoding | No | Encoding of the door’s output. Default: latin1. Any encoding iconv-lite knows. |
amigaConsole | No | Translate the Amiga console’s controls for PC terminals (see Characters and Fonts). Default: true with a Latin-1 encoding, false with any other. |
font | No | SyncTERM font for the door’s duration: a font name or alias, or none to leave the caller’s font alone. Default: topaz. |
persist | No | The door’s disk writes go into the image as the door makes them, however the session ends. false keeps every write in the emulator, so the image never changes (and needs only to be readable). Default: true. See Persistence. |
log | No | XIM, ARexx, Paragon and C-Net ARexx doors: log every request the door makes at debug level. Default: false. |
panicGraceSeconds | No | C-Net ARexx doors: after a hangup (when every command answers ###PANIC), how long the script has to save and stop before it gets a Ctrl-C, 0 to 25. 0 stops it before it sees its answer, for doors that would save ###PANIC as a player’s name. Default: 10. |
wordWrap | No | C-Net ARexx doors: break the door’s text between words at the caller’s width, as C-Net did. Default: true. |
warpBootSeconds | No | How long the first boot runs flat out, 0 to 3600. Default: 30. |
regTimeoutSeconds | No | XIM doors: the door must register with the shim within this many seconds (Paragon doors: send their first request), 0 to 86400; 0 waits for ever. Default: 30. |
disconnectGraceSeconds | No | After a hangup, time-up or break, how long ENiGMA½ waits for the door to finish and the shim to report its exit, 1 to 3600. The shim itself gives a door 30 seconds and then reports it gone, so keep this above 30. With no report in time the session is ended anyway; what the door wrote until then stays in the image. Default: 35. |
inputTimeoutSeconds | No | A door waiting this long for a key gives up, 1 to 86400. Default: users.idleLogoutSeconds, or the shim’s 300 seconds. |
crlf | No | A line feed in the door’s output goes out as CR LF, as /X does. Default: true. |
timezoneMinutes | No | Minutes east of UTC for the Amiga clock, -720 to 840. Default: the server’s. |
Every problem in a door’s configuration is reported at once in the log (Could not start Amiga door), and the caller sees ”image, rom or extRom file, an image ENiGMA½ cannot read and write (read, with persist: false), and an enigma-vamiga older than 0.2.0 are handled the same way.
persistOn, which chose the exits after which a door’s changes were saved, has no effect since ENiGMA½ 0.6.0, because the changes are written as the door makes them. A menu that still has it loads, and the log says once per door that it is ignored; remove it at your convenience.
The only system setting is doors.amiga.snapshotCacheEntries (default 4): how many booted-machine snapshots ENiGMA½ keeps in memory, about 1.5 MB each whatever the size of the image, one per door image and machine configuration. A door without a snapshot boots instead of restoring. 0 turns the cache off. The cache rebuilds itself: a snapshot is used only while its image is exactly the file it was taken with (same size, modification time and inode), so the first session after any session that wrote to the image, or after you changed it, boots and caches a new one. A snapshot made by another version of the emulator (enigma-vamiga 0.1.x, before ENiGMA½ 0.6.0) is refused and replaced the same way.
Example Menu Entry
Section titled “Example Menu Entry”doorDreamSweeper: { desc: Playing DreamSweeper module: amiga_door config: { name: DreamSweeper image: /home/enigma/amiga/dreamsweeper.hdf door: BBS:Doors/dreamsweeper/dreamsweeper.xim sharedState: true tooManyArt: DOORMANY }}CLI Doors
Section titled “CLI Doors”Many Amiga BBS games, RPGs and strategy games among them, are not XIM doors but ordinary AmigaDOS programs: they read keys from standard input and write to standard output, and the BBS ran them in a raw console. Set doorType: cli for these. The shim then starts the program with its input and output connected to the caller (it acts as the program’s console), and nothing else changes: the same image, snapshot, persistence and font handling apply.
-
The caller is anonymous unless you pass them. A CLI door cannot ask the BBS anything, so it knows only what is on its command line. Put what the door’s documentation asks for in
doorArgswith these placeholders:Placeholder Becomes {name}The caller’s user name, as one quoted argument {node}The node number {level}The caller’s security level {timeleft}Minutes left in the caller’s session {name}is always one quoted argument, with characters the Amiga shell would act on (quotes,*, back-quotes,$,;,<,>,|) replaced by_, so a user name can neither run a command nor add a keyword to the door’s command line. A name too long for the room left on the command line is cut short inside its quotes. Do not put quotes around placeholders yourself. There is no node number in front of a CLI door’s arguments. -
Console mode. The console starts in cooked mode: typed text is echoed, Backspace edits and Return ends a line, as in an Amiga Shell window. A door that wants single keys switches to raw mode itself. Some doors expect the BBS to have opened a raw console already (“run it through a RAW cli” in their notes) and never switch; set
consoleMode: rawfor those. -
Hangups. When the caller hangs up or runs out of time, the door’s input ends (end of file), its output is refused, and it gets a Ctrl-C, which is what Amiga BBSes did. A door that ignores all of that is given up on after 30 seconds, as for XIM doors, and its exit is reported as
carrier(ortimeout). Whatever it wrote until then is in the image, as it is after any session (see Persistence). -
Libraries. A door may need libraries that are not in the AROS ROM. Doors compiled with DICE C (Battle Grounds, for one) quit at once, without a word, unless
mathieeedoubbas.library,mathieeedoubtrans.libraryandmathieeesingtrans.libraryare inBBS:Libs. Copy them from the AROS m68k distribution (Libs/on the boot ISO), or from your own Workbench disks when you use a Kickstart ROM. -
Character set. Many CLI doors draw with the PC (CP437) character set rather than the Amiga’s. For those set
encoding: cp437andfont: none.
A CLI door’s image needs axshim 1.1 or later (the shim in this repository); an image made with axshim 1.0 runs it as an XIM door, which fails.
Example: Battle Grounds and Global War
Section titled “Example: Battle Grounds and Global War”Battle Grounds 0.9e is a hack-and-slash RPG with persistent characters. It takes the caller’s name on its command line, reads S:BattleG.config (whose first line is its data directory, here doors:rpgs/battleg/, which needs a Users directory) and expects a raw console. Global War 2.19 is a multi-player strategy game that takes AmigaDOS keyword arguments and keeps its world in DOORS:GlobalWar/GW.dat. Both are in the Up Rough door repository.
doorBattleGrounds: { desc: Playing Battle Grounds module: amiga_door config: { name: BattleGrounds image: /home/enigma/amiga/cli-doors.hdf door: BBS:Doors/rpgs/battleg/bg doorType: cli consoleMode: raw doorArgs: "{name}" encoding: cp437 font: none sharedState: true }}doorGlobalWar: { desc: Playing Global War module: amiga_door config: { name: GlobalWar image: /home/enigma/amiga/cli-doors.hdf door: BBS:Doors/GlobalWar/GlobalWar doorType: cli doorArgs: "{name} ACCESS {level} PAGELENGTH 24 TIMELEFT {timeleft}" encoding: cp437 font: none sharedState: true }}Global War 2.19 cannot save on a fresh install: it deletes GW.dat before renaming its new save over it, and gives up when there is no GW.dat to delete. Give it the empty world it would have written, the text GLOBAL WAR v2.19 (with the trailing space) padded with zero bytes to 68 bytes: printf 'GLOBAL WAR v2.19 ' > GW.dat && truncate -s 68 GW.dat, then copy it into the image with ./oputil.js amiga-door add IMAGE GW.dat Doors/GlobalWar/.
ARexx Doors
Section titled “ARexx Doors”Many /X doors were written as ARexx scripts. Their command icon says TYPE=AIM, and the script starts with parse arg NODE, options results and address value "AERexxControl"NODE. AmiExpress ran them through its REXXDOOR utility; the shim takes REXXDOOR’s place: it opens the AERexxControl<node> port, runs the script with RX, and answers its commands (GETUSER, PUTUSTR/PUTUSER, TRANSMIT, SENDSTRING, GETCHAR, QUERY, SHOWFILE, REMOVERESERVED, SHUTDOWN and the rest) from the same user information XIM doors get. Set doorType: aim and name the script in door.
./oputil.js amiga-door create ~/amiga/kickboxing.hdf \ --workbench ~/amiga/Workbench3.1.adf --doors ~/doors/Kickboxing--workbench copies, from the same paths on the Workbench disk: System/RexxMast; Libs/rexxsyslib.library and rexxsupport.library; Libs/mathieeedoubbas.library, mathieeedoubtrans and mathieeesingtrans (rexxsyslib will not start without the first, and neither the AROS ROM nor Kickstart 3.1 has it); Rexxc/RX and the rest of Rexxc/; and C/Avail, Copy, Date, Delete, List, MakeDir, Rename, Type and Wait, which scripts run with ADDRESS COMMAND. It stops, naming the files, if the disk lacks any of them.
- Where the script goes. Anywhere on the image: a script finds its data through its own paths (KickBoxing uses
doors:Kickboxing/...;DOORS:isBBS:Doors), anddoornames the script. - Hangups and time. When the caller hangs up, runs out of time or leaves the door waiting for a key longer than
inputTimeoutSeconds, every command the script sends fails with return code 10, as under AmiExpress. Scripts written for /X take that as the cue to save and stop (many setSIGNAL ON ERROR); one that carries on gets a Ctrl-C, which stops an ARexx script. - Libraries. A script that
ADDLIBs a library not on the Workbench disk needs it, and whatever that library opens, in the image’sLibs/. The Death Game plays withoutrexxarplib.libraryuntil its once-a-day reset, which needs rexxarplib together withscreenshare.library,diskfont.libraryand ARP’sarp.library. - What a script changes in the user record (
PUTUSER, for example The Death Game’s upload credits) lasts for the session only; ENiGMA½’s user record is not changed. - Errors. An ARexx error in the script (
+++ Error 41 in line 51: Invalid expression) is logged with the door’s exit. Without ARexx on the image, the session ends at once and the log saysno rexxsyslib.
Example: KickBoxing and Hacker
Section titled “Example: KickBoxing and Hacker”KickBoxing 1.0 (187 FAC, 1994; Demozoo) is a boxing and training game with Amiga-scene art; Hacker 5.2c (Up Rough door repository) is a hacker-wars game. Hacker draws with PC characters. For KickBoxing, move KickBox.Rexx into the archive’s Kickboxing directory and give that directory to amiga-door create (as above); for Hacker, give it the archive’s hacker directory.
doorKickBoxing: { desc: Playing KickBoxing module: amiga_door config: { name: KickBoxing image: /home/enigma/amiga/arexx-doors.hdf door: BBS:Doors/Kickboxing/KickBox.Rexx doorType: aim doorStack: 40000 sharedState: true }}doorHacker: { desc: Playing Hacker module: amiga_door config: { name: Hacker image: /home/enigma/amiga/arexx-doors.hdf door: BBS:Doors/hacker/hacker.rexx doorType: aim doorStack: 50000 encoding: cp437 font: none sharedState: true }}Hacker runs avail flush after every command and stops with an error if the image has no C:Avail, so build its image with --workbench. Its archive ships the author’s own players: leave out hackerdata/users/* and hackerdata/userlist for a fresh game.
Paragon Doors
Section titled “Paragon Doors”Paragon, StarNet and MAX’s BBS had a door protocol of their own, which AmiExpress also ran (TYPE=TIM in a door’s icon) and DLG, Xenolink and DayDream emulated. A Paragon door finds the BBS’s DoorControl<line> port and sends it its requests: print this, read a line, read a key, the caller’s name, time left, show a file, add some minutes. The shim publishes that port and answers, from the same user information XIM doors get. Set doorType: tim. Aminet’s comm/maxs directory holds a few hundred of these doors and utilities for MAX’s BBS, games among them (Master Space Empire, The Land of VEX, Sector Wars II, AndroFight, Hamurabi, Killer Instinct, Global War 1.18), and many /X boards ran Paragon doors as TYPE=TIM.
- The line number. A Paragon door reads its line from the first character of its argument, so it is started as
<door> <digit>: the last digit of the caller’s node. Each caller has an emulated machine of their own, so the lines never collide. Doors that take more arguments get them after it, fromdoorArgs. - Install notes. Paragon doors were installed with an assign or two and sometimes an environment variable in the sysop’s
S:Startup-Sequence, which a door image does not have. Put them in the door’s config:assigns: { MSE: "BBS:Doors/MSE" }andenv: { MSE: "" }makeMSE:and the fileENV:MSEfor each session.DOORS:(BBS:Doors) andPGDOORS:(the door path Paragon doors are told) are always there. Some doors also look for a file naming the BBS type (The Land of VEX readsDOORS:bbstype.dat, which saysmaxs). - Characters. Most of these doors draw with PC characters: set
encoding: cp437andfont: none. Line ends are taken care of: Paragon doors end lines with a carriage return, a line feed or both, and each reaches the caller as one new line. - Hangups and time. When the caller hangs up, runs out of time or leaves the door waiting for a key longer than
inputTimeoutSeconds, every answer the door gets says the carrier is lost, as a Paragon BBS said; doors check that after every request and save and quit. One that carries on gets a Ctrl-C. - What a door changes in the user’s record (time it adds, an access level it sets) lasts for the session only; ENiGMA½’s user record is not changed. A door asking for the BBS’s editor is refused, as for XIM doors.
- Libraries. As with CLI doors, a door that needs
mathieeedoubbas.libraryor the like needs it in the image’sLibs/(the AROS ones serve). Doors compiled with HiSoft BASIC need HiSoft’shisoftbasic.libraryorhbasic2.library, which are not freely available; they do not run without them.
Example: Master Space Empire and The Land of VEX
Section titled “Example: Master Space Empire and The Land of VEX”Master Space Empire 2.35 (Robert Masters, 1993; Aminet comm/maxs/mse_2.35.lha) is a multi-player space strategy game played a few turns a day; The Land of VEX 1.2 (Aminet comm/maxs/VEXv1_2.lha) is a fantasy role-playing game in the manner of Legend of the Red Dragon. Put MSE’s files in Doors/MSE/ and VEX’s lod directory in Doors/lod/, with its bbstype.dat in Doors/, and the AROS mathieeedoubbas and mathieeedoubtrans libraries in Libs/ for VEX.
doorMSE: { desc: Playing Master Space Empire module: amiga_door config: { name: MasterSpaceEmpire image: /home/enigma/amiga/paragon-doors.hdf door: BBS:Doors/MSE/MSE doorType: tim assigns: { MSE: "BBS:Doors/MSE" } env: { MSE: "" } encoding: cp437 font: none sharedState: true }}doorVEX: { desc: Playing The Land of VEX module: amiga_door config: { name: LandOfVEX image: /home/enigma/amiga/paragon-doors.hdf door: BBS:Doors/lod/Awarrior doorType: tim encoding: cp437 font: none sharedState: true }}MSE’s env value holds its options (FAST, TIME, INVITE; see its readme); empty is none. Leave out PARAGON, which asks for the BBS’s editor.
C-Net ARexx Doors
Section titled “C-Net ARexx Doors”C-Net Amiga (versions 3 to 5) ran door games and add-ons as “pfiles”, and many were ARexx scripts. C-Net started each one with its port’s ARexx host already chosen, so a pfile has no address line: it says options results and sends C-Net’s commands (TRANSMIT, SENDSTRING, GETUSER 1, PROMPT 30 NORMAL "Your word: ", MAYGETCHAR, CHANGEWHERE "Playing Bad Libs"), with C-Net’s colour and control codes in its text. The shim takes C-Net’s place: it opens the port CNETREXX<port> (C-Net counted ports from 0, so the caller on node 1 is port 0), starts the script the way C-Net did, and answers from the same user information other doors get. Set doorType: cnetrexx and name the script in door.
Pfiles live under PFILES:, and many hard-code it (Bad Libs looks in PFILES:BADLIBS/). make_image.sh -p DIR puts a pfile’s directory in PFiles/ on the image, and the shim assigns PFILES: to it. It also makes C-Net’s mail tree, CNET:Mail/Users/, where pfiles keep files for each caller (in a folder named after the caller’s account number, which is their ENiGMA½ user ID). A door that wants something else gets it from assigns. Give commands a script runs (address command) that Workbench does not have with -c:
XDFTOOL=~/amitools-venv/bin/xdftool misc/amiga_door/image/make_image.sh \ -w ~/amiga/Workbench3.1.adf -c ~/amiga/QSort/QSort \ -p ~/doors/Badlibs -p ~/doors/switchfont -p ~/doors/GoldMine ~/amiga/cnet-doors.hdf- Text codes. C-Net’s codes in a door’s text (
^Yc5colours,^Yf1clear the screen,^Yn2new lines, cursor moves) become ANSI for the caller, and the ones that wait work: a key ({G}), a line ({I}), yes or no ({?}), a pause ({W}), a file shown inside the text ({* file}). Text is word-wrapped at the caller’s width (wordWrap). C-Net’s “More” prompt is not emulated; doors that turn it off and on find it off. - Keys.
GETCHARandMAYGETCHARgive letters in capitals, as C-Net did; cursor keys reach the door as the caller’s terminal sends them (ESC [ A), which is what C-Net doors read. - The caller.
GETUSERanswers C-Net’s numbered fields from the caller’s ENiGMA½ record: handle (1), real name (3), location (4), time left (7, in tenths of a minute), calls (22), port (23), upload and download totals (30 to 33), account number (40), and the rest as an account with nothing in it would.BBSIDENTIFYgives the board’s and sysop’s names. The account number is the caller’s ENiGMA½ user ID, so only the root sysop (ID 1) is C-Net’s sysop account 1; a C-Net door runs only for a caller who has logged in (on a menu reached before login it says it could not be run, and the log says why). A script that reads C-Net’s memory directly (GETUSERwith a seven-digit number) gets 0 or nothing. The scratch account commands see only the caller’s own account;FINDACCOUNTfinds only the caller. - Hangups and time. When the caller hangs up, runs out of time or leaves the door waiting for a key longer than
inputTimeoutSeconds, every command answers###PANIC, as C-Net did, andGETCARRIERsaysFALSE. Doors check for that and save and quit; one that carries on gets a Ctrl-C afterpanicGraceSeconds. Bad Libs runs through its remaining prompts, counts the game and leaves by itself within seconds. - What a door changes in the user’s record (
PUTUSER,ADDTIME,ADDPOINTS) lasts for the session only. The editor, mail and file transfer commands are refused (a door that offers to mail something says it could not), andBBSCOMMANDdoes nothing. - Not supported: C pfiles (programs, not scripts), and ARexx pfiles that
ADDLIBcnet.libraryorcnetc.libraryor read C-Net’s own data files (its user base, message bases). Sub-pfiles started from a door’s text ({#0 file}) are not run.
Example: Bad Libs, Switchfont and Gold Mine
Section titled “Example: Bad Libs, Switchfont and Gold Mine”Bad Libs 1.5 and Switchfont 1.0 are by aNACHRONiST of Phenom Productions, written for C-Net 5 and played on aBSiNTHE BBS (the Up Rough door repository has pn-badlibs15.zip and pn-sf10.zip). Bad Libs is Mad Libs: it asks for nouns and verbs, shows the story they make, and keeps the busiest players and stories. It sorts those lists with QSort, a freeware command on Aminet (util/cli/QSort.lha): put QSort/QSort from that archive in C: with -c. Switchfont lets a SyncTERM caller pick a font with the cursor keys. Gold Mine 2.20 (Dotoran; Aminet comm/cnet/goldmine.lha) is a guess-the-square game with a high score list. For each, give make_image.sh -p the directory holding the script (Badlibs/, switchfont/, a GoldMine/ directory with the GoldMine script in it).
doorBadLibs: { desc: Playing Bad Libs module: amiga_door config: { name: BadLibs image: /home/enigma/amiga/cnet-doors.hdf door: PFILES:Badlibs/badlibs doorType: cnetrexx sharedState: true }}doorSwitchfont: { desc: Picking a font module: amiga_door config: { name: Switchfont image: /home/enigma/amiga/cnet-doors.hdf door: PFILES:switchfont/switchfont doorType: cnetrexx persist: false font: none }}doorGoldMine: { desc: Playing Gold Mine module: amiga_door config: { name: GoldMine image: /home/enigma/amiga/cnet-doors.hdf door: PFILES:GoldMine/GoldMine doorType: cnetrexx sharedState: true }}Switchfont’s choice is the caller’s font while it runs; with font: none ENiGMA½ leaves it alone afterwards too. Most C-Net art is Latin-1 for Amiga terminals, which is the default encoding; Dotoran’s CRAPS draws with PC characters and wants encoding: cp437.
Persistence
Section titled “Persistence”The door’s disk is the image file itself. The emulator reads the parts of the image the door uses as it asks for them, and writes the door’s changes into the file as it makes them: a moment after the emulated drive goes quiet (a tenth of a second of Amiga time after its last access), whatever the door wrote is in the image. A door that saves something (a high score, a message on a wall) has saved it in the image as soon as it is done writing, not at the end of the session. What that means:
- However the session ends, the image keeps what the door wrote: a clean exit (
ok), a hangup (carrier), the caller’s time running out (timeout), a sysop break, an error, a door the shim had to give up on, even the emulator stopping. When the session is over, ENiGMA½ lets the emulated Amiga finish writing what its file system still buffers (three seconds of Amiga time, a fraction of a second on the server), writes the rest into the image and syncs it to disk. Only then is the image free for the next caller. - After a hangup the door is told the carrier is gone and gets the shim’s 30 seconds to save and quit; ENiGMA½ waits for its exit report for
disconnectGraceSeconds(35 by default). A door that saves on a hangup has its save in the image. A door that is cut off between two writes (a CLI door is sent end-of-file and a break, an ARexx door a break) leaves its files as they were at that moment, as it would have on a real Amiga BBS when the caller dropped. There is no longer a choice of exits after which changes are kept:persistOnis ignored (see Configuration). - The image is written in place. There is no copy and no rename: if the server crashes or ENiGMA½ is killed mid-session, the image holds what had been written through until then. Writes go into the file a tenth of a second of Amiga time after the drive goes idle, so up to about 100 ms of the door’s last writes, and anything the guest’s own file system still buffered (AmigaOS writes dirty buffers back within a few seconds), can be lost, as after a power cut on a real Amiga. An uncaught error in the emulator’s worker thread ends the session without the final sync; what write-through had already written stays in the image. A door that keeps state you care about deserves a backup: keep a copy of a pristine image (or a nightly copy of the live one) yourself, and restore it if a door ever leaves its data in a bad state.
- When ENiGMA½ shuts down with Ctrl+C (SIGINT), callers are disconnected and every running door is told the carrier is gone and gets about two seconds to save and exit, after which its image is synced, for at most about three seconds in all; the log says which doors synced (
Amiga doors at shutdown: ... synced, ... not). A door still running when its two seconds are up is synced where it stands, like a power cut. A server stopped with SIGTERM or killed (ENiGMA½ handles only SIGINT), ends with the process: its image keeps what had been written through until then. - If the final sync fails (a full disk, a read-only file system, an I/O error), the log says
Amiga door disk sync FAILEDwith the reason; the image has what reached it before. - Snapshots follow the image. The cached snapshot of the booted machine is good only for the image exactly as it was when the snapshot was taken, so a session that wrote anything leaves it stale: the next session boots (about half a second) and caches a new one. Doors that write on every session therefore boot every time; a door that only reads keeps restoring.
persist: falsekeeps every write in the emulator: the door sees its own changes during the session, and they are gone when it ends. The image is never written, so it may be read-only.
Two emulators must never use one image while either writes it: each would hold its own view of the disk in memory and its own idea of which blocks are free, neither would see the other’s writes, and the two would overwrite each other’s files; an emulator that only reads would see the disk change under it and its door could misbehave. So a door that persists (the default) holds its image to itself for the whole session: while one caller is in it, anyone who picks a door on the same image, this door or another, persisting or not, is told it is busy (tooManyArt, or “Too many active instances”), just as nodeMax refuses. The image is released once the door has exited and the image is synced.
Sharing an image therefore serialises callers: all the persisting doors on one image run one caller at a time between them. Give doors their own images when you want them to run side by side; separate images run in parallel. A door that keeps nothing between sessions (a single-player game with no saved files) can set persist: false: its sessions never write the image, so any number of them share it, on as many nodes as nodeMax allows, every session starting from the image as it is. A non-persisting door and a persisting one on the same image never run at the same moment: while a persisting session is in, a persist: false session on that image is refused as busy, and while any persist: false session is in, a persisting one is.
Serial Line
Section titled “Serial Line”The door and ENiGMA½ talk over the emulated Amiga’s serial port, and the shim drives it the way a careful Amiga terminal program would. It raises RTS (the Amiga’s “ready to receive” line) when it opens the port, and drops it while its 4 KB receive buffer is three-quarters full and while it is loading a door, so the sending side waits instead of overrunning the port. Keys the door has not read yet stay in that buffer, and ENiGMA½ keeps the rest of a long paste and hands it over as the door takes it.
baud sets the line rate for a session. Inside the emulator the rate only paces the bytes; what decides whether a rate works is whether the emulated CPU fetches each byte before the next one arrives. The emulator ENiGMA½ ships today (enigma-vamiga 0.2) holds each received byte until the Amiga has read the one before, so every rate works with it, and the default stays 115200. A real Amiga has no such help, and the emulator is due to lose it. Without it, these rates are the fastest that measured lossless with the AROS ROM:
| CPU | baud |
|---|---|
68EC020 at 7 MHz (cpu: 68EC020, overclock: 1, the defaults) | 38400 |
68EC020 at 14 MHz (overclock: 2, an A1200’s clock) | 57600 |
| 68000 at 7 MHz (and the 68010, which is hardly faster) | 19200 |
Kickstart 3.1 (rom) handles the serial interrupt faster than AROS and keeps up with 57600 at 7 MHz. At 115200 a 7 MHz machine without the emulator’s help loses bytes, as a real one does. A rate is 10 bits per character: 38400 is 3840 characters a second each way, more than any modem caller had, and a full 80x25 ANSI screen arrives in about a second. Between sessions the shim listens at 38400 (19200 on a 68000), whatever baud says, because the user block it receives at the start of a session cannot be sent twice.
Pasted text that used to vanish. Before axshim 1.5 the shim kept at most 4 KB of keys the door had not read and threw away the rest, and lost one more key when a 4 KB paste came before the door started reading; a long paste into a door that was busy drawing its screen lost its end. Now the keys wait: the door gets every one of them, as fast as it reads, for as long as it keeps taking keys. (A door that takes no key at all for 3 seconds while its 4 KB of unread keys is full is treated as no longer reading, and what it cannot take is dropped, so a hang-up still reaches it.) A door that keeps reading but very slowly, one key every few seconds, with more than about 7 KB of a paste still unread, can hold the caller’s hang-up behind those keys for longer than disconnectGraceSeconds (35 by default); ENiGMA½ then stops the session before the door has seen the hang-up, so what an XIM door would have saved on the hang-up is not saved (what it wrote before is in the image). ENiGMA½ keeps up to 1 MB of a caller’s unread input and logs a warning if that ever fills. From enigma-vamiga 0.1.3 the emulator honours the shim’s RTS (ENiGMA½ turns this on for images with axshim 1.5 or later), so a door that reads nothing for a while after more than 8 KB of input no longer loses keys; with 0.1.2 and older it can lose about one key in every tenth of a second it waits. Images built before axshim 1.5 have the old shim: rebuild them with make_image.sh to get this.
Characters and Fonts
Section titled “Characters and Fonts”Amiga doors write ISO 8859-1 (Latin-1) text and draw with the Amiga’s Topaz font. Two things follow:
- Amiga console controls that PC terminals do not share are translated for the caller: the single-byte control sequence introducer
0x9BbecomesESC [, a form feed (the Amiga’s clear screen, which also drops the font on a SyncTERM-style terminal) becomesESC[2J ESC[H, the cursor on/off sequencesESC[ pandESC[0 pbecomeESC[?25handESC[?25l, a console reset keeps the font, and a cursor position below the screen is moved onto it (see below). Everything else in the door’s output is passed through. This is done for doors with a Latin-1encoding(the default) only: a door that writes CP437 is a PC-style door, where0x9Bis a cent sign, and its output is left as written.amigaConsole: trueorfalseoverrides that either way. - With a Latin-1
encodingand the Topaz font, door bytes reach the caller as they are, and the caller’s terminal shows them through the font. With anotherencoding, the output is converted to the caller’s character set first (a character split across two writes is kept whole). - When the font is not
none, ENiGMA½ switches a SyncTERM-compatible terminal to the font (topazby default) before the door starts and back afterwards (ESC[0;42 Dbefore,ESC[0;0 Dafter, for Topaz). Callers whose terminals do not support SyncTERM fonts see the door in their own font: the text is readable, and the Amiga’s box-drawing and graphic characters show as whatever Latin-1 gives them. If most of your callers are in that position, setfont: none.
The terminal size is the caller’s, polled once a second, so a resize reaches the door. Many /X doors were written on PAL Amigas with 32-line screens and place text on rows 26 and 27 without asking; with the Amiga console translation on, a cursor position below the caller’s last row is moved onto the last row, which is what the Amiga console itself does, so an 80x25 caller sees the bottom of the layout overwritten rather than the screen scrolling. Callers with taller terminals (SyncTERM’s 80x50 modes, for example) see the full layout, and a door that asks the BBS for the screen length is told the real one. Time left is polled every five seconds, so a door sees the caller’s budget shrink as it does everywhere else on the board.
Limits
Section titled “Limits”- CPU: the 68000, 68010 and 68EC020 only. There is no 68030, 68040 or 68060, and no FPU.
- Memory: at most 8 MB of fast RAM. The AROS ROM needs at least 1 MB in total (chip plus slow plus fast).
- Images up to 4066 blocks (2033 KB) with an AROS ROM built before AROS#1720 was merged (2026-10-19). An FFS volume bigger than that needs a second bitmap block, which the filesystem of an AROS ROM built before AROS#1720 was merged (2026-10-19) misreads: when a door writes, it can take blocks that belong to other files and overwrite them. Use 2032 KB or less (the largest 8 KB multiple under the 4066-block limit). The ROM bundled with ENiGMA½ (enigma-vamiga 0.1.2 and later) carries the fix, as do AROS builds since (AROS#1720), and Kickstart 3.1’s filesystem has no such limit, but
make_image.shmakes 2000K images by default and warns about bigger ones, so an image also works with an older AROS ROM given throughrom. Check an image you built bigger with amitools’xdfscan. - Images up to about 800 MB, named
.hdf. The emulator reserves the image’s size in its address space but loads only the parts the door touches. - One caller per emulator. Every session is its own emulated machine, with the memory and CPU that costs: about 60 MB of memory per running door whatever the size of its image (a 100 MB image cost about 340 MB per session before ENiGMA½ 0.6.0), and about 7% of one CPU core while the door sits idle waiting for a key (measured on a current 16-core desktop; about 40% more than before 0.6.0, from the newer emulator core). Use
nodeMaxto bound it. - One writer per image. Doors that persist on the same image take turns, and do not run alongside non-persisting doors on it (see Persistence).
- ARexx needs your Workbench. AROS does not have ARexx; ARexx and C-Net ARexx doors run only on an image built with your own Workbench 3.1 (
amiga-door create --workbench). - No transfers from doors. A door cannot start a ZMODEM (or any other) file transfer to the caller.
- No sysop break. There is no way for the sysop to break into a running door’s session from the door.
- No
JH_EFeditor. A door that asks the BBS for its full-screen editor is refused, and the door carries on without it. - XIM, ARexx, Paragon, C-Net ARexx and CLI doors only. C-Net’s C pfiles, which read C-Net’s own memory, and ARexx pfiles that need
cnet.libraryare not supported; nor are doors for other BBSes’ libraries (DLG’s, Xenolink’s). - CLI doors have no window. A CLI door that asks its console for the window size gets no answer; it should take the screen length from its command line.
Troubleshooting
Section titled “Troubleshooting”The door never registers. The shim waited regTimeoutSeconds for the door to announce itself and gave up, and the caller was returned to the menu. Turn on log: true and read the debug log. Usual causes: the door path is wrong (it must be a path inside the image, written with BBS:), the door needs a file or library that is not on the image (it will fail quietly before it reaches the shim), or the door is not an XIM door.
A CLI door ends at once, with no output. It could not start or quit before printing anything, usually for want of a library. The exit is logged with the door’s return code (rc). Check the libraries the door needs (see CLI Doors) and that its configuration files are where its documentation says.
An ARexx door ends at once. The log line for the exit says why. error=no rexxsyslib: the image has no ARexx; build it with amiga-door create --workbench. ARexx is not running: RexxMast is not on the image or did not start. script ended without a host command with an out= text: the script stopped before it said anything, usually an ARexx error (shown) or a missing ADDLIB library.
A C-Net ARexx door stops with “Error: … Line: …” on the screen. Most pfiles trap every failed command (SIGNAL ON ERROR) and print where it happened. The usual cause is a command the script runs with address command that is not on the image (Bad Libs needs C:QSort; Workbench’s own commands come with -w), or a missing directory under PFILES: or CNET:. An exit with script ended without a host command is a script ARexx could not run at all (the out= text says why), or a door path that is not a script.
A Paragon door ends at once. The exit is logged with door exited without a DoorControl request and the first line the door printed, often its own complaint: a port it could not find (the door wants another BBS type or a line argument of its own; see its notes), a missing assign or library. A door that waits for something before its first request is reported after regTimeoutSeconds.
A CLI door waits for Return after every key. It expects a raw console and never asks for one; set consoleMode: raw.
Unknown ROM. The ROM given as rom is not one vAmiga knows. Use the bundled ROM, or a Kickstart ROM from a supported release (Kickstart 3.1 is the target).
“File does not match its type” for a ROM. vAmiga picks how to read a ROM from its file extension. A ROM file with no .rom or .bin extension is rejected with this message. Rename the file, for example kick31.rom.
The image is not bootable. The emulator booted but the shim never said hello. Check that the image is an FFS partition made by oputil.js amiga-door create (or make_image.sh), that C/axshim and S/Startup-Sequence are on it (oputil.js amiga-door info checks its structure and ls shows what is on it), and that the first session logs “Amiga door snapshot cached”. A raw floppy .adf is not a hard-disk image.
The first caller waits a moment, later ones do not. The first session boots the machine; the others restore a snapshot. A restart of ENiGMA½ empties the cache, and a session that wrote to the image makes the next one boot (see Persistence).
A door’s changes vanish. persist is false; or the door was stopped before it wrote them (it ignored a hangup for longer than disconnectGraceSeconds, or did not save before being given a break); or the final sync failed: the log says Amiga door disk sync FAILED with the reason (a full disk, a read-only file system, an image ENiGMA½ may not write). Something else writing the image while a door runs (a sysop’s xdftool, a copy put in place) is not detected and can damage the volume: change images only while their doors are idle.
"persistOn" is ignored since 0.6.0 in the log. Harmless: changes are now written as the door makes them. Remove persistOn from the door’s menu entry to silence it.
“Amiga doors need 0.2.0 or later” when a door starts. The installed enigma-vamiga is older than the one this ENiGMA½ needs; run npm install in ENiGMA½’s directory.
“Too many active instances” with nobody in the door. Another door on the same image is in use: a door that persists holds its image to itself for the whole session, and while non-persisting doors are in an image, a persisting one waits for them (and the other way round). Give the doors separate images to run them at the same time.
The door’s screen looks wrong. Try font: none for callers without SyncTERM fonts, or set encoding if the door writes something other than Latin-1.
Licensing
Section titled “Licensing”- AROS is distributed under the AROS Public License (APL 1.1). The ROM in
enigma-vamigais unchanged AROS, and its source is available from aros.org. - Kickstart and Workbench belong to their owners. ENiGMA½ does not ship them, and you do not need them. If you use
rom, it is your own copy. - vAmiga is under the Mozilla Public License 2.0. The patches ENiGMA½ makes to it are published in the
enigma-vamigapackage. - axshim and the image tools are BSD-2-Clause.
AEDoor.libraryis NilBBS’s MIT-licensed library, with a small patch. Doors are their authors’ own, under whatever terms they chose.