Skip to content

Optimise book system: lazy-compile on open instead of batch-compiling at boot#955

Open
JSKitty wants to merge 1 commit intoTurningWheel:masterfrom
JSKitty:lazy-book-compilation
Open

Optimise book system: lazy-compile on open instead of batch-compiling at boot#955
JSKitty wants to merge 1 commit intoTurningWheel:masterfrom
JSKitty:lazy-book-compilation

Conversation

@JSKitty
Copy link
Copy Markdown

@JSKitty JSKitty commented Mar 14, 2026

Summary

  • Defer book compilation (text reflow + pagination) from startup to first open
  • Remove ~620 lines of compiled_books.json cache infrastructure
  • Boot time reduced by ~3 seconds (measured on MacBook Pro M4 Max, 128GB)

Details

I was curious at why Barony seemed to load relatively slowly (for the size and amount of assets in the game), I took a little dive and compiled it on MacOS, realised that Book Compilation took a relatively large chunk (around 50%!) of boot time, this was consistent over both Windows and MacOS in my testing.

I've implemented lazy-loading (or "lazy compiling") in to Barony, this completely eliminates the startup cost (even the compiled book cache still uses relatively high resources), removes CPU cycle wastage on books that people potentially will never read in that session, and also vastly reduces the amount of book.cpp code: faster, cleaner, leaner.

Mods that add books will not be affected, and updates that add/edit/remove books will also not be affected, this system has less moving parts, and is therefore even more reliable than the previous implementation, while granting massive performance gains.


Copy-Pasted Commit Message for maintainer convenience:

Previously, createBooks() read all 34 .txt files at boot, compared them
byte-for-byte against a JSON cache, and either parsed the cache or recompiled
every book before the main menu appeared. This took ~3 seconds every launch.

Now createBooks() only discovers filenames via PhysFS (no file reads).
When a book is opened for the first time, compileBook() loads and paginates
that single book on demand. The compiled pages stay cached in memory, so
reopening is instant.

Book indices, mod reload, banned book filtering, and multiplayer sync are
all unaffected since allBooks is populated in the same sorted order.

Test plan

  • Boot game, verify no book compilation logs at startup
  • Open short book (My Journal), verify correct display
  • Open long multi-page book (The History of Baron Herx), flip through all pages
  • Reopen same book, verify instant display (pages cached in memory)
  • Verify numbooks = 34

Previously, all 34 books were compiled (text reflow + pagination) at
startup. This involved reading every .txt file, parsing a 192KB JSON
cache for byte-for-byte comparison, and either loading or recompiling
all books before the main menu appeared. The entire process took
roughly 3 seconds on every boot, wasting CPU cycles on content the
player may never read.

This refactor defers compilation to the moment a book is actually
opened. At startup, createBooks() now only discovers filenames via
PhysFS without reading any file contents. When a book is opened for
the first time, compileBook() loads that single .txt file, normalizes
whitespace, reflows text to fit page dimensions, and paginates. The
compiled pages are cached in memory, so subsequent opens of the same
book are instant.

Performance results (MacBook Pro M4 Max, 128GB):
- Boot time reduced by ~3 seconds (book init now runs in under 1ms)
- Individual book compilation is imperceptible (microseconds per book)
- No observable hitch when opening any book, including multi-page ones

Code reduction:
- Removed ~620 lines of cache management (readCompiledBooks,
  writeCompiledBooks, booksRequireCompiling, readBooksIntoTemp)
- Removed compiled_books.json read/write/validation infrastructure
- Removed rapidjson/filereadstream.h dependency from book system
- Added ~45 lines for the lazy compilation path

The change is platform-agnostic with no preprocessor conditionals.
Book indices, mod reload (physfsReloadBooks), banned book filtering,
and multiplayer sync are all unaffected since allBooks is populated
in the same sorted order and numbooks is set at discovery time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant