
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
Quick answer
Which HoR Performance Optimizer release should I use?
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.
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.
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.
- 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.
- 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.
- 03
Put it on the correct side
It must be installed on the client. Installation on the dedicated server is optional.
- 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 callingGridRecipe.Matcheson 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 skippedinitOverviewGuientirely, 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
TheinitOverviewGuiskip and empty-searchFilterItemsfast 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.1GetHandbookInfopatch and IL transpiler were causingNullReferenceExceptioncrashes 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 fullGetPageText()scan on all 40,000+ pages every time you open the handbook. A newPriority.Highprefix 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 - noGetPageText()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 deferredrecomposeOnRenderflag 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 reachGridRecipe.Matches(). - addCreatedByInfo transpiler (page navigation lag)
An IL transpiler replaces the singleIWorldAccessor::get_GridRecipes()callsite insideaddCreatedByInfowith 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 storingRichTextComponentBase[]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. Returnsfalseimmediately (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.
- 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.
📚 System 2: Handbook Page Caching ▼
Patch Types: Harmony Prefix + Postfix
- Page-Level Cache
Caches the full RichTextComponentBase[] array for each handbook page, keyed byitemclass-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.
📦 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.
⚙️ 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.
1.22.1
1 loader build1.22.0
1 loader buildCheck 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
1.0.5
HoR-PerformanceOptimizer.zip
31 May 2026
1.0.4
HoR-PerformanceOptimizer.zip
30 May 2026
1.0.3
HoR-PerformanceOptimizer.zip
4 May 2026
1.0.2
HoR-PerformanceOptimizer.zip
3 May 2026
1.0.1
HoR-PerformanceOptimizer.zip
3 May 2026
1.0.0
HoR-PerformanceOptimizer.zip
22 Apr 2026
Looking for an older file? The official Vintage Story Mod DB project page is in Resources.