Skip to main content

VPK mounts

traceless.vpk mounts named assets from the current project's catalog. Names contain 1..64 letters, digits, underscores or hyphens. Pass an asset name rather than archive bytes or a filesystem path.

The feature is disabled by default. A catalog lookup can return unknown_asset; a known asset's queued request ends with feature_disabled when activation is disabled.

mount​

handle, err = traceless.vpk.mount("project_asset")

Returns: mount handle userdata and nil, or nil and an error table. Invalid or non-string names return invalid_input.

A successful call queues validation; it does not mean the archive is mounted. Repeated requests by one owner for the same pending or mounted generation return its existing handle. Identical generations share one native mount across owners without changing search priority.

Mounting runs at a frame boundary after background validation. V1/v2 archives, preload bytes, embedded data and split sets retain their native member names. Each member must be smaller than 2 GiB and directory trees are capped at 64 MiB. Resources must use engine-compatible compiled formats such as .vmat_c, .vtex_c and .vmdl_c.

unmount​

ok, err = traceless.vpk.unmount(handle)

Returns: boolean and nil or an error table. Repeating an unmount succeeds. A cancelled handle stays unmounted even if another request in the same candidate fails activation. Wrong userdata types raise a Lua argument error; foreign owner generations return false and foreign_owner.

The state changes to unmounted immediately. The next frame removes lookup precedence when no owners remain. Outstanding reads retain the resources they need until completion. Unmount does not unload or replace existing engine resources.

status​

state = handle:status()

Returns: pending, mounted, failed, or unmounted. A foreign owner generation raises a Lua error. Retaining userdata does not keep its script alive.

error​

err = handle:error()

Returns: nil or an error table with string fields code and message. A foreign handle returns foreign_owner.

codeMeaning
feature_disabledMounting is currently disabled.
engine_unsupportedThe current client cannot mount the asset.
unknown_assetThe asset is absent from this project's catalog.
foreign_ownerThe handle belongs to another owner generation.
invalid_inputInvalid asset name or data.
io_failureAsset storage could not be read or written.
authentication_failedAsset verification failed.
hash_mismatchAsset contents do not match the expected version.
invalid_archiveInvalid archive structure, bounds or normalized paths.
missing_memberA numbered VPK member is unavailable.
oversized_memberA member is at least 2 GiB.
loaded_override_unsupportedAn existing resource cannot be replaced.
engine_mount_rejectedThe engine did not insert the search path.
cancelledThe owner or request was cancelled.
out_of_memoryAllocation or worker queue capacity was exhausted.

vpk_mount​

local traceless = require("traceless")
traceless.events.on("vpk_mount", function(event)
traceless.console.info(event.asset .. ": " .. event.state)
if event.error then
traceless.console.error(event.error.code .. ": " .. event.error.message)
end
end)
local handle, err = traceless.vpk.mount("project_asset")
if err then
traceless.console.error(err.message)
end

This script-scoped event runs on the normal Lua thread after a frame update. Workers never invoke Lua. Its table contains handle, asset (string), state (state string), and error (nil or an error table). Events report completion or unmount. Synchronous argument/catalog failures have no handle or event. Transitions before dispatch may be coalesced to the current state.

Initialization requests stay staged until the candidate's complete set validates and activates. Reload keeps the old script active while its replacement waits. Failure destroys the candidate and logs the mount error; undelivered events are discarded with the candidate. Successful commit dispatches its mounted events. Shutdown invokes the callback before releasing ownership.

Resource visibility​

Mounted asset paths are visible to engine consumers. Handles and cleanup belong to each script instance. Unmount does not unload or replace resources that the engine has already loaded. A mount that would replace an existing resource fails with loaded_override_unsupported.