Skip to main content

Thorn Objects

Every scene contains at least three objects: a scene descriptor, monitor object and camera object.

Every object has a name that must be unique within the script. More than one object using same name will cause glitches and bugs.

These are properties common to most object types:

PropertyTypeDescription
entity_namestringThe name of the object in the scene.
typestringDenotes the object type. Options are as follows:
SCENE: Scene descriptor.
MONITOR: Target render monitor.
CAMERA: Viewport camera.
LIGHT: Light source.
COMPOUND: Compound mesh (ships, solars, etc).
DEFORMABLE: Deformable mesh (characters).
PSYS: Particle system effect.
SOUND: Sound effect.
MARKER: Marker/dummy.
MOTION_PATH: Motion path curve (ex: ship fly path).
template_namestringObject template name from catalog specific to certain types.
lt_grpintegerReceiving light group.
srt_grpintegerRender order sorting group. First to last is back to front.
usr_flgintegerSpecial flags.
For compound type: If set to 1 the object will be rendered as a static background layer. Used for starscapes, stars and such.
When used in conjunction with starsphere_generic_exclusion or similar, allows lighting/fog to set the nebula colors. (set to 2)
flagsstringLIT_DYNAMIC: Mesh receives dynamic light.
LIT_AMBIENT: Mesh receives ambient light.
HIDDEN: Object is invisible.

Flags can be summed with with + symbol.

spatialprops

PropertyTypeDescription
posfloat[3]Object position (unless attached to another object it is typically relative to scene).
orient{float[3]}[3]Rotation matrix. Use when setting up object in scene and denotes the orientation of the object.
q_orientfloat[4]Quaternion orientation. Used for animation.
axisrot{float, AXIS}Single axis object rotation. Used for animation.

When defining objects in a scene you should use the orient property to set orientation. However in the START_SPATIAL_PROP_ANIM event you should use q_orient quaternion property for animation. Alternatively if you need to rotate an object along a single axis you can simply use axisrot.

SCENE

Scene control object. Every cutscene must have only one scene object. This object is referenced by certain events and can be used to set things like fog and ambient lighting.

PropertyTypeDescription
upAXISDefault Y_AXIS.
frontAXISDefault Z_AXIS.
ambientAXISAmbient (unlit/shadow) color.
	{
entity_name = "Scene_Untitled_2",
type = SCENE,
template_name = "",
lt_grp = 0, srt_grp = 0, usr_flg = 0,
spatialprops =
{
pos = { 0, 0, 0 },
orient = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }
},
up = Y_AXIS,
front = Z_AXIS,
ambient = { 128, 128, 128 }
},

MONITOR

Cutscene render target. Every cutscene must have only one monitor object. Monitor spatial properties are irrelevant, as it is a meta object that doesn’t exist in the scene and is referred only when switching between cameras.

    {
entity_name = "Shot01_Monitor_1",
type = MONITOR,
template_name = "",
lt_grp = 0, srt_grp = 0, usr_flg = 0
},

CAMERA

Viewport camera object. A cutscene may have multiple cameras and use SET_CAMERA event to toggle between them.

PropertyTypeDescription
fovhfloatHorizontal Field of View (FOV)
hvaspectfloatHorizontal to vertical aspect ratio. Default is 1.333333 representing 4:3 display aspect ratio the game was designed for. 1.777777 for 16:9 widescreen.
nearplanefloatFrustum near plane cutoff distance. Default to 1 unless you have a scene with very small objects and very close up camera.
farplanefloatFrustum far plane cutoff distance. Object farther away from this distance will be cut off. Be reasonable in setting this value to avoid z-buffer flickering on older hardware.
    {
entity_name = "Zs/NPC/mFloor2/02/ACU/Camera",
type = CAMERA,
template_name = "",
lt_grp = 0, srt_grp = 0, usr_flg = 0,
spatialprops =
{
pos = { 0.752384, 2.833098, 6.642779 },
orient = { { -0.967908, 0.000000, -0.251306 },
{ -0.010469, 0.999132, 0.040322 },
{ 0.251088, 0.041659, -0.967068 } }
},
cameraprops =
{
fovh = 25,
hvaspect = 1.85,
nearplane = 0.3,
farplane = 4000
}
},

LIGHT

Light source object that illuminates scene mesh objects. Be aware that due to the old DirectX version Freelancer uses, a mesh object can receive light from a maximum of six light sources. However you can group light sources using lgt_grp property and objects can specify which group they will receive light from. For example environment scenery can be lit by one group of light sources while characters in it are lit by another group. Light sources in cutscenes can behave slightly differently to [Lightsource] objects in systems.

PropertyTypeDescription
onbooleanToggle switch. You can turn light source on or off.
colorfloat[3]Unused
diffusefloat[3]Diffuse color. This is the actual color tint.
specularfloat[3]Specular intensity.
ambientfloat[3]Additional ambient color tint.
directionfloat[3]Unclear what this does.
rangefloatLight range.
cutofffloatDistance from center at which light intensity starts to gradually fall off.
typestringL_POINT: Point light source.
L_DIRECT: Directional light source
L_SPOT: Spot light source.
thetafloatPolar coordinates for directional light source.
attenfloat[3]Attenuation
    {
entity_name = "Ambi_Lightning_ALL_LtG11",
type = LIGHT,
template_name = "",
lt_grp = 11, srt_grp = 0, usr_flg = 0,
spatialprops =
{
pos = { -3.188878, 0, 0.014479 },
orient = { { 0.034878, 0.000000, -0.999392 },
{ 0.000000, 1.000000, 0.000000 },
{ 0.999392, 0.000000, 0.034878 } }
},
lightprops =
{
on = Y,
color = { 255, 255, 255 },
diffuse = { 0, 0, 0 },
specular = { 0, 0, 0 },
ambient = { 0, 0, 0 },
direction = { 0, 0, 1 },
range = 100000,
cutoff = 98.99998,
type = L_DIRECT,
theta = 90,
atten = { 1, 0, 0 }
}
},

COMPOUND

A generic mesh object such as solar, ship or a static prop. Characters use their own type (see DEFORMABLE).

PropertyTypeDescription
template_namestringName of object from archetypes depending on catalog specified in userprops.

userprops

PropertyTypeDescription
categorystringMesh category lookup file (see below).

Categories used by compound objects:

CategoryFilename
PropDATA\petaldb.ini
RoomDATA\petaldb.ini
SpaceshipDATA\SHIPS\shiparch.ini
SolarDATA\SOLAR\solararch.ini
AsteroidDATA\SOLAR\asteroidarch.ini
EquipmentDATA\EQUIPMENT\prop_equip.ini
Equipment CartDATA\petaldb.ini
    {
entity_name = "li_elite_3",
type = COMPOUND,
template_name = "li_elite",
lt_grp = 0, srt_grp = 0, usr_flg = 0,
flags = LIT_DYNAMIC + LIT_AMBIENT,
spatialprops =
{
pos = { 0, 0, 0 },
orient = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }
},
userprops =
{
category = "Spaceship",
}
},

DEFORMABLE

Animated character objects (Trent, Juni, etc).

CategoryFilenameDescription
template_namestringName of a character template from DATA\CHARACTERS\costumes.ini.

compoundprops

PropertyTypeDescription
floor_heightfloatFloor height for character. Deformable meshes ignore height position in spatial properties.

userprop

PropertyTypeDescription
actorstringName of template from category list. Should match template_name.
categorystringMesh category lookup file (see below).

When using START_MOTION be aware that certain animations such as walking will make a character modify its position in space and it will be retained once animation is complete. Many animations are specific to single player cutscenes so there might be not a whole lot you can do about them, but there are also a fair amount of generic animations all human characters can use and a number of unused but functional animations (like dancing).

To find character animation names open .anm files in DATA\CHARACTERS\ANIMATIONS with UTFEditor. Be aware that certain versions of UTFEditor may crash when opening some nodes in those files. Animations are stored in Animation/Script node. Most script names have two digits at the end of the name, those indicate running time to help you chain them together.

Head, body and hand animations are sometimes separate and can run independently of each other. For example you may run a hands gesture animation on a character while running a different facial expression animation. Despite somewhat clunky data format the animation system in Freelancer is fairly robust.

It’s worth to note that for some reason character placement requires specifying vertical position independently from common spatial properties (see floor_height). Animating height placement is also done via separate event: START_FLR_HEIGHT_ANIM.

	{
entity_name = "Char_Trent",
type = DEFORMABLE,
template_name = "trent",
lt_grp = 0, srt_grp = 0, usr_flg = 0,
flags = LIT_DYNAMIC + LIT_AMBIENT,
spatialprops =
{
pos = { -18.33887, 0, -51.12214 },
orient = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }
},
compoundprops =
{
floor_height = 0
},
userprops =
{
actor = "player",
category = "Character",
}
},

PSYS

Particle system effect (Alchemy effect).

psysprops

PropertyTypeDescription
sparamfloatNumerical value passed to effect. Used for engines intensity and such. Default 0.

Template_name will refer to [Effect] nickname attribute in any of the *_ale.ini files found within DATA\FX subfolders (ex: engines_ale.ini in DATA\FX\ENGINES). Not all effects are listed in DATA\FX\effects.ini.

	{
entity_name = "Ambi_Roids_gf_blsmallasteroid_03",
type = PSYS,
template_name = "gf_blsmallasteroid",
lt_grp = 0, srt_grp = 0, usr_flg = 0,
flags = LIT_DYNAMIC + LIT_AMBIENT,
spatialprops =
{
pos = { -500, 500, 0 },
orient = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }
},
psysprops =
{
sparam = 0
}
},

SOUND

Sound effect. You’ll need to use START_SOUND event to play it.

PropertyTypeDescription
flagsSPATIALSound effect is spatial and uses coordinates.

audioprops

PropertyTypeDescription
attenuationfloatSound effect attenuation.
panfloatStereo panning. Default is 0.
dminfloat
ainfloat
aoutfloat
atoutfloat
rmixfloat

userprops

PropertyTypeDescription
categorystringSound source catalog. Default is “Audio”.
    {
entity_name = "Ship_b_e_engine_br_small_1",
type = SOUND,
template_name = "engine_br_small",
lt_grp = 0, srt_grp = 0, usr_flg = 0,
flags = SPATIAL,
spatialprops =
{
pos = { 0, 0, 0 },
orient = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }
},
audioprops =
{
attenuation = 0,
pan = 0,
dmin = 50,
dmax = 1000,
ain = 360,
aout = 360,
atout = 0,
rmix = 0,
},
userprops =
{
category = "Audio",
}
},

MARKER

Dummy placeholder object without visual representation. It can be used as a rotational pivot for other objects or a moving point which a camera looks at while following a path track.

PropertyTypeDescription
flagsREFERENCEMarker is a placeholder for other objects to be placed dynamically upon cutscene initialization.

In certain scripts it serves as a placeholder object, for example a player ship in landing/takeoff base cutscenes. Upon starting a cutscene the game will attach player ship model to that marker if found in the scene.

Some placeholder marker names:

NameAttachment
X/Shipcentre/01Player 01 ship.
Zg/PC/Player/01/A/Stand Player 01 costume character in standing animation.
Zs/NPC/Bartender/01/P/StandBar bartender 01 character in standing animation.
    {
entity_name = "Mk_Pr_Smooth_straight_to_LEFT",
type = MARKER,
template_name = "",
lt_grp = 0, srt_grp = 0, usr_flg = 0,
spatialprops =
{
pos = { 0, 21.13857, 0 },
orient = { { 0.864434, 0.384713, -0.323651 },
{ -0.387993, 0.919888, 0.057158 },
{ 0.319712, 0.076165, 0.944449 } }
}
},

MOTION_PATH

Curves are used to move an object along its path. Paths can be open or closed loops.

pathprops

PropertyTypeDescription
path_typestringPath type. Default “CV_CROrientationSplinePath”.
path_dataflag, {x, y, z}, {x, y, z, w} [...]Path data: flag, points, quaternions.

Only one path type is available: CV_CROrientationSplinePath.

First attribute in path_data is a flag specifying whether this is an open path (“OPEN”) or a closed loop (“CLOSED”).

Each path point consists of a coordinates set and rotation quaternion.

Creating path point data by hand (especially quaternions) is a rather daunting task so I’d recommend to use your favorite 3D modeling software to create smooth paths and export them into plain text that you can use in THN files.

    {
entity_name = "Path_1",
type = MOTION_PATH,
template_name = "",
lt_grp = 0, srt_grp = 0, usr_flg = 0,
spatialprops =
{
pos = { -10, 7.5, 30 },
orient = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }
},
pathprops =
{
path_type = "CV_CROrientationSplinePath",
path_data = "OPEN,{0.000000,0.000000,0.000000}, {1.000000,0.000000,0.000000,0.000000}, {0.000000,0.100000,0.000000}, {1.000000,0.000000,0.000000,0.000000}, "
}
}