No description
Find a file
Erik 2213abf475 docs: rewrite README to reflect current plugin features
Full rewrite covering:
- VitalSharingTracker + DxHud overlay (cross-machine vital sharing
  replacing UB's localhost-only VTankFellowHeals)
- CombatStatsTracker (~50 Mag-Tools regex patterns, per-element
  breakdown, session/lifetime split)
- LiveInventoryTracker (OnCreate/OnChange/OnRelease → inventory_delta)
- Full event stream catalog (telemetry, vitals, character_stats,
  combat_stats, share_*, nearby_objects, dungeon_map, quest, rare, etc.)
- DECAL STA threading rules (WinForms.Timer not Timers.Timer)
- Hot reload path
- Per-character YAML config structure
- In-game /mm commands (including new radar + vitalsharing toggles)
- Complete project structure
- Cross-repo contract guidance

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-24 14:55:36 +02:00
MosswartMassacre fix(combat): remove plugin-side lifetime — backend accumulates now 2026-04-14 10:58:21 +02:00
MosswartMassacre.Loader feat: add searchable metas sync tab and configurable auto-updates 2026-03-09 11:36:47 +01:00
Shared feat: add ContainerId to MyWorldObject for inventory tracking 2026-02-28 15:34:16 +00:00
Unused te 2025-06-09 02:03:11 +02:00
.gitattributes Add .gitattributes and .gitignore. 2025-03-28 22:11:15 +01:00
.gitignore Remove files that should not be in repo 2026-02-27 08:10:39 +00:00
AGENTS.md feat: add searchable metas sync tab and configurable auto-updates 2026-03-09 11:36:47 +01:00
mossy.sln Added hot reload 2025-06-22 12:10:15 +02:00
README.md docs: rewrite README to reflect current plugin features 2026-04-24 14:55:36 +02:00

MosswartMassacre — DECAL Plugin for Asheron's Call

Status: Production · In-game companion plugin for the Mosswart Overlord backend

A comprehensive DECAL plugin for Asheron's Call that streams live telemetry, vitals, inventory, combat, chat, and rare discoveries to a backend server via WebSocket. Pairs with the Mosswart Overlord web dashboard for real-time multi-account tracking, analytics, and cross-machine utilities.


📋 Table of Contents


🚀 Features

Core Tracking

  • Telemetry: Position, kills, kills/hour, online time, VTank state, memory/CPU stats — streamed every 2 seconds
  • Vitals: Health / Stamina / Mana / Vitae percentages, updated continuously
  • Character Stats: Full attributes, skills, allegiance, augmentations — sent every 10 minutes
  • Chat: All chat lines forwarded with color preservation (supports server-side filtering by channel)
  • Rare Discoveries: Automatic detection + classification (common vs great rares)
  • Quest Timers: Progress tracking with countdown/ready state

Inventory

  • Full Inventory Dump: Complete snapshot on login via full_inventory
  • Live Deltas: inventory_delta events for add/update/remove on OnCreate, OnChange, OnRelease
  • ID Requests: Auto-requests appraisal for items needing spell/combat data
  • Rich Metadata: Spells, materials, tinkers, workmanship, mana charge, imbues, spellcraft

Combat Stats (Mag-Tools Style)

  • CombatStatsTracker: Parses ~50 chat regex patterns matching Mag-Tools combat output
  • Per-element Breakdown: Damage offense/defense split by slashing/piercing/bludgeoning/fire/cold/acid/lightning
  • Monster Records: Per-monster damage given/received/kill count
  • Aetheria Surge Tracking: Counts surge triggers
  • Session Deltas: Sends session snapshot every 10s; backend accumulates lifetime

Cross-Machine Vital Sharing (VTankFellowHeals Replacement)

  • Broadcasts own vitals + debuff state via WebSocket at 150ms intervals
  • Receives peer vitals and feeds them into UBHelper.vTank.Instance, making fellow members visible to VTank's heal logic across different machines (vs UB's localhost-only default)
  • DxHud Overlay: In-game UB-style vital bars with direction arrows, Ctrl+drag repositioning

Nearby Objects / Radar

  • On-demand broadcast of nearby monsters, players, NPCs, containers
  • Dungeon tile data for the browser's radar overlay
  • Range + entity-type filters configurable from backend command

Navigation Visualization

  • Parses VTank .nav files (Circular, Linear, Target, Once; Point/Portal/Recall/Pause/ChatCommand/OpenVendor/UseNPC/Checkpoint/Jump waypoints)
  • Renders routes as red lines in the 3D game world
  • Side-by-side comparison with UtilityBelt's active navigation
  • Performance-capped at 500 rendered segments

Remote Command Execution

  • Backend can send {player_name, command} envelopes via the /ws/live route → plugin executes in-game
  • Supports /radar, /mm subcommands, chat sends, and any / command that VTank/game accepts

Death & Idle Detection (backend-assisted)

  • Plugin reports vitals; backend detects vitae 0→>0 transitions (death) and continuous idle state (5-min grace period) and posts to Discord

Rare Meta Auto-State

  • Optional: toggles VTank meta state on rare detection (e.g., to auto-loot or pause)

🏗️ Architecture

┌─────────────────────────────────────────────────┐
│ Asheron's Call client                          │
│  ┌────────────────────────────────────────────┐ │
│  │ DECAL                                     │ │
│  │  ┌──────────────────────────────────────┐ │ │
│  │  │ MosswartMassacre.dll                │ │ │
│  │  │                                      │ │ │
│  │  │  • PluginCore — lifecycle + wiring  │ │ │
│  │  │  • WebSocket client                 │ │ │
│  │  │  • KillTracker / CombatStatsTracker │ │ │
│  │  │  • LiveInventoryTracker             │ │ │
│  │  │  • VitalSharingTracker              │ │ │
│  │  │  • VitalSharingOverlayView (DxHud)  │ │ │
│  │  │  • NavVisualization                 │ │ │
│  │  │  • VVSTabbedMainView (UI)           │ │ │
│  │  └──────────────────┬───────────────────┘ │ │
│  └─────────────────────│────────────────────── │
└─────────────────────────│─────────────────────┘
                          │ wss://
                          ▼
           overlord.snakedesert.se/ws/position
           (Mosswart Overlord backend)

DECAL COM objects are apartment-threaded (STA) — the plugin carefully uses System.Windows.Forms.Timer (never System.Timers.Timer) for any periodic work touching the game API, and hooks EchoFilter.ServerDispatch early enough to catch pre-login events.

📥 Installation

Prerequisites

  • Windows with .NET Framework 4.8
  • Asheron's Call client with DECAL Adapter installed
  • VirindiViewService (included in lib/)

Quick Setup

  1. Build (or grab the release DLL): see Building
  2. Copy MosswartMassacre.dll to C:\Games\Decal Plugins\MosswartMassacre\
  3. Restart DECAL and enable the plugin under Plugins → MosswartMassacre
  4. Configure settings through the tabbed in-game UI

Building from Source

# From repo root
dotnet build mossy.sln -c Release -v minimal

Output DLL: MosswartMassacre\MosswartMassacre\bin\Release\MosswartMassacre.dll

⚙️ Configuration

Settings are stored per-character in YAML at <PluginDir>\<CharacterName>.yaml:

# Core
websocket_enabled: true
telemetry_enabled: true
char_tag: "default"
rare_meta_enabled: true
remote_commands_enabled: true
http_server_enabled: false

# Vital Sharing
vital_sharing_enabled: true
vital_sharing_overlay_x: 100
vital_sharing_overlay_y: 200

# Navigation
vtank_profiles_path: "C:\\Games\\VirindiPlugins\\VirindiTank\\"

# UI
main_window_x: 100
main_window_y: 100

Backend endpoint

The WebSocket URL is set in WebSocket.cs. Shared-secret auth is sent as a query string parameter.

🎮 In-Game Commands

Access plugin commands via /mm:

/mm help                    — show all commands
/mm report                  — current kill stats
/mm loc                     — current map coordinates
/mm reset                   — reset counters/timers
/mm meta                    — toggle auto rare meta state
/mm start_radar             — start broadcasting nearby objects
/mm stop_radar              — stop radar broadcasts
/mm http <on|off>           — toggle local HTTP command server (port 8085)
/mm telemetry <on|off>      — toggle telemetry streaming
/mm vitalsharing <on|off>   — toggle cross-machine vital sharing
/mm combat <show|reset>     — combat stats session control

📡 Event Streams

All events are JSON frames over a single /ws/position WebSocket connection. Type discriminator is the type field.

Event Frequency Purpose
telemetry 2s Position, kill count, session metrics
vitals 150ms (on change) HP / Stam / Mana / Vitae
character_stats 10 min Full attributes/skills
full_inventory login Complete inventory snapshot
inventory_delta on item add/change/remove Incremental per-item update
equipment_cantrip_state on equip change Current equipped spell effects
combat_stats 10s Mag-Tools-style combat deltas
chat on line Any chat message
rare on discovery Rare item find
spawn on spawn observation Monster appeared nearby
portal on discovery Portal with coordinates
quest on update Quest timer/progress
nearby_objects on radar command Entities within range
share_vitals / share_debuffs / share_cast continuous Cross-machine vital sharing
dungeon_map on dungeon entry Floor tile data

See backend EVENT_FORMATS.json for exact schemas.

🩺 Cross-Machine Vital Sharing

Default UtilityBelt VTankFellowHeals only works across characters on the same machine (IPC-based). This plugin replaces it with a WebSocket relay through the backend, enabling multi-box setups across multiple machines.

How it works

  1. Each plugin instance publishes its own vitals / cast state via WebSocket at 150ms intervals
  2. The backend relays share_* envelopes to every subscribed plugin
  3. VitalSharingTracker feeds peer data into UBHelper.vTank.Instance — VTank then behaves as if the peers are on the same machine
  4. Hooks packet 0xF7B1 and 0x004A for cast-attempt detection, plus chat regex for cast success

DxHud Overlay

A draggable in-game overlay shows each peer's vital bars with a direction arrow pointing toward that player. Ctrl+drag to reposition; click the × to hide.

🛠️ Building

Standard build

dotnet build mossy.sln -c Release -v minimal

Deploy (local test)

cp MosswartMassacre\MosswartMassacre\bin\Release\MosswartMassacre.dll \
   "C:\Games\Decal Plugins\MosswartMassacre\MosswartMassacre.dll"

Some repo workflows keep the release DLL checked in. If the path is gitignored, use git add -f when publishing a release.

Hot Reload

PluginCore supports an InitializeForHotReload path that re-wires trackers without a full DECAL restart. Useful during development — modify, rebuild, replace DLL, invoke hot-reload.

🔧 Technical Details

Build Configuration

  • Target: .NET Framework 4.8
  • Platform: AnyCPU / x86 (depending on DECAL host)
  • Architecture: Direct VirindiViewService integration (no wrapper abstraction)
  • Unsafe blocks: Enabled for P/Invoke

Threading Rules

  • Never touch DECAL COM objects from background threads — they're STA
  • Use System.Windows.Forms.Timer (UI-thread marshaled), not System.Timers.Timer
  • WebSocket send methods (SendXxxAsync) marshal to a background send queue safely

Key Files

File Responsibility
PluginCore.cs Lifecycle, tracker wiring, hot-reload entrypoint
PluginSettings.cs YAML per-character config
WebSocket.cs Single WS connection, reconnect, send helpers
ChatEventRouter.cs Dispatches chat to KillTracker + CombatStatsTracker + others
KillTracker.cs Parses kill messages, tracks session kills
CombatStatsTracker.cs Parses ~50 regex patterns (Mag-Tools style)
LiveInventoryTracker.cs OnCreate/OnChange/OnRelease → inventory_delta
VitalSharingTracker.cs Cross-machine vital/debuff relay
VitalSharingOverlayView.cs DxHud peer-vitals overlay
MossyInventory.cs Rare detection + classification
NavRoute.cs / NavVisualization.cs VTank .nav parser + renderer
VtankControl.cs VTank automation interface
Views/VVSTabbedMainView.cs Main tabbed UI

Dependencies

  • DECAL Framework — Decal.Adapter, Decal.Interop.Core, Decal.Interop.D3DService
  • VirindiViewService — UI framework for game overlays
  • Newtonsoft.Json — JSON serialization
  • YamlDotNet — Config file management
  • Mag.Shared — shared Mag-Tools utilities
  • UBHelper / UtilityBelt interop — for VTank state injection

📁 Project Structure

MosswartMassacre/
├── MosswartMassacre/
│   ├── PluginCore.cs
│   ├── PluginSettings.cs
│   ├── WebSocket.cs
│   ├── ChatEventRouter.cs
│   ├── KillTracker.cs
│   ├── CombatStatsTracker.cs
│   ├── CombatInfo.cs
│   ├── LiveInventoryTracker.cs
│   ├── VitalSharingTracker.cs
│   ├── MossyInventory.cs
│   ├── NavRoute.cs
│   ├── NavVisualization.cs
│   ├── VtankControl.cs
│   ├── HttpCommandServer.cs
│   ├── Telemetry.cs
│   ├── Utils.cs
│   ├── Views/
│   │   ├── VVSBaseView.cs
│   │   ├── VVSTabbedMainView.cs
│   │   └── VitalSharingOverlayView.cs
│   ├── ViewXML/
│   │   └── mainViewTabbed.xml
│   └── lib/                 # DECAL / VVS / UB interop DLLs
├── Shared/
│   ├── MyWorldObject.cs
│   └── MyWorldObjectCreator.cs
├── mossy.sln
└── README.md

🤝 Contributing

  1. Fork & branch (feature/... or fix/...)
  2. Respect the DECAL STA threading rules
  3. When changing event payload schema, update both plugin and backend in the same change — the systems are tightly coupled. See MosswartOverlord/EVENT_FORMATS.json for the authoritative contract.
  4. Prefer additive payload changes (new optional fields) over renames/removes
  5. Test end-to-end: plugin → backend WebSocket → browser dashboard

For cross-repo workflow guidance, see CLAUDE.md in both repos.

  • MosswartOverlord — the backend + frontend this plugin feeds
  • CLAUDE.md — developer guidance (AI assistant context)

📄 License

MIT — see LICENSE.


Built for the Asheron's Call community.