Skip to content
Garrett Guillotte edited this page Dec 10, 2025 · 14 revisions

EmptyEpsilon can use Wavefront (.obj) models. To make new OBJ models available for use:

  1. Place the OBJ files and any textures in the EmptyEpsilon/resources directory.

  2. Add a ModelData() entry to EmptyEpsilon/scripts/model_data.lua.

    Given this example:

    model = ModelData()
    model:setName("gentest")
    model:setMesh("gentest.obj")
    model:setTexture("gentest.png")
    model:setSpecular("gentest_specular.png")
    model:setIllumination("gentest_illumination.png")
    model:setNormalMap("gentest_normal.png") -- development builds only
    model:setScale(24)
    model:setRadius(120)
    
    model:addEngineEmitter(-13, -2.1500, 0.3,  0.2, 0.2, 1.0, 3.0)
    model:addEngineEmitter(-13,  2.1500, 0.3,  0.2, 0.2, 1.0, 3.0)

    EmptyEpsilon:

    • adds a model named gentest from OBJ file at resources/gentest.obj
    • uses resources/gentest.png for its texture
    • uses resources/gentest_specular.png for its specular/reflective map
    • uses resources/gentest_illumination.png for its illumination map
    • uses resources/gentest_normal.png for its normal map (development builds only as of Dec. 2025)
    • scales the model up 24x
    • sets its in-game collision radius to 120 meters, independently of the model's scale
    • adds two engine effect emitters, located at Blender coordinates X -13 (13 units backward), Y -2.15 and 2.15 (left and right), and Z 0.3 (up), with percentile colors red 20% (0.2), green 20% (0.2), and blue 100% (1.0), and a radius of 3 units in Blender.
  3. If you copied the above code, adjust your ModelData properties appropriately.

Tips

  • Ensure that your models are UV unwrapped. Many, but not all, models available online in OBJ format or for game development purposes are already UV unwrapped, but models available in STL format or for 3D printing generally are not.

    If your model is not UV unwrapped, unwrapping it yourself can be a complex subject with details that depend on the software you used to create or convert your 3D models. Some tools can automate at least some of the work; for example, here's a beginners' tutorial on UV unwrapping in Blender.

  • If you're exporting Wavefront OBJ files from Blender, ensure that UVs and normals are exported, that modifiers are exported, and that forward is -Z and up is Y. For example, use the following export settings:

    • Blender 2.8:

    Blender settings

    • Blender 4 and 5:
    Screenshot_20251209_212020
  • If you need to rotate a model, do so from a 3D modeling program. Some example programs include:

    • Blender (Windows, macOS, Linux): Note that positive values are forward on the X axis are up on the Z axis by default in Blender, which differs from the exported OBJ.
    • Misfit Model 3D (Windows; macOS and FreeBSD experimental)
  • EmptyEpsilon doesn't support OBJ materials (.mtl files). Place separate images in the resources directory to use as textures, preferably as PNG images alongside your model's OBJ file.

Since model_data.lua is a Lua script file, you can use loops, functions, or other code to add many similar models.

Model data function reference

EmptyEpsilon uses OpenGL's left-handed coordinate system, in which negative values on the Z axis face forward and Y faces up. 3D coordinates (vec3) in these functions translate to X, Y, Z values in Blender, which uses a right-handed, X-forward, Z-up coordinate system.

Blender default EmptyEpsilon Relative direction from center
X -Z Forward of the center point
Y X Right of the center point
Z Y Up from the center point

To view coordinates in Blender, press Tab to enter edit mode, then n to open the Transform panel.

For example, a point reported at X -24, Y 1, Z 20 in Blender is 24 meters forward, 1 meter to the right, and 20 meters above the center point. In EmptyEpsilon, this point is at Z 24, X 1, Y 20.

Functions

  • :setName(string name): The model's name, which is used to refer to the model in ship template scripts or entity model definitions.
  • :setMesh(string mesh_name): The relative path to the mesh file within either the resources directory or a pack in the packs directory.
  • :setTexture(string texture_name): The relative path to a texture file...
  • :setSpecular(string specular_texture_name): ... specular map ...
  • :setIllumination(string illumination_texture_name): ... and illumination map.
  • :setNormalMap(string normal_map_texture_name): ... and normal (simulated depth in detail) map, in development builds only.
  • :setRenderOffset(vec3 mesh_offset): Offset the mesh's position by this amount on each axis. Useful to recenter the model if its center point in the mesh file is not at 0, 0, 0.
  • :setScale(float scale): Scale the mesh by this multiplier.
  • :setRadius(float radius): Set the mesh's effective radius in in-game meters for collision purposes. Colliders are circular by default.
  • :setCollisionBox(vec2 collision_box): Set the width and height, respectively, of a rectangular collider if preferable to a circular collider.
  • :addBeamPosition(vec3 position): Add the origin point of a beam emitter at these coordinates on the unscaled model.
  • :addTubePosition(vec3 position): Add the origin point of a weapons tube at these coordinates on the unscaled model.
  • :addEngineEmitter(vec3 position, vec3 color, float scale): Add an engine emitter (visual effects trail) at these coordinates on the model, with a normalized RGB color (i.e. 1.0, 0.5, 0.1 representing 100% red, 50% green, 10% blue), and radius.

Creating a model for EmptyEpsilon in Blender

Create your model facing in the negative direction of X (with points intended to be the front of the ship having negative X values) with Y as up (points intended to be the top of the ship having positive Y values).

Screenshot_20251209_222705

Pictured model is Imperial from LowPoly Models by Quaternius, CC0

As of December 2025, EmptyEpsilon doesn't use materials or support model animations.

You can't use Blender's procedural materials natively in EmptyEpsilon, and you must bake them to texture images instead.

Remember to UV unwrap your model before exporting it.

Clone this wiki locally