acdream/tools
Erik a1ffe77af4 feat: mosswart client icon and Asheron's Call-inspired launcher icon
acdream had no application icon on either executable. Two marks now ship,
built from the game's own material rather than drawn freehand:

* Client - the retail mosswart head. Not an illustration of one: the actual
  creature mesh (Setup 0x02000B4F part 14, skin atlas 0x05001E11,
  ClothingBase 0x10000344) read out of client_portal.dat through acdream's
  own GfxObjMesh/SetupMesh port, then smoothed, lit and graded. Palette
  values are sampled from that texture, including the mustard belly the
  Mosswart lore calls a "foul yellow".

* Launcher - a forged ring enclosing a barbed crescent, rebuilt from
  measurements of the retail wordmark and the acclient.exe icon resource.
  An original construction in the same visual language, not a copy of the
  trademarked logo. Its warm field matches the retail client icon.

Three techniques carry the render quality, all in tools/IconForge:

* PN-triangle tessellation (smooth.py). The retail head is 104 triangles
  and renders faceted. Each triangle becomes a cubic Bezier patch built
  from its own corner positions and normals, so the silhouette genuinely
  rounds rather than merely shading smoothly - and it needs no mesh
  connectivity, which matters because UV seams would otherwise pull apart.
  Normals are welded across coincident positions first, but only within a
  crease angle, so ear fins and tusk edges stay sharp.

* Matcaps (ring.py). A Lambert rasterizer cannot produce chrome, because
  chrome is almost entirely reflection and there is nothing here to
  reflect. Sampling a lit-sphere image by the camera-space normal is the
  standard stand-in for an environment map.

* Distance-transform bevelling (chisel.py). Flat shapes become chiselled
  metal by treating distance-to-edge as height. The height field is
  blurred before differentiating; without that the medial axis of each
  stroke shows through as a hatched ridge.

Two facts worth recording, both discovered the hard way. Creature Setups
define no upright pose in PlacementFrames, so the exporter must be handed
the weenie's MotionTable id or all 17 parts stack on the origin. And a
mosswart's eyes sit on the sides of the skull like a frog's, so a dead-on
frontal turns them edge-on and the face stops reading as a mosswart at all;
the hero angle is az 266 / el 32.

Wiring: <ApplicationIcon> gives each executable its PE icon. The client's
runtime window icon is embedded rather than copied beside the binary - a
window icon has no sensible fallback if the file goes missing, and
embedding survives single-file publish. WindowIconLoaderTests guards the
resource names, which are coupled to LogicalName in the csproj by string
alone and would otherwise fail only as a silently icon-less window.

Both halves of the pipeline are deterministic and reproduce the committed
PNGs byte-for-byte, so an accidental edit shows up as a diff.

Solution builds clean; 14,378 tests pass on the standard hermetic lane
filter, 0 failures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 14:42:10 +02:00
..
A8CellAudit build: make release restore reproducible 2026-08-18 10:29:00 +02:00
cdb docs(physics): #347 premise revision — retail may alternate too; ftp:edge ratio is the discriminator 2026-08-07 13:42:14 +02:00
cdb-scripts fix(motion): full queue reset on locomotion-cycle direct transitions 2026-05-03 17:00:55 +02:00
diag-logs diag(motion): instrumentation for remote walk↔run leg-cycle bug (Commit A) 2026-05-03 20:38:47 +02:00
dump-keymap build: make release restore reproducible 2026-08-18 10:29:00 +02:00
ghidra_project feat(core): port decompiled AC client physics — CollisionPrimitives + PhysicsBody 2026-04-12 23:54:51 +02:00
IconForge feat: mosswart client icon and Asheron's Call-inspired launcher icon 2026-08-20 14:42:10 +02:00
InspectCoatTex docs(issues): #37 — Investigation 2 narrows bug to SubPalette coverage gaps 2026-05-05 14:45:50 +02:00
jsonl test(phys): A6.P5 fixture — 3 ticks from live door-stuck capture 2026-05-25 12:43:51 +02:00
MosswartArt feat: mosswart client icon and Asheron's Call-inspired launcher icon 2026-08-20 14:42:10 +02:00
pdb-extract fix(chat): Campaign CH user-gate round 2 -- portal notice rerouted to SpewBox, verbatim /help extraction, jump-in-air evidence 2026-08-10 08:40:24 +02:00
PesChainAudit build: make release restore reproducible 2026-08-18 10:29:00 +02:00
ProjectileVfxAudit build: make release restore reproducible 2026-08-18 10:29:00 +02:00
RainMeshProbe build: make release restore reproducible 2026-08-18 10:29:00 +02:00
RetailTimeProbe build: make release restore reproducible 2026-08-18 10:29:00 +02:00
SetupInspect build: make release restore reproducible 2026-08-18 10:29:00 +02:00
ShaderCompiler build: make release restore reproducible 2026-08-18 10:29:00 +02:00
SkyObjectInspect build: make release restore reproducible 2026-08-18 10:29:00 +02:00
StarsProbe build: make release restore reproducible 2026-08-18 10:29:00 +02:00
TextureDump build: make release restore reproducible 2026-08-18 10:29:00 +02:00
WeatherEnumerator build: make release restore reproducible 2026-08-18 10:29:00 +02:00
WeatherSetupProbe build: make release restore reproducible 2026-08-18 10:29:00 +02:00
analyze_265_steep_slope_capture.py test(physics): #265 mining tool + real-trajectory replay harness for the steep-slope response family 2026-07-30 17:55:49 +02:00
analyze_269_slope_stop_capture.py fix(physics): port retail slope landing stop 2026-07-31 09:10:53 +02:00
analyze_resolve_capture.py tools+plan(#182): resolve-capture histogram classifier + verbatim player-physics rebuild plan 2026-07-07 13:37:15 +02:00
audit-test-inventory.ps1 test: audit helper-mediated source reads 2026-08-18 14:18:00 +02:00
CampaignLaProcessCorrelation.ps1 fix(launcher): harden LA11 gate evidence 2026-08-15 01:45:15 +02:00
capture-campaign-la-session-process.ps1 fix(launcher): harden LA11 gate evidence 2026-08-15 01:45:15 +02:00
compile-shaders.ps1 ci(render): make V9's first CI run green on both operating systems 2026-07-28 21:52:53 +02:00
connected-dense-town.route.txt fix(diag): bind stationary samples to route checkpoints 2026-07-24 12:54:57 +02:00
connected-r6-soak.route.txt fix(diag): bind stationary samples to route checkpoints 2026-07-24 12:54:57 +02:00
connected-world-lifecycle.route.txt test(runtime): add connected lifecycle gate 2026-07-20 22:39:34 +02:00
connected-world-reconnect.route.txt test(runtime): add connected lifecycle gate 2026-07-20 22:39:34 +02:00
decompile_acclient.py research: decompile acclient.exe terrain/physics via Ghidra headless 2026-04-12 23:18:27 +02:00
decompile_full.py research: full acclient.exe decompilation — 22,225 functions, 688K lines 2026-04-12 23:25:51 +02:00
DecompileTargets.java research: decompile acclient.exe terrain/physics via Ghidra headless 2026-04-12 23:18:27 +02:00
ghidra_decompile.py research: decompile acclient.exe terrain/physics via Ghidra headless 2026-04-12 23:18:27 +02:00
new-campaign-la-update-fixture.ps1 fix(launcher): harden LA11 gate evidence 2026-08-15 01:45:15 +02:00
publish-bin.ps1 ci: put the launcher's update pointer in a release, and delete the dist branch 2026-08-19 14:40:41 +02:00
README.md build: make release restore reproducible 2026-08-18 10:29:00 +02:00
run-blank-world-ab-probe.ps1 docs(render): the occlusion-query verdict on the V4c blank world, and the options 2026-07-28 01:44:34 +02:00
run-blank-world-surface-probe.ps1 test(render): add blank-world attribution apparatus and a post-world GL sample 2026-07-28 00:08:10 +02:00
run-campaign-la-preflight.ps1 fix(launcher): harden Campaign LA11 gate evidence 2026-08-15 01:08:41 +02:00
run-connected-loss-gate.ps1 docs(net): N5 accepted - Opus review PASS; loss gate strengthened per review 2026-07-29 16:40:55 +02:00
run-connected-r6-soak.ps1 feat(streaming): shadow-publish flat collision assets 2026-07-25 16:38:54 +02:00
run-connected-world-lifecycle-gate.ps1 feat(net): N5 - loss observability, lossy decorator, the connected loss gate 2026-07-29 16:26:06 +02:00
run-offline-pixel-gate.ps1 feat(render): Vulkan campaign V11 step 4 — retire GL from CI and gate scripts 2026-07-29 03:06:45 +02:00
run-offline-vulkan-capture.ps1 feat(render): Vulkan campaign V11 step 4 — retire GL from CI and gate scripts 2026-07-29 03:06:45 +02:00
run-portal-churn-soak.ps1 feat(render): Vulkan campaign V11 step 4 — retire GL from CI and gate scripts 2026-07-29 03:06:45 +02:00
run-release-gate.ps1 test: introduce Lane=Timing for load-sensitive tests, and stop chasing them individually 2026-08-19 15:29:10 +02:00
run-repeat-connected-gate.ps1 feat(render): Vulkan campaign V11 step 4 — retire GL from CI and gate scripts 2026-07-29 03:06:45 +02:00
test-campaign-la-gate-helpers.ps1 fix(launcher): harden LA11 gate evidence 2026-08-15 01:45:15 +02:00
test-campaign-la-script-safety.ps1 fix(launcher): harden LA11 gate evidence 2026-08-15 01:45:15 +02:00
test-campaign-la-session-status.ps1 fix(launcher): harden LA11 gate evidence 2026-08-15 01:45:15 +02:00
update-package-locks.ps1 build: make release restore reproducible 2026-08-18 10:29:00 +02:00
verify_un2_fmul.py UN-2 RESOLVED: GetMaxSpeed x4 is byte-verified retail; doc-comment was the misread 2026-06-12 13:17:50 +02:00

Maintained .NET tools

Every .csproj under tools/ is part of AcDream.slnx. The complete Release gate restores and builds these tools, so a missing personal checkout or an API change cannot leave a tracked tool silently broken. They are diagnostic/manual programs: the gate builds them but does not run data-dependent investigations.

Tool Purpose Runtime prerequisite
A8CellAudit Inspect landblock, EnvCell, portal, and collision topology. Installed AC DAT files / the arguments documented by the program.
dump-keymap Extract the retail master input maps and decoded actions. Installed client_portal.dat.
PesChainAudit Walk weather PES call chains and particle emitters. Installed AC DAT files.
ProjectileVfxAudit Audit projectile physics-script and particle-emitter VFX mappings. Installed AC DAT files.
RainMeshProbe Inspect rain surfaces, polygon sidedness, and generated mesh counts. Installed AC DAT files.
RetailTimeProbe Read retail time-of-day and sky state for comparison. Windows, a running retail client, and process-read access.
SetupInspect Dump Setup parts, placement poses, and animation frames. Installed AC DAT files and a Setup ID.
ShaderCompiler Compile the Vulkan GLSL shader set to committed SPIR-V. Source and output directory arguments.
SkyObjectInspect Inspect Dereth sky/day-group objects and texture data. Installed AC DAT files.
StarsProbe Audit sky-object geometry, UV ranges, and surfaces. Installed AC DAT files.
TextureDump Dump render-surface statistics and texture images. Installed AC DAT files.
WeatherEnumerator Enumerate weather sky objects and their bounds. Installed AC DAT files.
WeatherSetupProbe Inspect the parts and surfaces of weather Setups. Installed AC DAT files.

Build the complete maintained graph with:

dotnet restore AcDream.slnx --locked-mode --force-evaluate
dotnet build AcDream.slnx -c Release --no-restore

Use pwsh ./tools/run-release-gate.ps1 for the authoritative bounded gate. Package versions and lock-file maintenance are documented in docs/release-gate.md.