ArcanumLib
A shared client/server utility library for Vintage Story mods.
Why use it?
Writing a Vintage Story mod usually means solving the same problems again and again: loading JSON assets, drawing icons, scheduling work, tracking cooldowns, saving per-world data, applying status effects, or handling item charges and modes. ArcanumLib extracts those patterns into reusable, mod-agnostic helpers so you can focus on gameplay instead of boilerplate.
What is inside?
The library is split into clear areas. Each page answers three questions: what is it for, when to use it, and how to use it with a minimal code example.
GUI & Rendering
Everything you need for custom in-game UI without fighting the low-level API.
| Page | Purpose | |
|---|---|---|
| Arcanum GUI Toolkit | Themed colour palette, layout helpers, composer, and reusable controls. | |
| Radial Menu | Generic Cairo-styled radial (pie) menu with pluggable styles via IRadialMenuStyle registry. | |
| ItemListElement | Scrollable vertical list with icon nodes, status colours, tooltips, and custom icon support. | |
| CustomTabContent | Data-driven scrollable tab content with decorative Cairo icons and section layout. | |
| GuiDateTimePicker | Reusable date/time picker for GuiComposer with Now/Clear buttons. | |
| Custom Icons | Registry and interface for custom Cairo-drawn GUI icons keyed by string. | |
| HUDs & Overlays | Generic HUD panels, client systems, packet icon HUDs, and transient overlays. | |
| Holograms | Floating text labels above blocks with texture caching and 3D projection. | |
| BlockEntityConfigDialog | Generic base dialog for editing block entity configuration with typed config and save/cancel. | |
| ImageIconCache | Load and draw .png/.jpg/.webp icons with clipping and tinting. |
Items & Equipment
State and behaviour for items that need extra data on the stack.
| Page | Purpose |
|---|---|
| ItemCharge | Charge, drain, refuel, and stat-gating for any ItemStack. |
| ItemMode | Multi-mode items with F-key tool mode integration. |
| ItemStackBuilder | Fluent builder for constructing ItemStack instances with attributes and durability. |
| Inventory / ItemStack helpers | Give, count, find, and consume items. |
| InventoryChangeTracker | Throttled inventory fingerprinting to skip expensive recalculations when nothing changed. |
Actions
A reusable action registry for executing JSON-declared actions through typed handlers.
| Page | Purpose |
|---|---|
| ActionRegistry | Register typed handlers and execute JSON action descriptors with validation, cooldowns, and permissions. |
Persistence & Progression
Per-save data and long-term player systems.
| Page | Purpose |
|---|---|
| ModDataStore | Versioned per-savegame data with schema migration. |
| ModConfig | Typed config wrapper with load, save, validation, and defaults. |
| PityTracker | Per-player pity/guarantee counters for loot or reward systems. |
| Status Effects | Timed buffs/debuffs with stack, refresh, and override modes. |
Assets & Data
Loading, validating, and managing JSON assets from multiple mods.
| Page | Purpose |
|---|---|
| ModAssetLoader | Load and merge typed JSON assets from all loaded mods. |
| ModAssetRegistry | Build validated, keyed, source-tracked registries. |
| TagMatcher | Match collectibles and item stacks against include/exclude tag-sets and code patterns. |
| ValidationResult | Accumulate errors and warnings from validation pipelines. |
Performance & Scheduling
Keep the server/client responsive.
| Page | Purpose |
|---|---|
| DeferredWorkService | Game-tick scheduler for one-shot, callback, and coalesced work. |
| StatCoalescingEngine | Batch EntityStats.Set calls into a single network sync. |
| GameTimeScheduler | Schedule recurring actions by in-game time (daily, hourly, after N hours). |
| TimedCache | Thread-safe cache with TTL eviction. |
| CleanupScope | Cancel listeners, work, and nested disposables in one call. |
Events & Commands
| Page | Purpose |
|---|---|
| EventBusService | Typed publish/subscribe event bus for cross-mod communication. |
Diagnostics
Runtime validation and monitoring for ArcanumLib modules and dependent mods.
| Page | Purpose |
|---|---|
| Diagnostics | Automatic startup checks for services, ModSystems, EventBus health, dependency versions, and runtime monitoring (tick time, memory, entities). |
Logging
Categorized file logging for any mod.
| Page | Purpose |
|---|---|
| CategorizedLogger | Categorized file logger with modes, throttling, auto-flush, and configurable folder/prefix. |
Common & Utility
Helpers that remove boilerplate for common Vintage Story patterns.
| Page | Purpose | |——|———|
| Misc Helpers | Thin sugar and helper factories: chat formatting, damage sources, side checks, health scaling, player filters. |
| CooldownTracker | Per-entity cooldowns in WatchedAttributes. |
| EventScope | Disposable event subscription scope. |
| PlaytimeTracker | Per-player online time tracking, login streaks, real-time cooldowns, and combat-state checks. |
| WatchedAttributes | Get-or-create and set helpers for ITreeAttribute. |
Randomization & Geometry
| Page | Purpose |
|---|---|
| WeightedRandom | Weighted random picks and reusable weighted tables. |
| LootTable | JSON-friendly loot tables with tiers, weighted entries, and luck multipliers. |
| PositionUtils | Random horizontal offsets and ground-level position finding around entities. |
| BlockEntitySearchUtils | Chunk-based block entity counting within a region. |
Particle Effects
| Page | Purpose |
|---|---|
| Particle Effects | Fluent ParticleEffectBuilder, named color presets, and ready-to-use effect presets (explosions, auras, impacts, shockwaves, ambient). |
Networking
| Page | Purpose |
|---|---|
| TypedNetworkChannel | Typed send/receive wrapper for network channels. |
| ServerBroadcaster | Broadcast packets to all online players with predicate, radius, and exclusion filters. |
Quick start
Add ArcanumLib.csproj as a project reference, set VINTAGE_STORY, and add arcanumlib to modinfo.json:
{
"type": "mod",
"modid": "mymod",
"name": "MyMod",
"dependson": [ { "modid": "arcanumlib" } ]
}
Two common examples:
using ArcanumLib.Items;
float charge = ItemCharge.GetChargeValue(stack);
using ArcanumLib.Persistence;
var store = ModDataStore.GetOrCreate<MySaveData>(sapi, "mymod", "state", 1);
store.Data.Counter++;
store.Save();