# `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.