Back to mods
HoR Performance Optimizer project artwork

Vintage Story Mod DB · Vintage Story mod

HoR Performance Optimizer

HoR Performance Optimizer is a unified server performance mod that dramatically reduces crafting grid recipe matching overhead and handbook page loading times on heavily modded servers. It builds shared reverse recipe indexes at startup and uses Harmony prefix

Choose a version Pick your version below, then grab the matching file.

Quick answer

Which HoR Performance Optimizer release should I use?

Updated 3 months ago
Latest stable file 1.0.5
Game version 1.22.0, 1.22.1, 1.22.2
Loader Built-in Vintage Story mod system

HoR Performance Optimizer 1.0.5 targets 1.22.0, 1.22.1, 1.22.2. It must be installed on the client. Installation on the dedicated server is optional. No extra mods listed for this file.

Where it goes

Is HoR Performance Optimizer required on the client, server, or both?

It must be installed on the client. Installation on the dedicated server is optional.

Client Required
Dedicated server Optional
Loader for this release Built-in Vintage Story mod system
Required install it here Optional supported, not mandatory Not supported do not install here Source doesn’t say do not assume

This release supports both sides, but the source does not require it on the server.

What else does HoR Performance Optimizer 1.0.5 need?

1.0.5. Change the file and its required mods may change too.

No extra mods listed for this file

This file does not list any required mods. Do not add a library just because a different file uses it.

This file does not list any required or optional mods.

Before you install it

Add HoR Performance Optimizer without breaking your instance.

Built for HoR Performance Optimizer 1.0.5. Pick another file and the loader, install side or required mods may change.

  1. 01

    Stick to this file

    Use 1.0.5. It targets 1.22.0, 1.22.1, 1.22.2; another release may have different loader, side or dependency requirements.

  2. 02

    Bring the mods it needs

    This file does not list any required mods. Do not add a library just because a different file uses it.

  3. 03

    Put it on the correct side

    It must be installed on the client. Installation on the dedicated server is optional.

  4. 04

    Pick the file you checked

    Use the “Get this file” button beside 1.0.5. It opens that exact file at the source.

About this project

What does HoR Performance Optimizer add?

HoR Performance Optimizer is a unified server performance mod that dramatically reduces crafting grid recipe matching overhead and handbook page loading times on heavily modded servers. It builds shared reverse recipe indexes at startup and uses Harmony prefix patches to skip impossible recipe matches before they reach the expensive vanilla logic, cutting recipe checks by 80-90%. Repeat handbook page opens become instant via component-level caching.

Stats: 80-90% Recipe Match Reduction • Fast Handbook Opens Restored • Stability-First Handbook Fixes • Shared Reverse Recipe Index • Universal

✨ What's New in v1.0.5
  • Vanilla shelf targeting FPS spikes reduced
    A heavy performance hotspot was identified in shelf interaction help generation. In large modpacks, looking at a vanilla shelf could trigger expensive dynamic matching work against very large interaction item lists. This update optimizes that path by removing high-cost dynamic shelf help matching while aiming at shelves and capping the shelf help sample stack list to a small bounded set. Result: much lower crosshair-on-shelf HUD overhead and smoother frame times in shelf view scenarios, including fresh empty shelves. Shelf gameplay behavior is unchanged: placing, taking, and using items on shelves still uses the normal vanilla logic.
✨ What's New in v1.0.4
  • Crafting grid lag with tools and modded items fixed
    Every time a slot changed in the crafting grid, the game iterated every single recipe in the game calling GridRecipe.Matches on each one. Even with fast per-call early exits this added up to hundreds of microseconds of stutter per keystroke, especially noticeable when placing tools or items used in many recipes. The fix adds an inverted ingredient index: rather than scanning all recipes, only recipes that share at least one concrete ingredient with what's actually in the grid are tested. A full wildcard fallback list handles any-item recipes. Typically 10–50 recipe checks instead of thousands. If the optimization cannot be applied due to game version differences, it silently falls back to the previous behavior.
✨ What's New in v1.0.3
  • Handbook search bar black box fixed
    When reopening the handbook or switching handbook tabs/pages, the search bar would briefly show a solid black rectangle until clicking it. This happened because the reopen fast path skipped initOverviewGui entirely, which also skipped the placeholder text refresh and focus restore that vanilla performs each open. The fix mirrors those two steps (placeholder rewrite + focus) inside the skip path so the search field always renders correctly without triggering the expensive full GUI rebuild.
✨ What's New in v1.0.2
  • Handbook open optimization scoped to overview-only
    The initOverviewGui skip and empty-search FilterItems fast path now only apply during a normal handbook open (pressing H with no item in hand). They no longer fire on unrelated handbook flows such as pressing H while holding an item to jump directly to its detail page, preventing those paths from being affected by the optimization.
  • GetHandbookInfo patch and transpiler removed
    The v1.0.1 GetHandbookInfo patch and IL transpiler were causing NullReferenceException crashes when pressing H while holding an item to open its handbook detail page directly. Both have been removed in v1.0.2. As a result, pressing H on an item to view its details is back to vanilla speed. The crash that was happening was random based on race conditions.
✨ What's New in v1.0.1
  • Handbook open lag fixed (~500ms to near-instant)
    Diagnosed via priority-bracketed Harmony diagnostics that proved AttributeRenderingLibrary's own FilterItems replacement was running the full GetPageText() scan on all 40,000+ pages every time you open the handbook. A new Priority.High prefix intercepts FilterItems before ARL runs. For empty search (opening the handbook with no search text) it populates the shown pages list with a direct category and duplicate check only - no GetPageText() calls at all - then skips ARL entirely. For actual typed searches it steps aside and lets ARL run normally.
  • initOverviewGui rebuild skipped on reopen
    The full GUI element rebuild and Cairo surface compose is now skipped when reopening an already-built handbook. The static background texture is refreshed via the engine's built-in deferred recomposeOnRender flag on the next frame instead of blocking when the handbook opens.
  • Crafting grid pre-filter upgraded to ALL-required logic
    The ingredient pre-filter now rejects a recipe the moment any required concrete ingredient is absent from the grid, not just when none match. For a recipe requiring iron + stick, if only iron is present the recipe is immediately rejected without a spatial layout check. This substantially reduces the candidates that reach GridRecipe.Matches().
  • addCreatedByInfo transpiler (page navigation lag)
    An IL transpiler replaces the single IWorldAccessor::get_GridRecipes() callsite inside addCreatedByInfo with a call to the pre-built reverse output index. Instead of scanning 22,000+ recipes on every page navigation, only the 5-50 recipes that actually produce the viewed item are checked. Items with no recipes at all receive an empty sentinel so the loop runs zero iterations.
  • Broken page cache removed
    The v1.0.0 component-level page cache was storing RichTextComponentBase[] arrays whose elements are disposed by VS when navigating away. On second open this returned disposed objects and caused blank or broken handbook sections. Removed. The transpiler fix above makes the cache unnecessary.
✨ What's New in v1.0.0
  • Initial Release for VS 1.22
    Brand-new mod combining the crafting grid optimizer (successor to HoR-RecipeOptimizer) with a new handbook page caching system. Built from scratch for VS 1.22 APIs using PascalCase properties (ResolvedIngredients, ResolvedItemStack, Shapeless, etc.).
  • Unified Architecture
    Both optimization systems share a single SharedRecipeIndex built once at startup, eliminating redundant recipe scanning. Previous HoR-RecipeOptimizer was crafting-only, this version adds handbook optimization.
⚡ System 1: Crafting Grid Optimization

Patch Types: Harmony Prefix + Event Filter

  • Harmony Prefix on GridRecipe.Matches() (CraftingGridPatch.cs)
    Intercepts every recipe match check before the expensive vanilla logic runs. Returns false immediately (skip original) if any pre-check fails:
    • Slot count check: If the grid has fewer filled slots than the recipe requires, skip.
    • Concrete item check: If the recipe requires specific items but none exist in the current grid, skip.
    • Grid size check: If the recipe is shaped and the grid is too small, skip.
    Only recipes that pass all pre-checks run the original Matches() logic.
  • Event-Based Filter (CraftingGridFilter.cs)
    Secondary pass registered on the MatchesGridRecipe event. Maintains an “impossible recipes” cache per grid state, once a recipe is determined impossible for the current grid contents, it's cached and instantly rejected on subsequent checks without any computation. Cache clears automatically when grid contents change (detected via hash comparison).
  • Smart Grid Hashing
    Computes a grid content hash from item IDs and slot positions: hash = 17; foreach (slot) { hash = hash*31 + id + index }. Only when the hash changes does the system rebuild its item ID set and clear the impossible cache.
Why: On a heavily modded server with 50K+ items and thousands of grid recipes, every keystroke or inventory change triggers Matches() against every recipe. Without filtering, 200-300 recipes are checked per grid change. The pre-filter eliminates 80-90% of these checks, leaving only 20-30 plausible candidates for the expensive pattern-matching logic.
📚 System 2: Handbook Page Caching

Patch Types: Harmony Prefix + Postfix

  • Page-Level Cache 
    Caches the full RichTextComponentBase[] array for each handbook page, keyed by itemclass-itemcode. Uses ConcurrentDictionary for thread safety (handbook pages can load from async threadpool). Cache is invalidated on world unload.
  • Harmony Prefix (Cache Read)
    Before GetHandbookInfo() runs, checks if the page is already cached. If found, returns the cached result immediately without running any of the expensive recipe scanning, ingredient lookup, or component generation logic.
  • Harmony Postfix (Cache Write)
    After GetHandbookInfo() finishes computing a page for the first time, stores the result in the cache for future instant retrieval.
Context: VS 1.22 added engine-level FastSearchRecipesByIngredient, so first-time handbook opens already benefit from engine optimization. This cache adds zero-cost repeat opens, especially impactful on servers with 10K+ recipes where handbook opens were 500ms+.
📦 Shared Recipe Index

Core Infrastructure, used by both optimization systems

  • Reverse Output Index
    Maps collectible ID → list of recipes that produce that item. Used by handbook for instant “Created by” lookups. O(1) dictionary access.
  • Reverse Ingredient Index
    Maps collectible ID → list of recipes that use that item as an ingredient. Used by crafting grid filter for fast candidate recipe lookup. O(1) dictionary access.
  • Recipe Metadata
    Per-recipe pre-computed metadata: RequiredIngredientCount, ConcreteItemIds (HashSet), and IsShapeless flag. Built once at startup, consumed by CraftingGridPatch for instant pre-checks.
Performance: Index builds in ~10-50ms for a typical 5K recipe server. All lookups are O(1) dictionary operations. Total startup overhead is negligible compared to the runtime savings.
⚙️ Lifecycle & Initialization
  • Early Load (ExecuteOrder 0.01)
    Registers Harmony patches at StartClientSide/StartServerSide for maximum coverage.
  • Index Building (GameReady / LevelFinalize)
    SharedRecipeIndex built when all recipes are loaded. Triggers CraftingGridPatch.BuildMetadata() and initializes HandbookPageCache (client-side only).
  • Startup Logging
    "Fully initialized in Xms. Optimizing N grid recipes. Reverse index: M output entries, K ingredient entries."
  • Cleanup
    All caches, indexes, and Harmony patches disposed on mod unload.
🔧 Dependencies

Required: Vintage Story 1.22.0+

Optional: None

Side: Universal (required on both client and server)

Originally developed and tested for the Horizons of RustFall server, running 150+ mods. If it runs there, it probably runs anywhere,  but no guarantees. Use at your own risk.

Project description from Vintage Story Mod DB.

Pick your setup

HoR Performance Optimizer releases for each Vintage Story version.

Choose the version and loader you play, then open the matching release.

3 available setups

Check the dependencies, then try the file in a copied instance before changing a world you care about.

Recent files

HoR Performance Optimizer versions and loaders

6 of 6 releases match

Looking for an older file? The official Vintage Story Mod DB project page is in Resources.