447 lines
23 KiB
Markdown
447 lines
23 KiB
Markdown
# MossTank research: Virindi Tank parity and UtilityBelt expressions
|
||
|
||
Date: 2026-08-26
|
||
|
||
This report is the requirements baseline for turning MossTank from the small
|
||
self-buffing sample into acdream's full automation plugin. The product target is
|
||
deliberately broad: **all Virindi Tank functionality**, with UtilityBelt's more
|
||
capable expression dialect as the scripting baseline. File compatibility is a
|
||
separate decision; behavioral capability is not.
|
||
|
||
## 1. Evidence and limits
|
||
|
||
The following primary VTank pages were read and cross-checked (the live wiki
|
||
and its indexed historical revisions were both used where a mirror was
|
||
temporarily unavailable):
|
||
|
||
- `http://virindi.net/wiki/index.php/Virindi_Tank`
|
||
- `http://virindi.net/wiki/index.php/Virindi_Tank_Standard_Options`
|
||
- `http://virindi.net/wiki/index.php/Virindi_Tank_Advanced_Options`
|
||
- `http://virindi.net/wiki/index.php/Virindi_Tank_Commands`
|
||
- `http://virindi.net/wiki/index.php/Virindi_Tank_Meta_System`
|
||
- `http://virindi.net/wiki/index.php/Meta_Expressions`
|
||
- `https://utilitybelt.gitlab.io/docs/expressions/`
|
||
|
||
The 2026-08-27 MT2 follow-up also verified the exact documented distinctions
|
||
that drive the combat scheduler:
|
||
|
||
- A+R requires `MinimumRingTargets` inside Ring Range; R without A rings with
|
||
any configured target inside range and falls back to standard war outside;
|
||
- `UseArcs` prefers an arc over a bolt only at/above `ArcRange`;
|
||
- `Void Basic`, `Drain Auto`, and `Harm` are distinct Monsters damage choices;
|
||
- `GhostMonsterSpellAttemptCount` counts spell attempts which never start,
|
||
while `BlacklistMonsterAttemptCount` counts successful attacks which miss;
|
||
- the health-tracker ghost detector is independent and applies to melee,
|
||
missile, and magic.
|
||
|
||
Sources: the official `Virindi_Tank_Standard_Options`,
|
||
`Virindi_Tank_Advanced_Options`, `Virindi_Tank_FAQ`, `Options_List`, and
|
||
`Virindi_Tank_Changelog` pages listed above.
|
||
|
||
For UtilityBelt, documentation was checked against the primary source rather
|
||
than relying on the generated web page alone. The inspected repository was
|
||
`https://gitlab.com/utilitybelt/utilitybelt`, commit
|
||
`5fe9825a82f38047737768fd92c61dd47d88e467` (2026-03-05). The grammar is
|
||
`UtilityBelt/Lib/Expressions/MetaExpressions.g4`; every method carrying an
|
||
`ExpressionMethod` attribute was enumerated. The source is MIT licensed.
|
||
|
||
This report extends, rather than replaces,
|
||
`2026-07-29-vtank-plugin-automation-requirements.md`. That earlier report
|
||
already decoded VTank's `.met`, `.nav`, and `.utl` structures from primary
|
||
sources and remains the format reference.
|
||
|
||
## 2. Complete VTank capability map
|
||
|
||
### 2.1 Combat
|
||
|
||
VTank is a priority-driven combat controller, not merely an auto-attack loop.
|
||
Its supported combat family includes:
|
||
|
||
- melee, missile, mage, hybrid, two-handed, Void and Summoning characters;
|
||
- Life harm/martyr attacks, grenades, lenses, cast-on-strike weapons, streaks;
|
||
- automatic damage/weapon choice and monster-specific weapon, offhand and pet
|
||
element overrides;
|
||
- monster rules with `DEFAULT` plus ordered first-match expressions;
|
||
- per-rule priority from ignore (`-1`) through `4`, attack/debuff flags,
|
||
damage type, attack height, ring/streak choices, and void curses;
|
||
- target selection by distance, angular deviation, or the hybrid method using
|
||
angle inside a configurable cutoff and distance outside it;
|
||
- target lock, blacklist/retry behavior, and ghost-target retirement after
|
||
failed casts or missing health updates;
|
||
- debuff scheduling by one target, priority group, or all targets before
|
||
attack; spell-level versus skill-based debuff choice and reapply windows;
|
||
- automatic ring use by nearby-target density and arc/bolt choice by range;
|
||
- melee high/middle/low attacks, automatic or explicit power, Recklessness;
|
||
- pet density, element, refill and test behavior.
|
||
|
||
VTank's macro scheduler checks multiple action lists in priority order. Combat
|
||
therefore cannot be implemented as an isolated timer: healing, buffing,
|
||
navigation, looting, fellowship assistance and combat all need one arbiter.
|
||
|
||
### 2.2 Buffing and vitals
|
||
|
||
- automatic trained attribute/skill buffs, protections, banes, auras,
|
||
regeneration and configured extra buffs;
|
||
- protection/bane profile sets, exclusions, level/tier selection, signed
|
||
skill-over-difficulty thresholds, force buff and idle top-off;
|
||
- time-remaining rebuff and persisted item-buff duration knowledge;
|
||
- combat, idle and fellowship-helper vital thresholds;
|
||
- kits, vital transfers, post-switch recharge behavior and special healing
|
||
items;
|
||
- self-dispel in response to high-level vulnerabilities.
|
||
|
||
MossTank's current buff engine already owns the first useful subset: known
|
||
self buffs, tier/difficulty choice, in-force enchantment timing, force buff,
|
||
and stamina/mana upkeep. It remains plugin policy over host primitives.
|
||
|
||
### 2.3 Inventory and crafting
|
||
|
||
- AutoStack and AutoCram;
|
||
- pea splitting and priority rules;
|
||
- crafting of kits, foods, arrowheads and special ammunition;
|
||
- mana-stone acquisition, filling and application to equipped items;
|
||
- lockpick selection and use;
|
||
- component, consumable, tool and ammunition upkeep.
|
||
|
||
### 2.4 Looting
|
||
|
||
- corpse approach/open/retry/timeout/blacklist;
|
||
- all/fellow/rare loot modes and priority boosts;
|
||
- appraisal/ID wait, unknown-scroll reading and salvage combining;
|
||
- a loot-plugin seam, with VTClassic as the canonical ordered, first-match
|
||
rule engine over raw and computed item properties;
|
||
- actions including no-loot, keep, keep-up-to, salvage, sell, read and custom
|
||
user actions.
|
||
|
||
The host must expose object property bags, appraisal completion and
|
||
transaction primitives. Rule ordering and loot-profile policy belong in
|
||
MossTank.
|
||
|
||
### 2.5 Navigation
|
||
|
||
- circular, linear, once/runback and follow routes;
|
||
- points, portals, recalls, pauses, chat, vendor, repeated NPC talk/use,
|
||
server-confirmed checkpoints and charged/shift/strafe jumps;
|
||
- closest-entry, reversal, arrival/off-course ranges, door use and
|
||
follow-around-corners;
|
||
- combat/nav priority interaction.
|
||
|
||
Route storage belongs to the plugin. The host owes move-to, follow, turn,
|
||
jump, use and authoritative-arrival primitives.
|
||
|
||
Direct inspection of the official assembly on 2026-08-27 pinned the route
|
||
contract more tightly:
|
||
|
||
- `eNavType` is Circular, Linear, Target and Once; Once destructively removes
|
||
its first completed row and Linear deliberately visits each endpoint once
|
||
while flipping direction;
|
||
- `eWaypointType` assigns Point/Portal/Recall/Pause/ChatCommand/OpenVendor/
|
||
Portal2/UseNPC/Checkpoint/Jump to numeric ids 0..9;
|
||
- `fd.cs` turns outside 4°, moves while turning only within 45° beyond 3 m or
|
||
15° inside 3 m, and stops at `NavCloseStopRange` (default 2 m);
|
||
- `gr.cs` compares the checkpoint against the last server position rather
|
||
than client prediction and nudges forward after 15 seconds without an
|
||
acknowledgement;
|
||
- `gl.cs` records the followed player's path by approximately 9.6 cm and
|
||
drops old breadcrumbs when the follower comes within 2.4 m of a later path
|
||
segment, preserving follow-around-corners;
|
||
- `e9.cs` and `fa.cs` reacquire exact-name/class objects within 2.5 m of the
|
||
stored position. Portal2 retries when portal exit remains within 15 m of
|
||
its origin; UseNPC repeats until the named NPC tells or gives to the player;
|
||
- `b7.cs` is a rule independent of the route node list. `OpenDoors` defaults
|
||
false; it IDs doors at 20 m, opens at 4 m, and accepts a lock when Lockpick
|
||
is at least `difficulty - 50` using an owned lockpick.
|
||
|
||
These are plugin policies over additive canonical projections, not a second
|
||
movement model. The host applies semantic movement intent through Runtime's
|
||
existing command interpreter and supplies the accepted server position needed
|
||
only by Checkpoint.
|
||
|
||
### 2.6 Fellowship and social automation
|
||
|
||
- tell-driven recruitment and waiting lists;
|
||
- fellowship leader/member/state queries and leader replacement voting;
|
||
- fellowship healing, corpse permissions and coordinated target/debuff policy;
|
||
- multi-client composition through chat rather than a privileged macro API.
|
||
|
||
### External loot-classifier seam
|
||
|
||
VTank loads one `LootPluginBase`, asks `DoesPotentialItemNeedID`, and then
|
||
calls `GetLootDecision(GameItemInfo)`. Its public result vocabulary is
|
||
NoLoot, Keep, Salvage, Sell, Read, User1–User5 and KeepUpTo with `Data1` as the
|
||
limit. MossTank modernizes discovery into a host-owned classifier registry:
|
||
plugins register a namespaced classifier for their own lifetime, while
|
||
MossTank remains the corpse/appraisal/pickup/action executor. The selected
|
||
engine is durable policy; if it unloads, MossTank returns no classifier match
|
||
instead of silently applying the built-in profile.
|
||
|
||
Direct inspection of the official `hv.cs` also shows that a custom loot
|
||
plugin's per-item action is retained only after the item enters owned
|
||
inventory and is removed when the item leaves. The modern registry therefore
|
||
has matching `OnLooted` and `OnItemRemoved` callbacks. MossTank invokes them
|
||
only from authoritative inventory publication/removal, never when pickup is
|
||
merely dispatched.
|
||
|
||
### Options-page scheduler findings
|
||
|
||
The official Options controls are not merely presentation aliases:
|
||
|
||
- `fz.cs` runs the ordinary `RebuffTimeRemainingSeconds` rule before combat;
|
||
- `cLogic.cs` runs a second `IdleBuffTopoffTimeSeconds` pass only behind
|
||
`IdleBuffTopoff`, after attack/loot work has gone idle;
|
||
- the PRETARGETAPPROACH `g8` rule navigates only between `AttackDistance` and
|
||
`ApproachDistance`, and requires both combat and navigation to be enabled;
|
||
- `cm.cs` changes to Peace only as the final no-target/no-work fallback.
|
||
|
||
The UI displays AC-distance settings multiplied by 240. MossTank stores metres
|
||
in its typed controllers and converts only at the VTank option boundary.
|
||
|
||
### 2.7 Meta state machine
|
||
|
||
- named states beginning at `Default`;
|
||
- state-local rules, each firing once per state entry;
|
||
- nested conditions (`All`, `Any`, `Not`) and conditions for chat regex,
|
||
inventory, timers, nav state, death, vendors, monsters, buffs, coordinates,
|
||
portals, burden, route distance, expressions and captured chat groups;
|
||
- actions for state transition, chat, grouped actions, embedded navigation,
|
||
call/return stack, expression execution, expression-derived chat, watchdogs,
|
||
option read/write and runtime-created views;
|
||
- a roughly 293 ms decision cadence plus evaluation when the macro asks for
|
||
its next action.
|
||
|
||
### 2.8 Profiles, commands and companion behavior
|
||
|
||
- independent settings, navigation, loot and meta profiles; global and
|
||
per-character variants; hot loading and automatic persistence;
|
||
- command parity for macro state, options, buffing, meta, item testing,
|
||
property dumps, monster/spell diagnostics, route editing, attack power and
|
||
debug output;
|
||
- extensibility equivalent to VTClassic, VI2, item tools, follower/status HUD,
|
||
alerts and cross-character inventory. Some belong as separate acdream
|
||
plugins, but MossTank's API must permit them without privileged host code.
|
||
|
||
## 3. Expression language target
|
||
|
||
### 3.1 Why UtilityBelt is the baseline
|
||
|
||
VTank expressions are enough to power classic metas, but UtilityBelt preserves
|
||
the familiar syntax while adding typed lists and dictionaries, slicing,
|
||
higher-order collection functions, broader object queries and more action
|
||
primitives. MossTank should implement the UtilityBelt-compatible semantic
|
||
superset and offer a VTank compatibility mode for old expressions.
|
||
|
||
### 3.2 Grammar and evaluation semantics
|
||
|
||
The audited UtilityBelt grammar supports:
|
||
|
||
- multiple `;`-separated statements, returning the final result;
|
||
- session (`$`), persistent (`@`) and global (`&`) variables;
|
||
- decimal and hexadecimal numbers, booleans and two string forms;
|
||
- function calls using `name[...]`;
|
||
- typed values: number, string, boolean, list, dictionary, coordinate, world
|
||
object, stopwatch and UI control;
|
||
- list/string/dictionary indexing, slices and negative indices;
|
||
- complement, shifts, bitwise operators, exponentiation, arithmetic, regex
|
||
match (`#`), comparison, short-circuit `&&` and `||`;
|
||
- registered function metadata, arity/type validation and documented return
|
||
types;
|
||
- collection creation/mutation/copying plus map/filter/reduce/sort/range.
|
||
|
||
Implementation requirements follow directly: parse into an immutable AST;
|
||
compile or interpret without ambient reflection; use explicit value kinds;
|
||
short-circuit logical nodes; attach cancellation and an instruction budget;
|
||
make all world/action functions capabilities supplied by the MossTank engine;
|
||
and serialize only persistent/global variable stores.
|
||
|
||
### 3.3 Audited UtilityBelt function catalog (260 declarations)
|
||
|
||
The declaration count includes aliases/overloads. Grouped by capability, the
|
||
public names are:
|
||
|
||
- **language/conversion/math:** `abs`, `acos`, `asin`, `atan`, `atan2`,
|
||
`ceiling`, `chr`, `cnumber`, `cos`, `cosh`, `cstr`, `cstrf`, `floor`,
|
||
`hexstr`, `iif`, `ifthen`, `isfalse`, `istrue`, `lumavg`, `lumtotal`,
|
||
`ord`, `randint`, `round`, `sin`, `sinh`, `sqrt`, `strlen`, `tan`, `tanh`,
|
||
`tostring`, `vitae`;
|
||
- **variables:** `getvar`, `setvar`, `testvar`, `touchvar`, `clearvar`,
|
||
`clearallvars` and the corresponding `pvar` and `gvar` families;
|
||
- **execution/chat:** `exec`, `delayexec`, `clearexec`, `echo`, `chatbox`,
|
||
`chatboxpaste`;
|
||
- **lists:** `listcreate`, `listadd`, `listinsert`, `listremove`,
|
||
`listremoveat`, `listgetitem`, `listcontains`, `listindexof`,
|
||
`listlastindexof`, `listcopy`, `listreverse`, `listpop`, `listcount`,
|
||
`listclear`, `listfilter`, `listmap`, `listreduce`, `listsort`,
|
||
`listfromrange`;
|
||
- **dictionaries:** `dictcreate`, `dictgetitem`, `dictadditem`, `dicthaskey`,
|
||
`dictremovekey`, `dictkeys`, `dictvalues`, `dictsize`, `dictclear`,
|
||
`dictcopy`;
|
||
- **time/location:** `getdatetimelocal`, `getdatetimeutc`, `getunixtime`,
|
||
`getworldname`, `getplayercoordinates`, `getplayerlandblock`,
|
||
`getplayerlandcell`, coordinate parse/get/distance/string functions,
|
||
stopwatch functions, and the eleven `getgame*`/day/night functions;
|
||
- **character:** raw typed property reads, base/buffed skills, training level,
|
||
base/current/buffed-max vitals, base/buffed attributes, burden, free slots,
|
||
cooldown expiration, account hash and character index;
|
||
- **spells/components:** `getknownspells`, `getisspellknown`,
|
||
`getcancastspell_buff`, `getcancastspell_hunt`, `getspellexpiration`,
|
||
`getspellexpirationbyname`, `spelldata`, `spellname`, `componentdata`,
|
||
`componentname`;
|
||
- **world objects:** validity/data/ID-time, raw typed properties, identity,
|
||
health/vitals, spells, coordinates, selection/player/open-container, door
|
||
state, nearest monster/door/by class/name/template, and `wobjectfindall*`
|
||
variants over world, landscape, inventory and containers;
|
||
- **actions:** select, use, apply, give, equip wand, cast, cast-on-target,
|
||
move, split and drop;
|
||
- **combat/movement:** combat state get/set, busy state, equipped weapon type,
|
||
heading/get-heading-to, motion get/set/clear and portal-state query;
|
||
- **inventory/loot/salvage:** counts by name/regex/type, give-profile,
|
||
unopened corpse queries, `ustadd`, `ustopen`, `ustsalvage`;
|
||
- **fellowship/quest/XP:** thirteen fellowship queries, quest state/progress,
|
||
seven XP-meter operations;
|
||
- **UI/options/network/login:** status HUD, view/control get/set/visibility,
|
||
VT option/meta get/set, macro status, UtilityBelt options, regex capture,
|
||
network clients and next-login control.
|
||
|
||
This catalog is a compatibility test ledger. Each name must eventually be
|
||
implemented, deliberately aliased, or marked unsupported with a documented
|
||
reason; silent omission is not acceptable.
|
||
|
||
## 4. acdream mapping after the 2026-08 campaigns
|
||
|
||
The 2026-07 report's architecture remains correct, but its gap table is stale.
|
||
The Runtime now owns inventory transactions, selection, combat mode and power
|
||
state, casting, fellowship, allegiance, vendor and secure-trade state. MossTank
|
||
already consumes a small BCL-only `IAutomationSurface` for vitals, skills,
|
||
spells, enchantments, casting and local chat.
|
||
|
||
The gaps relevant to the first autocombat milestone are narrower:
|
||
|
||
| Need | Canonical owner today | Plugin gap |
|
||
|---|---|---|
|
||
| hostile query and live position | `RuntimeEntityDirectory` + `ClientObjectTable` | no target snapshot/query |
|
||
| health and selected target | `RuntimeActionState` | no combat view |
|
||
| melee/missile charge/release | `RuntimeCombatAttackState` | no command surface |
|
||
| combat-mode transition | `RuntimeCombatModeState` | no command surface |
|
||
| known offensive spells | `Spellbook` | only self buffs are enumerated |
|
||
| target-specific cast | selection + `RuntimeSpellCastState` | possible only by composing two old services |
|
||
| polished plugin controls | retained `IUiRegistry` markup | markup lacks bound visibility/enabled/style affordances |
|
||
|
||
The first implementation therefore does not need a second runtime bridge or a
|
||
second object model. It needs a narrow additive projection of those exact
|
||
owners.
|
||
|
||
## 5. Decisions for MossTank
|
||
|
||
1. MossTank remains an ordinary plugin. It never references App, Runtime,
|
||
rendering, networking or DAT assemblies.
|
||
2. The host API exposes snapshots and attempt-style commands; MossTank owns
|
||
target scoring, rule ordering, spell/attack choice and timing.
|
||
3. The first combat milestone supports melee, missile and direct offensive
|
||
magic, target lock, range/angle/hybrid scoring, priority rules, attack
|
||
height and power. Navigation, weapon swapping, debuffs, vulnerabilities,
|
||
pets and monster expressions are later combat slices, not hidden stubs.
|
||
4. Expressions will use UtilityBelt's richer typed semantics. Compatibility
|
||
is defined by parser/evaluator tests and the audited function ledger, not by
|
||
copying UtilityBelt implementation code.
|
||
5. Native MossTank profiles will be versioned JSON. Importers for VTank files
|
||
can be added later without constraining the internal model.
|
||
6. The UI uses acdream's retained plugin UI contract. Missing generic controls
|
||
should improve that contract/markup rather than making MossTank depend on a
|
||
presentation implementation.
|
||
|
||
### 5.1 Follow-up implementation findings (2026-08-27)
|
||
|
||
VTank's official `e0.d(name)` first looks in `MonsterDamageOverrides`, then
|
||
maps the monster to `SpeciesDamages`; `ga.g(...)` walks that ordered preference
|
||
list and finally tries the unlisted elements 0..6. acdream already projects
|
||
retail `CreatureType` as `PluginCombatTarget.SpeciesId`, so MossTank can bypass
|
||
VTank's name-to-species compatibility table while preserving the same ordered
|
||
damage result. Exact name overrides still win. The imported official feed has
|
||
59 overrides and 103 species rows.
|
||
|
||
### 5.2 Official inventory and loot findings (2026-08-27)
|
||
|
||
The official VTank assembly and its GameInfoDB were inspected rather than
|
||
inferring behavior from the UI labels:
|
||
|
||
- `el.cs`/`cf.cs` supply 757 exact craft rows; prerequisites are recursive and
|
||
share the canonical item-use transaction;
|
||
- `fo.cs` identifies every corpse before selection, parses `Killed by ...`,
|
||
admits the player's own corpse immediately, admits a Share Loot fellow
|
||
immediately, waits 100 seconds for a non-sharing fellow or unrelated public
|
||
corpse, and never crosses ownership on another player's rare-generating
|
||
corpse;
|
||
- the default corpse-open retry contract is 30 attempts, then a 200-second
|
||
blacklist; completed corpse records expire after 60 minutes;
|
||
- `hv.cs` applies the ordered loot rule first, then falls back to readable
|
||
unknown scrolls and automatic mana-stone/tank acquisition;
|
||
- `dy.cs` proves that ManaTank is a mana-bearing donor target, not a worn-item
|
||
recharge consumable. A ManaStone is used on that donor when its mana is at
|
||
least `ManaTankMinimumMana` (default 1000);
|
||
- `c7.cs` combines only same-material salvage bags in exact workmanship bands
|
||
`<7`, `7–<9`, `9–<10`, and exactly `10`; one bugged source is abandoned after
|
||
40 failed combine attempts;
|
||
- `gmSalvageUI::Salvage` calls
|
||
`CM_Inventory::Event_CreateTinkeringTool`: game action `0x027D`, tool id,
|
||
then `PackableList<unsigned long>` (count plus ordered item ids). This same
|
||
operation handles ordinary source salvage and salvage-bag combination.
|
||
|
||
The native implementation keeps settings, loot, route, and meta documents
|
||
independent, matching VTank's profile model while using versioned JSON as the
|
||
working format. It also emits and imports exact compatibility files: `uTank2
|
||
NAV 1.2`, CondAct `.met`, and VTClassic `UTL 1` (plus legacy UTL v0 reads).
|
||
The UTL port preserves unknown length-delimited requirement and extra-block
|
||
payloads, executes the complete 31-type requirement vocabulary, and carries
|
||
the `SalvageCombine` material ranges/value modes into the live combine planner.
|
||
VTClassic's color rules use the original ordered ObjDesc subpalettes and the
|
||
original sample index `length*16 + offset*32 + 8`, resolved from portal DAT
|
||
palette colors rather than approximated from icon pixels.
|
||
|
||
Profiles are implemented over manifest-scoped JSON with exact VTank files as
|
||
an interchange/export layer: `By char` hashes the canonical character name into a distinct
|
||
document, named profiles are explicit shared snapshots, and the index records
|
||
owner plus per-character active selection. Create/copy/clear/select all hot-
|
||
load the same mutable policy owners already borrowed by the controllers. The
|
||
generic retained markup contract gained editable fields and retail dropdown
|
||
menus for this editor; later Monsters, Loot, Route, and Meta editors reuse the
|
||
same controls.
|
||
|
||
## 6. Acceptance boundary for “autocombat ported”
|
||
|
||
The milestone is complete when an in-world MossTank panel can enable/disable
|
||
combat, periodically capture canonical hostile targets, preserve a valid
|
||
locked target, choose a target by configured range/angle/hybrid policy and
|
||
priority, enter the equipped default combat mode, drive retail's physical
|
||
press/charge/release state machine at configured height/power, or cast the
|
||
best usable learned direct offensive spell in magic mode. It must stop cleanly
|
||
on session loss, invalid/dead/out-of-range targets, and user disable; it must
|
||
not duplicate Runtime state or issue overlapping requests.
|
||
|
||
Full VTank parity is the campaign target. This acceptance boundary is only the
|
||
first executable slice requested for this work session.
|
||
|
||
## 7. Official binary combat-item findings (2026-08-27)
|
||
|
||
The official `vt.tar.gz` update was decompiled for behavior research and the
|
||
live GameInfoDB v9 feed was read directly. The decisive implementations are
|
||
`dz.cs` (debuff source selection), `ga.cs` (item classification), `gs.cs`
|
||
(caster-item confirmation), `bo.cs` (physical/proc confirmation), and `hi.cs`
|
||
(attack-power policy).
|
||
|
||
- `dz.b.CompareTo` ranks spell quality then source skill/spellcraft for
|
||
`SpellLevel`, reverses those two for `Skill`, and gives a learned spell the
|
||
final tie. Spell quality is normally spell difficulty.
|
||
- Caster items activate on the target. Melee/missile proc weapons are equipped
|
||
and repeatedly attack at power 0/1 respectively. Neither path counts as
|
||
applied until color-7 combat chat matches `^You cast (.*) on .*$`.
|
||
- Grenades are missile-class items with CombatUse 0 and `Phial` in the name;
|
||
the official database contains exactly 72 names across eight material tiers,
|
||
with Alchemy requirements 75..400 and spellcraft 100..520.
|
||
- Normal physical attack power is not a smooth heuristic. `hi.cs` emits the
|
||
exact 0, .2, .49, .5 or 1 values for slash/pierce hybrid arrangements, then
|
||
clamps to .11..90 when trained Recklessness is enabled.
|
||
|
||
These findings require three host facts VTank formerly obtained through
|
||
Decal: retained per-item appraisal SpellBooks, ordered transcript capture, and
|
||
an explicit combat-mode command. They are additive BCL plugin contracts;
|
||
MossTank retains all source-choice and retry policy.
|