Skip to main content

Combat and Camera Contract

Combat and camera share targeting observations but remain separate capabilities. Lua chooses whom to engage and under what risk policy. The engine owns tracking, aim quality, attack cadence, pursuit, occlusion, stabilization, and cleanup.

Candidate surface

CapabilityPurpose
combat.engagePursue and engage targets under bounded policy
combat.disengageReach a safe disengaged state
camera.look_atTimed movement toward a world or entity target
camera.trackMaintain framing until cancelled or target loss

Combat request

local fight = hexis.combat.engage({
targets = pack.entities.zealots,
constraints = {
max_distance = 24,
max_duration = 45,
minimum_health = 12,
avoid_players_within = 3,
},
loadout = pack.loadouts.melee,
})

Target selectors are declarative and evaluated against immutable snapshots. Pack selectors may interpret server-specific entity markers, but the engine validates the resulting live entity before acting.

Camera requests

Camera accepts a world point, rotation, block hit, or stable entity reference. It requires duration, maximum angular velocity, and loss behavior when tracking. The engine clamps unsafe or impossible values and never exposes an internal camera controller.

Camera progress reports phase and angular error. Results include final angular error and target-loss reason, not proprietary interpolation state.

Arbitration

Combat normally holds combat, camera, and interaction; pursuit additionally holds movement. Standalone camera actions hold camera. Resource loss, manual-user override, script stop, screen change, or world change produces bounded cancellation and releases attack/use input before completion.

User input policy is explicit: yield, pause, or an approved override mode. Scripts cannot silently fight the user for camera control.

Results

Combat progress phases are acquiring, pursuing, engaging, recovering, and disengaging. Terminal data contains targets engaged/defeated, elapsed time, damage/risk observations when available, and the stop reason.

Combat adds NO_TARGET, TARGET_LOST, TARGET_INVALID, OUT_OF_RANGE, RISK_LIMIT, LOADOUT_UNAVAILABLE, ATTACK_REJECTED, and DISENGAGE_FAILED.

Camera adds TARGET_OCCLUDED, TARGET_LOST, ROTATION_LIMIT, and USER_OVERRIDE.

Safety and pack boundary

  • Core targeting never assumes armor stands, name colors, boss-bar formats, or a server brand.
  • Packs may classify semantic targets but cannot authorize attacks outside the script manifest.
  • Friend, protected-target, and user-defined deny rules are evaluated before engagement and again before attack.
  • Attack cadence and packet/input behavior stay inside supported Minecraft interaction paths.

Acceptance tasks

  1. Track a moving target without concurrent Lua callbacks.
  2. Cancel aim or attack and release control within one tick.
  3. Reject a stale entity reference after world generation changes.
  4. Respect health, duration, distance, and protected-target limits.
  5. Resolve camera-versus-navigation contention deterministically.
  6. Pause or yield correctly on manual user input.
  7. Disengage after target loss without continuing attacks.
  8. Run a generic hostile-mob fixture without a pack.
  9. Verify a pack selector without exposing its server-specific logic to core.
  10. Measure live tick cost, targeting quality, and false-engagement rate.