# Chaos Deathmatch portable build notes

This source tree was updated from the original Chaos Deathmatch 1.14B4-style code so it can still build the old Linux i386 module while also building modern 64-bit game modules.

The goal of this pass was portability and obvious bug repair only. No intentional weapon balance or gameplay feature changes were made.

## Build examples

Native x86_64 Linux:

```sh
make ARCH=x86_64
```

Native i386 Linux, requires 32-bit/multilib headers and libraries:

```sh
make ARCH=i386
```

Native aarch64/arm64 Linux:

```sh
make
# or explicitly:
make ARCH=arm64
```

Cross-compile Linux arm64 from x86_64:

```sh
make ARCH=arm64 CC=aarch64-linux-gnu-gcc
```

Windows x64 with MinGW-w64:

```sh
make ARCH=win64
# or:
make win64
```

Outputs are written under `build/<build>-<arch>/`, for example:

- `build/release-i386/gamei386.so`
- `build/release-x86_64/gamex86_64.so`
- `build/release-arm64/gamearm64.so`
- `build/release-win64/gamex86_64.dll`

Use `BUILD=debug` for debug builds.

## Build-system changes

- Replaced the old single-target Makefile with a portable multi-arch Makefile.
- Added `ARCH=i386`, `ARCH=x86_64`, `ARCH=arm64`, and `ARCH=win64` targets.
- Added convenience targets: `linux-i386`, `linux-x86_64`, `linux-arm64`, and `win64`.
- Normalized native `uname -m` value `aarch64` to `arm64`, so native ARM64 builds produce `gamearm64.so` rather than `gameaarch64.so`.
- Kept Linux i386 output as `gamei386.so`.
- Added x86_64 Linux output as `gamex86_64.so`.
- Added ARM64 Linux output as `gamearm64.so`.
- Added Win64 output as `gamex86_64.dll`.
- Fixed the Win64 compiler selection bug where `make win64` could accidentally keep using host `gcc` and then fail at link time on `-Wl,--export-all-symbols`.
- Win64 builds now default to `x86_64-w64-mingw32-gcc` when the user did not explicitly set `CC`.
- Removed `-fPIC` from Win64 builds while keeping it for Linux shared objects.
- Added `-fcommon` so the old header-defined globals continue linking under modern GCC defaults.
- Added `BUILD=debug` and `BUILD=release` separation with per-arch build directories.

## 64-bit / compiler compatibility changes

- Replaced Quake II field-offset macros with `offsetof`-based versions for 64-bit correctness.
- Included the needed standard header support for `offsetof`.
- Guarded MSVC-only pragmas and x86 inline assembly with `_MSC_VER`, not `_WIN32`, so MinGW/GCC do not try to parse MSVC-only code.
- Kept generic Windows path sections under `_WIN32` where they are not pragma/compiler-specific.
- Avoided making the tree purely 64-bit: i386 remains supported through `make ARCH=i386`.
- Fixed `INFINITY` naming collision risk with modern math headers by keeping bot route infinity under its own project-local name.
- Added/kept missing prototypes needed by modern compilers.

## Obvious bug fixes included

These are fixes I considered obvious from compiler diagnostics, local code inspection, or the root `KNOWNBUGS` / `MAYBEBUGS` files. I avoided speculative fixes where the intended behavior was unclear.

- Fixed several format-string hazards like `sprintf(buf, user_string)` by converting them to bounded `snprintf(buf, sizeof(buf), "%s", user_string)` copies.
- Fixed Win32 path construction sites that appended raw strings through `sprintf(file + i, source)`.
- Fixed the CTF auto-team comparison typo: `team1count < team1count` is now `team1count < team2count`.
- Fixed bot weapon pickup logic using `!current->solid == SOLID_TRIGGER`; it now correctly tests `current->solid != SOLID_TRIGGER`.
- Fixed bot waving health check using `!ent->health > 0`; it now correctly tests `ent->health <= 0`.
- Fixed an accidental semicolon in bot armor pickup logic that made the armor check always return failure.
- Initialized the flash-grenade blend alpha to avoid using an uninitialized float.
- Initialized the bot-chat `line` counter before parsing.
- Fixed the StdLog death-flags format string from `%ul` to `%lu`.
- Fixed flashlight cleanup paths so freed flashlight entities are cleared instead of leaving stale client pointers.
- Fixed flashlight-off/disconnect paths that only scheduled a free by `think` instead of immediately freeing and clearing the pointer.
- Added a Vortex visibility check so it no longer pulls valid targets through solid walls.
- Allowed the Vortex to affect ordinary nearby items, while still excluding CTF flags and CTF tech items.
- Added `turret_base` as a Vortex target so turret bases are not left behind when the visible turret entity is destroyed.
- Added a grapple line-of-sight sanity check while attached; if solid geometry appears between the player and hook, the grapple resets instead of remaining through a wall.

## Known items intentionally not changed

- I did not rebalance turret ammo, weapon damage, bot accuracy, Vortex radius, or any cvar defaults.
- I did not import the newer GitHub tree wholesale because that branch mixes bug fixes with new weapons, effects, menu work, model changes, rebalancing, and other gameplay changes.
- The Airfist wall-push bug is noted in `KNOWNBUGS`, but I did not change Airfist physics because the safe fix is not obvious without gameplay testing. It already checks `visible()` and `infront()` before pushing entities, so a deeper fix would likely alter movement behavior.
- The CTF spectator-mode bugs are still listed because the exact intended behavior is not obvious from this source alone.
- The client "no such oldframe" warning is still listed because it appears harmless and the correct fix is not obvious.

## Verification performed here

Verified in this environment:

```sh
make ARCH=x86_64
```

Result:

```text
build/release-x86_64/gamex86_64.so
ELF 64-bit LSB shared object, x86-64
GetGameAPI exported
```

Also checked `make win64 -n`; it now emits `x86_64-w64-mingw32-gcc` commands instead of host `gcc` commands. This container does not have MinGW-w64 installed, so the actual Win64 build cannot be completed here.

The i386 build still requires multilib support such as `gcc-multilib` and 32-bit libc development headers.
