This record describes API changes and additions in 1.8 Alpha 3.

Items

Reference Text

Devices and armor have a line of reference text which is designed to provide the player with key numerical stats about the item. In API 38 you can override this reference line in a couple of way:

  • Specify a language element with id: core.reference. See: https://ministry.kronosaur.com/record.hexm?id=72242.
  • Add a <GetReferenceText> event. If this event is present, it override others. The event should return a reference string. The event defines gItem and gSource (though the latter may sometimes be Nil).

Enhancements

The +hpBonus enhancement can be used to specify damage type resistance for armor and shields. Simply use the syntax: +hpBonus:{damageType}:{bonus}. See also: https://ministry.kronosaur.com/record.hexm?id=73473

Enhancer Items

Some items are defined as enhancements on other items. For example, field crystals are items that enhance shields. These kinds of items use the enhancement= parameter to define the enhancement that they confer.

In API 38, you can use the <EnhancerItem> sub-element:

<ItemType ...>
   <EnhancerItem enhancement="+hpBonus:50"/>
</ItemType>

The above item can be used with objAddItemEnhancement to confer the enhancement on some item.

OnDocked Event

When a ship docks, any items carried on the ship (installed or not) get an <OnDocked> event. The parameters for the event are:

  • gSource: The ship.
  • gItem: The item.
  • aObjDocked: The ship.
  • aDockTarget: The object that the ship docked with.

Armor

Regen Type

For regenerating armor, the regeneration can come from different methods. For example, you can specify photoRepair="true" to indicate that regeneration is tied to solar power. Or you can specify chargeRegen="true" to indicate that regeneration consumes charges on the armor.

In API 38, all of these different methods are specified with the regenType= parameter:

regenType="charges"      -> Regenerate from charge
regenType="healer"       -> Regenerate from healer (for bioships)
regenType="photoRepair"  -> Regenerate from solar power
regenType="shields"      -> Regenerate by consuming shields
regenType="standard"     -> Normal regeneration

This new method is more intuitive, since it implies that armor can only have one method of regeneration (e.g., you can't have photoRepair and chargeRegen at the same time). This was true in the old method, but the result of specifying two or more methods was unspecified.

API 38 also introduces regenType="shields". This method consumes 4 hit points of shields for every hit point of armor regenerated.

Armor Drop

When a ship is destroyed, there is a chance that installed armor will drop as loot in the wreckage. The chance that any one segment will drop is proportional to the chance of having a wreck in the first place.

If there is a 0% chance of wreckage, the chance that any one armor segment will survive is 0%. If the chance of wreckage is 100%, then the chance that any one armor will survive is 50%.

For surviving armor, we use the following algorithm:

  • If the armor is 5% damaged or less, and if it is not virtual, then it drops intact (undamaged).
  • If the armor is virtual and it has components, then any non-virtual components drop proportionally to the armor integrity, but never more than 80% probability.
  • If the armor is virtual but has no components, then it never drops.
  • If the armor is not virtual but has components, then there is a 50% chance that it will drop component as above.
  • If the armor is 75% damaged or more, then it never drops.
  • Otherwise, a damaged segment drops.

Relative Install/Repair Cost

Armor has a default install and repair cost, based on armor level. In previous versions you could override this with an absolute value. For example, repairCost="10" define the armor as costing 10 credits per hit point to repair.

In API 38, you can specify a cost relative to the default cost for the level. You must prefix the cost with + or - to indicate the percent increase or decrease over the default cost.

For example, repairCost="+50" means that it costs 50% more than the default price to repair armor.

Devices

OnDestroyCheck

Devices now get an <OnDestroyCheck> even when the ship they are installed on is about to be destroyed. If the event returns Nil, then destruction is avoided. The event can do things like repair armor or teleport the ship.

The event gets the following arguments:

  • gSource: The ship about to be destroyed.
  • gItem: The installed device.
  • aDestroyed: The object that caused the destruction.
  • aOrderGiver: The object that controls aDestroyer (could be the same).
  • aDestroyReason: The method of destruction.

Device Drop

The chance that an installed device will drop as loot in the wreckage of a ship is equal to the chance of having a wreck, but never more than 50%. For devices that drop, the algorithm is as follows:

  • If a device is virtual and has components, then we drop non-virtual components, each with probability 56% (if the device is damaged, the component drop probability is 28%).
  • If a device is not virtual and has components, and if it is undamaged, then it will drop intact 20% of the time; 40% of the time it will drop damaged, and 40% of the time it will drop as components (as above).
  • If a device is not virtual and has components and is damaged, then 50% of the time it will drop as components (each component has a 28% chance of dropping). 40% of the time, it will not drop at all, and 10% of the time it will drop damaged.
  • If a device is virtual but does not have components, then it never drops.
  • For non-virtual, non-component devices, 20% of the time, the device drops as is (either damaged or undamaged depending on its state). The other 80% of the time, if the device is undamaged, it drops damaged. Otherwise, it never drops.

Shields

Regen Type

Just as with armor, you can specify regenType= on shields to alter the normal shield regeneration algorithm. The only values supported are:

  • byShieldIntegrity: With this type, regeneration is proportional to shield level. When shields are down to 50%, regeneration proceeds at the normal rate (specified by regen=). When shields are down to 0%, they regenerate at 10% the normal rate. When they are at 100%, they regenerate at 200% the normal rate.
  • standard: This is the normal regeneration system.

Aimed Reflection

In API 38 you can set aimedReflection="true" to specify that any reflected damage is aimed at the nearest enemy ships. This only works for shields that reflect damage.

Weapons

OnDestroyObj Event

Weapons now get an <OnDestroyObj> event when an object is destroyed by a shot from the weapon. The event gets the following arguments:

  • gSource: The ship with the weapon.
  • aObjDestroyed: The object that was destroyed.
  • aDestroyer: The ship with the weapon.
  • aOrderGiver: The object that orders the ship.
  • aWreckObj: The wreck created (if any).
  • aDestroyReason: The method of destruction.

Variable Fire Rate

Missiles and weapon variants can now override the fire rate by setting their own fireRate= parameter.

Enhancer Device Class

Scalable Armor

The <EnhancerDevice> is now scalable. Use the <Scaling> sub-element to specify a list of enhancement entries, each with a level.

<ItemType ...
   level="2-8"
   >
   <EnhancerDevice ...>
      <Scaling>
         <Enhance level="2" criteria="..." enhancement="..." powerUse="..."/>
         <Enhance level="3" criteria="..." enhancement="..." powerUse="..."/>
         ...
         <Enhance level="8" criteria="..." enhancement="..." powerUse="..."/>
      </Scaling>
   </EnhancerDevice>
</ItemType>

For attributes that do not change from level to level (usually, criteria) you can move those up to the <EnhancerDevice> element:

...
<EnhancerDevice criteria="...">
   <Scaling>
      <Enhance level="2" enhancement="..." powerUse="..."/>
      ...
   </Scaling>
</EnhancerDevice>

Enhancing Armor

Devices can now enhance armor. For example:

<ItemType ...
   >
   <EnhancerDevice ...>
      <Enhance criteria="aI" enhancement="+hpBonus:laser:50"/>
   <EnhancerDevice>
</ItemType>

Level Check

API 38 adds a levelCheck="true" option to <EnhancerDevice>. If set to true, the enhancer only works if the item being enhanced is at least the same level as the enhancer device.

This is mostly useful for scalable devices, where the level of the enhancer device is not constant.

Ships

Thrust

Starting in API 38, thrust will be specified such that 1 unit of thrust is sufficient to accelerate a 1 ton mass to 1,000 km per second in 1 tick (2 game seconds). This is equivalent to a force of 500 million newtons.

1,000 km per second is approximately 0.33% of lightspeed. At that acceleration, you will reach 20% of lightspeed in 60 ticks, or 2 real seconds.

This matches the current definition of thrust ratio, in which a thrust ratio of 1.0 implies a thrust sufficient to accelerate the ship to 1,000 km per second in 1 tick.

With this new interpretation, you can specify thrust equal to mass to get a thrust ratio of 1.0. This is particularly helpful for drive devices, which generally cannot specify a thrust ratio.

In previous versions, 1 unit of thrust had double the acceleration of the new unit. Thus, in previous versions you needed only 50 units of thrust to get a thrust ratio of 1.0 for a 100 ton ship. [In API 38 you need 100 units.]

Extensions using previous APIs will retain the old units, but whenever you update to use API 38, you must change your thrust values (multiply by two).

Lastly, I'll note that an acceleration of 500 km per second squared is equal to more than 50,000 Gs. This is done entirely for game mechanics purposes (otherwise, everything would take too long to accelerate). We assume that in-universe real accelerations are much lower (1 G for thrust ratio 1.0), which would still allow for relatively fast interplanetary travel.

Fire Arc

When defining the fire arc for a weapon, previous versions specify the minimum and maximum fire angle with minFireArc and maxFireArc. In API 38, you can also specify it with the single parameter fireArc. This is the fire angle arc centered on the position angle posAngle.

For example, if a weapon is at posAngle="90" and fireArc="30", then the weapon will fire from 75 degrees (90 - 15) to 105 degrees (90 + 15). You can optionally use the fireAngle= parameter to center the arc at a different angle from posAngle.

GetHullPrice Event

A ship can have a dynamic hull price by implementing the <GetHullPrice> event. This event should return the hull price in the ship's default currency. The arguments are:

  • gSource: The ship.
  • aCurrency: The ship's default currency.
  • aPrice: The current hull price (if set in XML).

Stations

Hull

Stations usually define their armor as parameters on the root element. In API 38 you can specify hit points, armor type, etc. on a sub-element called <Hull>. For example:

<StationType ...
   >
   <Hull
      armorID="..."
      armorLevel="..."
      hitPoints="..."
      regen="..."
      />
</StationType>

This allows you to specify all the relevant parameters in one place. In addition, you can specify armorLevel=, which is used for scalable armor. Lastly, when using <Hull>, multiHull="true" is implied and need not be explicitly added.

Dock Ports

Docking ports on stations can be specified by angle and radius. For example:

<StationType>
   ...
   <DockingPorts>
      <Port posAngle="90" posRadius="10" .../>
   </DockingPorts>
</StationType>

The origin use is always the center of the station. Under certain cases, however, it would be useful to specify a different origin. For example, the image might have circles offset from the center.

In API 38 you can specify an origin on each <Port> element:

...
<Port posAngle="90" posRadius="10" originX="-10" originY="20"/>
...

The above shifts the origin to the given spot relative to the center (in Cartesian coordinates).

[Note, however, that shipRegen= still belongs on the root element.]

Missions

  • Added 'priority property for missions.
  • Added P option for msnFind to return the mission with the highest priority.

Dock Screens

Custom Picker Improvements

A customer picker list requires a list of entries to display. In previous versions, each entry consisted of a list of elements, with each element represented something about the row, such as the icon or the title.

In API 38, you can use a struct to specify the list entry. The struct may have the following fields:

  • title: This is the title to display in the list entry.
  • icon: This is an image descriptor indicating the icon to show on the entry.
  • desc: This is the long description.

You may return a list of struct entries in <OnDisplayInit>. For example:

<DockScreen...
   <Display type="customPicker"
      rowHeight="80"
      iconWidth="128"
      iconHeight="80"
      iconScale="0.7"
      >
      <OnDisplayInit>
         (list
            {  title: "First entry"
               icon: ...
               desc: ...
               }
            {  title: "Second entry"
               icon: ...
               desc: ...
               }
            ...
            )
      </OnDisplayInit>
   </Display>
</DockScreen>

Note also that we've added some parameters to control scaling of icons. These are:

  • iconWidth: iconWidth and iconHeight define the size of the icon in the list entry. The icon is scaled (proportionally) to fit inside the given box.
  • iconScale: This tells the engine to shrink or grow the icon before displaying. If this parameter is specified, we use this instead of the scale implied by iconWidth and iconHeight. However, we still use iconWidth and iconHeight to define the box in which the icon paints. The icons will be centered on the box.

TLisp

  • Added additional math functions: acos, asin, atan, cos, exp, log, sin, tan.
  • Added damageDesc property for ships. This returns a struct with up to three fields: armorIntegrity, shieldLevel, and hullIntegrity. These are values from 0 to 100, where 0 is destroyed and 100 is undamaged. The last two are only available if appropriate.
  • fmtNumber now takes regenRate as a number type. This formats an integer (or double) as a regeneration rate (in units of hps per 180 ticks). It returns a value in hps per seciond, such as, "1.5 hp/sec".
  • The hp property on ships can now be set. This will distribute the hit points proportionally across all armor segments (including armor in attached sections). It does not include interior hit points.
  • Added objSendMessageTranslate. Instead of a message, it takes a text ID value, which it looks up in the language block of the sender. If the sender is Nil then we look it up in the language block of the receiving object.
  • Static data is now returned as a property as long as it does not conflict with other properties.
  • aWeaponLevel is now defined in all events that have aWeaponType. This is useful for scalable weapons.
  • Added noDeterminer flag for itmGetName (and others). When used, nouns never have an article or count, but they are pluralized if necessary.
  • Added noQuotes flag for itmGetName, which converts all double-quotes in the item name to single quotes. Use this when display items names in quoted dialogue.
  • Added hasDebrief property for missions.
  • xmlGetAttrib now returns a number if possible.
  • Added hasUseScreen property to items. Returns True if using the item brings up a dock screen.
  • Added canBeUsed property to items. This works with objGetItemProperty to return True if and only if the item can currently be used. It checks the same conditions as the Use menu.
  • Added scrShowItemUseScreen, which programmatically shows the item's use screen. It only works on items that show a dock screen; this is equivalent to using such item from the menu.