Installing & Importing Packages on UEFN
This page covers how UEFN packages are installed, laid out, and imported into your Verse code. For the platform-neutral rules (version ranges, the lockfile, private access), see Concepts.
Installing packages
A UEFN project’s manifest lives in its Content/ folder. Run forest install from Content/ (or anywhere inside the project, the CLI finds the manifest and installs at the project level):
forest i cool-studio/navmeshThis downloads the package, unpacks it under Content/ForestPackages, and records it in your forest.json and lockfile.
UEFN discovers Verse files when a project opens. After installing, removing, or updating packages, reopen the project in UEFN, then Build Verse Code. Files added while the editor is open are invisible to the build until you reopen. If the editor is closed during install, the next open picks everything up automatically.
The layout
Packages install flat, two levels deep, under the Forest-owned ForestPackages mount:
- forest.json
- forest-lock.json
- cool_studio.verse
- navmesh.verse
- ...
Direct and transitive dependencies install exactly the same way. The flat mount is what makes packages location-independent: a package’s own using { ForestPackages.x.y } imports resolve only because x/y sits at this canonical path in every project.
Put your own code in a sibling folder such as Src/, not in a root-level .verse file. Root files are an ancestor of every package and are the one place where your definitions can collide with a package’s. See Scopes & Collisions.
Importing a package
Import a package by its dotted module path and call its members:
using { ForestPackages.cool_studio.navmesh }
# on a name conflict, qualify the call instead of adding another import:
(ForestPackages.cool_studio.navmesh:)FindPath(Start, Goal)using is the only import mechanism, and it is file-scoped: add it to each file that needs the package. The same dotted path works from a root file, from Src/, and from inside another package.
Scope name mapping
Forest scopes are kebab-case slugs, but Verse identifiers can’t contain hyphens (- is the minus operator). Scope folders and imports use a mapped form:
| Forest scope | Verse identifier |
|---|---|
cool-studio | cool_studio |
123-team | _123_team |
module | _module |
The rule: hyphens become underscores, and a leading underscore is added if the result would start with a digit or would be a Verse reserved word. The mapping only applies to the scope segment. Package names are validated as Verse identifiers at publish time and are never rewritten. Everywhere outside Verse (your manifest, the registry, the website) the original kebab-case scope is used, which is why you install cool-studio/navmesh but import ForestPackages.cool_studio.navmesh.
Module markers
Alongside each installed package, Forest generates small marker .verse files:
# Generated by Forest Package Manager. Do not edit.
navmesh<public> := module {}These make the package’s module reachable from your code. Forest regenerates them on every install, so:
- Don’t edit or delete them by hand. Any file whose first line is the generated header is Forest’s to rewrite or remove.
- Direct dependencies get a
<public>marker (importable anywhere). Transitive-only dependencies get a<scoped {...}>marker, so packages insideForestPackagescan use them but your own code can’t import something you didn’t declare. Add it to your manifest to import it directly. - Marker regeneration also heals paths after a project rename or first publish, another reason to re-run
forest installif imports stop resolving.
One version per package
Because a Verse module path has no version in it, a project installs exactly one version of each package. Forest unifies every requester’s range onto a single version. If two requesters need genuinely incompatible ranges (say ^1 and ^2), the install fails with an error naming both. Align the ranges or drop one. See Dependencies & Versioning.
Folders under ForestPackages
Forest classifies each folder under ForestPackages so it never touches code that isn’t its own:
- Installed (has a Forest install receipt): fully managed. Updated and removed to match the lockfile.
- Authored (has a
forest.jsonbut no receipt): a package you’re writing in place. Markers are generated for it, but Forest never deletes it. See Authoring & Publishing. - Unknown (neither): left untouched, with a warning suggesting you add a
forest.jsonor move it out of the mount.