Collision boxes tell OpenBOR (or any other game engine) what portions of an entity are able to hit or get hit and what areas of a level are walls or platforms. In OpenBOR these boxes are geometric cubes the engine continuously compares to each other – whenever two or more cubes overlap, that’s a collision and the engine will react accordingly.
Depending on the type of collision box, it will have other properties that tell the engine how to handle the collision event. This article focuses on Attack (hitting with attacks) and Body (Receiving attacks and taking up space). Walls and platforms work on a similar principal and are covered in level design.
Contents
Multiple Boxes
OpenBOR supports multiple collision boxes per frame. To define a second box of any type, add collision.index {index}
with your desired index and then define a set of properties for the next box. You may use any integer value for {index}
. All subsequent collision box properties below collision.index {index}
now act on the new index.
You can repeat this process to add a third box, a forth box, and so on. To adjust or disable the boxes, again use collision.index {index}
to define which box you wish to act on, then disable or adjust the box properties as you would a single occurrence.
When two or more attack boxes overlap a body box or body boxes, OpenBOR will acknowledge a single collision with the earliest attack and body boxes in defined order taking priority.
Tip: There’s no hard code limit, but don’t get carried away with this feature. Even high precision vs. fighters like Street Fighter and King of Fighters typically use just two or three body boxes and one attack box. Most beat em’ up games never need more than one of each except for special cases (ex. oddly shaped limbs).
Attack
Attacks hit and presumably cause damage to other entities. To define an attack, add the necessary attack commands from list below immediately before the frame. In most cases you only need the basic dimensions and damage value. The other attack properties are optional and most are disabled by default.
Once defined, an attack remains active throughout remainder of the animation unless you redefine it. To disable an attack, add attack 0
or attack none
before a frame.
Command List
Command | Default | Description |
---|---|---|
attack.block.cost | 0 | Amount attack removes from target’s guardpoints when blocked. |
attack.block.penetrate | 0 | If this meets or exceeds target’s block threshold, target cannot block attack. |
attack.counter | 0 | If 1+, this attack treats target’s attack boxes as body boxes. If both attacks have counter value, highest value has priority. |
attack.damage.force | 0 | Value deducted from target’s hit points. |
attack.damage.land.force | 0 | If attack causes a fall, value deducted from target’s hit points on landing. |
attack.damage.land.mode | 0 | If attack causes knockdown, target’s projectile status and landing ability. Projectile status has no effect if target’s fall animations do not have an attack box. * 0 – Normal fall. Target’s attack boxes are disabled until landing. * 1 – Target’s attack boxes are enabled in projectile mode until landing, meaning target will hit its allies. * 2 – Same as 1. Additionally, if player controlled targets have LAND animation available, they may play it on landing and nullify land force by holding Up + Jump. |
attack.damage.lethal.disable | 0 | If true, attack cannot reduce target’s hit points below 1. |
attack.damage.recursive.force | 0 | Amount deducted from target’s hitpoints on each recursive tick. See Recursive Damage. |
attack.damage.recursive.index | 0 | Index ID applied to recursive damage. See Recursive Damage. |
attack.damage.recursive.mode | 0 | How recursive damage applies to target’s hit points or magic points. See Recursive Damage. |
attack.damage.recursive.tag | 0 | Creator defined value ignored by native engine logic. See Recursive Damage. |
attack.damage.recursive.time | 0 | How long (in centiseconds) the recursive damage effect will last. See Recursive Damage. |
attack.damage.recursive.rate | 0 | How long (in centiseconds) between each tick of recursive damage. See Recursive Damage. |
attack.damage.steal | 0 | If true, attack.damage.force is added to attacking entity’s hit points. |
attack.damage.type | 1 | Attacking type. Works with target’s defense values and reacting animations. Accepts following values: * Any 1+ number. For legacy compatibility, attacks are NOT 0 indexed. If you provide a value of 0, 1 is used instead. * Blast * Burn * Freeze * Shock * Steal See Attack Types for details. |
attack.effect.block.flash.model | None | Name of model to spawn when target blocks attack. |
attack.effect.block.sound.path | None | Path to sound file that plays when target blocks attack. |
attack.effect.hit.flash.layer.adjust | 0 | Added to global layer adjustment of flash spawn drawing layer. See Hit Effects. |
attack.effect.hit.flash.layer.source | 0 | Added to global hit flash layer source value for controlling source of flash spawn drawing layer. See Hit Effects. |
attack.effect.hit.flash.model | None | Name of model to spawn when attack hits target. If undefined, the global flash model spawns. |
attack.effect.hit.flash.disable | 0 | If true, no model spawns when attack hits target. |
attack.effect.hit.sound.path | None | Path to sound file that plays when attack hits target. |
attack.ground.mode | 0 | Ability to hit fallen targets on the ground. * 0 = Attack cannot hit lying targets. * 1 = Attack can hit lying targets. * 2 = Attack only hits lying targets. |
collision.index | 0 | Used for multiple attack boxes on one animation frame. 0 is the first attack box. 1 is the second, and so on. Place this immediately before other properties to have them act on that index. See multiple collision boxes for details. |
attack.map.index | 0 | If 1+, target entity switches to this palette index. For example, if hit by attack.map.index 3 , the target switches to palette 3 if available. If -1, target applies its freeze palette. You can also use one of following named indexes. If the defending target has a matching named palette index defined, it will apply that palette index. burn freeze ko shock |
attack.map.time | 0 | Time in centiseconds to maintain attack.map.index effect. Target reverts to previous palette afterward. |
attack.position.x | 0 | X position of attack box, starting from far left of image. Positive integers move right, negative moves left. |
attack.position.y | 0 | Y position of attack box, starting from far top image. Positive integers move down, negative moves up. |
attack.reaction.fall.force | 0 | Amount deducted from target’s knockdowncount. If this value is 1+ and target’s knockdowncount is 0, target is knocked down. Note the knock down check is made immediately after deduction, so if the target has a knockdowncount of 1 and is hit attack with attack.reaction.fall.force 1 , the target falls.Note: Default knockdowncount is 0, so unless the target is set up with a specific knockdowncount or some other means to resist falling, setting this value to any causes knockdown. |
attack.reaction.fall.velocity.x | 1.2 | X axis toss velocity applied to target if attack knocks it down. |
attack.reaction.fall.velocity.y | 3.0 | Y axis toss velocity applied to target if attack knocks it down. |
attack.reaction.fall.velocity.z | 0.0 | Z axis toss velocity applied to target if attack knocks it down. |
attack.reaction.freeze.mode | 0 | Freeze effect. * 0 – No freeze effect. * 1 – Target freezes in place. |
attack.reaction.freeze.time | 0 | Time in centiseconds to maintain attack.reaction.freeze.mode effect. |
attack.reaction.invincible.time | 0 | Time in centiseconds target is invincible to subsequent hits. Note: 0 is allowed and is the default property value. However, the engine will substitute a 0 value with 40 when applying the invincibility time. The legacy fastattack command works by setting this property to 10. |
attack.reaction.pain.disable | 0 | If true, target does not play a reaction animation when hit by attack. |
attack.reaction.pause.time | 0 | Time in centiseconds target and attacker pause (freeze) when attack hits. |
attack.reaction.reposition.direction | None | Force target to face specific direction when attack hits. * Left – Target faces left. * Opposite – Target faces opposite direction of attacker. * None – No direction adjustment. * Same – Target faces same direction as attacker. * Right – Target faces right. * Toward – Face toward attacker position. * Away – Face away from attacker position. |
attack.reaction.reposition.distance | 0 | Horizontal distance between attacker and target when applying attack.reaction.reposition.mode . |
attack.reaction.reposition.mode | 0 | Horizontal position adjustment when attack hits and does not knock down. * 0 – None. * 1 = Target moves to attacker. * 2 = Target and attacker move to each other, splitting distance. |
attack.seal.cost | 0 | If 1+, this is maximum allowed MP cost target for target specials. For example, if target is hit with seal 10, the target may only use specials that cost 10 MP or less each. |
attack.seal.time | 0 | Time in centiseconds to apply attack.seal.cost . |
attack.size.x | 0 | X size in pixels, moving right from attack.position.x . |
attack.size.y | 0 | Y size in pixels, moving down from attack.position.y . |
attack.size.z.background | grabdistance setting / 3 + 1 | Z size in pixels, moving further from player’s viewpoint from entity position. Note: For legacy compatibility, it is impossible to set a 0 value using native text. If you do, it is replaced with the default value. |
attack.size.z.foreground | grabdistance setting / 3 + 1 | Z size in pixels, moving toward player’s viewpoint from entity position. Note: For legacy compatibility, it is impossible to set a 0 value using native text. If you do, it is replaced with the default value. |
attack.staydown.rise.time | 0 | Time in centiseconds added to target’s risetime if knocked down. |
attack.staydown.attack.time | 0 | Time in centiseconds before target can use its RISEATTACK animation if knocked down. Note: Normally, RISEATTACK is available immediately after a knockdown. |
attack.tag | 0 | Creator defined integer ignored by engine logic. Note: Subject to removal on completion of meta_data feature. |
Example
Single
This example defines a single attack box that knocks down and does 10 points of damage, then closes the box on the subsequent frame. Notice only the necessary properties are defined. Order is irrelevant.
attack.position.x 58
attack.position.y 90
attack.size.x 92
attack.size.y 25
attack.reaction.fall.force 1
attack.reaction.pause.time 10
attack.damage.force 15
attack.effect.hit.flash.model flash_fatal_fury
frame data/chars/terry/atk_j_side_kick_c_1.png
attack none
frame data/chars/terry/atk_j_side_kick_c_1.png
Multiple
This example takes advantage of multiple boxes to place a more accurate attack area around Ryu’s leg. The second box has an index of 1. Since we didn’t bother to define an index for the first box, it gets a default index of 0. Unless the target is really close, we want the contact area (and thus flash spawns) to be around Ryu’s foot, so we place that box first in order to give it priority. The attack definitions are otherwise identical to single boxes. On the following frame, we close both the attack boxes.
attack.damage.force 12
attack.effect.hit.flash.model flash_fatal_fury
attack.reaction.fall.force 1
attack.reaction.pause.time 12
attack.position.x 138
attack.position.y 44
attack.size.x 32
attack.size.y 26
collision.index 1
attack.damage.force 12
attack.effect.hit.flash.model flash_fatal_fury
attack.reaction.fall.force 1
attack.reaction.pause.time 12
attack.position.x 112
attack.position.y 61
attack.size.x 33
attack.size.y 25
frame data/chars/ryu/20_3.png
collision.index 0
attack none
collision.index 1
attack none
frame data/chars/ryu/20_4.png
Body
Body boxes detect incoming attacks. If an entity doesn’t have a body box on a given frame, it can’t detect attacks and is effectively invincible from conventional hits. Defining a body box is nearly identical to attack boxes, except body boxes are far simpler as they have fewer properties.
To end a body box, add bbox 0
or bbox none
before a frame.
Command | Default | Description |
---|---|---|
bbox.effect.hit.flash.layer.adjust | 0 | Added to global layer adjustment of flash spawn drawing layer. See Hit Effects. |
bbox.effect.hit.flash.layer.source | 0 | Added to global hit flash layer source value for controlling source of flash spawn drawing layer. See Hit Effects. |
bbox.defense | None | At time of writing, no function. This is a feature in progress that will allow setting up defense properties for individual body boxes. |
bbox.meta_data | None | At time of writing, no function. This is an in progress feature to allow unlimited storage of creator defined data. |
bbox.meta_tag | 0 | Creator defined integer ignored by engine logic. Note: Subject to removal on completion of meta_data feature. |
bbox.position.x | 0 | X position of body box, starting from far left of image. Positive integers move right, negative moves left. |
bbox.position.y | 0 | Y position of body box, starting from top of image. Positive integers move down, negative moves up. |
bbox.size.x | 0 | X size in pixels, moving right from body.position.x . |
bbox.size.y | 0 | Y size in pixels, moving down from body.position.y |
bbox.size.z.background | 0 | Z size in pixels, moving further from player’s viewpoint from entity position. |
bbox.size.z.foreground | 0 | Z size in pixels, moving toward player’s viewpoint from entity position. |
Example
Single
This example defines a single body box to detect hits.
bbox.position.x 66
bbox.position.y 49
bbox.size.x 38
bbox.size.y 98
Multiple
This example takes advantage of multiple boxes to place a more accurate hit area area area around Ryu. The second box has an index of 1, and the third an index of 2. Since we didn’t bother to define an index for the first box, it gets a default index of 0. Unless the target is really close, we want the contact area (and thus flash spawns) to be around Ryu’s head, then body, so we place the boxes in order from head to feet to give higher areas priority. The body definitions are otherwise identical to single boxes.
bbox.position.x 78
bbox.position.y 48
bbox.size.x 25
bbox.size.y 21
collision.index 1
bbox.position.x 67
bbox.position.y 57
bbox.size.x 35
bbox.size.y 51
collision.index 2
bbox.position.x 62
bbox.position.y 103
bbox.size.x 47
bbox.size.y 46
frame data/chars/ryu/idle_0.png
collision.index 0
bbox none
collision.index 1
bbox none
frame data/chars/ryu/idle_1.png
Advanced
Hit Placement
Each time a collision occurs, OpenBOR records the location and several other data points into a structure called lasthit. This is then used for items like the native flash effects. Lasthit is available as a system variable and as local vars in didhit and takedamage scripts.
Hit location is the calculated center point where the respective collision boxes overlap on each Axis.
Legacy Attack
Legacy attack boxes use a single attack command with multiple parameters. Additional parameters are available through separate commands we call “Supplements”.
Note: Legacy attack commands are depreciated and will not receive further updates.It is highly recommended any new projects utilize the current attack box commands.
Base commands
Attack
Default legacy attack box. Other than {#}, you cannot omit an optional parameter and use any other parameters rightward. For example, if you want to include a {pausetime} value, you must also include {power}, {block}, and {noflash}.
attack{#} {x} {y} {right} {down} {damage} {power} {block} {noflash} {pausetime} {z}
- {#} – See
attack.damage.type
(numbers only). {#} is part of the command name, no spaces. As an example, if you wanted an attack type 2, you would writeattack2 {x} {y} ...
. Optional. If omitted, defaults to 1. - {x} – See
attack.position.x
. - {y} – See
attack.position.y
. - {right} – See
attack.size.x
. - {down} – See
attack.size.y
. - {damage} – See
attack.damage.force
. - {power} – Optional. See
attack.reaction.fall.force
. - {block} – Optional. See
attack.block.penetrate
. - {noflash} – Optional. See
attack.effect.hit.flash.disable
. - {pausetime} – Optional. See
attack.reaction.pause.time
. - {z} – Optional. See
attack.size.z.1
andattack.size.z.2
. Legacy Z affects both directions.
Blast
Same as Attack other than following:
blast {x} {y} {right} {down} {damage} {block} {noflash} {pausetime} {z}
attack.damage.type
= Blast. Note blast type does nothing on its own and defaults to type 1 reactions.attack.reaction.fall.force
= 1.attack.reaction.fall.velocity.x
= is 2.083.attack.damage.mode
= 1.
Burn
Same as Attack other than the following:
Burn {x} {y} {right} {down} {damage} {knockdown} {block} {noflash} {pausetime} {z}
attack.damage.type
= Burn.
shock
Same as attack# other than the following:
shock {x} {y} {right} {down} {damage} {knockdown} {block} {noflash} {pausettime} {z}
attack.damage.type
= Shock.
Freeze
Same as Attack other than the following:
freeze {x} {y} {right} {down} {damage} {time} {block} {noflash} {pausetime} {z}
attack.damage.type
= Freeze. Note freeze type does nothing on its own and defaults to type 1 reactions.attack.reaction.freeze.mode
= 1.- {time} – See
attack.reaction.freeze.time
. attack.map.index
= 1.
Steal
Same as Attack other than the following:
steal {x} {y} {right} {down} {damage} {knockdown} {block} {noflash} {pausetime} {z}
attack.damage.type
= Steal. Note steal type does nothing on its own and defaults to type 1 reactions.attack.damage.steal
= 1.
Supplements
grabin
grabin {type} {distance}
- {type} – See
attack.reposition.mode
. - {distance} – See
attack.reposition.distance
.
Fastattack 1
When enabled, applies a static value of attack.reaction.invincible.time 10
.
Forcedirection
forcedirection {dir}
- {dir} – See
attack.reposition.direction
.
Damageonlanding
damageonlanding {value} {type}
- {value} – See
attack.damage.land.force
. - {type} – See
attack.damage.land.mode
.
Dropv
dropv {height} {speedx} {speedz}
- {height} – See
attack.reaction.fall.velocity.y
. - {speedx} – See
attack.reaction.fall.velocity.x
. - {speedz} – See
attack.reaction.fall.velocity.z
.
Nokill
nokill {bool}
- {bool} – See
attack.damage.lethal.disable
.
stun {int}
- {int} – See
attack.reaction.freeze.mode
.
Seal
seal {time} {energy}
- {time} – See
attack.seal.time
. - {energy} – See
attack.seal.cost
.
Forcemap
forcemap {map} {time}
- {map} – See
attack.map.index
. - {time} – See
attack.map.time
.
Noreflect
noreflect {bi}
{bi} – See attack.reaction.pain.disable
.
Jugglecost
jugglecost {int}
- This command limits juggling ability of the attackbox.
- Juggling means attacking falling opponents (assuming they are vulnerable while falling). It doesn’t matter if the attackbox knocks down or not cause juggling always knock down opponent.
- This command is used in conjunction with ‘jugglepoints’ (see Header Data above).
- The command works like this:
- If attackbox hits opponent whose ‘jugglepoints’ is higher than or equal with ‘jugglecost’, the attack will connect. At this condition, opponent’s ‘jugglepoints’ will be subtracted by that ‘jugglecost’. This drops ‘jugglepoints’ which limits juggling ability. If attackbox hits opponent whose ‘jugglepoints’ is lower than ‘jugglecost’, the attack will not connect. At this condition, opponent’s ‘jugglepoints’ will remain the same.
OTG
OTG {bi}
{bi} – See attack.ground.mode
.
Guardcost
guardcost {int}
{int} – See attack.block.cost
.
- Defines how much ‘guardpoints’ will be subtracted from opponent if they block this attack.
DOT
DOT {Index} {Time} {Mode} {Force} {Rate}
- {index} – See
attack.damage.recursive.index
. - {time} – See
attack.damage.recursive.time
. - {mode} – See
attack.damage.recursive.mode
. - {force} – See
attack.damage.recursive.force
. - {rate} – See
attack.damage.recursive.rate
.
Staydown
staydown {rise} {riseattack}
{rise} – See attack.staydown.rise.time
.
{riseattack} – See attack.staydown.attack.time
.
Legacy Body
Legacy body box commands are nearly identical to legacy attack box commands in format.
Note: As with legacy attack commands,legacy body commands are depreciated and will not receive further updates.It is highly recommended any new projects utilize the current body box commands.
body {x} {y} {width} {height} {depth back} {depth front}
- {x} – See
body.position.x
. - {y} – See
body.position.y
. - {width} – See
body.size.x
. - {height} – See
body.size.y
. - {depth back} – See
body.size.depth.back
. - {depth front} – See
body.size.depth.front
. If omitted, {depth back} sets depth in both directions.
bboxz {depth back} {depth front} – See body.size.depth.back
and body.size.depth.front