HammeriteNavigationAgentProfiles

Navigation. Inherits Resource

The game's table of HammeriteNavigationAgentProfiles, handed to the bake.

Hammerite has no bestiary. "Guard", "rat" and "brute" are the game's vocabulary, the same way "footstep" and "glass_break" are - hammerite-audio hands its sound types over the same way - so the table is authored as a resource and handed over. What the addon provides is the measuring and the matching. The table is what turns measurements into layer bits at bake time: every patch of ground and every link is stamped with the profiles that can use it, and an agent that sets its own bit on its NavigationAgent3D is then routed through exactly what it fits.

Properties

TypeNameDefault
HammeriteNavigationAgentProfile[]profiles[]
floatstep_height18.0

Methods

ReturnsMethod
boolsame_as(other: HammeriteNavigationAgentProfiles)
HammeriteNavigationAgentProfilesplaceholder() static
HammeriteNavigationAgentProfileget_profile(profile_name: StringName)
intlayer_bit(profile_name: StringName)
intlayers_for_surface(surface: HammeriteNavigationSurface)
Arraylayers_and_cost(surface: HammeriteNavigationSurface)
intlayers_for_link(link: HammeriteNavigationLinkData, reversed: bool = false)
intall_layers()
String[]validate()
voidrebuild_index()

Property descriptions

profiles

var profiles: HammeriteNavigationAgentProfile[] = []

The kinds of agent this game has. Indexed by name on the first lookup, and again after it is assigned; after changing an entry in place, call rebuild_index(). Each needs its own HammeriteNavigationAgentProfile.navigation_layer, and all default to 0 - see validate().

step_height

var step_height: float = 18.0

The tallest rise any agent walks up as a step rather than climbs - the rise of this game's stairs. It decides which rises are STEP links and how far a floor goes on up a flight, for every profile; whether one agent can manage a step is still its HammeriteNavigationAgentProfile.climb_height.

Method descriptions

same_as()

func same_as(other: HammeriteNavigationAgentProfiles) -> bool

Whether other describes the same agents, value for value. again for each scene holds a new copy of the same table every time, and navigation built against one is navigation for the other - told apart by identity, it was built again on the main thread.

Experimental: How the runtime tells a table it baked for from another; a game compares nothing. A game that reads its tuning file

placeholder()

static func placeholder() -> HammeriteNavigationAgentProfiles

A table with one middling profile in it, for a project that has not authored one yet. Deliberately a stand-in and not a default worth keeping: it says something can duck under 96 units, climb a crate and drop off a low roof, which describes no particular creature. A bake made against it is a bake made against an assumption, and the tool says so.

get_profile()

func get_profile(profile_name: StringName) -> HammeriteNavigationAgentProfile

The entry named profile_name, or null.

layer_bit()

func layer_bit(profile_name: StringName) -> int

The navigation-layer bit of the profile named profile_name, or 0 if there is no such profile - which is a mask that matches nothing, so an agent naming a profile that was never authored goes nowhere rather than going everywhere.

layers_for_surface()

func layers_for_surface(surface: HammeriteNavigationSurface) -> int

Bits of every profile that can stand on surface. Zero means nothing in this game can use this ground, and the bake leaves it out.

layers_and_cost()

func layers_and_cost(surface: HammeriteNavigationSurface) -> Array

Who can use surface, and what the region carrying it should cost, as [layer mask: int, travel cost: float]. One cost, not one per agent. Godot puts travel cost on the REGION, and two regions cannot occupy the same ground: their free edges collide when the map is synchronised and the connections to the rest of the level break, so the shortcut ends up unreachable for everyone. That is measured rather than assumed - baking a crawlspace twice, once per opinion of it, disconnected it. So where agents disagree, the ground is priced for the ones who can stand up in it, and the crouch penalty applies only where EVERY agent using it has to crouch. That is the case it was for: a vent a guard can just about get down is dear, and if a rat runs down the same vent standing, it is a corridor and priced like one. A game that wants those two priced apart makes them two rooms. Water the same way (#64): everyone on it is in it, so it is priced for whoever it is easiest for - a pool a rat has to swim and a guard only wades costs the guard's wading.

Experimental: The mesh writer's; ask layers_for_surface() for who can stand there.

func layers_for_link(link: HammeriteNavigationLinkData, reversed: bool = false) -> int

Bits of every profile that can take link in the given direction.

all_layers()

func all_layers() -> int

Every layer bit in the table, for anything that wants "all agents".

validate()

func validate() -> String[]

What is wrong with this table, as messages an author can act on. Empty when it is sound. Called whenever HammeriteNavigationRuntime.profiles is assigned, which warns of each. The mistake worth catching is two profiles on one layer: nothing fails, nothing is logged, and a rat simply walks wherever a guard can because the server cannot tell the two masks apart. A profile with no layer at all is reported too.

rebuild_index()

func rebuild_index() -> void

Rebuild the name index. Call after editing profiles at runtime.

Hammerite 1.0 · built from a6dd634, 2026-10-10