Starward Rogue:XML - GameEntity Definitions

From Arcen Wiki
Jump to navigation Jump to search

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

These are things that go directly on the entity node, in the format attribute=”value”. So in the code <entity name="Goldbug">, name is the attribute and Goldbug is the value for that attribute.

Most Important General

  • name (string)
    • All entities must have a name. The name for an entity must be absolutely unique from any other entities in the game, no matter what file they are in.
    • The name is actually more of a “primary key” identifier, and it’s not something players would ever see.
      • “SDT#$S” is a perfectly valid name if you want, although it’s a super unhelpful one so please don’t do it.
    • By default, the image for any entity is based on its name. This can (and often should be) overridden, however -- the image_name property does that.
      • Ships:
        • By default they will use the image RuntimeData/Images/Ships/yournamehere
      • ItemPickups:
        • By default they will use the image RuntimeData/Images/Items/yournamehere
      • Shots:
        • By default they will use the image RuntimeData/Images/Shots/yournamehere
        • It’s unlikely you will ever define a shot, however. You’ll define bullet patterns and systems and ships, but all a shot is is a graphic and a collision box. You’ll reference those, but not define them.
          • The systems and bullet patterns denote how shots move, what their damage is, speed is, etc, etc, etc.
      • Obstacles:
        • It’s really complicated how these use the images, and tends to be very tileset-dependent, which is not something in the purview of what you’re really designing here. That’s more to do with environment than enemies/items.
  • category (GameEntityCategory)
    • Oi! What is this thing? Depending on what you say, it will be parsed differently.

Ship-Only Stuff

  • display_name (string)
    • THIS is what the player sees as the “name of the ship.”
  • acceleration (float)
    • How fast the ship moves from speed zero to its max speed. Does not impact deceleration speed. Default: insta-accelerates (0).
  • acceleration_seconds (float)
    • This is kind of a cap on the amount of time it will take to hit max speed. If you want to make sure it hits max speed within 2 seconds no matter what, set this to 2, for instance. Then it can accelerate more slowly at first, and then suddenly jump to top speed at the 2 second mark. Default: no limit (0).
  • deceleration (float)
    • How quickly the ship will stop when it wants to stop. Most useful for player ships. Default: insta-decelerates (0).
  • speed (float)
    • What is the maximum speed this ship can move at? This is measured in pixels per second, or thereabouts.
  • max_shield (int)
    • How many shots can the ship completely block per room. Each shield point block one shot of any magnitude and then that block disappears.
  • ship_category (ShipCategory)
    • Determines a lot about how the ship is seeded.
  • movement_particle (particle_pattern, optional)
    • this ship emits this particle while moving
AI-Only Ship Stuff
  • rotates_to_face_firing_direction (bool)
    • Whenever the ship fires, the ship instantly faces the direction of the target Default: false
  • passive_rotation_speed (float)
    • A passive rotation that happens over time, having nothing to do with movement. Default: false
  • behavior (FlockBehaviorType)
    • Determines the way that the ship will act, at least to start off with (something could change that later in the life of the ship). Default: Attacker
  • seeds_directly_in_rooms (bool)
    • Default true. If this is set to false, then the enemy will not naturally show up in the game! This is normally bad, right?
    • The main purpose of this is for multi-stage enemies. With those, when one enemy dies, it turns into another enemy type. If you don’t want that second enemy type showing up except via this process, then set this property to true.
    • TLDR: this is typically true on the later stages of enemies, but omitted everywhere else.
  • familiar_type (FamiliarType)
    • For familiars that hang out around the player (or behave like normal ships, if set that way), there are different movement patterns that they can use. Default: None.
  • damage_per_second_from_touching (float)
    • If a player is touching this ship, how much damage per second does that cause to the player? Default: 10.
Low-Importance Ship-Only Stuff
  • description (string)
    • We’re not really using this much. But for ship hulls, we can use this to give players a description of what the pros and cons of that ship hull is. Overall ignore.
  • exhaust_offset (int)
    • This is an int that defines how far forward or backward the exhaust is from the ship. Default 0.
  • strafing_time (float)
    • If this is set, then every time the ship fires, it loses the ability to steer for this amount of time, and will just continue on at max speed during that interval. Default 0.
    • This was used a lot in TLF for ships that would do “strafing runs” past the player and then would wheel around in a slow arc and come back. But because the slow-arc style of ship movement is not in SR (because walls), this doesn’t really make as much sense conceptually.
      • Could still be interesting, though, for making an enemy that goes zipping past you while firing, and then has to regroup and turn back around. Would probably only work well with systems on the ship that fire when they have line of sight on the player or else this ship might just always be going nuts.
  • never_renders (bool)
    • The ship is… invisible? Default false.
    • This is really useful if you want to have an invisible, invincible ship that does something like spawn enemies. Though honestly, this is a relic from TLF where stuff spawned offscreen from out of empty space, and here it would probably make more sense to have a visible spawner.
  • never_stops_shots (bool)
    • Funky! Rather than shots hitting this and dying, any shots that hit it stay alive and just keep moving. Default false..

Any Type Of GameEntity Stuff

  • max_health (int)
    • How much health does this thing have?
      • For the player, each box in the health bar is 2 health points. So 1 damage is half a block, 2 is a whole block, etc.
    • For enemies, they have VASTLY larger amounts of health, and the player does more damage, too. Average enemy healths might be more like 100 early in the game, whereas an equivalent player health might be 6.
      • The reason for this is based around how players can hit enemies repeatedly and there’s no break between when the player can hit them, versus the players are immune to damage for a short while after taking a hit (during the period of the red flash of showing damage).
  • image_name (string)
    • Normally the name of the entity is what is used to find the image for the entity. This lets you override that logic.
    • The two particularly-relevant cases:
      • Ships:
        • When you set this, they will use RuntimeData/Images/Ships/image_name
      • ItemPickups:
        • When you set this, they will use RuntimeData/Images/Items/image_name
  • image_folder (string)
  • This can be used with or without image_name. Often it is used without image_name.
  • For organizational purposes, it’s nice to be able to put graphics into arbitrary subfolders. So for instance, we have an Enemy_Bosses subfolder inside the Ships folder.
  • To make sure that our entity looks for an image in there, we just set image_folder=”Enemy_Bosses” and that’s it.
  • You can do folders-in-folders if you want, too, and then have a forward slash (/) separating those out.
    • Make sure to always use forward slashes when referencing filenames. If you’re working on windows it will work with a backslash, but then someone running this on osx or linux will have it fail.
  • flies_through_obstacles (bool)
    • Is this thing able to move straight through non-wall obstacles? Default false.
  • on_pickup_grants_item: ~*~
    • CHRIS_TODO: to come back to later, once a few more changes are in.
  • on_pickup_grants_health (bool)
    • When this thing dies, does it give health to the player? Default: false
  • on_pickup_grants_amount (int)
    • Used with several other on_pickup properties. Default 0.
    • With on_pickup_grants_health: this specifies how much health the player gets.
  • wall_collision_reduction (int)
    • If you are looking at the collision data for entities (hit F7), you’ll notice that the red circles are the hitboxes where the entity collides with other entities.
    • But the big blue square box is what it uses in order to collide with walls, because of the nature of rotating multiple circular hitboxes and so on. The blue box is “pessimistic” in order to make sure that it doesn’t look like the enemy is clipping into walls normally, but sometimes it can be too pessimistic.
    • TLDR: if you want to shrink that blue box, then you can use a positive integer here. Default 0.
  • immune_to_all_damage (bool)
    • I’m invincible! ...You’re a looney. Default false
  • on_death_ability_explosion_radius (int)
    • When I die, how big of a shot-clearing explosion do I make? Default 0.
    • Note that this does not hurt entities except for clearing shots it touches.
  • periodic_movement_mode_interval_min (float)
    • If there is one or more periodic movement modes assigned to this entity (via sub-nodes), then what is the minimum interval of time (in seconds) between invocations of one of those modes? Note that during a mode being active, it won’t cause this to count down. Default 0.
  • periodic_movement_mode_interval_max (float)
    • Same deal as above, but this is the max interval between choosing the modes. It does rand(min,max) as you might expect.
  • on_death_transforms_into (string)
    • When this thing dies, does it instead turn into something else? For multi-stage enemies or obstacles, this is how you go from one stage to the next. The string here should be the name of the other entity. Default blank.
  • particle_on_death (particle_pattern, optional)
    • this ship emits this particle when dying
  • familiars (comma-delimited strings list)
    • This is the list of entity names in the format “name1,name2” and so on of any familiars the ship might have by default. Most will not have any, but some enemies might have some built in. Who knows!
  • sounds_on_takes_damage (comma-delimited strings list)
    • If this entity takes damage from a shot hitting it, then one of the sounds in the list will be played at random.
  • sounds_on_death (comma-delimited strings list)
    • If this entity dies, then one of the sounds in the list will be played at random.
  • shader (ShaderType)
    • The type of shader that will be used to draw the entity. Generally you’ll want to use Normal, but Additive can be quite interesting also.

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
periodic_movement_mode

This is a large enough subject that it is defined here in its own section: Starward_Rogue:XML - PeriodicMovementModeType Definitions


Starward Rogue XML Documentation Main