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>
This commit is contained in:
parent
b9029082ae
commit
7ac43cee63
1 changed files with 56 additions and 38 deletions
|
|
@ -35,7 +35,12 @@ gets serialized to a `.usd` file. The same database format is reused for
|
|||
`refs/vtank/decompiled/bd.cs:422-426`, used when a setting's *value* is a
|
||||
nested table) and a length-prefixed raw-text blob class (tag `"ba"`,
|
||||
`refs/vtank/decompiled/f6.cs:9-30`, `int` length line then that many raw
|
||||
characters — not lines — allowing embedded newlines).
|
||||
characters — not lines — allowing embedded newlines). If the tag is unknown
|
||||
to the registry, `y.a(text)` returns null and `gy.a` consumes **exactly one
|
||||
line** (the tag) and reads no value line (`gy.cs:50-55`) — the parse
|
||||
silently desynchronizes from that point rather than erroring. A `.usd`
|
||||
writer must never emit a tag the reader does not register (citation pass
|
||||
2026-09-06).
|
||||
- **`cw`** (`refs/vtank/decompiled/cw.cs:9-40`) is one row: a fixed-size list
|
||||
of `gy` cells, one per column of its owning table.
|
||||
- **`bd`** (`refs/vtank/decompiled/bd.cs`) is one table. Its text format
|
||||
|
|
@ -177,8 +182,8 @@ is currently selected.
|
|||
| 56 | `RebuffTimeRemainingSeconds` | int | 300 | Buffing | Advanced Options list only (`lOptionList`, filter category Buffing) | `refs/vtank/decompiled/gw.cs:14 [j]` |
|
||||
| 57 | `RefillWornMana` | bool | True | Misc | Advanced Options list only (`lOptionList`, filter category Misc) | `refs/vtank/decompiled/ev.cs:108 [k]` |
|
||||
| 58 | `RefillWornMana-Item-ManaPercent` | int | 33 | Misc | Advanced Options list only (`lOptionList`, filter category Misc) | `refs/vtank/decompiled/ev.cs:113 [j]` |
|
||||
| 59 | `BuffProfile-Prots` | string | "ALFCBPS" | Buffing | Advanced Options list only (`lOptionList`, filter category Buffing) | `refs/vtank/decompiled/eq.cs:161 [g]` |
|
||||
| 60 | `BuffProfile-Banes` | string | "ALFCBPS" | Buffing | Advanced Options list only (`lOptionList`, filter category Buffing) | `refs/vtank/decompiled/eq.cs:248 [g]` |
|
||||
| 59 | `BuffProfile-Prots` | string | "ALFCBPS" | Buffing | **Not exposed** — `tString` has no case in the Advanced Options list switch (`db.cs:132-166`) and the click handler no-ops for it (`db.cs:201-203`); no control binds it and no code writes it. Settable only via `/vt opt set`, read only when `BuffProfile_Prots == 1` (Custom). | `refs/vtank/decompiled/eq.cs:161 [g]` |
|
||||
| 60 | `BuffProfile-Banes` | string | "ALFCBPS" | Buffing | **Not exposed** — `tString` has no Advanced Options case (`db.cs:132-166`, `:201-203`); `/vt opt set` only, read only when `BuffProfile_Banes == 1` (Custom). | `refs/vtank/decompiled/eq.cs:248 [g]` |
|
||||
| 61 | `BuffProfile_Prots` | enum | 2 | Buffing | Advanced Options list only (`lOptionList`, filter category Buffing) Enum: 1=Custom, 2=All, 3=None, 4=B, 5=BPS, 6=BPSA, 7=ALFC, 8=BPSAC | `refs/vtank/decompiled/eq.cs:160 [f]`; `refs/vtank/decompiled/eq.cs:161 [b]` |
|
||||
| 62 | `BuffProfile_Banes` | enum | 2 | Buffing | Advanced Options list only (`lOptionList`, filter category Buffing) Enum: 1=Custom, 2=All, 3=None, 4=B, 5=BPS, 6=BPSA, 7=BPSAC, 8=ALFC | `refs/vtank/decompiled/eq.cs:247 [f]`; `refs/vtank/decompiled/eq.cs:248 [b]` |
|
||||
| 63 | `DebuffEachFirst` | enum | 1 | MeleeCombat\|SpellCombat | Advanced Options list only (`lOptionList`, filter category MeleeCombat\|SpellCombat) Enum: 1=One, 2=Priority, 3=All | `refs/vtank/decompiled/dz.cs:712 [c]`; `refs/vtank/decompiled/dz.cs:712 [c]`; `refs/vtank/decompiled/dz.cs:713 [c]` |
|
||||
|
|
@ -230,7 +235,7 @@ is currently selected.
|
|||
| 109 | `BuffCastRecast_Seconds` | int | 30 | Buffing | Advanced Options list only (`lOptionList`, filter category Buffing) | `refs/vtank/decompiled/fz.cs:83 [j]`; `refs/vtank/decompiled/gw.cs:17 [j]` |
|
||||
| 110 | `BuffCastRecastReset_Seconds` | int | 30 | Buffing | Advanced Options list only (`lOptionList`, filter category Buffing) | `refs/vtank/decompiled/fz.cs:118 [j]` |
|
||||
| 111 | `EnableMeta` | bool | False | Misc | `c1EnableMeta` (Checkbox, tab "Options"): "Enable Meta" | `refs/vtank/decompiled/a7.cs:91 [k]`; `refs/vtank/decompiled/ao.cs:79 [b]`; `refs/vtank/decompiled/cp.cs:148 [b]` |
|
||||
| 112 | `BlacklistedSpellComps` | string | "" | Recharge\|SpellCombat\|Buffing | Advanced Options list only (`lOptionList`, filter category Recharge\|SpellCombat\|Buffing) | `refs/vtank/decompiled/uTank2/MySpell.cs:403 [g]`; `refs/vtank/decompiled/uTank2/PluginCore.cs:7734 [g]`; `refs/vtank/decompiled/uTank2/PluginCore.cs:7749 [b]` |
|
||||
| 112 | `BlacklistedSpellComps` | string | "" | Recharge\|SpellCombat\|Buffing | **Not exposed** by the Advanced Options list (`tString` has no case, `db.cs:132-166`); settable via `/vt opt set` and by `PluginCore.cs:7749 [b]`. | `refs/vtank/decompiled/uTank2/MySpell.cs:403 [g]`; `refs/vtank/decompiled/uTank2/PluginCore.cs:7734 [g]`; `refs/vtank/decompiled/uTank2/PluginCore.cs:7749 [b]` |
|
||||
| 113 | `DropToPeaceModeRetryCount` | int | 34 | Misc\|MeleeCombat\|SpellCombat | Advanced Options list only (`lOptionList`, filter category Misc\|MeleeCombat\|SpellCombat) | `refs/vtank/decompiled/ga.cs:1511 [j]` |
|
||||
| 114 | `FollowAroundCorners` | bool | True | Navigation | Advanced Options list only (`lOptionList`, filter category Navigation) | `refs/vtank/decompiled/gl.cs:83 [k]`; `refs/vtank/decompiled/gl.cs:121 [k]`; `refs/vtank/decompiled/gl.cs:142 [k]` |
|
||||
| 115 | `BlacklistCorpseOpenAttemptCount` | int | 30 | Misc\|Looting | Advanced Options list only (`lOptionList`, filter category Misc\|Looting) | `refs/vtank/decompiled/fo.cs:339 [j]` |
|
||||
|
|
@ -337,16 +342,17 @@ determine").
|
|||
|
||||
**Profile listing and selection UI** (`refs/vtank/decompiled/uTank2/PluginCore.cs`):
|
||||
four near-identical list-builder methods populate the four combo boxes —
|
||||
`a0()` (settings, `cmbSettingsSet`, lines 7057-7115) always seeds
|
||||
`a0()` (settings, `cmbSettingsSet`, lines 7054-7128) always seeds
|
||||
`"[Default]"` and `"[By char]"` first, then every non-`--` `*.usd` file
|
||||
(filtered to only the currently-selected one when the "Mine only" checkbox
|
||||
`cSettingsShowAll`/field `a9` is checked, `7020-7024`) plus every
|
||||
`cSettingsShowAll`/field `a9` is checked, `7072-7078`; the same test appears in the
|
||||
display-name helper `h()` at `7020-7024`) plus every
|
||||
`dw`-matching `"[Char] "`-labeled file; `aa()` (loot, `cmbLootSet`,
|
||||
lines 7127-7154) seeds only `"[None]"` and lists **every** non-`--` file
|
||||
lines 7130-7166) seeds only `"[None]"` and lists **every** non-`--` file
|
||||
across all of `dz.ah.a()`'s loot-profile extensions with no "mine only"
|
||||
filter and no `"[By char]"` option; `l()` (nav, `cmbNavSet`, lines
|
||||
7156-7185) seeds `"[None]"`/`"[By char]"` and filters out both `--` and
|
||||
`~~`; `ac()` (meta, `cmbMetaSet`, lines 7187+) seeds `"[None]"`/`"[By char]"`
|
||||
7168-7207) seeds `"[None]"`/`"[By char]"` and filters out both `--` and
|
||||
`~~`; `ac()` (meta, `cmbMetaSet`, lines 7209-7248) seeds `"[None]"`/`"[By char]"`
|
||||
and filters only `--`. **Loot profiles are structurally the odd one out**:
|
||||
no auto per-character file, no "mine only" filtering, and (per Classic
|
||||
Looter's own file format — out of scope for this doc, see doc 05) a
|
||||
|
|
@ -373,7 +379,7 @@ still tolerates.
|
|||
`refs/vtank/decompiled/da.cs:259-367` — the settings-profile loader):
|
||||
after loading a `.usd` file's `Settings`/`MyMonsters`/etc. tables, VTank
|
||||
checks the **column count** of the loaded `MyMonsters` table
|
||||
(`this.c["MyMonsters"].d()`) against ten hardcoded thresholds
|
||||
(`this.c["MyMonsters"].d()`) against eleven hardcoded thresholds
|
||||
(`da.cs:280-323`) and appends a new column with a hardcoded default value
|
||||
for every column added by a newer build than the one that saved the file
|
||||
(e.g. `if (...).d() <= 16) { ...a("Corrosion", gy.a(false)); }` at
|
||||
|
|
@ -386,15 +392,24 @@ method also adds three whole tables outright if missing
|
|||
addition uses a row-count-like column-count threshold; neither uses an
|
||||
explicit schema-version field.** If the `.usd` file fails to parse at all,
|
||||
`da.k()` falls back to the **template** resource and immediately overwrites
|
||||
the file on disk with defaults (`da.cs:347-358`) — a corrupt/foreign `.usd`
|
||||
the file on disk with defaults (`da.cs:347-352`; `da.cs:354-359` is the
|
||||
separate file-missing branch with the identical body) — a corrupt/foreign `.usd`
|
||||
is silently replaced, not preserved or backed up.
|
||||
|
||||
**`defaultsettings.usd` vs `defaultsettingstemplate.usd`**: both share the
|
||||
identical 10-table/137-setting schema; `defaultsettings.usd` (2270 lines)
|
||||
additionally seeds real starter content in the grid tables (`GemFoodItems`
|
||||
has 2 rows: "Asheron's Benediction"→spell 3810, "Blackmoor's Favor"→spell
|
||||
3811; `MyMonsters` has 1 row, the `<DEFAULT>` monster rule) while
|
||||
`defaultsettingstemplate.usd` (141 lines) ships the same tables **empty**.
|
||||
**`defaultsettings.usd` vs `defaultsettingstemplate.usd`**: they are NOT the
|
||||
same schema (corrected by the citation pass 2026-09-06). `defaultsettings.usd`
|
||||
(2270 lines) carries **10 tables**, including `Settings` (4 columns × 137
|
||||
rows), `SettingsCategories` (136 rows) and `SettingsEnumInfo` (33 rows).
|
||||
`defaultsettingstemplate.usd` (141 lines) carries only **8 tables**: it drops
|
||||
`SettingsCategories` and `SettingsEnumInfo` entirely, and its `Settings` table
|
||||
has just **2 columns (`Setting`, `Value`) and zero rows**. The grid tables are
|
||||
identical in both files — `GemFoodItems` has the same 2 rows ("Asheron's
|
||||
Benediction"→3810, "Blackmoor's Favor"→3811) and `MyMonsters` the same
|
||||
single 21-column `<DEFAULT>` row; the whole 2129-line delta is the three
|
||||
settings tables. Consequence: a template-seeded profile (`da.f()`) starts
|
||||
with an **empty** `Settings` table, so every scalar read falls through
|
||||
`f3.e()`'s defaults fallback to `da.b` — an independent confirmation of the
|
||||
fallback chain in section 1.
|
||||
`defaultsettings.usd` is the built-in fallback database (`da.b`, never
|
||||
written to disk on its own); `defaultsettingstemplate.usd` is what a brand
|
||||
new (or unparseable) profile is seeded from (`da.f()`,
|
||||
|
|
@ -406,8 +421,10 @@ grammar, but no `"--"` prefix and not user-selectable — always exactly
|
|||
(`refs/vtank/decompiled/dm.cs:391`, class `dm`). Live inspection of
|
||||
`+Horan_sawato.ast` (65 bytes) shows one table, `Spells`, four columns
|
||||
(`SpellID`, `EndTime`, `Target`, `CastTime`), zero rows in the sample
|
||||
inspected. `dm.g()` (`dm.cs:389-399`) falls back to seeding from the
|
||||
embedded `defaultitemagedb.ugd` resource if the file is missing or
|
||||
inspected. `dm.g()` (`dm.cs:389-414`) reseeds from the
|
||||
embedded `defaultitemagedb.ugd` resource on two triggers — clock-rollback
|
||||
detection (`dm.cs:396-401`) and the catch for a missing/corrupt file
|
||||
(`dm.cs:408-413`) — i.e. if the file is missing or
|
||||
corrupt. This looks like a per-character cast/assist-tracking cache
|
||||
(tracking spell durations placed on other players) rather than a settings
|
||||
profile; its exact runtime semantics were not traced further as out of
|
||||
|
|
@ -425,9 +442,9 @@ chat-command dispatcher — the surrounding `if` chain is a long
|
|||
| `/vt opt` (no args) | `opt` | prints usage | `"Usage: /vt opt [list/get/set/setinall]"` (`:5450`) |
|
||||
| `/vt opt list` | `opt list` | prints `"Available options: (" + <count> + ")"` then every `Settings` row's name from the **built-in defaults** table (`dz.m.b["Settings"]`, not the loaded profile), four per line, `" "`-indented (`:5518-5538`) | `"Usage: /vt opt list"` if extra args (`:5514`) |
|
||||
| `/vt opt get <name>` | `opt get X` | prints `"Option " + name + " = " + f3.e(name)"` via the raw `gy.ToString()` (`:5539-5556`) | `"Option get: Invalid option specified."` if the name isn't found (`:5553`); `"Usage: /vt opt get [option name]"` for wrong arg count (`:5543`) |
|
||||
| `/vt opt set <name> <value>` | `opt set X V` | looks up the name's declared type in the **built-in defaults** table, converts `V` to that CLR type (`double`/`int`/`float`/`string`/`bool` — note **no case for a `tCustom` value**, so `RechargeHandlerSet` cannot be set this way), then calls `f3.b(name, gy)` (persists + refreshes) (`:5560-5602`) | `"Option set: Invalid option specified."` if name not found; `"Option set: Invalid value specified. Proper type of " + name + " is " + type + "."` on conversion failure or unrecognized type; `"Usage: /vt opt set [option name] [option value]"` for wrong arg count |
|
||||
| `/vt opt setinall <name> <value>` | `opt setinall X V` | same type resolution as `set`, but writes through `global::bk.a(name, gy)` instead of `f3.b` (`:5457-5498`) — `bk` was not traced further in this pass; likely writes to every loaded profile database rather than just the current one, but that inference is **not confirmed** from code read so far | `"Usage: /vt opt setinall [option name] [option value]"` if arg count != 4 (`:5462`) |
|
||||
| *(default)* | any other `opt <word>` | | `"Usage: /vt opt [list/get/set]"` (`:5606`) — note this usage string omits `setinall` even though it is a real, dispatched subcommand |
|
||||
| `/vt opt set <name> <value>` | `opt set X V` | looks up the name's declared type in the **built-in defaults** table, converts `V` to that CLR type (`double`/`int`/`float`/`string`/`bool` — note **no case for a `tCustom` value**, so `RechargeHandlerSet` cannot be set this way), then calls `f3.b(name, gy)` (persists + refreshes) (`:5566-5615`; type ladder `:5588-5607`) | `"Option set: Invalid option specified."` if name not found; `"Option set: Invalid value specified. Proper type of " + name + " is " + type + "."` on conversion failure or unrecognized type; `"Usage: /vt opt set [option name] [option value]"` for wrong arg count |
|
||||
| `/vt opt setinall <name> <value>` | `opt setinall X V` | same type resolution as `set`, but writes through `global::bk.a(name, gy)` instead of `f3.b` (case `:5457-5511`, call at `:5504`). `bk.a` (`bk.cs:6-35`) enumerates **every `*.usd` file in `PluginCore.dq`** with no `--` filtering (other characters' profiles included): the currently-loaded file (`dz.m.m`) goes through `f3.b`, every other file is loaded into a fresh `y`, has its `Settings` row inserted-or-overwritten, and is written straight back to disk (`y2.b(text)`); it reports `"Done saving setting X to all profiles. (Changed N profiles)"` and writes the canonical name from the defaults row (`gy.b(cw3[0])`), not the typed casing. Quirk: the arg-count guard at `:5459-5462` prints usage but does not `break` — it falls through and still attempts the lookup | `"Usage: /vt opt setinall [option name] [option value]"` if arg count != 4 (`:5462`) |
|
||||
| *(default)* | any other `opt <word>` | | `"Usage: /vt opt [list/get/set]"` (`:5617`) — note this usage string omits `setinall` even though it is a real, dispatched subcommand |
|
||||
|
||||
The exact same `/vt` ladder also contains many non-settings debug commands
|
||||
(`dumptracker`, `deletemonster`, `getdb`, `obtest`, `nav save/load`, …,
|
||||
|
|
@ -496,17 +513,22 @@ That said, real gaps and divergences were found:
|
|||
default `RechargeHandlerSet`, including its stance- and
|
||||
current-percentage-dependent order"). A user who customized their
|
||||
RechargeHandlerSet table in real VTank has no way to bring that
|
||||
customization into MossTank today, and `_vitalSettings.RechargeHandlerSet`
|
||||
does not appear to be read back by `VitalRechargePlanner` at all (not
|
||||
fully confirmed — would need a full read of `VitalRecharge.cs`, which
|
||||
this doc's scope did not require).
|
||||
customization into MossTank today; `_vitalSettings.RechargeHandlerSet` IS
|
||||
read back (`VitalRecharge.cs:59-63` → `Handlers(...)` → `TryParseHandlerSet`,
|
||||
`VitalRecharge.cs:308-340`): the sentinel default `"RechargeHandlerSet"`
|
||||
(`VitalPlan.cs:48`) and blank mean "no override" and fall through to the
|
||||
hardcoded table, while a non-sentinel string parses as a `key=value`
|
||||
segmented form keyed by `{stance}-{vital}-{band}` (`VitalRecharge.cs:305`)
|
||||
with a `-normal` fallback. So a customization channel exists — it is just
|
||||
not VTank's 5-column table (citation pass 2026-09-06; slice 1 replaces it
|
||||
with the parsed table).
|
||||
4. **Buff classification model is architecturally different, not just
|
||||
incomplete.** VTank's `BuffProfile_Prots`/`BuffProfile_Banes` are an
|
||||
8-way named enum (`Custom`/`All`/`None`/`B`/`BPS`/`BPSA`/`ALFC`/`BPSAC`,
|
||||
section 2 rows 61-62) whose letters index into **fixed, hardcoded lists
|
||||
of specific spell families** (not decompiled further in this pass —
|
||||
doc 04's scope). MossTank instead classifies buffs at runtime from each
|
||||
spell's own English description text (`BuffProfile.cs:1-70`, matching
|
||||
spell's own English description text (`BuffProfile.cs:6-140`, incl. `Unknown = 0`, matching
|
||||
phrases like "Increases the caster's ... skill by"), producing a
|
||||
`BuffTargetKind` (`Skill`/`Attribute`/`Protection`/`Aura`/`Bane`/
|
||||
`Regeneration`/`Other`) and exposing coarser boolean toggles
|
||||
|
|
@ -529,7 +551,7 @@ That said, real gaps and divergences were found:
|
|||
existing `--Name_Server*.usd` files from `C:\Games\VirindiPlugins\VirindiTank\`.
|
||||
6. **Minor naming difference, not a functional gap**: VTank's setting is
|
||||
`BlacklistedSpellComps`; `CombatSettings.BlacklistedSpellComponents`
|
||||
(`CombatSettings.cs:106`) and `BuffSettings.BlacklistedSpellComponents`
|
||||
(`CombatSettings.cs:113`) and `BuffSettings.BlacklistedSpellComponents`
|
||||
(`BuffPlan.cs:26`) spell the field out in full. `SetMetaOption`'s case
|
||||
label is still the exact VTank string (`"blacklistedspellcomps"`,
|
||||
`MossTankPanel.cs:3305`), so external-facing compatibility (`/vt`-style
|
||||
|
|
@ -544,16 +566,12 @@ programmatic diff) — the gaps here are all about **persistence fidelity**,
|
|||
|
||||
## 6. Could not determine
|
||||
|
||||
- **The exact runtime semantics of `global::bk.a(name, gy)`** used by
|
||||
`/vt opt setinall` (`uTank2/PluginCore.cs:5488`) — presumably "set this
|
||||
value in every loaded profile database," inferred from the command name
|
||||
and the fact it bypasses `f3.b`/`f3.a`, but `bk.cs` was not read in this
|
||||
pass to confirm.
|
||||
- **The `"~~"` filename prefix** filtered out of the nav-profile list
|
||||
alongside `"--"` (`uTank2/PluginCore.cs:7182`) — no assignment or
|
||||
producer of a `"~~"`-prefixed file was found in the code paths read for
|
||||
this document; possibly an auto-backup or in-progress-save marker used
|
||||
elsewhere in the nav system (doc 06's scope).
|
||||
- **The `"~~"` filename prefix — RESOLVED as far as VTank goes** (citation
|
||||
pass 2026-09-06): `uTank2/PluginCore.cs:7182` filters it but VTank never
|
||||
produces it — `grep -rn '~~'` over the decompile returns only that line
|
||||
and an unrelated string delimiter (`hw.cs:127`), and no `~~*` file exists in
|
||||
the live profile directory. It is a filter for files written by a different
|
||||
Virindi assembly, not by `utank2-i.dll`.
|
||||
- **Whether `RechargeHandlerSet` has *any* live UI editor at all.** No
|
||||
control in `mainView.xml` or `AdvancedOptionsView.xml` matches (no
|
||||
`lstRecharge`-style list), and both `/vt opt set` and the generic
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue