# `tecs.files` Where a game reads content from and where it is allowed to write. `nupp.io.files` owns every filesystem operation: reading, writing, atomic commits, directory streams, temporaries and metadata. This module keeps the one thing Nupp cannot supply, because it is a property of the product rather than of the platform: which directories belong to *this* game. ```nupp local disk = require("nupp.io.files") tecs.files.setPreferenceIdentity("Ex Nihilo", "Starfarer") local slot = tecs.files.writablePath("saves/slot1.json") disk.createDirectory(tecs.files.writablePath("saves")) local ok, reason = disk.writeAtomic(slot, bytes) ``` ## The three roots `assetRoot` is where shipped content lives and is never a place a build may write. `preferencePath` and `cachePath` are the two writable roots, and they differ in durability: saves and settings go under `preferencePath`, and anything the game can rebuild goes under `cachePath`, which the operating system may empty between any two runs. `assetPath` and `writablePath` resolve a relative path against the first and the second. Both join without checking existence, because a path that is about to be created is as valid a request as one that is about to be read. ## Identity `setPreferenceIdentity` names the publisher and the game, and the two writable roots are named from that pair. Set it before the first writable path resolves. The defaults are `"tecs"` and `"tecs"`, which are what an engine test and an unnamed tool write under. ## Caching Each root is resolved once and remembered, because resolving one asks the platform and may create a directory. `reset` forgets them, which a test that moves `HOME` between cases needs and nothing else does. ## Functions ### `assetPath` _function_ ```nupp function assetPath(relative: string): string ``` Resolves `relative` against the asset root. #### Arguments | Name | Type | Description | | --- | --- | --- | | `relative` | `string` | a path under the content root, with `/` separators | #### Returns | Type | Description | | --- | --- | | `string` | the joined path, without checking that anything is there | #### Raises - when relative is empty ### `assetRoot` _function_ ```nupp function assetRoot(): string ``` Returns the root the engine reads shipped content from. `TECS_ASSETS` wins, which is how a development run reads straight out of a build tree instead of a staged copy. Then the `__tecsContent` global, since a host knows the layout it installed and this is not something to sniff for. Then `basePath`, which is where a single-directory build puts everything. #### Returns | Type | Description | | --- | --- | | `string` | the root with a trailing separator | ### `basePath` _function_ ```nupp function basePath(): string ``` Returns the directory the running executable was loaded from. Nupp has no portable executable path, so this answers what the host said through the `__tecsBase` global, then the directory of `arg[0]`, and then an empty string. An empty answer is not a failure: it means the platform declined to say, and a caller falls back to a relative path. #### Returns | Type | Description | | --- | --- | | `string` | the directory with a trailing separator, or an empty string | ### `cachePath` _function_ ```nupp function cachePath(): string ``` Returns the system cache directory for this game, creating it if absent. The operating system may empty this directory between any two runs, so only downloads, compiled artifacts, thumbnails and similar derived data belong here. Saves and settings belong under `preferencePath`. #### Returns | Type | Description | | --- | --- | | `string` | the directory with a trailing separator, named from the identity | #### Raises - when the platform has no cache root or the directory cannot be created ### `preferenceIdentity` _function_ ```nupp function preferenceIdentity(): string, string ``` Returns the publisher and game names the writable roots are named from. The pair starts as `"tecs", "tecs"` and changes when `setPreferenceIdentity` succeeds. #### Returns | Type | Description | | --- | --- | | `string` | the current publisher, studio or organization name | | `string` | the current game or application name | ### `preferencePath` _function_ ```nupp function preferencePath(): string ``` Returns the writable directory for this game, creating it if it is absent. This is where a build writes durable state. `cachePath` is the other writable root and holds only data the game can rebuild. #### Returns | Type | Description | | --- | --- | | `string` | the directory with a trailing separator, named from the identity | #### Raises - when the platform has no writable root or the directory cannot be created ### `reset` _function_ ```nupp function reset(): nil ``` Forgets every cached root so the next call resolves again. A test that moves `HOME` or `TECS_ASSETS` between cases needs this. A game does not: nothing under a running process changes where these directories are. #### Returns | Type | Description | | --- | --- | | `nil` | | ### `setAssetRoot` _function_ ```nupp function setAssetRoot(root: string): nil ``` Overrides the asset root, for a test or a tool. #### Arguments | Name | Type | Description | | --- | --- | --- | | `root` | `string` | the content directory to read from, with or without a trailing separator | #### Returns | Type | Description | | --- | --- | | `nil` | | #### Raises - when root is empty ### `setPreferenceIdentity` _function_ ```nupp function setPreferenceIdentity(organization: string, application: string): nil ``` Sets the publisher and game names the writable roots are named from. Call this before the first `preferencePath`, `writablePath` or `cachePath`, because each root is resolved once and remembered. A later call changes which directory the next resolution answers. #### Arguments | Name | Type | Description | | --- | --- | --- | | `organization` | `string` | the publisher, studio or organization name | | `application` | `string` | the game or application name | #### Returns | Type | Description | | --- | --- | | `nil` | | #### Raises - when either name is empty ### `writablePath` _function_ ```nupp function writablePath(relative: string): string ``` Resolves `relative` against the writable root. #### Arguments | Name | Type | Description | | --- | --- | --- | | `relative` | `string` | a path under the preference directory | #### Returns | Type | Description | | --- | --- | | `string` | the joined path, without checking that anything is there | #### Raises - when relative is empty, or when the writable root cannot be resolved ## Values ### `ASSET_ROOT_VARIABLE` _variable_ ```nupp const ASSET_ROOT_VARIABLE ``` Read-only. Names the environment variable that overrides the asset root. ### `BASE_GLOBAL` _variable_ ```nupp const BASE_GLOBAL ``` Read-only. Names the global a host sets to the directory its executable was loaded from. Nupp has no portable executable path, so a host that knows where it is says so here and `basePath` answers an empty string otherwise. ### `CONTENT_GLOBAL` _variable_ ```nupp const CONTENT_GLOBAL ``` Read-only. Names the global a host sets to the content root it installed.