This repository was archived by the owner on Nov 13, 2024. It is now read-only.
Zero-Copy patching #15
rphsoftware
started this conversation in
General
Replies: 1 comment
|
A proof of concept for extension API-based request interception at below link (vfs.js is put into gomori/vfs.js) Changes in this approach include going from chrome.webRequest to chrome.debugger so we can transparently edit the response without having to redirect to data: URLs which would break engine internals. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Preamble
Currently (As of 2.2.0), gomori has a huge problem with the way it actually loads mods.
The primary issue is that it actually modifies the game's files.
This causes many issues, among which are:
Technical details
HOW THE GAME LOADS FILES?
Omori loads files using 2 different methods:
The node.js filesystem is used primarily for data, while the web requests are used primarily for assets and everything that's actually loaded into the browser.
How to modify files without modifying them?
A solution I'd like to propose is to use a virtual filesystem, where the root directory is
wwwof the game and every mod is mounted and overlayed over one another (with the core game files acting as the base) (the order of mounting isn't covered by the scope of this discussion and should be discussed in a separate, conflict resolution discussion)How to implement a virtual filesystem?
Since the game uses 2 different ways to load files, our virtual filesystem needs to also use 2 entry points into game logic.
For web request based asset loading, a simple technique based on the chrome.webRequest API can be used ( https://developer.chrome.com/docs/extensions/reference/webRequest/ ) where, since OMORI is an nw.js application, it can use the chromium extension API against itself. Therefore, creating a blocking webRequest handler on the
/www/route and redirecting request responses to files read out from the virtual filesystem, instead of letting the browser handle it, is a valid approach.For node.js filesystem API loading, a slightly more advanced technique would have to be used. The idea here would be to override
window.requireso that, in casefsis required, it returns a fake filesystem library instead, which if the game tries to read data from thewwwfolder results in it hitting the VFS instead, while letting it access every other area on the computer as-is.How to handle loading things like fonts?
Since that stuff is loaded in the
<head>, the only viable solution I see to this would be to run the initial VFS creation code in a script tag located right above<link rel="icon">and, in that "Stage 1" of mod loading, only inspect mods for thefonts/folder and theicon/folder, since those 2 are the only ones of concern this early on. Afterwards, the regular loading path can be taken all the way until the script tag loading gomori, at which point cached results of mod file inspection are used to mount the remaining files.On memory usage
Memory usage could be greatly reduced by not keeping files in memory, and instead using an on-disk cache for patched assets and data. A solution I'd like to propose to this would be using
md5hashes of files shipped inside a mod as file names, and usingsteamapps/OMORI/cacheas the root of the cache. That way, when mounting a file to the virtual filesystem, we can mount it as a reference to a cache entry. Additionally, this could speed up subsequent game loads by not having to re-encrypt assets. (The cache system could potentially be adapted in the future to cache the results of JSON patching, but that's not covered by the scope of this post)On file naming
Windows is case-insensitive and OMORI makes great use of that. Some files are stored in lower case but are referenced to in snakeCase and so on. A solution I'd like to propose to this is, inside the Virtual Filesystem, using
toLowerCase()on all operations that mount/load/write files.All reactions