Starward Rogue:XML - GameEntity Definitions
Contents
- 1 Overview
- 2 Attributes
- 3 Sub-Nodes
- 3.1 An Example
- 3.2 system (default schema)
- 3.3 system (alternate schema for when you want random variation in enemies)
- 3.4 hitbox
- 3.5 stacked_image
- 3.6 room
- 3.7 periodic_movement_mode
- 3.8 PeriodicMovementModeType.InsaneThroughWallCharge
- 3.9 PeriodicMovementModeType.ShadowDash
- 3.10 PeriodicMovementModeType.FreakOut
- 3.11 PeriodicMovementModeType.Reposition
Overview
A lot of these things cross over between any type of entity, and some things are specific to only certain entity types (ships only, or shots only). So we're going to break it out like that, with specific notes for each section as relevant.
An example
<entity name="Goldbug" display_name="Goldbug" behavior="Stationary" category="Ship" speed="0" turning_resistance="2.25" max_health="50" image_folder="Enemy_Stationary" > <system type="Goldbug" offset="0,0" /> <hitbox radius="32" /> <stacked_image src="Attachments/TarraCrawlerArm" size="60" offset="-20,20" /> <modifier target="MyShots" type="RicochetsOffTerrain"/> </entity>
Note that the above is all one xml node (entity) with a bunch of attributes, until you get down to the end carat (>). Then the next line has a self-terminating hitbox node (self terminating means it does <hitbox/> rather than having <hitbox></hitbox> -- you self-terminate nodes if they don’t have any sub-nodes). There’s then a stacked_image node, and a modifier node, all of which are sub-nodes of the entity.
Attributes
Most Important General
Ship-Only Stuff
Low-Importance Ship-Only Stuff
Any Type Of GameEntity Stuff
Low-Importance Stuff For Any Type Of GameEntity
ItemPickup-Only Stuff
Sub-Nodes
Until now, everything has been talking about attributes right on the entity node itself (so <entity attribute=”data”></entity>). Now we’re going to talk about sub-nodes that go inside the entity object, though.
An Example
From this example, there are four sub-nodes: one hitbox, two stacked_images, and one modifier.
<entity name="Goldbug" display_name="Goldbug" behavior="Stationary" category="Ship" speed="0" turning_resistance="2.25" max_health="50" image_folder="Enemy_Stationary" > <system type="Goldbug" offset="0,0" /> <hitbox radius="32" /> <stacked_image src="Attachments/TarraCrawlerArm" size="60" offset="-20,20" /> <stacked_image src="Attachments/TarraCrawlerArm" size="60" offset="20,20"/> <modifier target="MyShots" type="RicochetsOffTerrain"/> </entity>
A key thing to note about all of these sub-nodes is that they in turn also have attributes of their own. Another key thing to note is that you can have as many copies of these kinds of sub-nodes inside an entity as you want. Aka, you can have 1 hitbox or 10, as needed.
system (default schema)
Overall premise: a system attached to this ship, that can actually do something like shoot or trigger a player ability or whatever. These have locations inside the sim, but cannot collide with anything, have no concept of health, etc.
Example:
<system type="Minigun" offset="20,10" />
Attributes
- type (EntitySystem name)
- This tells it what system node to pull from the EntitySystem xml
- offset (int,int)
- This is the x,y offset of the center of the system from the center of the entity. Particularly useful when you have many systems on a single enemy.
system (alternate schema for when you want random variation in enemies)
Example:
<system offset="20,10"> <possibility type="Minigun" chance="3" /> <possibility type="TestWeapon" chance="1" /> </system>
possibility Attributes
- chance (int)
- the relative chance of that system being picked for that spot for each entity of this type being spawned
- So in this example, it has a 3-out-of-4 chance of picking minigun, and a 1-out-of-4 chance of picking TestWeapon
- Don't use on player hulls or familiars, or it will reroll every time you enter a new room
hitbox
Overall premise: this is a circular space that a ship can be shot in, or that a shot occupies and thus collides with ships via. It’s the part of the ship/shot/whatever that is “solid,” in most respects.
Attributes
- radius (int)
- This defines the radius of the red circle of the hitbox (hit F7 to see that).
- offset (int,int)
- This is the x,y offset of the center of the hitbox from the center of the entity. Particularly useful when you have many hitboxes on a single enemy.
- Note that the pessimistic blue bounding box for hitting walls will encompass all the hitboxes you define.
- incoming_damage_multiplier (float)
- a shot hitting this particular hitbox will have its damage multiplied by this before it's applied to the entity
- set to zero for immunity to damage
- negative numbers act like zero; they don't cause healing
- on_hit_triggers_systems_of_type (system)
- a shot hitting this particular hitbox will authorize this system to fire (only matters if it's got firing_timing=Never)
stacked_image
Overall premise: sometimes we want to show multiple images on top of the base image of the ship or shot or what have you. This lets us build up larger ships than we’d otherwise have, and it lets us take off pieces when we move to “later stage” copies of the ship (just remove the stacked_image entries and hitbox entries of relevance when doing that.)
Attributes
- src (string)
- This looks in the same folder that the base image of the entity is in, whatever that is. Generally speaking it’s nice to put the attachments in some sort of subfolder, and you can specify that all in this one field (as noted in the example above).
- size (int)
- What is the width (and height) of this square image? I’m honestly not positive why we care, but do set it accurately just in case.
- offset (int,int)
- This is the x,y offset of the center of the stacked image from the center of the entity. You’re presumably always going to want to set this to something.
- rotation (int)
- The number of degrees (0 to 364) that the image should be rotated from the basic orientation of the entity it is stacked on. Default 0.
- flipX (bool)
- Should we flip this horizontally? This is different from doing a rotation of 180, since this will keep it upright and mirrored rather than being upside-down.
- flipY (bool)
- Same as flipX, but in the vertical axis instead.
room
Only used for bosses, basically for boss rooms rather than picking a room of that type and then populating it, it picks a boss of the appropriate type (miniboss or boss) and then tries to pick a room that will fit the boss. The rooms that will fit are specified as room sub-nodes on the boss's entity record, like this:
Example:
<room src="Boss/CMP_BossNoWindows" buddies="SmallEnemy,SmallEnemy" />
Attributes
- src (string)
- the name of the room script to use, relative to RuntimeData/Rooms/ , and without the .txt extension.
- the room script must contain a B to seed the boss at, or it will throw an error during seeding
- buddies (list of GameEntity names, optional)
- the names of other monsters to seed with this specific setup (you can have more than one room node with the same src, and different buddy lists), at the 'U' tiles in the room script
- if the room script's number of 'U' tiles is not exactly equal to the number of buddies specified here, it will throw an error during seeding
- the names of other monsters to seed with this specific setup (you can have more than one room node with the same src, and different buddy lists), at the 'U' tiles in the room script
periodic_movement_mode
This is a large enough subject that it is defined here in its own section: Starward_Rogue:XML - PeriodicMovementModeType Definitions
PeriodicMovementModeType.InsaneThroughWallCharge
TLDR: The enemy runs at high speed through walls and everything, and then comes back to rest at the spot it started at. Gets big buff to on-touch damage.
Attributes Just For This Mode
- if only_charges_cardinal_directions, then it picks a random FourDirection and moves on that angle
- else, if only_charges_random_directions, then it picks a random angle and moves on that angle
- else, it picks the angle towards the player's current location (at the time this mode is started) and moves on that angle
- Gets a reddish hue, and then the following implicit attributes for the duration of the mode:
- IgnoresCollisionWithWallTerrain
- IgnoresCollisionWithNonWallTerrain
- And then the following implicit modifiers:
- MovementSpeed * 2
- MeleeDamage * 10
- Note: if you explicitly add DestroysTouchingNonWallTerrain, they work ok together.
- I.e.: <modifier type="NonMeleeCannotFire"/>
- To end this mode, it checks:
- when its pessimistic collision box is at least 100 distance outside the room world rect:
- instantly repositions back towards its origin to be within 100 distance
- moves back to the origin on the same modifiers, then stops the mode.
- when its pessimistic collision box is at least 100 distance outside the room world rect:
PeriodicMovementModeType.ShadowDash
The enemy picks a target point, turns invisible and invincible, moves there while ignoring collision with terrain, and reappears; optionally with a shot-clearing pulse.
Note: tries to not pick a spot where it will be colliding with terrain at the end
Attributes Just For This Mode
- chance_to_target_player (int)
- chance out of 100 to pick the player's current location (at the start of the charge) as the target point
- shockwave_radius (int)
- size of the shot-clearing pulse
PeriodicMovementModeType.FreakOut
The enemy makes random movement orders and gets big buff to movement speed, on-touch damage, and damage resistance
Attributes Just For This Mode
- max_duration (int)
- number of seconds this mode lasts
PeriodicMovementModeType.Reposition
The enemy moves to the specified tile, ignoring collision with terrain. Optionally pathfinds (as if not ignoring terrain collision).
Attributes Just For This Mode
- related_point (ArcenPoint)
- The tile to move to, in terms from the upper-left tile of the room. A tile is 64 pixels on a side at max zoom in.
- try_to_pathfind (bool)
- If true, tries to pathfind. If false or if no path found, moves straight to the target tile.