PSG Basics

A PSG (or "Papyrus Scene Graph") file is a file used to assemble a set of PAS ("Papyrus ASCII Scene") and/or 3DO files into one or more 3DO files.  PSG files are often referred to as PSG scripts.  These files are used to tell make3do how to assemble PAS and even pre-existing 3DO files into one or more new 3DO files.

Reference

The following reference is based on the mace3do.doc file that comes with Sandbox.  Anything enclosed in square brackets "[]" are optional.  When multiple options enclosed in curly brackets "{}", only one can be used at a time.  Options will be separated by a vertical line "|" character.  "xIdentifier" is the name of an object in the scene to be used by other commands.  Comments may be placed in files by using a "#" before the comment.  Comments will go to the end of the line.

BBOX

Creates an axis-aligned bounding box around a specified volume or MESH.  This can then be used in various other commands as an optional parameter.

Usage

bboxIdentifier: BBOX { MIN(x, y, z) MAX(x, y, z) | meshIdentifier }

MIN

Defines the minimum x, y, and z coordinates of the bounding box.

MAX

Defines the maximum x, y, and z coordinates of the bounding box.

BILLBOARD

A billboard is an object that always faces directly towards the camera.  The billboarded item does not have to be limited to a single mesh.

Usage

sceneIdentifier: BILLBOARD [bboxIdentifier] POS(x, y, z) [AXIS(x, y, z)] sceneIdentifier

POS

The position of the billboard.

AXIS

An optional unit vector which constrains how the billboard can rotate.  If used, then the billboard will rotate about the specified axis.  A unit vector has a length of one unit.  The length of a vector is defined as "length = sqrt(x2 + y2 + z2)".

CHILD

Used to access child nodes from a root group node of an imported 3DO file.  The item in question can be accessed either through its name or its index.  Items in the child list are zero-indexed.

Usage

sceneIdentifier: CHILD sceneIdentifier { childName | childIndex }

COPY

Copies a MESH so that the copy can later be modified by the MODIFY command.

Usage

meshIdentifier: COPY meshIdentifier

EMPTY_MESH

Creates an empty object.  This is typically used as the last entry of an LOD or STATIC_LOD to cause the object to disappear if the camera goes too far away from the object.  You will only need one of these in the entire PSG file.

Usage

sceneIdentifier: EMPTY_MESH

GROUP

Groups two or more items together.

Usage

sceneIdentifier: GROUP [bboxIdentifier] (sceneIdentifier1, sceneIdentifierN)

LOD and STATIC_LOD

Allows you to display different versions of the same mesh based on the distance between the 3DO and the player's camera.  Each version of the mesh will have a different level of detail to be displayed at a specific range of distances.  Each version of the mesh should be sorted from most detailed to least detailed.  And each distance specified must be sorted from closest to furthest.  For an object to disappear after a certain range, the last sceneIdentifier in the list should be an EMPTY_MESH.

There is no difference between LOD and STATIC_LOD that is useful in NR2003.

Usage

sceneIdentifier: LOD [bboxIdentifier] [POS(x, y, z)] (distance1 sceneIdentifier1, distanceN sceneIdentifierN)

POS

The offset used to calculate the distance between the 3DO and the player's camera.

LINKED_MESH

The LINKED_MESH command is used in place of the MESH command when a MESH_GROUP command is used with the LINK option.

Usage

meshIdentifier: LINKED_MESH meshGroupIdentifier meshName

MESH

Creates a reference to an individual meshes inside a MESH_GROUP.

Usage

meshIdentifier: MESH meshGroupIdentifier meshName [FRAME index]

FRAME

If the mesh has an animation, you can give key frames within the animation a name, where FRAME is the name to give the frame, and index is the zero-based index of the frame to name.

MESH_GROUP

The MESH_GROUP command is used to import the contents a Papyrus ASCII Scene (PAS).  Parts of an imported PAS file can then be accessed by various other commands for modification and/or assembly into the final 3DO scene graph.  Generally speaking, this command will be the first command in the file, but there are exceptions with more complex objects.

Usage

meshGroupIdentifier: MESH_GROUP "filename.pas" [LINK | USEPIVOTS] [RENAME_MAT (oldName1 newName1, oldNameN newNameN)] [ADDCHILDREN (objectName1 sceneIdentifier1, objectNameN sceneIdentifierN)]

LINK

Links meshes that are part of a hierarchy into a single LINKED_MESH.

USEPIVOTS

Imports the mesh objects relative to their local pivot point.  This results in the vertices of a mesh being moved to the scene origin based on the object's pivot that was defined in 3DS max.  Generally speaking, this option should be used to center the mesh around the 3DO's origin, then moved to the correct position and orientation in Sandbox.  If using a TRANSFORM or ANIMATED_TRANSFORM command, then using the USEPIVOTS option will make it easier to get the desired results.

RENAME_MAT

This option is used to rename one or more materials to make them accessible in-game.  This is how the game assigns paint schemes to race cars.  Each item in the list is separated by a comma.  The old and new names are separated by a space.

ADDCHILDREN

Allows you to link other objects referenced by the PSG to specific meshes during the mesh import.  "objectName" is the name of the mesh within the PAS file being imported, and "sceneIdentifier" is a previously-defined item in the PSG file.

MIP

Creates a reference to a mip file that will later be used in the MODIFY TEXTURE command.  You need two of these for every texture you want to modify.  One for the original texture, and one for the new texture.

Usage

mipIdentifier: MIP "filename.mip"

MODIFY TEXTURE

Replaces a texture on a specific mesh with another texture.  It appears that the MODIFY command can do more than just replace textures, but the original documentation has absolutely nothing on other uses.

Usage

MODIFY TEXTURE { BASE_TEXTURE | LIGHT_MAP | SHINENESS_MAP | ENVIRONMENT_MAP } meshIdentifier originalMipIdentifier newMipIdentifier

OUTPUT

Defines the final product to be exported to a 3DO file.  This command is typically the last command to be used in a PSG file.  You may have multiple output commands.  One for each file.  If the name of the output file is not specified, then the output file name in the command line is used.

Usage

OUTPUT sceneIdentifier ["filename.3do"]

POINTLIGHT

A POINTLIGHT is only valid for objects that are used as TSOs for race tracks.  They define a light with a specific diffuse and ambient color, as well as a glow effect.  These lights cannot be nested inside a TRANSFORM object, and cannot be used in anything other than a trackside object.

Usage

sceneIdentifier: POINTLIGHT POS(x, y, z) diffuseIntensity ambientIntensity COLOR(r, g, b) GLOW(diameter)

POS

The position of the point light relative to the 3DO's local origin.

COLOR

The color of the light, with each component being a value between 0 and 1.

GLOW

The diameter of the glow effect in meters.

PORTAL

A PORTAL is a render target, usually used for the rearview mirror of a car.  The portal must have a name because the game needs to be able to access the portal to render to it.

Usage

sceneIdentifier: PORTAL portalName meshIdentifier

REGION_MORPH

A region morph is a special type of mesh that can adjust its shape under certain conditions.  It is made from two or more meshes that have an identical number of vertices and indices, and who's vertices and indices are in the exact same order.  Examples of REGION_MORPH usages are to visualize roof flap deployment and vehicle damage.

Usage

sceneIdentifier: REGION_MORPH meshIdentifier DESTINATION meshIdentifier REGIONS (bboxIdentifier statVariableName [numBits firstBit], ...)

DESTINATION

What the mesh will look like when fully deformed.

REGIONS

A list of regions to apply deformation to.  Each region must specify a bounding box and a state variable.  Optionally, each region may specify a bitfield within the state variable that affects the mesh deformation.  The state value has 32 bits to choose from.

SCENE

The SCENE command is used to import an existing 3DO file into the scene graph.  If the root node of this 3DO is a group, then you can access the child nodes in the group with the CHILD command.

Usage

sceneIdentifier: SCENE "filename.3do"

SPANNING

Usage

sceneIdentifier: SPANNING meshIdentifier NESTED (bboxIdentifier transformIdentifier)

STATE_SWITCH

A STATE_SWITCH is used to control the conditions under which an object in a scene graph is rendered.  STATE_SWITCHES can be nested to create more complex conditions of visibility.  Like an LOD or STATIC_LOD, a STATE_SWITCH contains multiple versions of the same object, with each version being displayed under a different set of conditions based on the value of the selected stateVariable.  The list always ends with an extra value, which if exceeded, will cause the object to stop being rendered.  The rest of the values are associated with their respective versions of the object to be rendered, and define the first condition under which the object is rendered.

Usage

sceneIdentifier: STATE_SWITCH [bboxIdentifier] VAR stateVariable [PERIOD value] (value1 sceneIdentifier1, valueN sceneIdentifierN, valueN+1)

VAR

The name of the state variable that controls the conditions under which the different versions of the object are rendered.

PERIOD

I do not know what this does.  In a lot of 3DOs, this value is zero.

Examples

myStateSwitch: STATE_SWITCH VAR Population (1 garageArea, 2.9) # Causes a GROUP or MESH named "garageArea" to be visible when the "Trackside Objects" graphics setting is set to "Some" or "All".

List of State Variables

The following is a partial list of state variables in the game.  Sandbox can be used to define additional state switches as animations that play during the session.

Name Min Max Description
Population 0 2

This state variable is linked to the "Trackside Objects" dropdown in the "Graphics" settings screen.  0 is "Minimum", 1 is "Some", and 2 is "All".  If an object is visible regardless of the Trackside Objects setting, then this state switch should be omitted.  Generally speaking, there should only ever be one entry in the list, the sceneIdentifier to be rendered when the Trackside Objects setting is set to the minimum value to render the object.  The list will typically be either "(1 identifier, 2.9)" for objects that are rendered when "Some" or "All" is selected; or "(2 identifier, 2.9)" for objects that are rendered only when "All" is selected.

This state switch should apply to the entire 3DO.

Weekend 0 2

This variable is linked to the in-game session.  0 is "Testing", 1 is "Practice", "Qualifying", or "Warmup", and 2 is "Race".  Certain objects are only visible during certain sessions.  And some objects are visible during all sessions, but have different appearances depending on the session.  If an object does not change its appearance based on the session, then this switch should be omitted.  For example, grandstands may have the following list:  "(0 gs_empty, 1 gs_qual, 2 gs_full, 2.9)"

This state switch may be applied to the entire 3DO, or just the portions of the 3DO that change appearance based on the session.

caution_light 0 73 This variable controls the appearance of the caution light.  0 is "off", 1 is "green", and 2-73 is "caution".  Values 2-73 are used to define the caution light animation when the caution light is on while the race is under caution.  Game state is updated 36 times per second.
Day_Night 0 1 This variable controls the the appearance of the 3do based on whether a day or night track is loaded.  0 appears to be for "day" and 1 appears to be for "night".
wind_speed 0 infinity? This variable is the speed of the wind (perhaps in miles per hour or meters per second).
AnimObjs 0 infinity? This appears to be the animation state of the object.  All of the 3DOs I've examined have an end value of 1.9, but I haven't examined very many objects that have this state switch.

TRANSFORM

A TRANSFORM will move an object to a specified position and give it the specified rotation.  Do not put POINTLIGHT nodes inside transforms.

Usage

sceneIdentifier: TRANSFORM [NAME nodeName] [bboxIdentifier] POS(x, y, z) ROT(yaw, pitch, roll) sceneIdentifier

NAME

The name of the node inside the 3DO file.  This is probably so that the game can access specific transform nodes based on the intended use of the node.

POS

The position of the node relative to the parent TRANSFORM or the scene's local origin.

ROT

The rotation of the node relative to the parent TRANSFORM or the scene's local origin.