Why is there a UI virtual machine?

Over the last four years since I started modifying ioquake3, there have been occasions when I’ve wondered why Quake III Arena has separate UI (user interface: main menu, pause menu) and cgame (client-game: HUD, world scene generation, movement prediction, etc) virtual machines. They both run on the client and duplicate various code between them. Merging them had crossed my mind, though I hadn’t ever given it serious thought.

With the idea of having four player splitscreen with each player being able to open a menu, it seemed worth investigated merging UI and cgame as implementing per-player menus seemed difficult in UI and cgame because of the way input is handled. (As well as idea of allowing touch screens to cause things to happen when touching HUD elements.)

Why were UI and cgame VMs separate to begin with? How did id Software handling this before and after Quake III Arena?


Note: I’ve only modified ioquake3 and Sonic Robo Blast 2 (a Doom-based game), the rest are purely based on reading stuff online (including some source code).

Doom had a single executable. There were DEHACKED scripts which were applied to the doom exe, so the changed could be distributed / easierly changed. Later Doom source ports supported loaded DEHACKED scripts to change the game-logic. Doom multiplayer was peer-to-peer, so the game logic was always run (no client-side prediction code iirc).

Quake has compiled QuakeC, similar to C, game logic for server. Menus and scene rendering are handled by client (and cannot be changed by mods). I’m not sure if / how cgame-like client-side prediction was done.

Quake 2 has a single game DLL that was used by server. Like Quake menus and scene rendering are handled by client and not modable. Once again, I’m not sure if / how cgame-like client-side prediction was done.

Quake 3 makes UI and client-game modifiable for the first time in id Tech history, as far as I know.

Doom 3 has game and cgame-ish client-prediction together in one game DLL, with menus/HUD handled by client using gui scripts loaded from pk4 files.

My opinion based on limited research and speculation

Quake 3 is unique for splitting the code modifiable parts up, the rest only have one (or two, if you count Doom 3 GUI scripts).

cgame is closely related to game. You should always have the matching cgame for game, as they share Pmove (main player movement function), item definitions, etc. However, making the UI separate allows it to be replaced/modified separate. This allows for UI-only mods, as mods would not need to change the UI (before Quake 3, they couldn’t [other than EXE editing, which is pretty limited]).

Game and cgame were combined in Doom 3, it simplifies changing / write some of the prediction code (somewhat just by having the code in the same place or file?). With Doom 3 they could have kept UI as a DLL (used for HUD and menus), but they went with scripts via client instead. (Hmm, actually I don’t know much about how UI gets info for HUD, must be from game DLL import API call?)

If a quake3-based engine were to follow Doom 3 engine architecture, I think it would be game-logic and client-side prediction in one DLL and HUD/UI in another DLL (which is no small task).

I don’t really know enough about Quake 3 mods to answer this but, I assume most mods either were game VM only or touched cgame and UI VMs (even if changed UI wasn’t required to play the mod). Though there are some UI-only mods, such as UIE.

Keeping game as-is, merging ui into cgame seems reasonable to me. It keeps the familiar overall architecture of the quake3 engine, uses less memory, gets rid of some annoyances, and simplify things a bit. (I never did like BG_ prefix meaning both game(s) used in all three VMs anyway!)

The only disadvantage I can think of with merging ui into cgame is no mixing UI VM only mods with cgame VM mods. I think it’s less of an issue as cgame and ui (for standalone games at least) are free and open source, whereas Quake 3 mods could be closed source using the Q3 SDK code and license.

Merge cgame/ui into game?

Ignoring where the code is located in the source files, I think merging cgame into game would benefit running local games and use more memory when connected to network servers (at least, assuming there is no dynamically allocating memory in the VMs). I think it would be more work and less useful than merging UI into cgame.