HammeriteNavigationAgentProfile

Navigation. Inherits Resource

One kind of thing that moves, as far as navigation is concerned: how big it is and what it can haul itself up, drop off or jump across. Its measurements are in map units.

This is the other half of the arrangement the rest of this addon is built around. HammeriteNavigationBuilder and HammeriteNavigationLinkBuilder measure the world and say nothing about who could use it - how much headroom there is, how wide the passage is, how high the sill stands. A profile is the counterpart: it says what a guard is, and comparing the two answers "can a guard go here" without either side knowing about the other. Which is why the TABLE of profiles is the game's (HammeriteNavigationAgentProfiles), authored as a resource, exactly as its sound types are. A bestiary is vocabulary - guard, rat, brute, the player - and vocabulary belongs to the game. Hammerite provides the measurements and the matching. One bit each. A profile owns a navigation layer, and the bake stamps that bit on every piece of ground and every link the profile can use. An agent then sets its own bit on its NavigationAgent3D and the navigation server routes it through what it fits. One bake serves every kind of agent, rather than one baked mesh per enemy type.

Properties

TypeNameDefault
StringNameprofile_name&""
intnavigation_layer0
floatheight96.0
floatcrouch_height0.0
floatcrouch_cost_multiplier2.0
floatwading_depth_ratio0.5
floatwading_cost_multiplier2.0
boolcan_swimfalse
floatswimming_cost_multiplier4.0
floatwidth32.0
floatmax_slope_degrees46.0
floatclimb_height32.0
floatfall_height192.0
floatjump_span0.0
floatlink_cost32.0
floatclimb_cost_per_unit4.0
floatfall_cost_per_unit1.0
floatjump_cost_per_unit4.0

Methods

ReturnsMethod
intlayer_bit()
floatpassable_height()
boolcan_stand(surface: HammeriteNavigationSurface)
boolcan_be_over(surface: HammeriteNavigationSurface)
boolis_swimming_in(surface: HammeriteNavigationSurface)
floatwater_cost_multiplier(surface: HammeriteNavigationSurface)
boolis_crouching_on(surface: HammeriteNavigationSurface)
floattravel_cost_for(surface: HammeriteNavigationSurface)
boolcan_take(link: HammeriteNavigationLinkData, reversed: bool = false)
floatclimb_for(link: HammeriteNavigationLinkData, reversed: bool = false)
floatfall_for(link: HammeriteNavigationLinkData, reversed: bool = false)
floatcost_for(link: HammeriteNavigationLinkData, reversed: bool = false)

Constants

MEASURED_SHORT

const MEASURED_SHORT = 0.01

What a measure can come up short by: a doorway built 72 high measures 71.99976 a few thousand units from the origin, and an agent 72 tall was shut out of it.

Property descriptions

profile_name

var profile_name: StringName = &""

The profile's name, as the game refers to it. Conventionally lowercase and specific: &"guard", &"rat".

navigation_layer

var navigation_layer: int = 0

Which of the navigation server's layers this profile owns, numbered 1 to 32 as Godot's inspector and NavigationAgent3D.set_navigation_layer_value() number them. 0, the default, is none yet: such a profile routes nowhere. Distinct per profile - two profiles sharing a layer cannot be told apart, and each would walk wherever the other could. Nothing is a safe default for that reason, since any one layer would be every new profile's. HammeriteNavigationAgentProfiles.validate() reports both mistakes rather than leaving them to be discovered as a rat pathing along the battlements.

height

var height: float = 96.0

How tall it is. Ground with less headroom than this is not ground for it: the vent a rat runs down is a wall to a guard, from this one number.

crouch_height

var crouch_height: float = 0.0

The lowest it can get through at all, by ducking or crawling. Zero - the default - means it does not: anything it cannot stand up in is not ground for it. This is what makes a crawlspace a route rather than a wall, and it is the reason headroom is measured so carefully. Below height and down to here, the agent gets through but pays crouch_cost_multiplier for every unit of it.

crouch_cost_multiplier

var crouch_cost_multiplier: float = 2.0

What moving crouched costs, as a multiple of the distance. Applies below height, and only to an agent that can crouch at all.

wading_depth_ratio

var wading_depth_ratio: float = 0.5

The deepest water it wades, as a share of its height: waist-deep at the default. Deeper than that it swims, or - if it cannot - does not go.

wading_cost_multiplier

var wading_cost_multiplier: float = 2.0

What wading costs, as a multiple of the distance.

can_swim

var can_swim: bool = false

Whether it swims. One that does not treats water over its wading depth as a wall.

swimming_cost_multiplier

var swimming_cost_multiplier: float = 4.0

What swimming costs, as a multiple of the distance.

width

var width: float = 32.0

How wide it is, across the shoulders. Compared against the narrowest width of a patch, so a passage a body cannot fit down is not a route however much floor it has.

max_slope_degrees

var max_slope_degrees: float = 46.0

The steepest ground it will walk, in degrees from horizontal.

climb_height

var climb_height: float = 32.0

How high it can pull itself up: the step onto a crate, the sill of a window. This is what decides which way a link points - a drop everything can walk off is only a route back up for something that can climb it. It also decides whether stairs are stairs. A tread is a HammeriteNavigationLinkData.Kind.STEP and costs nothing to take, but only an agent whose stride reaches it can take one: below HammeriteNavigationAgentProfiles.step_height this wants to be at least the height of the stairs a game builds, or its guards will not use them.

fall_height

var fall_height: float = 192.0

How far it will deliberately drop. Not what would kill it - what it is willing to do.

jump_span

var jump_span: float = 0.0

How far it can jump across open air. Zero for anything that does not jump, which is most things.

var link_cost: float = 32.0

What taking any traversal link costs, as the distance this agent would rather walk than take one. Costs are in world units of walking. That is the currency the navigation server counts a route in, so saying a climb costs 400 means an agent goes round rather than up whenever the way round is less than 400 units longer. It is the question a designer is actually asking - "how far out of their way would a guard go to avoid a window" - rather than an abstract weight. Without any of this every link costs what walking costs, and a guard hauls themself through the window beside a perfectly good door because the window is four units shorter.

climb_cost_per_unit

var climb_cost_per_unit: float = 4.0

What each unit of climbing costs. Climbing is slow, exposed and undignified; a guard would rather walk a long way round than do it, and at the default a 96-unit sill is worth about 400 units of walking.

fall_cost_per_unit

var fall_cost_per_unit: float = 1.0

What each unit of dropping costs. Cheaper than climbing, because dropping is quick - but not free, since nothing sensible walks off a ledge it could have taken stairs down.

jump_cost_per_unit

var jump_cost_per_unit: float = 4.0

What each unit of jumped gap costs, over open air. Only jumps pay it: a drop's span is the lip of the ledge it goes over, incidental, while a jump's span is the thing being attempted.

Method descriptions

layer_bit()

func layer_bit() -> int

This profile's navigation-layer bit, for NavigationRegion3D.navigation_layers and NavigationAgent3D.navigation_layers; 0 while it has no layer.

passable_height()

func passable_height() -> float

The least headroom this profile can get through: its standing height, or what it can duck to.

can_stand()

func can_stand(surface: HammeriteNavigationSurface) -> bool

Can this profile get onto and across surface?

can_be_over()

func can_be_over(surface: HammeriteNavigationSurface) -> bool

Can some of this profile be over surface: everything can_stand() asks but the width. A strip of floor too narrow to stand on is still floor a body standing beside it overhangs.

is_swimming_in()

func is_swimming_in(surface: HammeriteNavigationSurface) -> bool

Is the water over surface too deep for this profile to wade?

water_cost_multiplier()

func water_cost_multiplier(surface: HammeriteNavigationSurface) -> float

What the water over surface costs this profile, as a multiple of the distance: nothing on dry ground, then wading, then swimming.

is_crouching_on()

func is_crouching_on(surface: HammeriteNavigationSurface) -> bool

Does this profile have to duck to get across surface?

travel_cost_for()

func travel_cost_for(surface: HammeriteNavigationSurface) -> float

What crossing surface costs this profile, as a multiple of the distance. What the author said about the room (HammeriteNavigationBrushProperties), times what this agent thinks of it: of the water over it, and of being bent double. A guard wading a crawlspace pays twice for the water and twice again for crouching, and would go a long way round rather than do it, while a rat that fits standing up pays only for the water - if it does not have to swim it.

can_take()

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

Can this profile take link, in the given direction? Everything asked here is a comparison against something measured, and the link decides nothing on its own. An authored link - a ladder, a rope - passes the climb test because placing it is the author's assertion that it can be climbed; a one-way one is never taken in reverse (HammeriteNavigationLinkData.one_way).

climb_for()

func climb_for(link: HammeriteNavigationLinkData, reversed: bool = false) -> float

What this profile has to climb to take link in the given direction. Out of water it swims, that is from the water line, not the bottom: a pool filled to its brim is no climb at all.

fall_for()

func fall_for(link: HammeriteNavigationLinkData, reversed: bool = false) -> float

How far this profile falls taking link in the given direction: into water it swims, only as far as the surface.

cost_for()

func cost_for(link: HammeriteNavigationLinkData, reversed: bool = false) -> float

What taking link costs this profile, in the world units of walking it is worth avoiding. Directional, and often sharply so: dropping off a balcony is quick and climbing back up is not, so the same link is cheap one way and dear the other. That asymmetry is the point - it is what makes an agent take the stairs down when the stairs are there, and what keeps it from treating a one-storey drop as a shortcut in both directions.

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