Overlays¶
Overlays allow loading asset files from ZIP archives, folders, and Lua callbacks. Conceptually, it is overlaying the assets in the assets directory with assets from these other sources. It is a form of union mount.
This is mainly used in new versions of Shatter Client to provide a cleaner overall implementation (no need for actually modifying rooms and segments) and support certain types of assets which don’t load using the standard resource manager (like streamed music), although it is useful in various scenarios.
Possible planned features: Support for manipulating the APK assets directory as if it were an overlay itself and changing precedence order without being restricted by a stack.
How Overlays Work¶
When the game tries to load an asset with overlays active, the overlay subsystem starts by trying to load the asset in each mounted overlay, starting with the most recently added overlay and proceeding to the last. It does this until it finds an overlay that can load the asset, in which case the data that the overlay returns for that asset is used as the asset’s data.
If no overlays can load and asset, it will be loaded normally from the APK.
Example: ZIP overlays¶
For example, if you mount a zip file forest.zip which has a level:
forest.zip
levels/
forest.xml
rooms/
forest.lua
segments/
forest.xml
then playing the level forest will load from the ZIP file.
If a segment then depends on an obstacle like scoretop, but it is
not in the ZIP file, then it is loaded from the mod’s assets directory.
-
knPushOverlay(type:
string, ...):boolean¶ Create a new overlay and push it to the top of the overlay stack. Returns true when the overlay is created successfully and false otherwise. The
typedetermines the kind of overlay that will be created and the parameters given to it:-
knPushOverlay("directory", path:
string)¶ Creates an overlay from a physical file system directory, where
pathis the path to the directory to use. For example:knPushOverlay("directory", knGetInternalDataPath() .. "/generated")
Paths will not be sanitised, so upper directories can still be accessed using
...
-
knPushOverlay("zip", zipFile:
string, [options:table])¶ Creates an overlay from a ZIP file on the physical file system, where
zipFileis the name of the ZIP file to use.knPushOverlay("zip", knGetInternalDataPath() .. "/mylevel.zip")
Assets will load from the root of the ZIP. File names should not have the
.mp3suffix, as it is stripped before attempting to load the file. File names are case sensitive.The
optionsare expressed in a table containing any of these fields, all of which are optional:prefix: String prepended to the path before trying to load itsuffix: String appended to the path before trying to load it
Changed in version 19: Added the
optionsargument and the ability to specify a prefix and suffix
-
knPushOverlay("apk", apkFile:
string)¶ This is equivalent to
knPushOverlay("zip", apkFile, {prefix="assets/", suffix=".mp3"})and is meant for using asset dirs from other Smash Hit APKs at load time.Added in version 19.
-
knPushOverlay("callback", functionName:
string)¶ Creates an overlay which uses a callback function in the main menu script to dynamically generate asset data. Note that
functionNameshould be a string; the callback function cannot be passed directly.The named function should take the path to load as its only argument, and it should return either a string representing the asset data or
nilif the asset should not be loaded from this function. Stated more compactly, its type isfunction(path: string): string | nil.Examples¶
Example #1: Dynamically generate
buttonN.xmlfilesIn
menu/main.lua:knPushOverlay("callback", "generateMenuButton") function generateMenuButton(path) if string.match(path, "menu/button%d+%.xml%.mp3") ~= nil then local start, stop, n = string.find(path, "(%d+)") return [[<ui texture="button.png" selected="button_select.png"> <rect coords="0 0 294 384" cmd="script:level ]] .. tostring(tonumber(n) - 1) .. [["/> </ui>]] else return nil end end
Example #2: Implement a cheap Data URI
In
menu/main.lua:knPushOverlay("callback", "knockoffDataUri") function knockoffDataUri(path) if string.match(path, "^data:") ~= nil then return string.sub(path, #"data:" + 1) else return nil end end
Added in version 14.
-
knPushOverlay("directory", path:
- knPopOverlay()¶
Pop the most recently mounted overlay off of the stack, unmounting it.
Added in version 14.