# Combat

> The combat system: damage, health, death, damage types, projectiles and the combat log.

Combat (originally the Combat2 Project, an enhancement to the Linden Combat system) is the standard way to build damage systems in Second Life. It is not meant to be a complete combat system on its own but provides the tools that let you make one.

In Second Life there are a host of combat communities scattered across the grid. These communities use a wide variety of combat systems, HUDs and weapon systems. Some are completely custom, relying on scripts to arbitrate health and damage, while others are based on the Linden Lab Combat System (LLCS).

The goal is a coherent set of tools that lets residents create complex and compelling combat systems using a common and easy to use framework. Damage only works where the [parcel allows it](/constants/PARCEL_FLAG_ALLOW_DAMAGE/) (check with [`llGetParcelFlags`](/functions/llGetParcelFlags/)).

## Concepts

- Can apply damage [directly](/functions/llDamage/), or on collision by giving a prim a [damage amount](/functions/llSetDamage/) ([`PRIM_DAMAGE`](/constants/PRIM_DAMAGE/))
- Damage can have a [damage type](/features/combat/damage-types/) associated to it
- Damage events
  - If a script (object, vehicle or attachment) has a [damage event](/events/on_damage/) this will be called first before [final damage](/events/final_damage/) is applied
  - Scripts may [modify the actual amount of damage](/functions/llAdjustDamage/) in a damage event if the region allows it
  - Inside the event, [what hit](/functions/llDetectedDamage/), [who owns it](/functions/llDetectedOwner/), [its key](/functions/llDetectedKey/) and [who rezzed it](/functions/llDetectedRezzer/) are read with the detected functions
- [Objects have a health property](/constants/PRIM_HEALTH/), and any avatar's or object's [health can be read](/functions/llGetHealth/)
  - Scripts have to manage this property themselves; Unlike agents the simulator will not apply damage to the object health and instead only trigger damage and final damage events
  - Sensors can scan for [damageable](/constants/DAMAGEABLE/) objects and avatars that are not on a safe parcel
  - When an avatar dies, its attachments get an [`on_death`](/events/on_death/) event
- [Combat Log](/features/combat/combat-log/) has been added which allows for auditing and other usecases
  - Records all damage events, damage adjustments and kills in a [combat-specific public channel](/constants/COMBAT_CHANNEL/)
  - System generated messages by a [specific ID](/constants/COMBAT_LOG_ID/) that scripts may filter to
  - Scripts may write to this channel if not restricted so by the region
- New region-wide settings, region owners may:
  - Throttle damage per second dealt to a target by a single source
  - Limit damage to a target by a maximum per a single event
  - Select a number of options as to what happens when agent health drops to 0 such as:
    1. Teleport home (same as old LLCS)
    2. Teleport to region's telehub
    3. Teleport to parcel's landing point
    4. No action -- Which can allow a custom scripted respawn system to act instead for example
  - Set a brief period of invulnerability, during which agents may neither deal nor receive damage
  - Whether health is reset to 100% on death
  - Tweak the speed of health regeneration per second or disable health regeneration
  - Whether scripts are allowed to adjust damage or write to the combat log
  - Scripts read these settings with [`llGetEnv`](/functions/llGetEnv/) (see [Additional](#additional))

## Functions and events

These are the functions and events directly related to combat, as well as related functions for rezzing projectiles.

- `key` [`llRezObjectWithParams`](/functions/llRezObjectWithParams/) `(string item, list options)`
- `void` [`llAdjustDamage`](/functions/llAdjustDamage/) `(integer number, float new_damage)`
- `void` [`llDamage`](/functions/llDamage/) `(key target, float damage, integer damage_type)`
- `list` [`llDetectedDamage`](/functions/llDetectedDamage/) `(integer number)`
- `key` [`llDetectedRezzer`](/functions/llDetectedRezzer/) `(integer number)`
- `float` [`llGetHealth`](/functions/llGetHealth/) `(key id)`
- `event` [`on_damage`](/events/on_damage/) `(integer num_detected)`
- `event` [`final_damage`](/events/final_damage/) `(integer num_detected)`
- `event` [`on_death`](/events/on_death/) `()`
- `string` [`llGetStartString`](/functions/llGetStartString/) `()`
- `integer` [`llDerezObject`](/functions/llDerezObject/) `(key id, integer flags)`

## [Combat Log](/features/combat/combat-log/)

System-generated log messages are collected and sent into the [`COMBAT_CHANNEL`](/constants/COMBAT_CHANNEL/) in a JSON format (see the [message format](/features/combat/combat-log/)). Read them with a [listener](/functions/llListen/) and [`llJsonGetValue`](/functions/llJsonGetValue/) in the [`listen`](/events/listen/) event.

## [Damage types](/features/combat/damage-types/)

The damage amount can be supported via a damage type field, which can match a default `DAMAGE_TYPE_*` or a custom integer; Additionally the field may be repurposed. See the [standard](/features/combat/damage-types/#standard-damage-types) and [community](/features/combat/damage-types/#community-damage-types) tables on the damage types page.

## Weapons and projectiles

Guns and spells combine several features: control capture or mouselook for [input](/features/input/), rezzing [physical](/features/physics/) projectiles [with parameters](/functions/llRezObjectWithParams/), [raycasts](/functions/llCastRay/) for hitscan weapons, and [sounds](/features/sound/) and [particles](/features/effects/) for feedback.

## Scripting Details

Here are the functions and events in detail.

- `key` [`llRezObjectWithParams`](/functions/llRezObjectWithParams/) `(string item, list options)`: New function for rezzing objects with a variety of parameters, particularly useful for avoiding the overhead of starting a script for each bullet

- `void` [`llAdjustDamage`](/functions/llAdjustDamage/) `(integer number, float new_damage)`: Modifies the amount of damage that will be applied by the current [`on_damage`](/events/on_damage/) event after it has completed processing

- `void` [`llDamage`](/functions/llDamage/) `(key target, float damage, integer damage_type)`: Delivers damage to tasks and agent in the same region with an [integer describing the type of damage](/features/combat/damage-types/). Negative damage can be used to heal instead. You can also go above 100.0 damage unlike collideable damage

- `list` [`llDetectedDamage`](/functions/llDetectedDamage/) `(integer number)`: Returns a list describing a single damage event within an [`on_damage`](/events/on_damage/) event

- `key` [`llDetectedRezzer`](/functions/llDetectedRezzer/) `(integer number)`: Returns a key that is the UUID of the object or avatar that rezzed the detected object

- `float` [`llGetHealth`](/functions/llGetHealth/) `(key id)`: Returns the current health of an avatar or object in the region

- `event` [`on_damage`](/events/on_damage/) `(integer num_detected)`: Triggered when damage has been inflicted on an avatar or task in the world but before damage has been applied or distributed

- `event` [`final_damage`](/events/final_damage/) `(integer num_detected)`: Triggered after after all [`on_damage`](/events/on_damage/) events in all scripts and attachments have processed and damage has been applied to the avatar or distributed to all seated avatars

- `event` [`on_death`](/events/on_death/) `()`: Triggered on all attachments worn by an avatar when that avatar's health reaches 0

- `string` [`llGetStartString`](/functions/llGetStartString/) `()`: New function to retrieve the string passed with [`llRezObjectWithParams`](/functions/llRezObjectWithParams/) via [`REZ_PARAM_STRING`](/constants/REZ_PARAM_STRING/), particularly useful for avoiding overhead and delay when having to communicate any necessary information

- `integer` [`llDerezObject`](/functions/llDerezObject/) `(key id, integer flags)`: Derezzes an object previously rezzed from within the object containing the script

## Additional

- [Damage types](/features/combat/damage-types/) — Provided for convenience and a suggestion. Scripters can add custom ones or repurpose the damage type fields
- [`llListen`](/functions/llListen/)
  - Channel reserved at [`COMBAT_CHANNEL`](/constants/COMBAT_CHANNEL/)
  - System generated combat log messages sent by [`COMBAT_LOG_ID`](/constants/COMBAT_LOG_ID/)
  - Scripts may also write to this channel if the region allows it (see `"restrict_combat_log"` below)
- [`llSensor`](/functions/llSensor/) — Scripts may filter by [`DAMAGEABLE`](/constants/DAMAGEABLE/) for objects in world that process damage (that is if they have a [`on_damage`](/events/on_damage/) and/or [`final_damage`](/events/final_damage/) event -- the object's health doesn't matter)
- [`llGetObjectDetails`](/functions/llGetObjectDetails/) — Additional values around health, damage and type
  - [`OBJECT_HEALTH`](/constants/OBJECT_HEALTH/) — Retrieves the health of an avatar or prim
  - [`OBJECT_DAMAGE`](/constants/OBJECT_DAMAGE/) — Retrieves the amount of damage a prim inflicts on collision
  - [`OBJECT_DAMAGE_TYPE`](/constants/OBJECT_DAMAGE_TYPE/) — Retrieves the type of damage a prim inflicts on collision
- [`llRezObjectWithParams`](/functions/llRezObjectWithParams/) — Apply damage to rezzed objects
  - [`REZ_DAMAGE`](/constants/REZ_DAMAGE/) — The amount of damage applied to an agent upon collision with this object
  - [`REZ_DAMAGE_TYPE`](/constants/REZ_DAMAGE_TYPE/) — The damage type to apply when this prim collides with another object
  - [`REZ_PARAM_STRING`](/constants/REZ_PARAM_STRING/) — String parameter that can be passed into the rezzed object with a maximum string length of 1024 bytes
- [`llSetLinkPrimitiveParamsFast`](/functions/llSetLinkPrimitiveParamsFast/) — New parameter added to adjust damage amount and damage type for collision damage
  - [`PRIM_DAMAGE`](/constants/PRIM_DAMAGE/) — Set damage amount and damage type
- [`llGetEnv`](/functions/llGetEnv/) — Several new values are added
  - `"allow_damage_adjust"` — Are scripts allowed to adjust damage
  - `"restrict_combat_log"` — Are scripts allowed to write to the combat log
  - `"restore_health"` — Is health reset to 100% on death
  - `"invulnerability_time"` — Invulnerablitiy time applied after avatar death
  - `"damage_throttle"` — The maximum number of points of damage a single source may inflict on a target per second. This is a Damage Per Second (DPS) throttle
  - `"damage_limit"` — The maximum number of points of damage a single damage collision or call via [`llDamage`](/functions/llDamage/) may inflict
  - `"health_regen_rate"` — The speed of health regeneration in hitpoints per second
  - `"death_action"` — Set the action to take when an avatar dies in the region
- [`llSetLinkSitFlags`](/functions/llSetLinkSitFlags/) — Flags that can be applied to sit targets
  - [`SIT_FLAG_NO_COLLIDE`](/constants/SIT_FLAG_NO_COLLIDE/) — Disable the avatar's collision volume when they are seated on this sit target
  - [`SIT_FLAG_NO_DAMAGE`](/constants/SIT_FLAG_NO_DAMAGE/) — Do not distribute damage to agents sitting on this sit target
- [`llGetParcelFlags`](/functions/llGetParcelFlags/) — [`PARCEL_FLAG_ALLOW_DAMAGE`](/constants/PARCEL_FLAG_ALLOW_DAMAGE/) is set where damage is enabled; elsewhere avatars are safe

## Related

- Thread on the Second Life community forums by Rider Linden announcing the project: [Pew! Pew! Pew! Linden Damage & Combat 2.0](https://community.secondlife.com/forums/topic/506317-pew-pew-pew-linden-damage-combat-20/)
- [Feedback for suggesting, voting and commenting on ideas](https://feedback.secondlife.com/combat-20)
- Thread on draft proposal for Combat 2.1 changes by adding Teams & Respawns concepts from Rider Linden: [Combat 2.1: Teams & Respawn](https://community.secondlife.com/forums/topic/516319-combat-21-teams-respawn/)

See also: [Input](/features/input/), [Physics](/features/physics/), [Effects](/features/effects/), [Sound](/features/sound/), [Inventory](/features/inventory/), [Guide: turret rotation (aiming a turret with the camera)](/guides/constraining-rotations/turret/)

## Known Issues

- Sitting Avatars with `SIT_FLAGS_NO_DAMAGE` may still attempt to process damage which can cause various issues, such as still generating damage logs and affecting objects with [`llSetDamage`](/functions/llSetDamage/)
  - [Adjust SIT_FLAG_NO_DAMAGE so combat log reports are not generated](https://feedback.secondlife.com/scripting-features/p/adjust-sit-flag-no-damage-so-combat-log-reports-are-not-generated)
  - [SIT_FLAGS_NO_DAMAGE still attempts to process LLCS damage on sitting avatars](https://feedback.secondlife.com/scripting-bugs/p/sit-flags-no-damage-still-attempts-to-process-llcs-damage-on-sitting-avatars)

## Wishlist

- [Combat2.1 Teams](https://feedback.secondlife.com/scripting-features/p/combat-21-teams)
- [Combat2.1 Respawns](https://feedback.secondlife.com/scripting-features/p/combat-21-respawns)
- [`PRIM_MAX_HEALTH`](https://feedback.secondlife.com/feature-requests/p/combat2-prim-max-health-prim-property-would-be-useful)

*Adapted from the Second Life Wiki [Category:LSL Combat2](https://wiki.secondlife.com/wiki/Category:LSL_Combat2), by Second Life Wiki contributors, under [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/).*

## Related features

- [Physics](/features/physics/)
- [Input](/features/input/)
- [Linksets](/features/linkset/)

## Categories

- [Combat](/categories/combat/)

---

From lsl.dev: https://lsl.dev/features/combat/
