====== Building from source ======
One source tree builds the versions. ''LORDSRC.ZIP'' has it, with ''BUILD.TXT''.
^ Version ^ Programs ^ Built with ^
| Linux | ''bin/lord'', ''bin/lordcfg'': native x86-64 programs, statically linked. | Free Pascal 3.2.2 for Linux. |
| DOS | ''LORD.EXE'', ''LORDCFG.EXE'', ''LORDFP.STR'': 16-bit DOS programs. | Free Pascal 3.2.2's i8086 cross compiler (target msdos, large memory model). |
| Windows | ''bin-win/lord.exe'', ''bin-win/lordcfg.exe'' for 64-bit Windows: the DOOR32.SYS door (''LORDFPW.ZIP'') and LORD Server's game. | Free Pascal 3.2.2 cross-compiling to win64: ''make windows''. |
The code that differs is inside ''{$IFDEF MSDOS}'', ''{$IFDEF WINDOWS}'' and their ''{$ELSE}'': the DOS side talks to a COM port (''doordos.inc''), the Linux side to stdin/stdout (''doorunix.inc''), the Windows side to the caller's socket from DOOR32.SYS, to pipes (LORD Server) or to the console (''doorwin.inc'').
===== The files =====
^ File ^ What it is ^
| ''Makefile'' | The Linux build. |
| ''dosbuild.sh'' | The DOS build. |
| ''mkdos.py'' | Splits the game into units and makes ''LORDFP.STR'' (DOS). |
| ''rttidecl.diff'' | A fix for FPC 3.2.2's i8086 RTL (DOS). |
| ''gen_records.py'', ''gen_tables.py'' | Make ''src/records_*.inc'' and ''src/tables.inc'' from lord.js's definitions. The generated files are included; only needed if the record layouts or tables change. |
| ''src/lord.pas'' | The game: globals and tables, then the include files. |
| ''src/*.inc'' | The game, by area (town, inn, forest, battle, ...). |
| ''src/doorkit.pas'' | Door I/O: drop files, ANSI output, keys, line input. |
| ''src/doordos.inc'', ''doorunix.inc'', ''doorwin.inc'' | The DOS, Linux and Windows I/O layers. |
| ''src/igm.inc'' | Other Places: runs DOS LORD IGMs. |
| ''src/lady.inc'' | Runs LADY scripts. |
| ''src/lordrec.pas'' | Data files: player.bin / PLAYER.DAT, state, lord.ini, locks. |
| ''src/lordcfg.pas'' | The set-up program, with ''cfgui.pas'' (screen and file helpers), ''cfgev.pas'' (LADY event installer) and ''cfg406.pas'' (LORD 4.06 tools). |
| ''src/lsys.pas'' | The SysUtils routines the DOS build uses. |
| ''src/strtab.pas'' | Reads the game's text from ''LORDFP.STR'' (DOS). |
| ''PORTING.md'' | Design notes for the port from lord.js. |
===== The Linux version =====
Tested on Ubuntu 24.04 (x86-64).
sudo apt install fpc make
make # in the directory LORDSRC.ZIP was unzipped into
This makes ''bin/lord'' and ''bin/lordcfg''. ''make clean'' removes the build. Copy them into the game directory.
===== The DOS version =====
- Install the tools. FPC 3.2.2 for Linux is the starting compiler that builds the cross compiler; NASM is the assembler the msdos target uses.sudo apt install fpc nasm git make python3 unzip patch
- Get the Free Pascal 3.2.2 source:git clone --depth 1 --branch release_3_2_2 https://gitlab.com/freepascal.org/fpc/source.git fpcsrc
- Apply the RTL fix:cd fpcsrc
patch -p1 < /path/to/rttidecl.diff Why: the compiler writes record field offsets in RTTI as PtrUInt, which is 4 bytes in the large memory model, but the RTL reads ''TRecordElement.Offset'' as SizeInt (2 bytes). Copying or freeing a record with two or more AnsiString fields then jumps to a bad address. The game copies such records all the time, so it crashes without the fix.
- Build and install the i8086-msdos cross compiler and its units, large memory model (a few minutes):
make all OS_TARGET=msdos CPU_TARGET=i8086 BINUTILSPREFIX= CROSSOPT="-WmLarge -CX -XX"
make crossinstall OS_TARGET=msdos CPU_TARGET=i8086 BINUTILSPREFIX= \
CROSSOPT="-WmLarge -CX -XX" INSTALL_PREFIX=$HOME/fpc-i8086
''BINUTILSPREFIX='' (empty) makes it call ''nasm'' rather than ''msdos-nasm''.
- Build the game, in the directory LORDSRC.ZIP was unzipped into:
sh dosbuild.sh
# or, with the cross compiler elsewhere:
FPCDIR=/somewhere/lib/fpc/3.2.2 sh dosbuild.sh
This makes ''bin-dos/lord.exe'', ''bin-dos/lordcfg.exe'' and ''bin-dos/LORDFP.STR''. Copy them into the LORD directory as ''LORD.EXE'', ''LORDCFG.EXE'' and ''LORDFP.STR''. Built this way they are identical to the ones in LORDFP.ZIP.
Steps 1-4 are only needed once.
===== The Windows version =====
Free Pascal for Linux cross-compiles to Windows with its own linker; it only needs the x86_64-win64 units, built once from a clean Free Pascal 3.2.2 source (not the one patched for DOS):
git clone --depth 1 --branch release_3_2_2 https://gitlab.com/freepascal.org/fpc/source.git fpcsrc-win64
cd fpcsrc-win64
make all OS_TARGET=win64 CPU_TARGET=x86_64 FPC=ppcx64
make crossinstall OS_TARGET=win64 CPU_TARGET=x86_64 FPC=ppcx64 INSTALL_PREFIX=$HOME/fpc-win64
Then, in the source directory, ''make windows'' makes ''bin-win/lord.exe'' and ''bin-win/lordcfg.exe'' (''make windows WINUNITS=...'' if the units are elsewhere). Test the DOOR32.SYS socket mode on Windows: Wine doesn't let a program use a socket handle it inherited.
===== How the DOS build fits in 640K =====
* An 8086 code segment is at most 64K, and so is the data group (DGROUP) that holds the global variables and constants. ''mkdos.py'' makes the sources in ''build-dos-src/'': ''lordglob.pas'' (the globals, types and tables), ''lfp_*.pas'' (one unit per include file) and a small ''lord.pas'' that uses them all.
* String literals of 8 characters or more are moved to ''LORDFP.STR'' and read back with ''S_(n)'', which keeps the text out of DGROUP. Windows-only text is kept in the units mkdos.py doesn't scan.
* ''lsys.pas'' replaces FPC's SysUtils, whose exception and Format code pulls in the floating point formatter and fills DGROUP. The game uses no floating point; the clock helpers use integers.
* ''LORDTXT.LRD'' is indexed by file offset and read one section at a time.
===== Naming =====
The game is a line-by-line port of lord.js, so the lord.js function names are kept (''sln'', ''lw'', ''lln'', ''more_nomail'' ...) and comments give lord.js line numbers. Internally the files keep their lord.js names (''player.bin'', ''state.bin'', ''lognow.lrd'', ''mail.lrd''); on DOS, ''dos_name'' in ''lordrec.pas'' maps them to the LORD 4.06 names.