Resources/DvScene: Difference between revisions
No edit summary |
No edit summary |
||
| (22 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
'''DvScene''' ''(also known as DiEvent)'' is a file format that's been used in Hedgehog Engine 2 since [[Games/Sonic Frontiers|Sonic Frontiers]], it's a collection of nodes and resources that are easily editable so it's simple to | {{Infobox Resource|type=[[Resources#Cinematics|Cinematics]]|extension=.dvscene|games=* [[Games/Sonic Frontiers|Sonic Frontiers]] | ||
* [[Games/Shadow Generations|Shadow Generations]]|tools=* [[Tools/010 Editor Binary Templates|DiEventTemplate]] | |||
* [[Tools/DvSceneTool|DvSceneTool]] | |||
* [[Tools/DevTools|DevTools]]|status=Almost finished|container=|name=DvScene}} | |||
'''DvScene''' ''(also known as DiEvent)'' is a file format that's been used in Hedgehog Engine 2 since [[Games/Sonic Frontiers|Sonic Frontiers]], it's a collection of nodes and resources that are easily editable for simple modification or creation of new cutscenes/cinematics. | |||
The format and sub-system originates from the [[wikipedia:Yakuza_(franchise)|Yakuza game series]] in which it was known as '''DiEvent'''. | |||
== File Structure == | |||
Each '''DvScene''' consists of 2 parts, '''DvCommon''' and '''DvResource'''. | |||
=== DvCommon === | |||
'''DvCommon''' consists of: | |||
* '''Frame start and end'''. | |||
* '''Number of visual nodes''' (not confirmed). | |||
* '''Cuts''', the timestamps of every camera cut in the cinematic. | |||
* '''Pages''', for skipping frames in the cutscene, based on a set condition. Used for QTEs. | |||
* '''Resource Cuts''', timestamps when the Resources should deload (all of the time it's a single item, obviously). | |||
* '''Node''', the main Path DvNode. | |||
The main path DvNode is the base node of the entire dvscene. Path standing for its Node Category. | |||
'''Every DvNode contains:''' | |||
* '''GUID''', used to connect the node to resources or just to easily tell them apart. Every node has a unique GUID. | |||
* '''Name''', to easily organize the nodes. | |||
* '''Node Category''', changes the nodes type, each node type does something else. | |||
* '''Node Flags''' | |||
* '''Priority''' | |||
* '''Child Nodes''', the child nodes of the node. | |||
* '''Node Data''', the parameters and values that change based on the Node Category. | |||
The node data is dependant on the Node Category, every category has its own set of parameters. | |||
{| class="wikitable" | |||
|+Node Categories in Sonic Frontiers | |||
!Name | |||
!Description | |||
!In-Engine Name | |||
!Basic structure | |||
|- | |||
|Path | |||
|Transforms the child nodes of this node | |||
|DvNodePath | |||
|Contains a Matrix4x4 which is then used to do transforms. | |||
|- | |||
|Camera | |||
|Creates a Camera Object in to the cinematic | |||
|DvNodeCamera | |||
|Usually empty, but it has support for a list of Frame Progressions, used to skip frames in the camera animation. | |||
|- | |||
|Camera Motion | |||
|Adds animation to the parent node Camera | |||
|DvNodeCameraMotion | |||
|Contains the frame start and end of the camera animation. The GUID connects the node to a Resource to set the [[Resources/Camera Animation|Camera Animation]] file. | |||
|- | |||
|Character | |||
|Creates a Character Model Object in to the cinematic | |||
|DvNodeCharacter | |||
|Contains the Model Name, Skeleton Name and sometimes a so called Internal Name is used; mostly used for characters that are very common, such as Sonic, Tails etc. These have a special shortcut for each, i.e. '''sh - Shadow, snc - Sonic, kn - Knuckles'''. The GUID connects the node to a Resource to set the [[Resources/Animation State Machine|Animation State Machine]] file. | |||
|- | |||
|Character Motion | |||
|Adds animation to the parent node Character | |||
|DvNodeCharacterMotion | |||
|Contains the frame start and end of the animation, [[Resources/Animation State Machine|Animation State Machine]] state name and animation speed. The GUID connects the node to a Resource to set the animation file. | |||
|- | |||
|Model | |||
|Adds a Model Object in to the cinematic | |||
|DvNodeModel | |||
|The exact same as Character. | |||
|- | |||
|Model Motion | |||
|Adds animation to the parent node Model | |||
|DvNodeModelMotion | |||
|The exact same as Character Motion | |||
|- | |||
|Model Node | |||
|Creates a node to which other nodes can be attached as if it was the bone of the parent Character node | |||
|DvNodeModelNode | |||
|Contains the bones name. | |||
|- | |||
|Element | |||
|Subcategory for nodes, contains mostly game specific elements such as DvElementRifleBeastLighting from [[Games/Sonic Frontiers|Sonic Frontiers]] | |||
|DvElement | |||
|Contains the Element ID, frame start and end, play type of the element and update timing of the element. | |||
There's only 3 Element Play Types and they're very straight forward, Normal - plays the element normally; OneShot - plays only once; Always - plays always. | |||
Update timing is a value that consists of multiple different types to change the update timings of the element, alot of these have yet to be found purposes. | |||
|} | |||
=== DvResource === | |||
'''DvResource''' is an array of resources that are loaded for a '''DvScene'''. These are connected with '''GUIDs''' to several '''DvNode types'''. | |||
They only consist of a '''filename''', '''GUID''' and '''file type'''. | |||
{| class="wikitable" | |||
|+Resource Types in Sonic Frontiers | |||
!Name | |||
!File extension | |||
!Used by Node | |||
|- | |||
|Character | |||
|'''[[Resources/Animation State Machine|(.asm)]]''' | |||
|Character | |||
|- | |||
|Camera Motion | |||
|'''[[Resources/Camera Animation|(.cam-anim)]]''' | |||
|Camera Motion | |||
|- | |||
|Character Motion | |||
|'''[[Resources/PXD Animation|(.anm.pxd)]]''' | |||
|Character Motion | |||
|- | |||
|Model | |||
|'''[[Resources/Animation State Machine|(.asm)]]''' | |||
|Model | |||
|} | |||
== Technical Info == | |||
All of the pointers in DvScene are 32-bit and relative to DvCommon. | |||
This is a structure that's used throughout DvScene, it's an easy way to read an array.<syntaxhighlight lang="c++" start="0"> | |||
template<typename T> | |||
struct DvObject{ | |||
int count; // amount of items in the array | |||
int size; // the total size of of all the elements | |||
long long unknown; // no instance with data here has been found | |||
T items; // the array itself, not a pointer | |||
}; | |||
</syntaxhighlight> | |||
DvScene starts with two simple values, the pointers to DvCommon and DvResource<syntaxhighlight lang="c++"> | |||
struct DvScene{ | |||
DvCommon* common; // 32-bit pointer relative to DvCommon | |||
DvObject<DvResource>* resources; // 32-bit pointer relative to DvCommon | |||
}; | |||
</syntaxhighlight> | |||
Before going into DvCommon, we first need to define the structures that are used in DvCommon. | |||
There's a fairly easy to use system for skipping frames for either translation issues or QTEs. They're called DvPages. <syntaxhighlight lang="c++">struct DvCondition{ | |||
int type; // the condition type | |||
uint parametersSize; // the size of condition dataa | |||
long unknown; // no instance with data here has been found | |||
char parameterData; // the data of the parameter, different for every condtion type | |||
}; | |||
struct DvTransition{ | |||
uint destinationPageID; // the page it should jump to | |||
uint conditionCount; // amount of conditions | |||
ulong conditionSize; // size of conditions | |||
}; | |||
struct DvPage{ | |||
uint unk0; // unknown | |||
uint unk1; // unknown | |||
uint frameStart; // the start tick of the page, it's in ticks meaning it's * 100 | |||
uint frameEnd; // the end tick of the page, it's in ticks meaning it's * 100 | |||
uint transitionCount; // amount of transitions | |||
uint transitionSize; // size of transitions | |||
uint skipFrame; // the tick the cutscene should skip to, it's in ticks meaning it's * 100 | |||
uint index; // the pages index | |||
uint pageSize; // size of the pageData | |||
char empty[12]; | |||
char name[32]; // the name of the page | |||
char pageData; // the data of the page, hasn't been researched | |||
DvTransition transitions; | |||
};</syntaxhighlight>The DvPages use ticks, or also could be called just a ''truncated float.'' | |||
The important part of DvScene's, the DvNode.<syntaxhighlight lang="c++"> | |||
struct DvNode{ | |||
Guid guid; // unique identifier for the node, also used for connection with DvResource | |||
uint nodeCategory; // the type of node | |||
uint nodeSize; // size of the node data | |||
uint childCount; // amount of child nodes | |||
uint nodeFlags; // yet to be researched | |||
uint priority; // the priority of the node when reading | |||
char empty[12]; | |||
char name[64]; // the name of the node | |||
char nodeData; // the data of the node, different for every node category | |||
DvNode childNodes; // the children of this node | |||
}; | |||
</syntaxhighlight>The Node Data is different for every single Node Category, it's the parameters of the node itself. | |||
Now the controller of DvScenes, DvCommon.<syntaxhighlight lang="c++"> | |||
struct DvDisableFrame{ | |||
float start; | |||
float end; | |||
}; | |||
struct DvCommon{ | |||
long unknown; // not read by the game | |||
float frameStart; // the start frame of the cutscene | |||
float frameEnd; // the end frame of the cutscene | |||
uint drawNodeNumber; // amount of visual nodes (unconfirmed, not read by the game) | |||
DvObject<float>* cuts; // every camera cut in cutscene | |||
DvObject<DvPage>* pages; // pages, used for QTEs and such | |||
DvObject<DvDisableFrame>* disableFrames; // ranges, which when playing the cutscene will get skipped | |||
DvObject<float>* resourceCuts; // when the resource should deload, always has just one item | |||
DvObject<float>* soundCuts; // not read by the game | |||
DvNode* node; // the main node of the cutscene | |||
float chainCameraIn; // not read by the game | |||
float chainCameraOut; // not read by the game | |||
int type; // unknown | |||
int skipPointTick; // not read by the game | |||
}; | |||
</syntaxhighlight>All of the pointers are 32-bit and relative to DvCommon itself. | |||
The second important part of DvScene, is the DvResource.<syntaxhighlight lang="c++"> | |||
struct DvResource{ | |||
Guid guid; // unique identifier for the resource, used to connect with DvNodes | |||
uint type; // the file type this resource is trying to use | |||
uint unk0; // unknown, always 0 | |||
uint unk1; // unknown, always 1 | |||
char filename[192]; // the filename of the file it's loading | |||
char unk2[596]; // unknown, could still be just space for the filename | |||
}; | |||
</syntaxhighlight> | |||
Latest revision as of 12:07, 27 August 2025
| Resource Type | Cinematics |
|---|---|
| File Extension | .dvscene |
| Used In Games | |
| Editing Tools | |
| Reverse Engineering Status | Almost finished |
DvScene (also known as DiEvent) is a file format that's been used in Hedgehog Engine 2 since Sonic Frontiers, it's a collection of nodes and resources that are easily editable for simple modification or creation of new cutscenes/cinematics.
The format and sub-system originates from the Yakuza game series in which it was known as DiEvent.
File Structure[edit | edit source]
Each DvScene consists of 2 parts, DvCommon and DvResource.
DvCommon[edit | edit source]
DvCommon consists of:
- Frame start and end.
- Number of visual nodes (not confirmed).
- Cuts, the timestamps of every camera cut in the cinematic.
- Pages, for skipping frames in the cutscene, based on a set condition. Used for QTEs.
- Resource Cuts, timestamps when the Resources should deload (all of the time it's a single item, obviously).
- Node, the main Path DvNode.
The main path DvNode is the base node of the entire dvscene. Path standing for its Node Category.
Every DvNode contains:
- GUID, used to connect the node to resources or just to easily tell them apart. Every node has a unique GUID.
- Name, to easily organize the nodes.
- Node Category, changes the nodes type, each node type does something else.
- Node Flags
- Priority
- Child Nodes, the child nodes of the node.
- Node Data, the parameters and values that change based on the Node Category.
The node data is dependant on the Node Category, every category has its own set of parameters.
| Name | Description | In-Engine Name | Basic structure |
|---|---|---|---|
| Path | Transforms the child nodes of this node | DvNodePath | Contains a Matrix4x4 which is then used to do transforms. |
| Camera | Creates a Camera Object in to the cinematic | DvNodeCamera | Usually empty, but it has support for a list of Frame Progressions, used to skip frames in the camera animation. |
| Camera Motion | Adds animation to the parent node Camera | DvNodeCameraMotion | Contains the frame start and end of the camera animation. The GUID connects the node to a Resource to set the Camera Animation file. |
| Character | Creates a Character Model Object in to the cinematic | DvNodeCharacter | Contains the Model Name, Skeleton Name and sometimes a so called Internal Name is used; mostly used for characters that are very common, such as Sonic, Tails etc. These have a special shortcut for each, i.e. sh - Shadow, snc - Sonic, kn - Knuckles. The GUID connects the node to a Resource to set the Animation State Machine file. |
| Character Motion | Adds animation to the parent node Character | DvNodeCharacterMotion | Contains the frame start and end of the animation, Animation State Machine state name and animation speed. The GUID connects the node to a Resource to set the animation file. |
| Model | Adds a Model Object in to the cinematic | DvNodeModel | The exact same as Character. |
| Model Motion | Adds animation to the parent node Model | DvNodeModelMotion | The exact same as Character Motion |
| Model Node | Creates a node to which other nodes can be attached as if it was the bone of the parent Character node | DvNodeModelNode | Contains the bones name. |
| Element | Subcategory for nodes, contains mostly game specific elements such as DvElementRifleBeastLighting from Sonic Frontiers | DvElement | Contains the Element ID, frame start and end, play type of the element and update timing of the element.
There's only 3 Element Play Types and they're very straight forward, Normal - plays the element normally; OneShot - plays only once; Always - plays always. Update timing is a value that consists of multiple different types to change the update timings of the element, alot of these have yet to be found purposes. |
DvResource[edit | edit source]
DvResource is an array of resources that are loaded for a DvScene. These are connected with GUIDs to several DvNode types.
They only consist of a filename, GUID and file type.
| Name | File extension | Used by Node |
|---|---|---|
| Character | (.asm) | Character |
| Camera Motion | (.cam-anim) | Camera Motion |
| Character Motion | (.anm.pxd) | Character Motion |
| Model | (.asm) | Model |
Technical Info[edit | edit source]
All of the pointers in DvScene are 32-bit and relative to DvCommon.
This is a structure that's used throughout DvScene, it's an easy way to read an array.
template<typename T>
struct DvObject{
int count; // amount of items in the array
int size; // the total size of of all the elements
long long unknown; // no instance with data here has been found
T items; // the array itself, not a pointer
};
DvScene starts with two simple values, the pointers to DvCommon and DvResource
struct DvScene{
DvCommon* common; // 32-bit pointer relative to DvCommon
DvObject<DvResource>* resources; // 32-bit pointer relative to DvCommon
};
Before going into DvCommon, we first need to define the structures that are used in DvCommon.
There's a fairly easy to use system for skipping frames for either translation issues or QTEs. They're called DvPages.
struct DvCondition{
int type; // the condition type
uint parametersSize; // the size of condition dataa
long unknown; // no instance with data here has been found
char parameterData; // the data of the parameter, different for every condtion type
};
struct DvTransition{
uint destinationPageID; // the page it should jump to
uint conditionCount; // amount of conditions
ulong conditionSize; // size of conditions
};
struct DvPage{
uint unk0; // unknown
uint unk1; // unknown
uint frameStart; // the start tick of the page, it's in ticks meaning it's * 100
uint frameEnd; // the end tick of the page, it's in ticks meaning it's * 100
uint transitionCount; // amount of transitions
uint transitionSize; // size of transitions
uint skipFrame; // the tick the cutscene should skip to, it's in ticks meaning it's * 100
uint index; // the pages index
uint pageSize; // size of the pageData
char empty[12];
char name[32]; // the name of the page
char pageData; // the data of the page, hasn't been researched
DvTransition transitions;
};
The DvPages use ticks, or also could be called just a truncated float.
The important part of DvScene's, the DvNode.
struct DvNode{
Guid guid; // unique identifier for the node, also used for connection with DvResource
uint nodeCategory; // the type of node
uint nodeSize; // size of the node data
uint childCount; // amount of child nodes
uint nodeFlags; // yet to be researched
uint priority; // the priority of the node when reading
char empty[12];
char name[64]; // the name of the node
char nodeData; // the data of the node, different for every node category
DvNode childNodes; // the children of this node
};
The Node Data is different for every single Node Category, it's the parameters of the node itself.
Now the controller of DvScenes, DvCommon.
struct DvDisableFrame{
float start;
float end;
};
struct DvCommon{
long unknown; // not read by the game
float frameStart; // the start frame of the cutscene
float frameEnd; // the end frame of the cutscene
uint drawNodeNumber; // amount of visual nodes (unconfirmed, not read by the game)
DvObject<float>* cuts; // every camera cut in cutscene
DvObject<DvPage>* pages; // pages, used for QTEs and such
DvObject<DvDisableFrame>* disableFrames; // ranges, which when playing the cutscene will get skipped
DvObject<float>* resourceCuts; // when the resource should deload, always has just one item
DvObject<float>* soundCuts; // not read by the game
DvNode* node; // the main node of the cutscene
float chainCameraIn; // not read by the game
float chainCameraOut; // not read by the game
int type; // unknown
int skipPointTick; // not read by the game
};
All of the pointers are 32-bit and relative to DvCommon itself. The second important part of DvScene, is the DvResource.
struct DvResource{
Guid guid; // unique identifier for the resource, used to connect with DvNodes
uint type; // the file type this resource is trying to use
uint unk0; // unknown, always 0
uint unk1; // unknown, always 1
char filename[192]; // the filename of the file it's loading
char unk2[596]; // unknown, could still be just space for the filename
};