Files

9.7 KiB

Property Files

A few files don't have an archive format, and instead are flat files consisting directly serialized tables.

Texture Properties (textprop.dat)

This file contains a single table of texture property entries, after a header.

The table appears to be truncated. Since the game only uses 273 textures, this may have never been detected. The file has 4004 bytes on disk, meaning 4000 bytes are available for the table. In a test, the original engine appeared to be fine to read a smaller file with exactly 273 entries (3007 bytes) - which had the unknown fields set to zero.

The original source explains the difference: The texture property system would support up to 400 textures. It also assumed a property structure size of 10 bytes (hardcoded value), while the actual structure is 11 bytes long. In other words, one could feed the engine more than 273 textures, yet no more than 363. More than 363 would simply be ignored and the extra textures would just have their default properties. This also explains why the Mac port reads exactly 363 textures, as reading more would exhaust the file.

Header

The file starts with a 4-byte header.

Texture Properties File Header (4 bytes)

0000  int32    file version number, value 0x09

The engine rejects a properties file with a different version number.

Properties Entry

Texture Property Entry (11 bytes)

0000  byte     family (unused)
0001  byte     target (unused)
0002  sint16   resilience (unused); Default: 10 
0004  sint16   distance modifier; Default: 0
0006  byte     Climbable. 0x00: not climbable; != 0x00: wall can be climbed (original name: friction)
0007  byte     friction walk (unused); Always 0x00
0008  byte     Transparency control (original name: force_dir)
0009  byte     Animation group
000A  byte     Animation index - if texture is animated

The two bytes at the beginning (family and target) almost always are each set to the low-byte of the index. A few exceptions have both bytes 0x00. Since they are unused, it is unclear what they mean.

The resilience is nearly always 0x0A; The one existing exception has it 0. Since it is unused, it is unclear what it means.

The distance modifier always zero. It is used in the renderer to determine which texture resolution to use, based on distance from the camera. A higher modifier causes the smaller resolutions to be chosen at larger distances; A negative value causes an earlier switch.

See Texture Animation for details on animated textures.

Transparency Control

0x00  Regular texture; transparent pixel (palette index 0x00) are drawn black
0x01  Space texture (pixel data of image is ignored)
0x02  Texture with space background for transparent pixels

Object Properties (objprop.dat)

The object properties file contains several tables about properties of level objects. It has the following format:

| Header | Class 0 Tables   | Class 1 Tables     | ... | Common Table |

Header

The file starts with a 4-byte header containing the version number.

Object Properties File Header (4 bytes)

0000  int32   file version number, value 0x2D

The engine rejects a properties file with a different version number.

Class Tables

For each object class, one entry exists with a table of class-generic properties and a further table, subclass-specific:

| Class N Tables                                           |
| Generic | Subclass 0   | Subclass 1   | ... | Subclass N |

The sizes of the generic and specific tables are dependent on the object class, subclass and type amount. The generic table contains one entry per object type of this class. The specific tables contain one entry per object type of the subclass.

See Level Objects for an overview of the amount of types and their entry sizes.

Common Table

At the end of the file is the table with common properties. For each object type one entry.

Common Object Properties (27 bytes)

0000  int32    Mass
0004  int16    Default hitpoints
0006  uint8    Armour
0007  byte     Render type
0008  byte     Physics type; 0x00: none (insubstantial), 0x01: regular, 0x02: special
0009  byte     Hardness; 0..253
000A  byte     Unused; Internally called "pep", this value appears to not be used by the engine.
000B  byte     Physics XR; 0..253
000C  byte     Unused; Internally called "physics_y". These values are set (almost) identical to 000B and have no effect.
000D  byte     Physics Z; Set to 0x30 for all barriers (10/x/x).
000E  byte     Vulnerabilities
000F  byte     Special vulnerabilities
0010  [2]byte  Unused
0012  byte     Defence value
0013  byte     Toughness; 0x03: Invincible
0014  int16    Flags
0016  int16    MFD/Mesh ID
0018  [2]byte  Bitmap 3D field model index
001A  byte     Destruction effect

Physics type governs how collisions shall be handled. 0x00 makes the object insubstantial, ignoring forces applied to it. For instance, most scenery stays where it was put. 0x01 is for regular objects meant to react "normal" in a physical world. 0x02 behaves strange is set for exactly one object (14/0/6, "SONIC THE HEDGEHOG", an unused critter). Objects with a physics type of 0x02 aren't affected by gravity for instance, but are repelled if hacker runs into them. The hardness acts as repulsion force on the object if it collides with the ground or walls - or on the hacker if hacker runs into it. Hardness depends on the mass; Objects with more mass bounce around less.

The physics xr value is applied to vertically center (animated) sprites on their position. If 0x00, the sprites are rendered with their bottom anchored at the object's position. Higher values will move the sprites downwards.

Related, the physics z value is inconsistently used as a height value. Only if this value is 0x00 (most of the time), then physics xr is used for height calculation. Still, the XR value is used far more often than the Z value.

The vulnerabilities and special vulnerabilities match the corresponding damage type fields from Generic Weapon Info.

The engine, internally, calls this field resistances, yet the code does the opposite. Furthermore, this resistances field covers the four bytes from 000E.

The field of special vulnerabilities is split up into 0x0F primary vulnerabilities (double damage) and 0xF0 super vulnerabilities (quad damage). Damage is multiplied only if the originating special force equals the vulnerabilities in these fields.

Quad damage is reduced to triple damage on difficulty level 3 (either for real-world, or cyber, wherever it is calculated).

The defence value is compared to the offence value of a weapon or projectile to determine a "critical hit" (or critical reduction). Higher defence values will decrease the damage, higher offence values will increase the damage. If it is 0xFF, then the target is invulnerable to critical hits.

The toughness determines how much damage, after most of the calculation, goes through - this still requires the object to be solid to register damage. The value of 0x03 reduces the damage to zero. Otherwise, this value is considered to be a shift factor, so a value of 0x01 halves damage, 0x02 quarters it.

This value is set to 0x04 only for the non-used SHODAN critter 14/3/5. This one would have been affected by only the strongest weapons. Probably this value was intended to be in range of 0..3 only.

MFD/Mesh ID identifies the MFD to open for this type of object, if selected from inventory. For 3D objects in the world, this value identifies the 3D mesh to render, based on resource 0x08FC.

Render Type Enumeration (1 byte)

0x01  3D object
0x02  Sprite
0x03  Screen
0x04  Critter
0x06  Fragments (e.g. the Cyberdog)
0x07  Not drawn
0x08  Oriented surface (door, wall decoration)
0x0B  Special
0x0C  Force door

Common Object Flags (2 byte)

0x0001  Useful inventory object (green font)
0x0002  Solid - can't be passed through
0x000C  Use mode (see below)
0x0010  Usable inventory object - object is triggered on double-click in inventory list
0x0020  Blocks 3D rendering if closed (set for opaque doors)
0x00C0  Light type (see below)
0x0100  Solid if closed (set for barriers and repulsor object)
0x0200  Flat solid (objects can be placed on it)
0x0400  Doubled bitmap size (set for various explosion animations)
0x0800  Destroy on contact
0x7000  Class-specific flags
0x8000  Useless object. Unless specifically marked useful otherwise, object can be removed to make room

Use Mode Enumeration (2 bit)

0x00  Pickup - items can be taken
0x01  Use - items are used, not taken
0x02  undefined
0x03  "Null" - can't be used

Light Type Enumeration (2 bit)

0x00  Normal, simple lighting
0x01  Complex lighting
0x02  Ignore darkness
0x03  Deferred light type (instance-specific)

Bitmap 3D Bitfield (2 byte)

0x03FF  Bitmap number low mask
0x8000  Bitmap number high mask
0x0400  Animation
0x0800  Repeat
0x7000  Frame number mask

Object Destruction Effect (1 byte)

This byte is a bitmask field with the following layout:

0x1F    Animation frame index -- refers to different types of animations
0x20    Play destruction sound
0x40    Play destruction sound (not used in main game)
0x80    Actual explosion (with damage) -- requires Animation frame index to be 0x0F

Some objects have their "private" destruction sounds and have none of the sound bits set. The actual explosion, set for larger electrical appliances, works only if the full value is 0x8F.