Legacy Overview¶
What the original Applejack was, how it was built, and which copy to trust.
1. Identity¶
| Name | Applejack - Cider Core (gamemode/sh_init.lua:38) |
| Authors | Lexi; original gamemode by kuromeku (sh_init.lua:40) |
| Base | Derived from Sandbox — DeriveGamemode("Sandbox") (sh_init.lua:45) |
| Language | Lua, Garry's Mod 12/13 era |
| Size | 289 .lua files under gamemode/ and entities/ |
| Internal prefix | cider / cider_ — the gamemode's earlier name, still the entity and command prefix throughout |
Applejack and Cider are the same thing. Cider was the original; Applejack is the fork
that this repository preserves. The names are used interchangeably in the source, and every
entity class, every console command and every network message still uses the cider prefix.
2. Engine era — everything here is dead API¶
The original targets an engine generation that no longer exists. Every one of these is removed from modern Garry's Mod, let alone S&box:
| Legacy API | Used for | Status |
|---|---|---|
usermessage / umsg.* |
All server → client messaging | Removed (superseded by net, itself irrelevant to us) |
datastream (require "datastream", sh_init.lua:46) |
Bulk table transfer | Removed |
glon |
Table serialisation into SQL columns and files | Removed |
tmysql |
MySQL access (init.lua:99) |
Third-party binary module, dead |
file.FindInLua |
The entire file loader | Removed |
_R.Player, _R.Item metatables |
The object model | Concept does not exist in C# |
DTInt / NWVar |
Entity state replication | Replaced by [Sync] |
There is no use of the net library anywhere in the codebase — that is how old it is.
The practical consequence: 100% of the legacy transport, serialisation and persistence layers must be rewritten. There is nothing to salvage below the gameplay-rules line, and attempting to preserve any of it would be actively harmful. See 11_NETWORKING_LEGACY.md.
3. The two copies¶
legacy/ contains two snapshots of the same gamemode.
legacy/applejack-old-final/ — canonical¶
Use this as the reference for all behaviour documentation.
legacy/Applejack/ — a later content fork¶
110 files differ, but only ~27 differ once line endings and whitespace are normalised. Only
two engine-level files genuinely diverge (libraries/sv_entity.lua,
metatables/sv_player.lua), plus the vehicles plugin. Everything else is content.
Worth taking from it as concepts, not code:
| Addition | Why it matters |
|---|---|
gamemode/plugins/crossserverchat/ |
Cross-server chat relay — evidence of a multi-server deployment |
Tiered contraband: cider_money_printer_2/3/4, cider_drug_lab_2/3/4 |
An upgrade progression the canonical copy lacks; good input to the crafting/economy design |
items/drinks/beer.lua |
Trivial |
Conversely applejack-old-final has items/illegal_weapons/cider_tranq.lua, which the fork
lacks.
Rule: when the two disagree on behaviour, document applejack-old-final and note the
fork's variation in a footnote.
legacy/content/ — reference assets, not in git¶
~162 MB of Source 1 models, materials and sounds. Present on disk, deliberately excluded by
.gitignore. It is copyrighted Garry's Mod content and cannot ship. It is useful only for
reading art direction, prop naming and the container model list. No asset is migrated.
4. Load order¶
Understanding the boot sequence matters because in the original, load order is load-bearing — items query plugins at include time, and jobs query items. This coupling is one of the things the new architecture explicitly designs out (Architecture/02_MODULE_MODEL.md).
From gamemode/sh_init.lua:
timer.lua custom timer.Conditional
DeriveGamemode("Sandbox")
require("datastream")
sh_enumerations.lua
sh_config.lua ~25 KB of tuning values
sv_config.lua (server only — DB credentials)
libraries/*.lua explicit prefix-dispatched loop ← pass 1
doload("libraries/") generic loader ← pass 2 ⚠ DOUBLE INCLUDE
doload("metatables/")
doload("hooks/")
gamemode.Call("LibrariesLoaded")
sv_commands.lua, sv_umsgs.lua (server) / cl_content.lua (client)
GM:LoadPlugins() ← plugins load BEFORE items
GM:LoadItems() ← items may call GM:GetPlugin(...)
sh_events.lua
sh_jobs.lua ← jobs reference item categories
derma/*.lua (client UI)
⚠
libraries/is included twice — once by the explicit loop atsh_init.lua:105and again bydoload("libraries/")atsh_init.lua:157. Every library file executes twice on every boot. See 12_DEFECTS_AND_LESSONS.md.
File-prefix convention¶
The loader dispatches purely on the first three characters of the filename:
| Prefix | Server | Client |
|---|---|---|
sv_ |
include |
— |
cl_ |
AddCSLuaFile (sent to client) |
include |
sh_ |
include + AddCSLuaFile |
include |
This is a genuinely good idea badly implemented — realm is declared by filename rather than
scattered if SERVER branches. The new architecture keeps the intent (explicit realm)
with C# types and attributes instead of filename magic.
5. Top-level anatomy¶
gamemode/
├── sh_init.lua (loader, above)
├── init.lua 47 KB — server bootstrap, payday loop, damage rules
├── cl_init.lua 36 KB — client bootstrap, HUD, ESP
├── sh_config.lua 25 KB — all tuning values + container/contraband tables
├── sv_commands.lua 58 KB — ~66 chat command implementations
├── sh_jobs.lua job/team definitions (data)
├── sh_events.lua event enumerations
├── libraries/ 16 files, 4094 lines — the framework
├── metatables/ the data model (player, item, entity)
├── hooks/ sh_player, sv_player, sv_sandbox
├── items/ 139 files across 15 categories — content
├── plugins/ 16 plugins — optional gameplay
├── derma/ VGUI panels
└── scoreboard/
entities/
├── entities/ 8 SENTs (cider_item, cider_padlock, printers, drug labs…)
├── weapons/ 17 SWEPs on a shared rg_base
└── effects/ 9 muzzle-flash / shell-eject effects
The three largest files — init.lua, cl_init.lua, sv_commands.lua — are classic God
files. Between them they hold the game loop, damage model, spawn logic, HUD, and every
command. Splitting these is the single biggest structural change in the rewrite.
6. What is worth taking¶
To be explicit, because the temptation runs the other way:
Take: the tuning values, the gameplay rules, the command vocabulary, the job hierarchy, the door/access model as a concept, the negative-size pocket mechanic, the log category taxonomy, the realm-declaration discipline.
Leave: every line of implementation. All of it.