# Changes from live (stock SWGEmu 14.1 / Core3 unstable)

Running changelog of every deliberate gameplay divergence on this
server. Companion docs: `~/.claude/plans/` (design plans), memory
`pre9-jedi-overhaul` (ops ledger), `client-handout/` (player-facing
install). Stock baseline: Core3 `unstable` @ 6856f315a8, publish-14.1
data.

Legend: **LIVE** = active on the running server now. **STAGED** =
implemented + deployed on disk, activates at the next server restart
(and, where marked, the matching client tre update).

---

## 1. Pre-Publish-9 Jedi system (deployed 2026-07-03 — LIVE)

Replaces the 14.1 village/five-discipline/FRS Jedi with the original
2003-2004 system, rebuilt by un-hiding the dormant legacy tree that
still ships inside stock `skills.iff`.

- **Trees**: `jedi_padawan` (novice + 4 branches ×4 + master) plus the
  light/dark **journeyman** (2h sabers) and **master** (polearm)
  continuation trees — all 96 legacy rows un-hidden (GOD_ONLY/IS_HIDDEN
  flipped in the custom tre). The 14.1 `force_sensitive_* /
  force_discipline_* / force_title_* / force_rank_*` trees (208 rows)
  are hidden client-side and unlearnable server-side.
- **Novice Jedi Padawan costs all 250 skill points** (stock legacy data
  — a Jedi can hold no other profession). All deeper boxes are 0-point,
  XP-gated (saber lines on weapon-specialize XP; the rest on
  jedi_general; padawan master at 1.5M, matching the historical record).
- **Unlock: open to all** — trainer NPC **Vokara** (custom mobile,
  stock jediTrainerConvoTemplate) outside in Mos Eisley (3508 5 -4806)
  teaches all 90 legacy boxes. No village, no hologrind; the 250-point
  cost is the gate. `jediProgressionType = NOJEDIPROGRESSION`,
  `frsEnabled = 0` (village/trials/FRS retired — authentic: all are
  pub9+ additions).
- **Kinetic lightsabers, ×2.5 damage**: all 195 saber templates
  converted (damageType LIGHTSABER→KINETIC — armor mitigates normally,
  no bypass; static and crafting-experimental damage scaled ×2.5;
  knobs PRE9_DAMAGE_TYPE / PRE9_DAMAGE_MULT in
  custom_scripts/object/pre9_sabers.lua). Examine shows Kinetic.
  Historical note: era sources conflict (energy vs kinetic); user's
  period screenshots show kinetic — one-constant flip if ever revisited.
- **Zero Force costs everywhere**: 115 command registrations zeroed
  (powers, heals, buffs, saber specials) + weapon per-swing forceCost 0
  + crafted-saber forcecost experimental slot zeroed. Force pool
  remains as a stat; nothing drains it.
- **Crafting kept**: fossil boxes grant the gen1-5 saber schematic
  groups (9 missing/case-mismatched schematic_group rows appended in
  the tre); gen certs (`cert_*lightsaber_gen1-4` + training) appended
  to the right boxes; crystal/pearl system untouched.
- **Light/dark mutual exclusion — engine-enforced**: Core3 parsed but
  never enforced `PRECLUSION_SKILLS`; added the check in
  `SkillManager::fulfillsSkillPrerequisites` (before the isPrivileged
  bypass, so staff/frog grants are bound too). Fossil preclusion data is
  symmetric on the journeyman novices; everything deeper chains via
  SKILLS_REQUIRED — one side locks out the other completely.
- **Blue frog Jedi grants** (branch-granular — LIVE): Character Options → Learn Skill → **Jedi (Pre-9)** → per
  tree: Novice, each branch's I-IV individually, Master. Recursive
  grants pull prerequisites (padawan novice's 250 points still charged
  → fresh characters only). Denials (points, preclusion) are silent —
  stock frog behavior.

## 2. Perfect Resources on the blue frog (deployed 2026-07-03 — LIVE)

- Frog → Items → Deeds → **Perfect Resources**: vet-deed-style chooser
  over the STATIC resource class tree (recycled + statless classes
  filtered). Picking a leaf shows a stat preview and grants a
  **100,000-unit container** with every applicable stat = **1000**.
  `perfect_resource:<qty>` token variant exists for smaller grants.
- Engine: singleton spawns named "Perfect <Class>" built on the
  recycled-resource template — no spawn maps, never in shift, NOPOOL →
  **permanently invisible to survey/sample/harvesters**; persisted in
  the resourcespawns DB; reused on repeat grants; stats above class
  caps are safe (crafting normalizes at ≤1000 = 100%).
- **Stock leak fixed**: `ResourceMap::addToSuiListBox` now skips
  out-of-shift spawns — the veteran Resource Deed browser can no longer
  hand out recycled resources (stock bug) or perfect ones. Visible
  side effect: deeds list only currently-spawned resources. KEEP this
  fix even if the feature is ever rolled back.

## 3. Player lots: 10 → 200 (LIVE since 2026-07-03 restart)

- New characters: `maximumLots = 200` knob added to
  `player_creation_manager.lua`, parsed/applied by PlayerCreationManager
  (new config plumbing; guarded to 10 if absent/invalid).
- Existing characters: `maximumLots` is persisted per character — use
  the stock admin command **`/adjustlotcount <n>`** (targets the
  selected player, ADDS to their max; e.g. target + `/adjustlotcount
  190`). Works on the RUNNING server right now, no restart needed.

## 4. Blue frog in every new character's inventory (LIVE since 2026-07-03 restart)

- `terminal_character_builder.iff` appended to `commonStartingItems`.
- NOTE: needs one in-game test that the frog's radial works from
  inventory (expected to — the SUI flow is object-based); if it turns
  out to require world placement, drop it from inventory first.
- Existing characters: admins can `/object createitem
  object/tangible/terminal/terminal_character_builder.iff`.

## 5. All city deeds on the blue frog (LIVE since 2026-07-03 restart)

- Frog → Items → Deeds → **City Deeds**: all **78** city structure
  deeds, grouped by planet (Corellia/Naboo/Tatooine: civic — Bank,
  Cantina, City Hall, Cloning Facility, Garage, Hospital, Shuttleport,
  Theater — plus Gardens; Dantooine/Dathomir/Endor garden styles too).
  Generated injector — regenerate with
  `~/code/pre9-jedi/gen_city_deeds.py` after upstream pulls.

## 6. Inventory capacity: 80 → 1000 (LIVE server-side since 2026-07-03 restart; client needs r2 copy)

- `containerVolumeLimit` patched 80→1000 in
  `object/tangible/inventory/shared_character_inventory.iff`, shipped
  in **pre9_jedi_r2.tre** (replaces r1 in the server TreFiles override
  — both files kept on disk; r1 line swapped to r2 in config-local).
- One artifact serves both sides: the server reads the same template
  from its tre stack (limit is read live → applies to existing
  characters), the client renders/limits from its copy. Client must
  swap to r2 (see client-handout/) — a transitional r1-client vs
  r2-server mismatch is benign (lower value wins in UI behavior).

## 7. Solo-QoL batch 2 (2026-07-03 — STAGED, pending batch rebuild + restart)

- **Player city ranks need 1/2/3/4/5 citizens** (stock 2/4/6/8/10) —
  `CitizensPerRank` in `managers/city_manager.lua`. A lone mayor
  sustains an Outpost; Township (rank 3 = registration eligibility)
  needs 3; Metropolis needs 5.
- **15 characters per galaxy** (stock 10) — `Core3.PlayerCreationManager.
  MaxCharactersPerGalaxy = 15` appended to config-local.lua (pure
  config; the client's "limited to 10" error text is cosmetic and only
  shows when the real 15-cap trips).
- **10 characters online per account at once** (stock 2) —
  `onlineCharactersPerAccount` in `managers/player_manager.lua`.
  (Admin-level characters bypass the check entirely, as stock.)
- **Training costs 25% of stock** — ×0.25 (floored) at all three
  `getMoneyRequired()` sites (`screenplays/trainers/trainerConvHandler
  .lua` ×2 — the only real charge path — + `skillTrainer.lua` display).
- **XP rate 20×, all types** — `globalExpMultiplier = 20.0` in
  `managers/player_manager.lua`. Applies to every type incl.
  jedi_general (which keeps its stock ×0.2 combat-kill pre-scale, i.e.
  jedi earns 20× ITS stock rate; flip the 0.2f in
  PlayerManagerImplementation.cpp:2172 only if jedi should also shed
  the stock penalty). Per-skill XP_CAPs still gate — you fill them 20×
  faster, never past them.
- **Stat migration anywhere out of combat, all players** (stock:
  tutorial zone or staff only) — gate replaced in
  `RequestSetStatMigrationDataCommand.h` with an `isInCombat()` block;
  species bounds + total-points anti-cheat checks kept. [C++ — in the
  pending batch rebuild]
- **Blue frog Credits: 100,000,000 per click** (stock 50,000) —
  SuiManager.cpp credits token. [C++ — in the pending batch rebuild]

- **Factory production time −75%** — per-item time = complexity ×2
  (stock ×8), single site in FactoryObjectImplementation.cpp:569 (the
  examine "manufacture_time" reflects it). [C++]
- **Factory crates hold 1000** — uniform, set at crate creation
  (TangibleObjectImplementation.cpp:1216; stock used the schematic's
  factoryCrateSize, typically 10-50 — never actually 100; the idl 100
  was a dead fallback). [C++]
- **Resource crates hold 10,000,000** (stock 100,000) —
  ResourceContainer.idl MAXSIZE; every spill/clamp/display/packet reads
  the constant, int32-safe throughout. Perfect-resource frog grants now
  hand a full 10M crate (PERFECT_RESOURCE_QUANTITY tracks MAXSIZE).
  [IDL]
- **Housing storage = 100,000 items per lot** (stock lots×100 capped at
  400) — BuildingObjectImplementation.cpp:1071 + MAXPLAYERITEMS ceiling
  raised (BuildingObject.idl). Civic structures keep 250. Practical
  note: a house with six figures of items will strain the client when
  opening/rendering — the cap permits it, physics is your problem. [C++/IDL]
- **Jetpack deed on the frog** — Items → Deeds → Vehicle Deeds →
  Jetpack (stock ships it commented out; deed/PCD/vehicle all
  registered, no cert required). Via pre9_frog_extras.lua injector.
- **Clothing Attachment Builder on the frog** — Items → "Clothing
  Attachment Builder" (token sea_builder): SUI lists the 113 lootable
  clothing-attachment skill mods **plus 24 builder-only extras**
  (`seaBuilderExtraMods` in loot_manager.lua — tweak the list there, no
  rebuild: jedi saber assembly/experimentation/customization,
  saber_block, saber speed+accuracy per type, force-power accuracies +
  force_choke, force pool max/regen, jedi_toughness, and the five
  engine-consumed weapon toughnesses: lightsaber/onehandmelee/
  twohandmelee/polearm/unarmed — ranged weapons have no toughness hook
  stock, and the legacy per-type saber toughness mods are engine-inert,
  so neither is listed). Extras never appear on random looted SEAs.
  Pick up to 6 (each +25), the [ Create ] row mints a clothing SEA
  (object/tangible/gem/clothing.iff) carrying all chosen mods. SUI
  lesson from the first cut (fixed same day): a no-other-button listbox
  returns the row in args[0], and button labels only render from @
  stringfile refs. Paired engine change: WearableObjectImplementation stock
  applied only ONE mod per attachment (break after first) — removed,
  so ALL mods on an attachment apply into its socket (bounded by the
  stock ≤6-mods-per-wearable guard; loot SEAs benefit too). NOTE:
  sockets only exist on CRAFTED wearables experimented with the
  "sockets" line (looted clothing has none) — craft socketed garb to
  use SEAs. [C++: new SeaBuilderSuiCallback.h, SuiManager token,
  LootManager mod-list accessor, WearableObjectImplementation]

## 11. Galaxy renamed to "New Kettemoor" (2026-07-03)

DB change only: `galaxy` table `name` column (galaxy_id 2, was
"Core3"). Shows on the client server list and in server logs
([ZoneServer New Kettemoor]). Update via
`podman exec swgemu-db sh -c 'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" swgemu -e ...'`.

## 10. Player-city STARPORTS (2026-07-03)

New civic structure line: **starports** — shuttleport client visuals,
full starport function. Per planet style (Corellia/Naboo/Tatooine,
mirroring the shuttleport variants and their allowedZones):

- **Interplanetary travel**: the starport building spawns a distinct
  `starport_shuttle` template; `ScheduleShuttleTask` (C++) detects it
  and flags the player-city travel point interplanetary (stock
  hardcoded false). Ticket terminal then offers cross-planet
  destinations both ways (fees per planet-pair from travel.iff; both
  endpoints must be interplanetary — static starports already are).
- **JTL ship launch**: a `terminal_space.iff` child object on the pad —
  launch keys purely off the SPACETERMINAL type + per-planet JTL
  config, so no launch C++ was needed.
- **Civic like shuttleports**: mayor-placed in a rank-4 city
  (place_shuttleport ability), unique per city, lotSize 0, **double**
  city maintenance (50,000 vs 25,000). NOTE: civic placement gates
  (in-city + mayor) intentionally still apply to everyone — the §8
  admin bypass covers non-civic structures only.
- **Master Architect exclusive**: schematics live in the
  `craftPlayerCityE` group (granted by crafting_architect_master) via
  tre rows — no skills.iff change. TWO more pieces proved necessary
  (found 2026-07-03 when the schematics showed "unknown" and wouldn't
  list): (1) SERVER: a schematic_group row alone doesn't create the
  DraftSchematic OBJECT — those persist in the `draftschematics` ODB
  and are only seeded from `schematics = {…}` lists; added
  `custom_scripts/managers/crafting/schematics.lua` with the 3 paths
  (boot log must show "Loaded 3 schematics from
  scripts/custom_scripts/managers/crafting/schematics.lua" on first
  boot, then they live in the DB). (2) CLIENT (r4): the client names a
  draft schematic via its craftedSharedTemplate -> crafted deed's
  objectName, and resolves paths through
  misc/object_template_crc_string_table.iff — r4 ships 6 cloned shared
  templates (shared_starport_{p}.iff with craftedSharedTemplate
  repointed; shared_starport_{p}_deed.iff with objectName/
  detailedDescription -> @deed:{p}_starport_deed) + 6 crc-table
  entries; server templates' clientTemplateFileName now point at the
  clones (client MUST be on r4 — the launcher moves both together).
  Also: **complexity 30 requires a PRIVATE structure crafting station**
  (personal tool caps at 20, public station 25, private station 100) —
  intended Master-tier constraint, craft next to a placed private
  structure station. Costs ~2.5× shuttleport: 3875
  metal / 5875 ore / 875 ore / 30 wall modules / 8 power cores / 8
  storage / 3 advanced droid frames; complexity 30; 20,000 structure xp.
  Crafted deed name "Deed for: <Planet> Starport".
- **Templates**: all server-side clones referencing shuttleport SHARED
  client iffs (deed/building/schematic/shuttle) — zero client visuals
  changes. Deed display names via 3 new `deed.stf` keys in
  **pre9_jedi_r3.tre** (also carries the schematic_group rows; r3
  replaces r2 both sides). r4 sha256
  467d112ca3466840638bc81cb838214585276b19d67b5ea330ea47a9ffc8ef8d
  (r3 df3b2ef7… superseded same day),
  published through the launcher pipeline 2026-07-03 (spec → r3, r2
  obsoleted+removed; CLI sync simulation verified cfg patch + checksum).
- **Frog**: Starport deeds appear under City Deeds per planet.
- Generated injector: `custom_scripts/object/pre9_starports.lua`
  (regen: `~/code/pre9-jedi/gen_starports.py`). C++:
  `PlanetTravelPoint.h` (setInterplanetary), `ScheduleShuttleTask.h`
  (detection + STARPORT scheduling) — ledger additions.
- Known cosmetic side effect: bounty-hunter mission targets may pick a
  player starport as a spawn point (getRandomStarport includes them).

## 9. Frog Factory Crates section (2026-07-03)

Items → **Factory Crates** → Tailor: mints full 1000-count factory
crates of all 9 statless tailor components (cargo pocket, fiberplast
panel, jewelry setting, metal fasteners, padding segment, reinforced
fiber panels, shoe sole, synthetic cloth, trim — every schematic under
draft_schematic/clothing/component/ carries no experimental properties,
so frog crates equal crafted ones). Menu token pattern
`crate:<server template path>` (SuiManager C++ branch — reusable for
future crate subsections: any registered tangible path works). Crate
visual auto-picks by item type; count shown as factory_count 1000.
Injector: custom_scripts/object/pre9_factory_crates.lua.

## 8. Admin structure placement in protected zones (2026-07-03)

Privileged (staff) characters can place structures from deeds anywhere —
inside NPC city limits (mid-Theed), no-build zones, water, POI margins.
Two permission gates in `StructureManager::placeStructureFromDeed` are
skipped for `isPrivileged()` placers: the `isBuildingPermittedAt` check
(no-build ActiveAreas / client-structure footprints / water / POI) and
the client-city-region rejection. The player-structure footprint
OVERLAP check still applies to everyone (no accidental stacking on
player buildings). Normal players see identical stock behavior. Design
note: the bypass lives at the placement call sites, NOT inside
isBuildingPermittedAt — its other callers (city decorations, mission/
bounty spawn spots) keep strict behavior. FOUR files carry the bypass
(the placement flow validates at each step, and each layer's error only
surfaces after the previous one is bypassed — found iteratively via
in-game testing): PlaceStructureModeCommand.h (deed use / enter
placement mode — client-city check, fires first),
PlaceStructureCommand.h (confirm — THREE gates: its own client-region
"city_too_close" check, the no-build ActiveArea loop, and
findObjectInNoBuildZone static-structure footprints),
StructureManager.cpp (final placement — isBuildingPermittedAt +
client-region), PlaceCityHallSuiCallback.h (city FOUNDING — range to
other player cities + the 2×-radius NPC-city buffer via
validateCityInRange/validateClientCityInRange, so a privileged mayor
can found a city inside Theed for a starport). [C++: 4 files]

---

## Local-diff ledger (recheck after every Core3 `git pull`)

**Stock C++ (rebuild required after pulls)** — all additive unless noted:
`Skill.h` (+getPreclusionSkills), `SkillManager.cpp` (preclusion check),
`ResourceSpawner.{h,cpp}` (perfect mint + chooser builders),
`ResourceTreeNode.h` (4 child accessors), `ResourceManager.idl`
(+PERFECT_RESOURCE_QUANTITY + 4 natives; autogen regenerates),
`ResourceManagerImplementation.cpp`, `ResourceMap.cpp` (2-line inShift
leak fix), `SuiManager.cpp` (perfect_resource token + include),
`PlayerCreationManager.{h,cpp}` (maximumLots knob). NEW file:
`sui/callbacks/PerfectResourceSuiCallback.h`.

QoL batch 2 additions: `RequestSetStatMigrationDataCommand.h` (out-of-
combat-anywhere gate), `SuiManager.cpp` (credits 100M + sea_builder
token), `FactoryObjectImplementation.cpp` (×2 timer),
`TangibleObjectImplementation.cpp` (crate cap 1000),
`ResourceContainer.idl` (MAXSIZE 10M), `BuildingObject.idl` +
`BuildingObjectImplementation.cpp` (storage/lot),
`WearableObjectImplementation.cpp` (apply all attachment mods),
`LootManager.idl` (+`include system.util.Vector` — idlc REQUIRES that
include for `Vector<T>` params, unlike C++) +
`LootManagerImplementation.cpp` (mod-list accessor + seaBuilderExtraMods
load; LootManager.idl also carries the @dereferenced extras member).
NEW file: `sui/callbacks/SeaBuilderSuiCallback.h`. Plus
`StructureManager.cpp` (privileged placement bypass, §8), the
`seaBuilderExtraMods` table in stock `managers/loot_manager.lua`,
`SuiManager.cpp` crate: token (§9), and the starport pair (§10):
`managers/planet/PlanetTravelPoint.h` (setInterplanetary) +
`objects/building/tasks/ScheduleShuttleTask.h` (starport detection).

**Stock Lua one-liners**: `commands/commands.lua` (EOF
RunSlashCommandsFile hook), `managers/jedi/jedi_manager.lua:14`
(NOJEDIPROGRESSION), `managers/jedi/frs_manager.lua:1` (frsEnabled=0),
`managers/player_creation_manager.lua` (maximumLots knob + frog in
commonStartingItems), `managers/city_manager.lua` (CitizensPerRank),
`managers/player_manager.lua` (onlineCharactersPerAccount 10,
globalExpMultiplier 20), `screenplays/trainers/trainerConvHandler.lua`
+ `skillTrainer.lua` (×0.25 training costs). Plus config-local.lua:
`Core3.PlayerCreationManager.MaxCharactersPerGalaxy = 15`.

**custom_scripts (untracked, survive pulls)**: object/{pre9_sabers,
pre9_charbuilder, pre9_perfect_resources, pre9_city_deeds}.lua +
serverobjects.lua hook lines; commands/pre9_zero_force.lua;
screenplays/pre9_jedi.lua; mobile/pre9_trainer_jedi.lua (+ hook files).

**Data**: `pre9_jedi_r2.tre` (skills.iff edits, schematic_group
appends, 1000-slot inventory template) first in server TreFiles
(config-local.lua) and at client searchTree_00_26. Build tooling:
`~/code/pre9-jedi/{build_tre.py, generate_phase1.py, gen_city_deeds.py}`.

**Boot health markers** (`podman logs swgemu`): pre9_sabers 195 /
pre9_zero_force 115 / pre9_charbuilder / pre9_perfect_resources /
pre9_city_deeds 78 / pre9_jedi trainer 90 boxes.
