Entity sets

Entity types most games want and no game should have to write again: lights, things that decide when to trigger something, brushwork that moves, any Godot scene placed as a prop, and particle emitters. Each group is an entity set (HammeriteEntitySet) that a project takes or leaves on its own, and core ships them all as HammeriteEntitySets.

Adding them

The lights are there by default, since every map has them. The rest are added by asking, before the map is built - with the editor, through it, so each set also gives the editor its pickers:

map_editor.add_entity_set(HammeriteEntitySets.everything())

A game without the editor asks core instead, with the same effect on the game:

HammeriteEntityTypeRegistry.add_set(HammeriteEntitySets.logic())
HammeriteEntityTypeRegistry.add_set(HammeriteEntitySets.movers())

everything() is a set of no types of its own that includes the other five: lights(), logic(), movers(), scenes() and particles(). A project that wants no lights takes them away with HammeriteEntityTypeRegistry.remove_set(HammeriteEntitySets.lights_id()). Core's own group, trigger, prop_model and decal belong to no set and are always there.

A game that wants to refine one of these types does so as it refines any, after the set is in:

HammeriteEntityTypeRegistry.extend_brush(&"door", {&"key_item": ""})

A set never takes a type name that is already registered, so a game that already has its own door keeps it, and the movers set says it went without one.

Wiring

Every entity here that triggers something names it by target, as core's trigger does: every entity of that name that can be triggered is, with the target_impulse (HammeriteMap3D.trigger_named). What the impulse means is the receiver's to say; most types here read true and false as on and off or open and shut, and anything else as switch over. Select one in the editor and a dashed line runs to each entity it would trigger. Each target field offers the map's entity names to pick from, and a platform's path and a corner's next offer its path_corners.

Lights (lights)

light_point, light_spot and light_directional are baked; their _dynamic twins are baked and can be switched and dimmed; light_point_movable and light_spot_movable are real-time lights that move. See the core README's Lighting section.

Logic (logic)

Point entities with no body. Each has target, target_impulse and delay - seconds between deciding to fire and firing, counted only while the world runs and dropped by a reset.

Type Does
logic_relay triggered, triggers its target. pass_impulse hands on the impulse it was given; once fires only the first time
logic_timer fires every interval seconds, give or take jitter, while on. Starts on unless start_on is off
logic_counter fires on reaching count triggers. A number as the impulse counts that many. repeats starts again
logic_toggle on or off. A change triggers target with the new state, and target_on or target_off with the impulse
logic_auto fires on the world's first frame, and again after each reset

Movers (movers)

Brushwork on HammeriteBrushEntityAnimatableBody3D, so whatever stands on it is carried. It hands its lighting from its lightmap to the probes as it leaves where it was authored, and back when it returns (see Moving brush entities).

Type Does
door slides distance along direction and turns angle degrees about rotation_axis through its middle plus pivot_offset, together over move_time. Shuts itself after wait unless that is 0; locked refuses to open. Triggers target_opened and target_closed on arriving. Drag its handle to set the slide
button a door whose opening is the press: triggers target when pressed home, comes back out after wait (0 stays in). Something presses it by triggering it - the game's use key, a trigger on a plate
platform travels from the path_corner named in path along the corners' next, at speed, waiting wait at each. Author the brushwork where it stands at that first corner
path_corner one point of a platform's path. Its own wait and speed override the platform's when not negative; target fires as a platform arrives. A path naming its first corner goes round for ever

Each mover's runtime properties - how open, whether locked, where it is heading - are the inspector's while the world runs, and how the game reads and sets them.

Scenes (scenes)

prop_scene places any PackedScene, turned and sized as a prop is. The editor offers every scene in the project to pick from, narrowed as you type; a scene saved since is listed within ten seconds. It is held still - not processed, its bodies out of the physics - until the world runs, and built afresh on a reset. Triggering it calls trigger(impulse) on the scene's root if the root has one, which is how a scene of the game's own becomes a working entity without an entity class.

Particles (particles)

env_particles is a GPUParticles3D made from its properties: amount, lifetime, speed, spread, gravity, emission_radius, size, a colour that fades from color to color_end, an optional texture picked from the project's images, additive for sparks and fire, shaded for smoke. It emits up its own Y, so turning it aims it. Triggered it starts, stops or - one_shot - bursts again. Like the scene, it is held still until the world runs.

Writing a set of your own

A genre's pickups, a game's own furniture - written as core's are:

extends HammeriteEntitySet

func _init() -> void:
    id = &"pickups"
    title = "Pickups"
    requires = [&"logic"]

func _register_types() -> void:
    register_point(&"pickup_health", {&"classname": &"HealthPickup", &"amount": 25})

A set gives the editor what only it shows of its types in _extend_editor(editor), which hammerite-editor calls as it starts, or as the set is added through it - offer_choices(editor, type, property, provider) gives a string property a searchable list, unless the game gave it a control of its own first. The editor is passed untyped, so a set needs nothing but core.

Add it as core's are. A set that requires another is refused until that one is added; one that includes others adds them along with it, so a pack can bring the sets it builds on.

Not yet

  • Every class here is experimental.
  • Wiring is one target per event, by name. Named inputs and several outputs per entity, each with its own delay, are the next step.
  • A map does not record which sets it was made with. Opened in a project that left one out, its entities of that set's types still load, built from their own properties, but nothing says the set is missing.

Hammerite 2.0 · built from 6d57ab2d, 2026-10-17