URL Resolving System - Outerra/anteworld GitHub Wiki

Outerra Engine URL Resolving System

Overview

URLs, as the name implies, are used to uniquely locate the resources queried from other resources (e.g., texture files referenced by material files).

An Outerra URL consists of three parts: the URL root, the file path, and the resource name. In its string representation, it looks like this:

[URL root]/[file path]@[resource name]
  • [URL root] tells the URL resolver where to look for the [file path]. Depending on the [URL root], the [file path] can be a relative path, an absolute path, or an empty string.
  • The [file path] may be preceded by a path separator (/ or \) depending on context.
  • The [resource name] is used as an internal identifier within the file, and in string form is preceded by the @ character.

The URL is resolved by the URL resolver on the engine side, which takes a URL object, main root path, and alternative root path as arguments (e.g., the Material subsystem uses the parent directory of the material file as main root path and the corresponding package parent directory as alternative root path).
To see how the URL resolver works in practice, check the examples below.


Root Types

The following types of URL roots are supported:

1. Main URL Root Path

  • The resolver looks for the file in the main root path argument.
  • In the string form, the [URL root] is an empty string, and the following path separator is omitted.
  • The [resource name] is optional.
  • Format:
[file path]@[resource name]

or

[file path]

2. Alternative URL Root Path

  • The resolver looks in the alternative root path.
  • In the string form, the [URL root] is still an empty string, but a leading path separator is used.
  • The [resource name] is optional.
  • Format:
/[file path]@[resource name]

or

/[file path]

3. Project Packages URL Root Path

  • The resolver looks in the project's package directory.
  • The string form uses the <pkg_proj> tag as the [URL root].
  • Followed by the [file path] .
  • The [resource name] is optional.
  • Format:
<pkg_proj>/[file path]@[resource name]

or

<pkg_proj>/[file path]

4. Root Packages URL Root Path

  • The resolver looks in the application's root package directory.
  • The string form uses the <pkg_root> tag as the [URL root].
  • Followed by the [file path].
  • The [resource name] is optional.
  • Format:
<pkg_root>/[file path]@[resource name]

or

<pkg_root>/[file path]

5. Root URL Root Path

  • The resolver looks in the application's root directory.
  • The string form uses the <root> tag as the [URL root].
  • Followed by the [file path].
  • The [resource name] is optional.
  • Format:
<root>/[file path]@[resource name]

or

<root>/[file path]

Special Cases

1. Absolute Path

  • The [URL root] is not present, and the [file path] is an absolute path.
  • The [resource name] is optional.
  • Format:
[absolute file path]@[resource name]

⚠️ Warning: Using absolute paths is discouraged in production code. It is best to use them only for testing or debugging purposes.

2. Internal Path

  • Both the [URL root] and [file path] are not used.
  • Only the [resource name] is specified.
  • Used to address internal resources such as class interfaces.
  • Format:
@[resource name]

Examples

Assume the engine is installed in C:\Outerra, so:

  • Root packages path: C:\Outerra\packages
  • Project packages path: C:\Outerra\game\packages

For developers using .../outerra_svn/bin as the root:

  • Root packages path: .../outerra_svn/bin/packages
  • Project packages path: .../outerra_svn/bin/projects/[project name]/packages

Example 1: Material File

Material file path:

C:/Outerra/game/packages/some_package/variant1/materials.mtl

Corresponding package path:

C:/Outerra/game/packages/some_package/some_package.pkg

The material subsystem sends:

  • materials.mtl parent directory as main root path
  • some_package.pkg parent directory as alternative root path

JSON fragment:

{
  "tex_albedo" : "textures/albedo.dds",
  "tex_normal" : "/normal.dds",
  "tex_roughness" : "<pkg_proj>/shared_textures/rough.dds",
  "tex_reflectance" : "<pkg_root>/shared_textures/rough.dds",
  "tex_emissive" : "<root>/textures/emissive.dds"
  "tex_opacity" : "C:/opacity.dds"
}

Resolution:

  • tex_albedo → no URL root, no leading separator → main root path:
    C:/Outerra/game/packages/some_package/variant1/textures/albedo.dds
    
  • tex_normal → no URL root, with leading separator → alternative root path:
    C:/Outerra/game/packages/some_package/normal.dds
    
  • tex_roughness<pkg_proj> URL root → project packages path:
    C:/Outerra/game/packages/shared_textures/rough.dds
    
  • tex_reflectance<pkg_root> URL root → root packages path:
    C:/Outerra/packages/shared_textures/rough.dds
    
  • tex_emissive<root> URL root → root path:
    C:/Outerra/textures/emissive.dds
    
  • tex_opacity → absolute file path:
    C:/opacity.dds
    

Example 2: Object Definition File

Object definition file path:

C:/Outerra/game/packages/some_package/variant1/some_object.objdef

JSON fragment:

{
  "script" : "/script.dll@some_object_implementation"
}

Resolution:

  • File path:
    C:/Outerra/game/packages/some_package/script.dll
    
  • Resource name:
    some_object_implementation
    

In this case, the resource name refers to a symbol or interface inside the referenced script.dll file.

⚠️ **GitHub.com Fallback** ⚠️