Sims 3:Jazz

From SimsWiki
Jump to: navigation, search
For information on the data format of jazz scripts, see the type entry for Sims_3:0x02D5DF13

Jazz scripts define animation sequences used by The Sims 3. While they are not directly animations, anything that animates in some way involves using a jazz script, even little things like a door opening or closing.

The rest of this article assumes you are working with the jazz data in scripts as used and defined by Smooth Jazz. Smooth Jazz can be downloaded from [Mod The Sims].

Contents

Overview

Sequences of animations in The Sims 3 are controlled by [finite state machines] defined in jazz scripts. Core game scripts do not directly request animations in most cases, rather they create state machine clients to access the defined state machines, and the state machines are responsible for performing the correct animations. This provides a layer of separation such that the game scripts do not need to understand the details of animations, and some details of what animations do can be changed without having to involve any game script changes.

Jazz scripts ARE NOT animations. There has been some confusion about what exactly they are, since there is no obvious visible action to the casual observer. The animations themselves are of course visible, and the game scripts obviously exist. But the existence of some amount of logic between the two is not apparent. Jazz scripts are responsible for taking instructions from the game scripts such as "Make sim X eat food Y" and turning it into specific animations for the game to perform on X and Y.

In the simplest terms, the animation is the visual effect that is visible to the player, the Jazz script controls how and when various pieces of the animation are displayed, and the C# script begins the Jazz script (and can tell it to end prematurely if needed).

State Machines

TBD

Smooth Jazz Syntax

This is a preliminary language definition, and is subject to change.

Smooth jazz aims to provide a means to modify the inner workings of the state machine in a simple easy to follow form. Therefore, the language aims to be terse in the most common cases by providing defaults where it makes sense. As a result, some block types can be distilled down to a single line in many cases. The default values will be noted wherever necessary.

For the most part, elements in Smooth Jazz correspond directly to the RCOL chunk definitions from Sims_3:0x02D5DF13. However, a few cases exist where the data is simple enough it only has the short form, and as a result, it appears to be just part of another definition block. A lot of the extraneous details linking between different chunks is hidden by the simplicity of the syntax.

All keywords in Smooth Jazz are case insensitive.

Names in Smooth Jazz

Internally to the state machine data, there are very few cases where the data contains strings. Most everything is identified by number. However the number is formed by performing FNV hashing of what would otherwise be the name. In Smooth Jazz, names can be identified as strings enclosed in double quotes (Following typical string escape sequence rules) "name" or can be identified by the number in hex or decimal, such as 0x2f8b3bf4 (FNV-32 hash of "name"). In most cases, either form works.

There is one odd quirk. Occasionally, a name is a hash formatted to a string and hashed again. For example "0x2f8b3bf4" used for "name". This appears to be a bug in the game data, but in the interested of reproducing the data, a name string can be prefixed with an asterisk (*) to indicate that the resulting hash should be formatted as a string and hashed again.

<name-hash>      ::= <opt-qualifier> <name-value>
<opt-qualifier>  ::= * |
<name-value>     ::= <number> | <string>
<number>         ::= <hex-number> | <digits>
<hex-number>     ::= '0x' <hex-digits>

Animation Priorities

At several points in the state machine scripts, there is a specification for the animation priority. This can be any numeric value, however in most cases it is not necessary to use anything outside a named priority. Here is a list of animation priorities, from highest to lowest. There are also the special values "Broadcast" (-1) and "Default" (-2).

Priority Name Equivelent Value
Low 6000
LowPlus 8000
Normal 10000
NormalPlus 15000
FacialIdle 17500
High 20000
HighPlus 25000
CarryRight 30000
CarryRightPlus 35000
CarryLeft 40000
CarryLeftPlus 45000
Ultra 50000
UltraPlus 55000
LookAt 60000

Incomplete Research

Some values used in the state machines are still not fully understood. In cases where the understanding is so little to even guess what the value is used for, it appears in the scripts as an "Unknown Value". In most cases, these are just values that were always the same in existing data. As these are understood, the language definition will be updated to reflect the new understanding. Until some of the common unknown values are understood, it is recommended keeping any scripts which include these values in binary form, where the name is unimportant, to avoid errors with future versions.

<unknown-value> ::= Unknown Value <number> = <number>

Comments

Comments in Smooth Jazz follow the C++ style syntax where "//" denotes a comment to the end of the line, "/*" denotes the start of a comment block, and "*/" denotes the end of a comment block.

Smooth Jazz Usage

In addition to the Smooth Jazz Studio interface, Smooth Jazz can be used in a command line context for importing scripts into packages, or exporting scripts from packages. For full usage information, run SmoothJazz.exe with the option /help.

(To be completed later)

Smooth Jazz Block Types

State Machine

<state-machine>            ::= State Machine <string> { <state-machine-definition> }
<state-machine-definition> ::= <state-machine-fields> <state-definitions>
<state-machine-fields>     ::= <state-machine-field> | <state-machine-fields> <state-machine-field>
<state-machine-field>      ::= <actor-definition> | <parameter-definition> | <state-machine-properties>
                               | <state-machine-priority> | <animation-actor-assignment> | <unknown-value>
<actor-definition>         ::= Actor <name-hash> | Actor <name-hash> = <name-hash>
<parameter-definition>     ::= Parameter <name-hash> | Parameter <name-hash> = <name-hash>
<state-machine-properties> ::= Properties <property-list>
<property-list>            ::= <property> | <property-list> , <property>
<state-machine-priority>   ::= Priority <priority-value>
<animation-actor-assignment> ::= Assign Actor <name-hash> . <name-hash> as <name-hash>
<state-definitions>        ::= <state> | <state-definitions> <state>

Parameter and Actor Definitions

In order for the script to communicate with the state machine, it can assign parameters or actors.

An actor is an object which is represented by some sort of mesh or bone data in the world. For example, a sim, a toy box, or occasionally an animation jig. Actors are directly acted on and influenced by the animation clips, but are not used directly by the state machine.

A parameter is some sort of value which the state machine uses for various operations.

In both cases a default value can be assigned, however an actor definition is typically never assigned a default value.

State Machine Properties

Properties influence how the state machine will run. The following are valid properties for state machines.

Default:

Properties 0
Property Name Value Usage Notes
UnilateralActor
PinAllResources
BlendMotionAccumulation
HoldAllPoses

Priority

It is currently unclear what a priority setting on the state machine is for. Presumably it is provided as a default for other priorities within the state machine.

Actor Assignments

Animation clips can reference specific actors, however the name is not always the same as the actor name that the state machine uses. For cases where the name is not the same, actor assignments can be used. The format is the animation clip name and actor name as known by the animation, followed by the actor name as known by the state machine.

Unknown Values

There are presently 5 unknown values for state machines. Of those, only one has ever been seen with a value besides 0.

Value Index Values Seen Usage notes
0 1, 2, 3, 4, 5
1 0
2 0
3 0
4 0

State

<state>                ::= State <name-hash> | State <name-hash> { <state-fields> <decision-graph> }
<state-fields>         ::= <state-field> | <state-fields> <state-field>
<state-field>          ::= <state-properties> | <state-transitions> | <unknown-dg-value> | <unknown-value>
<state-properties>     ::= Properties <state-property-list>
<state-property-list>  ::= <state-property> | <state-property-list> <state-property>
<state-transitions>    ::= Transitions to <name-hash>
<unknown-dg-value>     ::= Unknown Decision Graph Value <number>

Properties

Properties influence how this state can be used by scripts.

Default:

Properties 0
Property Name Value Usage Notes
Public 0x0001
Entry 0x0002 The state is an entry state and can be explicitly set as the current state without using transitions
Exit 0x0004 The state is an exit state
Loop 0x0008 The state runs as a loop where the state machine will continually be coming back to it through transitions
OneShot 0x0010
OneShotHold 0x0020
Synchronized 0x0040
Join 0x0080
Explicit 0x0100

Unknown Values

There are two unknown values in state definitions, one is explicitly named as an unknown decision graph value, but is always used.

Value Index Values Seen Usage notes
0 2, 3, 4, 5, 6 The most common value is 6, which is the default if not explicitly given
*dg 0

Transitions

Any valid transition from this state must be explicitly named. The state machine will only ever follow named transitions, no matter what the request for a new state is and where it comes from.

Decision Graph

<decision-graph>      ::= <decision-graph> <decision-graph-node> | <decision-graph-node> |
<decision-graph-node> ::= <play> | <stop> | <actor-operation> | <create-prop>
                          | <random> | <select-on-parameter> | <next-state>

The decision graph is the meat of the animation system. Aside from the state machine logic, the decision graph is where the logic of deciding what animations to play comes from. A decision graph can be as simple as playing an animation, or more complex such as picking a random event weighted based off parameters passed into the state machine. Any decision graph node can be nested under nearly any other decision graph node to produce complex actions.

Play

<play>            ::= Play <clip-definition> <opt-actor> <opt-play-fields>
<clip-definition> ::= <resource-ref> | <string> With Substitution
<opt-actor>       ::= For <name-hash> |
<opt-play-fields> ::= { <play-fields> } |
<resource-ref>    ::= <name-hash> | <number> : <number> : <name-hash>
<play-fields>     ::= <play-field> | <play-fields> <play-field>
<play-field>      ::= <track-mask> | <actor-slot> | <slot-suffix> | <play-flags>
                      | <play-priority> | <blend-in> | <unknown-value> | <decision-graph>
<track-mask>      ::= Track Mask <resource-ref>
<actor-slot>      ::= Actor <name-hash> Slot <name-hash> <opt-slot-values>
<opt-slot-values> ::= , <number> , <number> |
<slot-suffix>     ::= Actor <name-hash> Suffix <name-hash>
<play-flags>      ::= Flags <play-flag-list>
<play-flag-list>  ::= <play-flag> | <play-flag-list> <play-flag>
<play-priority>   ::= Priority1 <priority-value> | Priority2 <priority-value>
<blend-in>        ::= Blend In <number>

Often times the short form of Play can be used, if no additional fields are required beyond the clip name and primary actor.

Animation Clip

Animation clips can be either explicitly named by the clip definition, or formed by substituting parameter values in for parts of the clip name. When the clip is explicitly named, the resource type and group are assumed to be 0x6B20C4F3 and 0, respectively, however the full resource key can be given. When substitution is performed, the type and group for the resource key are taken as the default.

Substitutions work by replacing any part if the string with curly braces with the value of the parameter specified. For example "{age1}2{age2}_greet" would create the clip name by substituting agr1 and age2. If age1 was given as "a" (adult) and age2 as "t" (teen), the clip used would be "a2t_greet".

If an actor is named after the clip, that is taken to be the primary actor for the animation, and the age and species of the the actor are applied to the clip instance to find the animation to use.

Animation clips are named in the resource files based on the age group for the animation. The animation hash codes are always based on the name for adult animations. When a play animation node is encountered, first it will try to load the age specific animation, then if that fails it will attempt to load the generic (adult) animation.

Track Mask

Track masks are used to mask off some or all motion to certain joints in the animation rig. The masks is a resource of type 0x033260E3, which is assumed to be the type of the resource if it is not explicitly requested. It is unclear if what is being masked is this animation, or all other animations

Actor Slot

Actor slot specifies a defined slot for the requested actor. Slots are defined in the appropriate RSLT associated with the actor. There are two additional unknown values which are unknown, and will default to 0.

Not a whole lot is known about this animation option, as it is only used once in all of the game jazz data.

Slot Suffix

An optional suffix can be applied to the animation slots used in an animation. This is typically used for determining which side of the bed a sim is on, or which seat of a car or sofa they are sitting in. The suffix is defined in term of the actor name and a parameter to be used for the substitution.

Priority

A special note should be made for animation priority. The state machine data contains not one, but two animation priority definitions. The first is assumed to be the priority for the animation itself, while it is unclear what the use of the second is.

Blend In

When an animation starts, it can be blended with an existing animation to provide a smooth transition. For example, when a sim runs, the state machine responsible first starts the sim walking, then blends it into a run animation.

Flags

The following flags can be used when playing an animation. Default:

Flags AtEnd
Flag Name Value Usage Notes
AtEnd 0x0001
LoopAsNeeded 0x0002
OverridePriority 0x0004
Mirror OverrideMirror 0x0008
OverrideTiming0
TimingMaster
0x0010 Both flags have the same value
OverrideTiming1
TimingSlave
0x0020 Both flags have the same value
TimingIgnored 0x0040 Shorthand for OverrideTiming0, OverrideTiming1
Interruptible 0x0060
ForceBlend 0x0080
UseTimingPriority 0x0100
UseTimingPriorityAsClockMaster 0x0200
BaseClipIsSocial 0x0400
AdditiveClipIsSocial 0x0800
BaseClipIsObjectOnly 0x1000
AdditiveClipIsObjectOnly 0x2000
HoldPose 0x4000
BlendMotionAccumulation 0x8000

Stop

<stop>            ::= Stop <opt-actor> <opt-stop-fields>
<opt-actor>       ::= For <name-hash> |
<opt-stop-fields> ::= { <stop-fields> } |
<stop-fields>     ::= <stop-field> | <stop-fields> <stop-field>
<stop-field>      ::= <stop-flags> | <stop-priority> | <unknown-value> | <decision-graph>
<stop-flags>      ::= Flags <play-flag-list>
<stop-flag-list>  ::= <stop-flag> | <stop-flag-list> <stop-flag>
<stop-priority>   ::= Priority1 <priority-value> | Priority2 <priority-value>

Priority

Stop has two priority fields like Play, it is unclear what they are used for.

Flags

Stop uses the same animation flags as play uses.

Actor Operation

<actor-operation> ::= Actor Operation <actor-op-list> ON <name-hash> <opt-acop-fields>
<actor-op-list>   ::= <actor-operation> | <actor-op-list> <actor-operation>
<opt-acop-fields> ::= { <acop-fields> } |
<acop-fields>     ::= <acop-field> | <acop-fields> <acop-field>
<acop-field>      ::= <unknown-value> | <decision-graph>

Operation

Operations can be applied to actors for the purpose of animations. Presently there is only one operation defined.

It is only assumed that multiple operations can be defined for a single actor operation node. Since there is only a single operation defined, all existing exampled assign exactly one operation.

Operation Name Value Usage Notes
None 0 Clear all operations
SetMirror 1 Mirror animations for this actor

Unknown Values

There are three unknown fields on actor operations. None of them have been seen with any value besides 0.

Value Index Values Seen Usage notes
0 0
1 0
2 0

Create Prop

<create-prop>     ::= Create Prop <resource-ref> as <name-hash> <opt-prop-fields>
<resource-ref>    ::= <name-hash> | <number> : <number> : <name-hash>
<opt-prop-fields> ::= { <prop-fields> } |
<prop-fields>     ::= <prop-field> | <prop-fields> <prop-field>
<prop-field>      ::= <unknown-value> | <decision-graph>

Resource Ref

In most cases, actors are existing objects from the game world which are passed in to the jazz script. However it is possible for the jazz script to create temporary objects for use as props. Examples of this are tools used for repairing items, toy xylophone mallets, and the grim reapers scythe.

The resource reference is the catalog GUID of an object to create. While the object is given as a resource key, the type value is 0x139f7591, which is an otherwise unknown type not present in any data files. A full resource key can be given, but it is unknown if it would work.

Unknown Values

There are five unknown fields in a prop node, none of which have any known value besides 0.

Value Index Values Seen Usage notes
0 0
1 0
2 0
3 0
4 0

Random

<random>           ::= Select Random { <opt-random-flags> <random-selection> }
<opt-random-flags> ::= Flags <random-flag-list> |
<random-flag-list> ::= <random-flag> | <random-flag-list> , <random-flag>
<random-selection> ::= Weight <number> { <decision-graph> }

A random selection is picked based off the weights of all options. If there are two options with weights of 1 and 10, the first option will be picked once for every ten times the second option is picked. Note that this is actually 1 in 11 times, not 1 in 10. Since the weights are important only with relation to other weights, the scale does not matter. The same result would occur if the weights were 10 and 100, 3 and 30, or .2 and 2.

Flags

The following flags can be applied to the process of random selection. Default:

Flags None
Flag Name Value Usage Notes
None No flags
AvoidRepeats Pick options that have not been picked yet

Choices

A choice is defined as a weight, and a list of 0 or more actions to take. The weight is defined as any positive number.

Select on Parameter

<select-on-parameter> ::= Select on Parameter <name-hash> { <sopn-choices> }
<sopn-choices>        ::= <sopn-choice> | <sopn-choices> <sopn-choice>
<sopn-choice>         ::= Value <name-hash> { <decision-graph> }

Select on parameter is the jazz version of a switch statement. The value of the parameter is compared to all the choices and the one which matches is selected for the action. However there is no concept of a default action.

Next State

<next-state> ::= Next State <name-hash>

Causes the state machine to transition to the named state. It is unknown if the decision graph continues to be evaluated before the transition, and what happens if multiple next state nodes are encountered.

Sample Script

This sample script illustrates the basics of the syntax.

State Machine "AlarmClock"
{
    Properties UnilateralActor
    Actor "AlarmClock"
    Assign Actor "o_alarmclockCheap_Ring.ma"."alarmclockcheap" as 0x0
    Assign Actor 0xC63B4209."alarmclockcheap" as 0x0
    State "Enter"
    {
        Properties Public, Entry, Explicit
        Transitions to "o_alarmClockCheap"
    }
    State "Exit"
    {
        Properties Public, Exit, Explicit
    }
    State "o_alarmClockCheap"
    {
        Transitions to "Ring"
        Play "o_alarmClockCheap"
        {
            Flags AtEnd, BaseClipIsObjectOnly
        }
    }
    State "Ring"
    {
        Properties Public, Explicit
        Transitions to "Exit"
    }
}
Personal tools
Namespaces

Variants
Actions
Navigation
game select
Toolbox