Starward Rogue:XML - BulletPattern Definitions

From Arcen Wiki
Jump to navigation Jump to search

Overview

Unlike the other things being read in (GameEntity, EntitySystem, etc) this is more of a programming language than a chunk of data. That is, it's imperative as much as it is descriptive.

It's also different in that it relies heavily on template "variables" to avoid duplicating a lot of xml when you want your bullets to do the same or similar thing a lot.

Here's an example usage:

In a file in Configuration/EntitySystem/

<system name="TestWeapon"
	category="Weapon"
	shot_type="BulletPointedYellow"
	damage_type="Ballistic"
	attack_power="40"
	fire_rate="3"
	range_actual="500"
	shots_per_salvo="1"
	targeting_logic="Lead"
	firing_timing="AllTheTime"
	special_bullet_patterns="TestVariablePattern"
	>
</system>

And in a file in Configuration/BulletPattern/

<bullet_pattern name="TestVariablePattern">
	$TestOuterVar SPEED=500
</bullet_pattern>

And in a file in Configuration/BulletPatternVariables/

<var name="TestOuterVar">
  <bullet angle="0" speed="0">
    <loop iterations="5">
      <spawn>
        <bullet_pattern>
          $TestInnerVar A1=45 A2=-45
          $TestInnerVar A1=-45 A2=45
        </bullet_pattern>
      </spawn>
      <wait time="0.1" />
    </loop>
    <die />
  </bullet>
</var>

<var name="TestInnerVar">
  <bullet angle="[A1]" speed="[SPEED]" shot_type="BulletBentEnergyRed">
    <wait time="0.5" />
    <loop iterations="5">
      <change angle="[A2]" time="0.0001" />
      <wait time="1" />
      <change angle="[A1]" time="0.0001" />
      <wait time="1" />
    </loop>
    <die />
  </bullet>
</var>

Now let's trace what's going on:

Massively more confusing than the examples of the data-chunk files, right? Well, welcome to the neighborhood, it's at least as bad as it sounds.

  • There's a system (TestWeapon) with special_bullet_patterns="TestVariablePattern" . This tells it to ignore a lot of its normal firing logic and instead "do whatever that pattern tells you" whenever it fires.
  • In TestVariablePattern's definition, it references the template "TestOuterVar" and passes in the value "500" for the parameter "SPEED"
    • the 500 could have been hardcoded later on, but this allows multiple patterns to use this behavior with different bullet velocities without extra copy-and-paste
  • In TestOuterVar's definition, it:
    • creates a single "starter" bullet with no velocity (it's still visible in this example, but that's probably not desirable), which does the following five times:
      • spawn another bullet pattern, whose description references the template "TestInnerVar" twice, each time with different parameter values for A1 and A2
        • Again, the angles could have been hardcoded, but then the code in TestInnerVar would have to be written twice: once for each different set of values. Code duplication is the enemy!
      • waits a tenth of a second (before going back to the beginning of the loop)
    • and then the starter bullet dies
  • In TestInnerVar's definition, it:
    • creates a BulletBentEnergyRed bullet with angle = A1 and speed = SPEED (note: TestOuterVar doesn't have to pass SPEED in, that's already defined), which then:
      • travels at that course and speed for half a second
      • changes angle to A2 (instantly, that's the time="0.0001"
      • travels at that course and speed for a full second
      • changes back to A1
      • travels at that course and speed for a full second
      • switches back and forth four more times
      • dies

The overall result is that it fires two strings of bullets 45 degrees on either side of the line to the target, and the lines "crisscross" five times before disappearing.

IMPORTANT NOTE: the use of the template variables was completely optional and has no bearing on the actual xml schema: those just cause a bunch of text replacement when the xml is being read in. Here's how the file in Configuration/BulletPattern/ would have looked without any template vars, and also the actual xml text that the game would have _seen_ in the main parsing in the TestVariablePattern case:

<bullet_pattern name="TestVariablePattern">
  <bullet angle="0" speed="0">
    <loop iterations="5">
      <spawn>
        <bullet_pattern>
  <bullet angle="45" speed="500" shot_type="BulletBentEnergyRed">
    <wait time="0.5" />
    <loop iterations="5">
      <change angle="-45" time="0.0001" />
      <wait time="1" />
      <change angle="45" time="0.0001" />
      <wait time="1" />
    </loop>
    <die />
  </bullet>
  <bullet angle="-45" speed="500" shot_type="BulletBentEnergyRed">
    <wait time="0.5" />
    <loop iterations="5">
      <change angle="45" time="0.0001" />
      <wait time="1" />
      <change angle="-45" time="0.0001" />
      <wait time="1" />
    </loop>
    <die />
  </bullet>
        </bullet_pattern>
      </spawn>
      <wait time="0.1" />
    </loop>
    <die />
  </bullet>
</bullet_pattern>

Node Types and Attributes

var

this is a template variable that can be referenced elsewhere to save effort. Can only be defined in files in Configuration/BulletPatternVariables/

attributes
  • name (string)
    • must be unique, this is how it's referenced
sub-node(s)
  • any
    • the game just basically copy-and-pastes it into whatever referenced it, after replacing any parameter names (enclosed in square brackets) with their values in that context
IMPORTANT NOTE

the syntax for referencing a variable is to have:

  • a $ as the first non-whitespace on a line
  • followed immediately by the name of the variable
  • followed by zero or more:
    • one space
    • followed immediately by a parameter name (alpha-numeric, starts with a letter)
    • followed immediately by an equal sign
    • followed immediately by the parameter value (alpha-numeric, most symbols probably work, no spaces)

bullet_pattern

this is the main thing being defined, but the node can also be used within a bullet's spawn sub-node

attributes
  • name (string, required unless this is within a spawn node)
    • Must be unique across all BulletPattern's being loaded by the game
sub-node(s)
  • bullet

bullet

this is the main point of defining anything, and corresponds to a single GameEntity spawned by the firing system

attributes
  • angle (float)
    • the angle of the shot's initial course, relative to the angle to the target (or to the angle of the shot spawning this, if this is a nested pattern)
  • speed (float)
    • the speed of the shot's initial course
  • dumbfire (bool, optional)
    • the shot's initial angle is relative to the firing ship's rotation, rather than to the angle to the target
  • shot_type (GameEntity name, optional)
    • if set, makes this shot this entity type, rather than whatever the system normally produces
  • damage_type (DamageType, optional)
    • if set, makes this shot do this kind of damage, rather than what the system specifies
  • interval_mult (int, optional)
    • if > 1, makes the pattern only do this bullet every N times. So if it this is 3 then this bullet entry will be processed on the system's 1st firing, 4th firing, 7th firing, etc
  • requires_difficulty_at_least (DifficultyType, optional)
    • If the difficulty is set lower than the specified one, this bullet does not fire.
  • requires_difficulty_at_most (DifficultyType, optional)
    • If the difficulty is set higher than the specified one, this bullet does not fire.
  • damage_mult (float, optional)
    • multiplies the damage done by the shot
  • behavior (FlockBehaviorType, optional)
    • makes the shot use the designated behavior, for example PathfindingAttacker, instead of normal shot movement logic; note that this will tend to override any angle/etc setting in the pattern
  • requires_parent_scale_less_than_or_equal_to (float, optional)
    • if the firing entity's scale (visual size multiplier) is currently greater than this, the bullet entry is not processed
  • requires_parent_scale_greater_than_or_equal_to (float, optional)
    • if the firing entity's scale is currently less than this, the bullet entry is not processed
  • requires_parent_health_percent_less_than_or_equal_to (float, optional)
    • if the firing entity's health percent (expressed between 0 and 100) is greater than this, the bullet entry is not processed
  • requires_parent_health_percent_greater_than_or_equal_to (float, optional)
    • if the firing entity's health percent (expressed between 0 and 100) is less than this, the bullet entry is not processed
  • requires_firing_system_range_to_player_less_than_or_equal_to (float, optional)
    • if the firing entity's range to the player is greater than this, the bullet entry is not processed
  • requires_firing_system_range_to_player_greater_than_or_equal_to (float, optional)
    • if the firing entity's range to the player is less than this, the bullet entry is not processed
  • is_invisible_and_does_not_collide_with_ships (bool, optional)
    • the shot does not render and does not collide with ships; still moves normally and can collide with terrain
      • this would be useful for a bullet that should spawn something when it either expires from duration or hits a wall
  • on_death_ability_explosion_radius (int, optional)
    • if > 0, the size of the shot-clearing pulse when this shot is removed from the game
  • spawns_offset_from_firing_entity (ArcenPoint, optional)
    • sets the origin of the shot relative to the center of the firing entity. Primarily useful for quasi-melee weapons
  • moves_with_firing_entity (bool, optional)
    • the shot maintains its position relative to the firing entity, as that entity moves around. Primarily useful for quasi-melee weapons
  • rotates_around_firing_entity (bool, optional)
    • the shot rotates with the firing entity, combined with the previous flag it updates its position to also stay constant relative to the firing ship's central axis (so if it's to the upper right, and you do a 180, it will be to the lower left on the screen)
sub-node(s)
  • modifier, wait, die, change, spawn, spawn_entity, loop

Note: all of these except "modifier" are "actions", and happen in sequence after the shot's creation. "modifier" nodes can be anywhere in the list, but their order is not significant (for consistency please put them all at the top of the node body, above all actions)

wait

attributes
sub-node(s)

die

attributes
sub-node(s)

change

attributes
sub-node(s)

spawn

attributes
sub-node(s)

spawn_entity

attributes
sub-node(s)

loop

attributes
sub-node(s)

Starward Rogue XML Documentation Main