hero
The hero — the thing the player is in **Hero Line Wars: Emberfront**.
hero.module
The hero — the thing the player is in Hero Line Wars: Emberfront.
This module attaches to the live local player's avatar
(layers.active.players.localPlayer.avatar), the clone the engine makes of the
scene's HeroPrototype when a peer joins. It never builds a second rig.
What it does
| Move | Retunes the avatar's CharacterController to Rules.K.hero.moveSpeed, and clamps the body into the ember lane band every frame with Rules.clampToLane. The lava rift and the canyon walls are hard bounds. The clamp is pulled EDGE_INSET metres inside the band: the lane shelf ends on exactly the band's line, and a capsule standing with its centre on the last inch of that ledge falls off and wedges inside the shelf's own collider, pushing at full speed against a velocity of zero with nothing in the game able to free it. A hero found under the floor anyway is set back on top of it. |
| Turn | The stock controller strafes without ever turning, so the hero would keep facing one way forever. Each frame the body is turned to face its own velocity. |
| Swing | attack — left mouse / right trigger / the on-screen Attack button. Resolved through Creeps.damageInArc on K.hero.attack (damage, cooldown, range, arc). Held, it keeps swinging on the cooldown. |
| Cleave | Q / gamepad north / the Cleave button. A radial burst through Creeps.damageInRadius on K.hero.abilities.cleave. |
| Surge | E / left shoulder / the Surge button. A dash: moveSpeed × speedMult for duration, with an ember trail riding the body. |
| Live and die | Damage in from the creeps slice, out-of-combat regeneration, death, and a respawn at K.points.emberSpawn after K.hero.respawnSeconds. |
Every effect it spawns — spark bursts, light flashes, the surge trail — is a
temporary entity with a time-to-live this module counts down and despawns, so
nothing it makes reaches a scene save and nothing outlives stop().
Controls
The three combat controls live in /zero/source/game/hero_controls.inputMap,
each carrying keyboard, gamepad and touch. Movement and the camera come from the
engine's own default map, which the avatar's CharacterController activates;
this map composes beside it in its own hero group and suppresses nothing.
What other slices call
local Hero = require("game.hero")
Hero.damage(amount, opts?) -> boolean -- the creeps slice's hook. `opts` is
-- free-form metadata for the feed.
-- false while dead or the match is over.
-- `applyDamage` / `takeDamage` are aliases.
Hero.position() -> { x, y, z }? -- where to march at, or nil while unbound
Hero.avatar() -> EntityProxy?
Hero.isAlive() -> boolean
Hero.tryAttack() / Hero.tryCleave() / Hero.trySurge() -> boolean
-- the same three actions without a keyboard, for a HUD button or a test.
What the HUD reads
Kept current every frame:
Hero.health Hero.maxHealth Hero.alive Hero.respawnIn
Hero.cooldowns.cleave Hero.cooldowns.surge -- seconds left, 0 = ready
Hero.cooldownMax.cleave Hero.cooldownMax.surge -- what to divide by for a bar
Hero.surgeActive -- seconds of dash left
Events it emits
On Rules.bus: heroDamaged { lane, health, max, amount, source },
heroDied { lane }, heroRespawned { lane },
abilityUsed { lane, ability, hits? } — ability is "attack", "cleave" or
"surge".
What binding also sets up
Three things are applied once, the first time the live avatar resolves, and left alone afterwards so anything the player does with them stands.
- The camera framing. The stock
orbital_followrings frame a conversation — head height, four metres out — which in this canyon puts the eye at the hero's ankles and fills the screen with basalt.CAMERAreplaces all three rings with a raised chase shot that sees a stretch of lane ahead, andCAMERA_HEADINGaims the opening shot into the oncoming column rather than at the nexus behind. The player still orbits and zooms from there. - The lantern. A warm point light named
hero_lanternthat rides the hero. The canyon is lit by the rift alone, which leaves the lane floor and everything standing on it reading as pure black from the chase camera. The lamp keeps the hero, the ground and whatever walked into range legible without lifting the ambient over the whole canyon. It istemporary, there is only ever one, and a reloaded copy of this module adopts the existing one rather than hanging a second light on the body. - The plate. Every
SkinnedModelunder the body is put intoart/hero_emberplate.material, because the avatar the engine mints for a joining peer wears a stock skin that reads as a pale mannequin standing in a volcano. The field is assigned directly rather than throughappearance.swapMaterials: that tool is an authoring one and marks what it touched with an outline, which on the player's own body is a blue ring that never leaves.
Lifecycle
start() / update(dt) / stop(), called by the scene entrypoint. start() is
idempotent, and tolerates being called before the avatar clone exists — update
keeps asking every half second until it is there. update also re-arms the
slice if it finds itself disarmed, which is what a hot reload of this file
leaves behind: fresh module locals, a false running flag, and an entrypoint
still ticking the same table.
Scoped to this part · feeds back into the world's score.