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
boolcan_swimfalse
floatclimb_cost_per_unit4.0
floatclimb_height32.0
floatcrouch_cost_multiplier2.0
floatcrouch_height0.0
floatfall_cost_per_unit1.0
floatfall_height192.0
floatheight96.0
floatjump_cost_per_unit4.0
floatjump_span0.0
floatlink_cost32.0
floatmax_slope_degrees46.0
intnavigation_layer0
StringNameprofile_name&""
floatswimming_cost_multiplier4.0
floatwading_cost_multiplier2.0
floatwading_depth_ratio0.5
floatwidth32.0

Methods

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

Property descriptions

can_swim

var can_swim: bool = false

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

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.

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.

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.

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.

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.

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.

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.

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.

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.

max_slope_degrees

var max_slope_degrees: float = 46.0

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

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.

profile_name

var profile_name: StringName = &""

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

swimming_cost_multiplier

var swimming_cost_multiplier: float = 4.0

What swimming costs, as a multiple of the distance.

wading_cost_multiplier

var wading_cost_multiplier: float = 2.0

What wading costs, as a multiple of the distance.

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.

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.

Method descriptions

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.

can_stand()

func can_stand(surface: HammeriteNavigationSurface) -> bool

Can this profile get onto and across surface?

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.

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.

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.

is_crouching_on()

func is_crouching_on(surface: HammeriteNavigationSurface) -> bool

Does this profile have to duck to get across surface?

is_swimming_in()

func is_swimming_in(surface: HammeriteNavigationSurface) -> bool

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

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.

measured_short()

static func measured_short() -> float

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.

passable_height()

func passable_height() -> float

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

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.

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.

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