Files
link/docs/SHARD_PREREQS.md
Claude 710dd17745 Phase 0: fix runtime script compilation
ScriptCompiler.Compile() runs `dotnet build Scripts/Scripts.csproj -c Release`
with no Platform, so MSBuild defaults to AnyCPU. Scripts.csproj gated both
OutputPath and DefineConstants on Configuration|Platform == Release|x64, so
under the server's own build the DLL landed in Scripts/bin/Release/ (while the
core loads Scripts.dll from the base directory) and TRACE;NEWTIMERS;ServUO went
undefined (XmlSpawner compiled its non-ServUO branches).

Compile() also never checks the build's exit code before Assembly.LoadFrom, so
the failure was silent and the stale DLL reloaded. Runtime script compilation
had had no effect since 2026-05-30.

Condition both property groups on Configuration alone. Server.csproj is left
alone: nothing under Server/ uses those symbols, and giving it OutputPath=..\
would make the boot-time build try to overwrite the running ServUO.exe.

Verified end-to-end: a plain boot now logs "Core: Compiling scripts... / Build
succeeded." and loads 206208 items, 42771 mobiles.

Also adds the implementation plan, the measured performance budget, the test
scaffolding used to produce it (seeder + probe, both default-off), and the
record of shard repairs that had to precede any of this.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 04:34:18 -05:00

4.9 KiB

Shard prerequisites

Repairs the target shard (C:\Users\colby\Desktop\servuo, ServUO 57.4) required before the bridge could load. These are deletions and edits of existing files, so they cannot be expressed as an overlay copy. They are recorded here, and where practical as diffs under patches/.

Applied 2026-07-10. Backups on the Desktop: servuo_saves_backup_2026-07-10_032608, servuo_bin_backup_2026-07-10_032608, servuo_removed_files_2026-07-10.


The symptom

Scripts.dll had not been rebuilt since 2026-05-30 17:01. Every script change after that — including all of Scripts/Custom/Named/, MyStats.cs, and SearchAdd.cs — had never executed.

ScriptCompiler.Compile() (Server/ScriptCompiler.cs:38-58) shells out to dotnet build, prints the output, ignores the exit code, then Assembly.LoadFrom("Scripts.dll") and returns true. A failing script build is invisible: the stale DLL simply reloads. The retry loop at Main.cs:525 never trips.

Four independent breakages, all introduced between 17:14 and 21:55 on 2026-05-30.


1. Stray Server/Gumps/Gumps.cs

A byte-identical copy of Scripts/Services/Pet Training/Gumps.cs (75,468 bytes), sitting in the Server project. It declares namespace Server.Mobiles and extends BaseGump, referencing BaseCreature, PlayerMobile, TrainingPoint — all defined in Scripts. Server cannot reference Scripts, so Server.csproj failed with 35 errors.

Action: deleted. The canonical copy under Scripts/Services/Pet Training/ was edited 10 minutes later and is the one that matters.

2. Eleven duplicate creature classes

Scripts/Custom/{Named,Legendary}/ redefined classes already present in Scripts/Mobiles/Normal/, producing CS0111 / CS0579.

NamedEowmu, SkeletalCat, Windrunner. The stock files each define two types: the mount and an ICreatureStatuette item (EowmuStatue, …) that Scripts/Services/UltimaStore/UltimaStore.cs references. Deleting the stock files outright would have re-broken the build.

Action: removed only the duplicate mount class from each stock file; kept the statues.

LegendaryFireSteed, Kirin, Nightmare, OsseinRam, Phoenix, PolarBear, ShadowWyrm, TsukiWolf. Clean 1:1 pairs. All custom versions sit in namespace Server.Mobiles, so the serialized type name is unchanged, and each Deserialize guards on version and migrates from 0 (ShadowWyrm: if (version >= 1); FireSteed: if (version < 1) skill-cap migration; Kirin: if (version == 0) AI fixup).

Action: deleted the eight stock files. Custom wins.

3. PolarBear — a base-class change, not a version bump

Custom PolarBear : BaseMount; stock PolarBear : BaseCreature. The saved world contained a bear serialized through the BaseCreature chain, so loading it as a BaseMount misaligned the stream. World load aborted at Server.Mobiles.PolarBear serial 0x00000412 with Delete the object? (y/n).

Changing a saved type's base class is not version-migratable. The custom class also carried [TypeAlias("Server.Mobiles.Polarbear")], which would have hijacked the same records.

Action: restored stock PolarBear : BaseCreature; renamed the custom mount to LegendaryPolarBear and dropped the TypeAlias. Stock scripts referencing typeof(PolarBear) (TalismanSlayer, SpeedInfo, RoyalZooDonationBox, SummonCreature, PetTrainingHelper) continue to resolve to the BaseCreature.

Note: Scripts/Custom/Legendary/PolarBear.cs was renamed to LegendaryPolarBear.cs.

4. AnimalLore.cs referenced a package that does not exist

Scripts/Skills/AnimalLore.cs had using ShrinkSystem; and two IShrinkItem branches. No ShrinkSystem namespace exists anywhere in the repo, and IShrinkItem appears nowhere in the stale Scripts.dllthe code had never compiled or run. (Scripts/Misc/ShrinkTable.cs is unrelated stock: namespace Server, class ShrinkTable.)

Action: removed the using and collapsed the shrink branches back to the BaseCreature path. This restores exactly the behavior the shard was already running.


Verification

After the repairs, dotnet build Scripts/Scripts.csproj -c Release -p:Platform=x64 succeeded with 0 warnings, 0 errors. Rebuilding ServUO.exe and Ultima.dll from current source produced byte-identical binaries (same SHA-256), confirming the core was never stale in content — only Scripts.dll was.

With Phase 0 applied, a plain boot shows:

Core: Compiling scripts...
Build succeeded.
Core: Verified 6023 item and 1385 mobile types
World: Loading...
...done (206208 items, 42771 mobiles, 0 customs)

Unrelated, still open

DllNotFoundException: zlibwapi64 crashed this shard once (Crash 6-5-2026-22-38-3.log) while sending a packed gump. zlibwapi64.dll is present in the repo root, so this is a working-directory / native-load-path problem. It will bite the bridge if the bridge ever triggers a gump send. Resolve before load testing.