📼 Also in this series:
This is a kit of game configuration files and importing scripts to design your level with TrenchBroom and export it to Defold as the collection.
TrenchBroom was originally created to design Quake-format levels, but thanks to its flexible game configurations it's suitable for any other game with low-polygon level geometry. It's cross-platform, has a great manual and usability.
🧪 Look at Retro Texture Pack by Little Martian used in the demo.
- Convert level geometry to meshes and collision objects.
- Use flag textures and checkboxes to define faces behavior.
- Place triggers, kinematic or dynamic bodies.
- Convert entities to game objects.
- Attach file components to your entities.
- Set custom entity properties and read them from the game logic.
- Define areas and handle their coordinates in scripts.
- Run importing with the editor script or the standalone lua module.
- Expand the game configuration file with your own classes.
- Request by adding an issue or contribute.
To run the example project, you first need to import the example map.
With the project open in Defold, right click on the level.map file then click on Convert Map to Collection
. This will create a variety of folders and files next to the .map
file. You can now build and run the example.
- Add link to the zip-archive of the latest version of defold-trenchfold to your Defold project as dependency.
- Copy the
trenchfold/assets/trenchbroom/games/Defold
folder according this instruction to TrenchBroom user data folder. - Set your game project path as the game path in TrenchBroom preferences when creating the first map.
- Setup
textel_size
andmaterial
in the worldspawn entity.
Find your .map
file in the resources pane of the editor and right click on it and select the Convert Map to Collection
action. It does the magic and creates the collection file and all the components files: buffers, meshes, convexshapes, collisionobjects and some scripts.
There is also the trenchfold/cli.lua
module to run the import script outside the editor. Just pass it two arguments - relative/map_folder
and map_name
.
There is a working example of launch configuration in .vscode/launch.json
. It launches trenchfold/cli.lua
with the /example/maps/level
map by using local-lua-debugger. Requires Lua or LuaJIT to be installed on your computer.
You can create a compilation profile inside TrenchBroom with the Run Tool
step to run cli.lua. Requires Lua or LuaJIT to be installed on your computer.
The game configuration includes marking textures at flags/textures
. They are handled by the exporting script to provide specific behaviour to the faces without normal textures.
This face will be skipped when exporting.
Use it to remove useless faces from the geometry.
Creates a collision object without texture.
Use it to create invisible walls and useful collision geometry.
Creates a trigger collision object.
Doesn't create collision objects but its vertices positions will be sent to the object with the init_area
message.
Use it to process the area programmaticaly.
There are few content flags in the face properties.
The face isn't solid and doesn't generate a collision object vertices.
Use it on objects that can be passed through or that the player will never reach.
The face generates a separate plane collision object.
A rare use case is when you have a wall corner with two solid faces and you don't want to create a triangular prism collision shape on its vertices.
There are brush entities and point entities. The difference is that a brush entity contains geometry brushes, while the point entity has only an origin position and rotation.
The default entity for all the geometry outside of the other entities. Also has some general settings of exporting.
textel_size
— how much Trenchbroom grid units are equal to one unit in Defold metrics.material
— the relative path to the material that will be used for generated meshes by default.textureN
— path to the texture whereN
is number from1
to7
. See texture path patterns.physics_*
— collision object properties used by default.
A brush entity with the static collision type. The only reason to use it is to attach components and set properties because the worldspawn
is static by default. To use areas or destroy parts of the level, e.g.
id
— the identifier of the game object.#component_id
— the relative path to the file component that will be attached to this game object ascomponent_id
.#component_id.property
— the script component property override.material
— the relative path to the material that will be set in generated meshes.textureN
— path to the texture whereN
is number from1
to7
. See texture path patterns.physics_*
— collision object properties related to static collision type.
To be fair, triggers are created by the trigger texture, not the entity. But you also need to put scripts and parameters on this trigger, so which is what this entity is for.
If you place brushes with normal textures to this entity they also become triggers.
id
— the identifier of the game object.#component_id
— the relative path to the file component that will be attached to this game object ascomponent_id
.#component_id.property
— the script component property override.physics_*
— collision object properties related to trigger collision type.
A brush entity with the kinematic collision type. Use it for moving platforms or sliding doors, for example.
id
— the identifier of the game object.#component_id
— the relative path to the file component that will be attached to this game object ascomponent_id
.#component_id.property
— the script component property override.material
— the relative path to the material that will be set in generated meshes.textureN
— path to the texture whereN
is number from1
to7
. See texture path patterns.physics_*
— collision object properties related to kinematic collision type.
A brush entity with dthe ynamic collision type. This could be, for example, a crate that the player can move.
id
— the identifier of the game object.#component_id
— the relative path to the file component that will be attached to this game object ascomponent_id
.#component_id.property
— the script component property override.material
— the relative path to the material that will be set in generated meshes.textureN
— path to the texture whereN
is number from1
to7
. See texture path patterns.physics_*
— collision object properties related to dynamic collision type.
This is a point entity to add a game object without meshes and collision objects. You can attach any file components to it or replace it with you .go
file.
origin
— the position of the game object that defined automatically when you place it.angle
— the Y-axis rotation of the game object that defined automatically when you rotate it.rotation
— X, Y and Z-axis rotation of the game object. Y-axis will be ignored if theangle
property exists.id
— the identifier of the game object.go
— the relative path to the.go
file that should replace the entity.#component_id
— the relative path to the file component that will be attached to this game object ascomponent_id
. Ignored if thego
property exists.#component_id.property
— the script component property override.
These are helpers for placing 💡 Illumination objects on the map. Don't forget to fill the go
property with default value.
The textureN
property allows to set additional material textures 1-7. The next patterns are available:
/path/to/texture.png
— a specific texture./path/to/prefix_*_suffix.png
— a specific path where * is texture0 original name./path/to/alternative/*
— a specific folder with the same texture file name.prefix_*_suffix.png
— the same folder.prefix_*_suffix
— the same folder and extension.
All the custom properties will be a part of the script component with the properties
identifier that attached to the game object. These properties can be accessed in runtime by calling go.get()
.
go.get('#properties', 'property')
The values true
and false
are converted to boolean.
The value which can be handled with tonumber()
is converted to number.
If the number is flags value then you can parse it with utils.flags_from_integer(value)
from the trenchfold/utils/utils.lua
module.
- Value
x y
is converted tomath.vector3(x, y, 0)
. - Value
x y z
is converted tomath.vector3(x, y, w)
. - Value
x y z w
is converted tomath.vector4(x, y, z, w)
.
Property ending with url
is converted to msg.url('value')
.
Any other string property is converted to hash 'value'
.