Commit graph

4688 commits

Author SHA1 Message Date
Erik
f8c4149ca3 docs(vt): slice-1 ledger — Part A re-review verdicts, round 3 dispatched
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 00:56:23 +02:00
Erik
44fd5ce580 docs(vt): slice-1 ledger — Part A round 2 landed, re-reviews dispatched
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 00:38:14 +02:00
Erik
a6c2e3918e docs(vt): VT1 complete, VT2 FINAL — every catalog doc citation-verified and folded
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 23:53:41 +02:00
Erik
7ac43cee63 docs(vt): fold the citation-pass corrections into KB 01 (tString rows not in Advanced Options, template schema is 8 tables with an empty Settings table, PluginCore list-builder ranges, bk.a semantics, RechargeHandlerSet read-back, ~~ prefix resolved)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 23:53:41 +02:00
Erik
b9029082ae docs(vt): slice-1 ledger — Part A round 1b complete, round 2 dispatched
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 23:39:27 +02:00
Erik
68627a873b docs(vt): slice-1 ledger — Part A fix round 1 (3/12) and round 1b dispatched
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:55:10 +02:00
Erik
208599fae7 docs(vt): slice-1 ledger — full App suite on the merged branch (36 pre-existing env-gated failures)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:43:47 +02:00
Erik
467cb1c381 docs(vt): slice-1 ledger — Part B merged at da0fcb374
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:42:20 +02:00
Erik
da0fcb3741 merge(vt): slice 1 Part B — multi-column <list> markup (review-closed)
Campaign VT slice 1 Part B: <list><column type=text|check|icon> with
per-column bindings, text onclick, width="*" auto share, row-bound
callback guards, shared UiCheckLamp, Meta/Monsters-shaped end-to-end
tests. Two Opus lenses + fix round + narrow re-review: MERGE-READY.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:40:54 +02:00
Erik
b44282071c docs(vt): owner clarification — VTank has no real API; acdream may create its own plugin API later
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:35:18 +02:00
Erik
4ce6ffe6ff docs(vt): KB index counts match the verified docs (49 instantiations / 66 entries; 11 waypoint types)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:34:41 +02:00
Erik
bda8745448 docs(vt): owner decision — no interop; slice 9 dropped, all plugins rewritten against acdream's own API
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:34:30 +02:00
Erik
d078863306 docs(vt): owner sharpened the UI decision — resemblance + same interactions, not VVS internals
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:32:02 +02:00
Erik
026b512074 fix(vt): list column fix round 11/11 — docs for the whole fix round
docs/plugin-ui-markup.md's Columns section is rewritten to match every
production change from items 1-9:

- New "Width semantics" section: width="*", the last-column-always-auto
  rule (and how it combines with an earlier explicit "*"), the
  non-last-column Build-time throw, and the runtime overflow clamp.
- The <column> attribute grammar table gains column onclick
  (type="text", optional, Action<int>) and points width at the new
  section instead of the retired "last column ignores its own width"
  one-liner.
- New "Short columns past their own row count" section: text/icon draw
  nothing, check draws unchecked.
- Check-column glyph section updated for the shared UiCheckLamp
  primitive and its horizontal centering.
- New "The PITCH convention for transcribing a VTank column table"
  section: VVS's WPaddingOuter=3px/WPadding=7px/16px scrollbar reserve/
  forced-13px-check-columns have no direct acdream equivalent, so
  transcribing a real mainView.xml column table means declaring each
  column's PITCH (fixedwidth+7, or 13+7 for a check column regardless
  of its real fixedwidth) and reserving 16px on the last column.
- The worked example now uses rowheight="18" (VVS's own Padding*2+
  ControlHeight pitch, already the widget's default) and PITCH-computed
  widths (20 for a check column, 127 for a 120px text column) instead
  of arbitrary numbers, with a text onclick and a width="*" icon
  column added to demonstrate both new attributes in place.
- The bindings truth table gains column onclick (type="text") and both
  column width throw/silent rows (non-last vs. the list's last column).
- Testing conventions paragraph updated to mention width semantics, the
  row-bound click guard, and the two end-to-end tests.

Verification: dotnet build AcDream.slnx -c Release (green), dotnet test
tests/AcDream.App.Tests -c Release --filter
"FullyQualifiedName~Markup|FullyQualifiedName~UiMarkupList|FullyQualifiedName~PluginSidePanel"
(130/130), dotnet test tests/AcDream.Plugins.MossTank.Tests -c Release
--filter "FullyQualifiedName~Markup" (9/9) — closes the fix round.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:31:58 +02:00
Erik
e178c6abac fix(vt): list column fix round 10/11 — Meta/Monsters-shaped end-to-end tests
Two tests built through the full MarkupDocument.Build parse -> bind ->
draw (recording renderer) -> click pipeline, transcribing the two real
VTank list shapes named in the fix round brief
(refs/vtank/uTank2.ViewXML.mainView.xml):

- EndToEnd_MetaShapedSixColumnList: lstMetaRules's shape (3 icon
  columns, a 150px text column, then two width="*" text columns, the
  second with an onclick) at a list width (703) chosen so the two auto
  columns' 505px leftover does NOT divide evenly (252/253) — proving
  the last one absorbs the rounding slack. Asserts each column kind
  draws inside its own x-range and a click in each of the six columns
  reaches its own bound callback with the right row (icon columns
  fire their own onclick; the plain text column still selects; the
  onclick-bearing trailing text column fires that instead).

- EndToEnd_MonstersShapedTwentyThreeColumnList: lstMonsters's shape
  (14 check columns, 7 text columns each given an onclick per fix item
  1, 2 icon columns) built from real fixedwidth values with NO "*"
  anywhere, at a list width (724) equal to the exact sum of every
  column's declared width — the "no auto column, last absorbs the
  remainder as today" case. Asserts the column-kind counts, each drawn
  kind's x-range, and one representative click per kind reaches its own
  callback (other same-kind columns share a dummy callback, proving the
  bound-per-column dispatch, not just "some column of that kind fired").

Both use iconkind="item" for their icon columns (not the default
"did") so the fake resolver's echoed id is the literal texture drawn,
sidestepping PluginIcons.Normalize's did-namespace OR — an incidental
discovery while writing these (the first draft asserted on raw ids and
failed against the normalized 0x06000000-tagged textures).

Verified meaningful two ways: both failed first against the pre-fix
raw-id assumption (texture ids came back normalized), and — a stronger
check specific to these integration tests, since the underlying
mechanics were already covered by earlier fix-round commits — a
temporary mutation of ColumnLayout's auto-column share computation
(forcing share=0) made EndToEnd_MetaShapedSixColumnList fail exactly as
expected before being reverted.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:28:10 +02:00
Erik
92f9b36b8f docs(vt): slice-1 ledger — Part A landed, both review verdicts, two-round fix plan
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:26:21 +02:00
Erik
0f79ee03ee fix(vt): list column fix round 9/11 — MossTankMarkupContractTests learns <column>
The contract test suite's per-element binding-shape check treated
EVERY element's onclick as a plain Action, and its interactive-element
set (used both for "declares a real handler" and "has an accessible
tooltip") had no entry for <column> at all — both would misvalidate a
future mosstank.xml <column> the way Campaign VT slice 1 Part B and
this fix round's item 1 actually shipped it (onchange/onclick as
Action<int>, the row index).

Extracted the per-element dispatch out of
EveryInteractiveBindingMatchesTheRetainedUiDelegateShape into
AssertElementBindingsMatchRetainedUiDelegateShape, which now
special-cases "column": both onchange and onclick must resolve to
Action<int>, never plain Action. The interactive-element name list is
now the single shared InteractiveElementNames array (was duplicated
inline in EveryInteractiveControlDeclaresARealHandlerBinding and
TextlessAndAbbreviatedControlsHaveAccessibleRetailTooltips), with
"column" added — zero behavior change against mosstank.xml today (it
has no <column> elements yet), confirmed by the existing 190-control
count assertion staying green.

New tests: InteractiveElementNames_IncludesColumn pins the addition
directly; Column_OnchangeAndOnclick_MustBeActionOfInt builds a
synthetic <column> (not loaded from mosstank.xml, which has none) and
proves both a correctly-typed Action<int> onchange passes and a
column onclick bound to a plain Action (the shape every OTHER
element's onclick uses) is rejected — confirmed by temporarily
removing the "column" special case and rerunning: the plain-Action
onclick then passed silently ("No exception was thrown", the
generic Action check being satisfied by a real Action property),
proving the test only passes because the fix's column-specific
Action<int> enforcement is present.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:20:19 +02:00
Erik
8fb4909cc8 fix(vt): list column fix round 8/11 — shared UiCheckLamp + factory-only column
New internal static UiCheckLamp (LampSize=11f, the four checked/
unchecked colors, Draw) is the ONE definition of the five-band lamp
glyph, promoted out of UiMarkupToggle's private/internal fields —
UiMarkupToggle.OnDraw and UiMarkupList.DrawCheckCell both call
UiCheckLamp.Draw now instead of each carrying (or one exposing to the
other) its own copy of the same five DrawFill calls and four colors.

DrawCheckCell also centers the lamp horizontally in its cell instead of
drawing it flush left at cellX+1 — matching DrawIconCell, which already
centers its sprite. A check column declared wider than the glyph itself
(routine under fix item 11's PITCH-based authoring convention) no longer
strands the glyph in the cell's left edge.

UiMarkupListColumn's settable members are now internal init (Kind/Width
lost their `required` modifier — C# forbids `required` pairing with a
setter less visible than the containing public type, CS9032 — every
factory already sets both unconditionally, so this is a compiler-level
demotion, not a behavior change) — the type is constructible only
through its Text/Check/Icon factories from any external assembly (a
plugin) with no InternalsVisibleTo grant, so it can never assemble an
inconsistent instance via object-initializer syntax.

Replaced the inert draw-offset assertion in
Columns_CheckThenIcon_EachCellDrawsInsideItsOwnColumnBounds (check
column FIRST, so its own-cell assertion held trivially even with
completely broken column offsets) with
Columns_IconThenCheck_EachCellDrawsInsideItsOwnColumnBounds — check
column now SECOND, so the assertion can only pass if the glyph actually
moved into its own [20,100) cell.

New test: a single 50px-wide check column's glyph lands near the cell's
midpoint (~22.5) rather than the old flush-left x=4 — shown to fail
first before the centering change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:16:00 +02:00
Erik
f8e5edb848 fix(vt): list column fix round 7/11 — short check columns draw unchecked
DrawCheckCell drew nothing for a row past its own column's bound data —
inconsistent with docs/plugin-ui-markup.md's own description of VVS's
HudList, which materializes every cell in a row regardless of which
columns actually have data for it. Text/icon cells rightly stay
no-draw past their own count (no sensible default string or icon), but
a check cell always has one: unchecked.

DrawCheckCell now computes isChecked defensively (false when the flags
array is null or too short) instead of returning early, so a short
check column draws the unchecked lamp for every row past its own data
just like every other row.

New test: a 3-row list (driven by a longer text column) with a check
column bound to only 1 row now shows the unchecked lamp for rows 1 and
2 — shown to fail first (0 unchecked lamp quads, since DrawCheckCell
returned early past index 0).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:09:41 +02:00
Erik
184f687691 fix(vt): list column fix round 6/11 — kill per-frame/per-event allocations
DrawColumns allocated four fresh IReadOnlyList<T>?[] sidecar arrays and
ColumnLayout allocated a fresh (float,float)[] EVERY draw call; worse,
OnEventColumns re-invoked every column's source Func a SECOND time (via
UiMarkupListColumn.RowCount()) just to recompute the same row count
DrawColumns had already materialized, and called ColumnLayout a second
time to recompute the same layout — on every single click/scroll event.

Columns is now a property with a custom setter that (re)sizes seven
instance-field caches to Columns.Count exactly once per assignment:
_cachedTextRows/_cachedColorRows/_cachedCheckRows/_cachedIconRows (the
per-column sidecar arrays), _cachedLayout (the column x/width array),
and _scratchIsAuto/_scratchFixedWidth (ComputeColumnLayout's own working
arrays, previously freshly allocated on every layout computation too).
DrawColumns writes into these caches instead of local arrays and records
_cachedRowCount; ComputeColumnLayout (the renamed, now-instance
ColumnLayout) writes into _cachedLayout in place instead of returning a
new array. OnEventColumns reads _cachedRowCount/_cachedLayout/the
per-column cached row arrays instead of re-invoking anything — this also
completes fix item 3's row-bound guard without a second RowCount() call.
UiMarkupListColumn.RowCount() stays as public API (still asserted by an
existing test) but is no longer called from UiMarkupList internally,
which is the "single row-count definition" the fix round asked for.

This does make OnEvent depend on at least one prior Draw call for
correct row/layout data (mirrors real frame order: draw every frame,
then handle input) — the four hit-test click tests that previously
fired OnEvent with no preceding Draw now draw once first, matching what
Scroll_OffsetIsRespectedBySubsequentHitTests already did.

New test: each column source Func increments its own call counter; one
Draw call invokes each exactly once, and five rounds of subsequent
click events invoke none of them again — shown to fail first (16 calls
instead of 1, from OnEventColumns's old RowCount()-per-column-per-event
re-invocation) before the caching change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:07:40 +02:00
Erik
8fa70c3e4a docs(vt): KB 01 RechargeHandlerSet seeds 26 rows, not 24 (found by the Part A implementer against the fixture)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:06:37 +02:00
Erik
5d760331f6 fix(vt): list column fix round 5/11 — every column throw names its column
BuildListColumn's per-attribute binder calls used the generic "column
items"/"column values"/"column onchange"/"column onclick" context
strings from the initial slice — indistinguishable when a list has
several columns of the same type. Route every column-attribute binder
call (text items/colors/onclick, check values/onchange, icon
values/onclick) through the ColumnContext helper item 2 introduced, so
every throw message reads column[N] type="..." attr. ValidateIconKind
gains an optional context parameter (default "iconkind" for the
existing non-column call sites — <icon>, <button icon>, <list icons>,
none of which changed message-wise beyond wording) so the column
iconkind check can identify its own column too.

Updated all twelve column-throw tests in MarkupListColumnsTests to
assert Assert.Contains on the distinguishing phrase: the ten
attribute-specific ones now check column[0] type="..." attr; the
unknown-<column type> and combined-with-legacy-attribute tests keep
(and, for the type one, add to) their existing distinguishing
assertions. Confirmed each attribute-specific assertion is meaningful
by first running the malformed-colors case against the pre-fix
"column colors must be..." message (mismatch), then landing the
production change alongside the rest.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:03:43 +02:00
Erik
b58668c6cd fix(vt): list column fix round 4/11 — try/finally around per-cell clip
Matches UiButton.cs:896-906 / UiElement.cs:683-720's own clip
discipline: every per-cell PushClip in DrawColumns now has its matching
PopClip in a finally, so a cell draw that throws (e.g. a plugin's icon
resolver misbehaving) doesn't leak that PushClip onto the context's
clip stack. Without this, the leaked entry combines badly with
UiElement.DrawSelfAndChildren's own outer clip pop on the way out
(it pops the wrong stack entry), permanently corrupting the shared
UiRenderContext's clip state for every draw that follows in the frame.

Added UiRenderContext.ClipStackDepth (internal, InternalsVisibleTo
AcDream.App.Tests) purely to make this provable from a test — the
number of PushClip calls not yet matched by PopClip.

New test: a column whose icon resolver throws mid-draw still leaves
the clip stack at its pre-draw depth after the exception propagates —
shown to fail first (leaked to depth 1 instead of 0, reproducing
exactly the "outer pop consumes the wrong stack entry" mechanism
described above) before the try/finally was added.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 21:00:41 +02:00
Erik
ed94acb862 fix(vt): list column fix round 3/11 — per-column row-bound click guard
A short column (fewer bound rows than the list's own max-across-columns
row count) already draws nothing past its own row — DrawCheckCell/
DrawIconCell/DrawTextCell all no-op once index >= their own array's
Count. OnEventColumns's click routing didn't share that bound: a click
landing on a row the OVERALL list considers valid (row < the longest
column) but past a SHORTER column's own data would still invoke that
column's callback with a row index it never bound anything for.

Add the same per-column bound (index < columns[c].RowCount()) to the
check-column, icon-column, and text-column-with-onclick click paths —
text-without-onclick's plain SelectionChanged fallback is unaffected,
since row selection is a list-level concept already bounded by the
outer rowCount check.

New tests: a click past a short check/icon/onclick-bearing-text
column's own row count fires nothing (each shown to fail first — the
callback fired with the out-of-bound row index before this guard).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:56:44 +02:00
Erik
96ee7b3214 fix(vt): list column fix round 2/11 — width="*" auto-sizing + overflow clamp
VVS's HudList shares remaining width equally among every 0-width column
(docs/research/vtank-kb/08-ui-views.md's HudList row, Decal3XMLParser.cs
:409-418) after fixed-width columns are subtracted — the initial slice
only let the LAST column auto-size. Port the real rule:

- A non-last <column width> that is missing, unparseable, or non-positive
  throws FormatException at Build naming the column index and declared
  type (column[N] type="..." width) — UNLESS it is width="*".
- width="*" (any column, including the last) marks it auto: every auto
  column shares the list's remaining width equally, with the LAST column
  in the list (always implicitly auto, regardless of its own width or
  IsAutoWidth) absorbing the integer-division rounding slack. With no
  "*" anywhere this reduces to exactly the original "last column gets
  100% of the remainder" contract — zero behavior change for every
  existing column-less/single-"*" list.
- A declared width overflowing the list's total width is clamped to
  whatever room is left, walked left to right; every column after the
  overflow point gets 0 width (and never draws — DrawColumns already
  skips a <=0-width cell).

UiMarkupListColumn gains IsAutoWidth (internal to the width contract,
set via each factory's new optional isAutoWidth parameter); ColumnLayout
in UiMarkupList is rewritten around an explicit auto/fixed classification
pass instead of the old "only index n-1 is special" one-liner.
MarkupDocument's new ParseColumnWidth owns the Build-time validation,
shared through the same ColumnContext helper item 1 introduced.

New tests: non-last missing/unparseable/non-positive width throws
(each naming column[N] type="..." width), width="*" parses without
throwing on both a non-last and the last column, two auto columns
share the remainder with the last absorbing the odd pixel, and an
overflowing declared width clamps with later columns drawing nothing
— each shown to fail first (compile error for the missing isAutoWidth
parameter, then a wrong split before the ColumnLayout rewrite).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:54:38 +02:00
Erik
fd521f7816 fix(vt): list column fix round 1/11 — text column optional onclick
None of VTank's eight HudList instances relies on row selection
(PluginCore.cs Monsters/Items/Meta/Route/Buffs/Consumables cell
handlers) — every real text cell is an action target. Add an optional
onclick="{Action<int>}" to <column type="text">: when present, a click
fires it with the row index INSTEAD of selecting; when absent, the
original select-the-row behavior is unchanged. BuildListColumn now
takes the column's own index (used for its onclick throw message and
threaded through for the rest of the fix round's column-context
messages); the unknown-<column type> throw also picked up the index
as a side effect of that signature change.

New tests (MarkupListColumnsTests): the onclick attribute binds and
falls back correctly when absent, a malformed onclick throws at Build,
and a click actually reaches the bound callback instead of firing
SelectionChanged — each shown to fail first (missing TextClicked
member / no 4-arg Text() overload before the production change).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:49:43 +02:00
Erik
054bf32605 docs(vt): slice-1 contract amended from the Part B reviews (text onclick, auto width, no header); review ledger
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:34:18 +02:00
Erik
dc91245ba8 docs(vt): KB 05 second citation pass — 31 requirement types, f0.c categories and dz.o.h readers resolved
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:25:19 +02:00
Erik
959a694823 feat(vt): Campaign VT slice 1 Part B — multi-column <list> markup
VVS HudList parity (docs/research/vtank-kb/08-ui-views.md 2-3): <list>
accepts <column type="text|check|icon" width=... [iconkind] [colors]/>
children, each binding its own per-row source parallel to the row count.
Row count is the longest bound column; a click in a text column selects
(the list's own selected/onchange, unchanged), a click in a check/icon
column fires that column's own required onchange/onclick with the row
index and does NOT change selection. Last column always absorbs the
remaining width, recomputed live off the list's own Width rather than
baked in at Build. Per-cell horizontal clipping via UiRenderContext's
existing PushClip/PopClip. The check-column glyph reuses <toggle>'s own
five-band lamp primitive (UiMarkupToggle.DrawLamp/colors promoted from
private to internal) so it looks like every other checkbox. Unknown
column type, a missing required column binding, <column> combined with
the legacy items/icons/colors list attributes, or any non-<column> child
of <list> all throw FormatException at Build. A column-less <list> is
byte-for-byte the original single-text-column widget (new if/Columns
branch in OnDraw/OnEvent; the legacy branch's code is untouched).

New UiMarkupListColumn model (src/AcDream.App/UI/UiMarkupListColumn.cs)
carries each column's kind/width/bindings; MarkupDocument's `list` case
now builds either the legacy single-column fields or a Columns list,
never both. MarkupListColumnsTests (27 new tests) cover parse/binding
validation, draw-level column-offset/clipping/check-glyph/icon pins
against the recording renderer, hit-test routing, and a backward-
compatibility proof (a column-less list built through MarkupDocument
produces a byte-identical draw record to a hand-built UiMarkupList with
equivalent fields). Every new assertion was verified to fail first via
targeted temporary mutations (hit-test isolation, clip removal, last-
column-absorbs-remainder, required onchange/onclick, row-count = max),
each reverted after confirming failure.

docs/plugin-ui-markup.md gets a full Columns section (attribute grammar,
a Monsters-tab-style example, the no-header-row idiom, backward
compatibility) and the old single-text-column LIMITATION note is
retired; the bindings truth table gains the six new column-attribute
rows.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:21:16 +02:00
Erik
4549eb02af docs(vt): VT2 ledger records the folded citation pass and the re-judged rows
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:19:33 +02:00
Erik
caf7307522 docs(vt): fold the citation-pass corrections into KB 06 (0.01° turn threshold, OpenVendor busy paths, cm sites vs instantiations, resolved f9.j and item.c meanings, path/count nits)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:19:19 +02:00
Erik
d8f85848b6 docs(vt): KB 08 gap table gains the menu-overflow row the citation pass asked for
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:18:18 +02:00
Erik
69bb164845 docs(vt): fold the citation-pass corrections into KB 08 (icon-id decode, menu wraps not scrolls, slider fixed 0-1, HudList press-point click, dc.xml, resolved clRings and loot-editor call site); repair KB 09 path
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:18:07 +02:00
Erik
19a32cde2e docs(vt): KB 09 header points at the real UtilityBelt tree; slice-1 A3 carries the Change-vs-Bonus fix
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:17:11 +02:00
Erik
ee901b7f26 docs(vt): fold the citation-pass corrections into KB 05 and 09
05: recognized-vs-unrecognized rule payloads, 25 materials, only 3-arg
SpellInfo entries are live, Read/User1..5 unreachable from any loot plugin,
hv.a.e is a dead field, id.a.j = shareLoot, the Change-vs-Bonus branch
selector mis-port in the evaluator.
09: obtest location, the broken params dedup overload, the real ah call
sites, internal relay ctor, the next-waypoint handler at 3621-3639,
TryHandle is host-only, Classic Looter registry narrowed, UtilityBelt's
Harmony bypass route resolved.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:16:56 +02:00
Erik
642eacc13c docs(vt): fold the citation-pass corrections into KB 07 (hn.cs line map, dh/q hierarchy, 74-function count, ReturnFromCall guard, resolved fm/a shapes)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:15:22 +02:00
Erik
b7ed65bc64 docs(vt): VT2 slice 4 re-judged after the KB 04 citation pass (G4 is ordering only)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:04:24 +02:00
Erik
2e36ea8268 docs(vt): fold the citation-pass corrections into KB 04 (Armor Self row, stance legend swap, cr registered twice, G4 global pool, resolved handler-table and HP-yield bullets, MossTankPanel line sweep)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:04:10 +02:00
Erik
887242cd15 docs(vt): fold the citation-pass corrections into KB 02 (ga.a line map, gj/gs identity, fd.cs IdlePeace gate scope, VitalPlan.Threshold branch, entry counts)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 20:02:39 +02:00
Erik
1b81836747 docs(vt): fold the citation-pass corrections into KB 03 (DebuffScheduler.cs path, DebuffScope, six-member l enum, offhand enum, pet comparison owed)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 19:59:25 +02:00
Erik
59f247664a docs(vt): slice-1 contract — per-column list bindings per KB 08 §3; .af is the only meta/nav store
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 19:58:47 +02:00
Erik
986bd9668a docs(vt): land KB doc 07, VT2 gap audit draft, slice-1 contract; metas/navs move to metaf .af
Owner amendment 2026-09-06: MossTank implements the human-readable metaf
.af format for metas and nav routes instead of VTank's binary .met/.nav;
the reference converter lives in the owner's metas repo. Docs 06 §1/07 §1
stay as the binary record; their semantics sections remain the oracle.

Doc 07 spot-checked by the lead: ExpressionEvaluator.cs:787-790 (';'
returns the first operand), hn.cs:41-80 (the pass loop), bw.cs:25 (the
'> 5' six-view cap), d6.cs:7-8 (Button/Layout only).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 19:56:45 +02:00
Erik
b320cbfbc7 docs(vt): VT1 catalog index
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 19:49:54 +02:00
Erik
58483a1a53 docs(vt): VT1 catalog 05 — VTank loot flow and the Classic Looter .utl format
VTClassic's .utl blocks, all requirement types, EarlyMatch/NeedsID
identify-avoidance, ComputedItemInfo, salvage-combine extra block; VTank's
host-side corpse selection (rare-first, fo.cs:436-446), approach/open/loot
rules, the ownership-denial chat regexes (fo.cs:71-73), timeouts. MossTank
gap ranked. Lead spot-check of those three claims.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 19:48:33 +02:00
Erik
cf04897694 docs(vt): the UtilityBelt gitlab.io repo is the full plugin source; cloned locally
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 19:47:53 +02:00
Erik
f1418903fd docs(vt): record the UtilityBelt and Mag-Tools source references supplied by the owner
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 19:47:19 +02:00
Erik
1a35b83cf8 docs(vt): VT1 catalog 06 — VTank navigation engine and the .nav format
x.cs reader/writer (uTank2 NAV 1.2, route types, ten waypoint types incl.
the live-position quirk of five of them), ca.cs cycle driver, fd.cs steering
and creep band, bi.cs jump (2000 ms cap), b7.cs door/lockpick, priority
interactions, 240 m/unit confirmed at four sites, two real routes decoded.
MossTank gap ranked. Lead spot-check: header vs a real file, jump cap,
conversion sites.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 19:46:04 +02:00
Erik
289c6706ba docs(vt): VT1 catalog 04 — VTank buffs, item enchantments, helpers and vitals
Buff plan and per-tick re-evaluation, the profile-item enchant pipeline
(PluginCore.cs:8327-8445), helper heals/random helper, the nine recharge
thresholds and rule order, kits/potions/food, dispel and worn-item mana.
MossTank gap ranked. Lead spot-check: fk.b() dead check, ba.cs 100-draw
loop, MySpell.HasScarabsInInventory.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 19:44:02 +02:00
Erik
cf6d5b94bb docs(vt): VT1 catalog 09 — /vt commands, chat sinks, and VTank's plugin interop surface
~48 documented subcommands plus 15 parser-only debug verbs (no /vt pause),
the d5/ah chat sinks, the three-tier export model (public static PC,
permission-gated relay, LootPluginBase SPI) annotated against
MosswartMassacre's real usage, and the interop gaps in Plugin.Abstractions.
Lead spot-check: PC field, eExternalsPermissionLevel, start/stop parser.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 19:42:51 +02:00
Erik
8872a9286a docs(vt): VT1 catalog 01 — VTank settings, defaults and the .usd profile format
All 137 settings with type/default/category/UI control/consumer citation,
the self-describing .usd table grammar (parsed from the decompile and
verified against defaultsettings.usd), profile selection and /vt opt.
MossTank gap: no .usd reader/writer, BuffProfileDocument drops ten fields,
RechargeHandlerSet opaque; setting-name coverage is already 137/137.
Lead spot-check: f3 accessors, the four reader classes, catalog count.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 19:33:06 +02:00