ROOM (File Format): Difference between revisions

no edit summary
>Aruki
No edit summary
>Aruki
No edit summary
Line 1: Line 1:
The '''ROOM format''' is used to store object layout data in Tropical Freeze.
The '''ROOM format''' is used to store object layout data in Tropical Freeze.


{{research|major|Most of this format hasn't been researched yet.}}
{{research|moderate|Still a lot of unknown values and a lot of things that aren't known about how objects interact with each other.}}


__TOC__
__TOC__
Line 7: Line 7:
== Format ==
== Format ==


=== RMHD ===
{| class="wikitable"
! Type
! Count
! Name
! Notes
|-
| [[Form Descriptor (Tropical Freeze)|Form Descriptor]]
| 1
| '''ROOM Form Descriptor'''
| Data type is <code>ROOM</code>
|-
| [[#Header|Header]]
| 1
| '''Header'''
|
|-
| [[#Layer|Layer]]
| Varying
| '''Layers'''
| Each layer is under its own form. Unsure if the format has a layer count anywhere.
|}
 
=== Header ===


{| class="wikitable"
{| class="wikitable"
! Type
! Type
! Size
! Count
! Description
! Name
! Notes
|-
| [[Form Descriptor (Tropical Freeze)|Form Descriptor]]
| 1
| '''Header Descriptor'''
| Data type is <code>HEAD</code>
|-
| [[#Room Header|Room Header]]
| 1
| '''Room Header'''
|
|-
| [[#Performance Groups|Performance Groups]]
| 1
| '''Performance Groups'''
|
|-
| [[#Generated Object Map|Generated Object Map]]
| 1
| '''Generated Object Map'''
|
|-
| [[#Load Unit|Load Unit]]
| Varies
| '''Load Units'''
| Unsure whether there's a count of these
|}
 
==== Room Header ====
 
{| class="wikitable"
! Type
! Count
! Name
! Notes
|-
|-
| [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]]
| [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]]
| 0x18
| 1
| '''RMHD chunk descriptor'''
| '''Room Header Descriptor'''
| Data type is <code>RMHD</code>
|-
|-
| u16
| u16
| 2
| 1
| {{unknown|'''Unknown''' (Always 3?)}}
| {{unknown|'''Unknown'''}}
| Always 3?
|}
|}


=== PGRP ===
==== Performance Groups ====
 
PGRP likely stands for Performance Group, a term referenced by a few objects.


{| class="wikitable"
{| class="wikitable"
! Type
! Type
! Size
! Count
! Description
! Name
! Notes
|-
|-
| [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]]
| [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]]
| 0x18
| 1
| '''PGRP chunk descriptor'''
| '''Performance Groups Descriptor'''
| Data type is <code>PGRP</code>
|-
|-
| u16
| u16
| 2
| 1
| '''Count'''
| '''Performance Group Count'''
|
|-
| [[#Performance Group|Performance Group]]
| ''Performance Group Count''
| '''Performance Groups'''
|
|}
|}


For count:
===== Performance Group =====


{| class="wikitable"
{| class="wikitable"
! Type
! Type
! Size
! Count
! Description
! Name
! Notes
|-
|-
| u32
| u32
| 4
| 1
| '''Name length'''
| '''Name Length'''
|
|-
|-
| string
| char
| -
| ''Name Length''
| '''Name''' (not zero-terminated)
| '''Performance Group Name'''
| Not zero-terminated
|-
|-
| u128
| GUID
| 0x10
| 1
| '''ID'''
| '''PerformanceGroupController Instance GUID'''
|
|-
|-
| u8
| bool
| 1
| 1
| {{unknown|'''Unknown'''}}
| {{unknown|'''Unknown'''}}
|
|-
|-
| u16
| u16
| 2
| 1
| '''ID count''' (IC)
| '''Layer Count'''
|
|-
|-
| u128
| GUID
| 0x10 * IC
| ''Layer Count''
| '''IDs'''
| '''Layer GUIDs'''
|
|}
|}


=== LGEN ===
==== Generated Object Map ====


{| class="wikitable"
{| class="wikitable"
! Type
! Type
! Size
! Count
! Description
! Name
! Notes
|-
|-
| [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]]
| [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]]
| 0x18
| 1
| '''LGEN chunk descriptor'''
| '''Generated Object Map Descriptor'''
| Data type is <code>LGEN</code>
|-
|-
| u16
| u16
| 2
| 1
| '''Count'''
| '''Count'''
|
|-
| [[#Generated Object|Generated Object]]
| ''Count''
| '''Generated Object Array'''
|
|}
===== Generated Object =====
{| class="wikitable"
! Type
! Count
! Name
! Notes
|-
| GUID
| 1
| {{unknown|'''Unknown'''}}
|
|-
| GUID
| 1
| {{unknown|'''Unknown'''}}
|
|}
==== Load Unit ====
{| class="wikitable"
! Type
! Count
! Name
! Notes
|-
| [[Form Descriptor (Tropical Freeze)|Form Descriptor]]
| 1
| '''Load Unit Descriptor'''
| Data type is <code>LUNT</code>
|-
| [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]]
| 1
| '''Load Unit Header Descriptor'''
| Data type is <code>LUHD</code>
|-
| u32
| 1
| '''Name Length'''
|
|-
| char
| ''Name Length''
| '''Load Unit Name'''
| For some reason these seem to generally have really short names (sometimes a single character).
|-
| GUID
| 1
| {{unknown|'''Unknown'''}}
| Probably the GUID for this load unit
|-
| u16
| 1
| {{unknown|'''Unknown'''}}
|
|-
| [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]]
| 1
| '''Load Unit Resources Descriptor'''
| Data type is <code>LRES</code>
|-
| u32
| 1
| '''Resource Count'''
|
|-
| GUID
| ''Resource Count''
| '''Load Unit Resources Array'''
| Likely a list of all resources that are used by this load unit.
|-
| [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]]
| 1
| '''Load Unit Layers Descriptor'''
| Data type is <code>LLYR</code>
|-
| u32
| 1
| '''Layer Count'''
|
|-
| GUID
| ''Layer Count''
| '''Load Unit Layers Array'''
| Likely a list of all layers that are part of this load unit. (Note that it seems layers can be included in multiple load units.)
|}
|}


For count:
==== Layer ====


{| class="wikitable"
{| class="wikitable"
! Type
! Type
! Size
! Count
! Description
! Name
! Notes
|-
|-
| u128
| [[Form Descriptor (Tropical Freeze)|Form Descriptor]]
| 0x10
| 1
| '''ID'''
| '''Layer Form Descriptor'''
| Data type is <code>LAYR</code>
|-
|-
| u128
| [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]]
| 0x10
| 1
| '''ID'''
| '''Layer Header Descriptor'''
| Data type is <code>LHED</code>
|-
| u32
| 1
| '''Name Length'''
|
|-
| char
| ''Name Length''
| '''Layer Name'''
|
|-
| GUID
| 1
| '''Layer ID'''
|
|-
| u8
| 21
| {{unknown|'''Unknown Data'''}}
| This section is usually entirely 0s so not sure what the structure of it is.
|-
| [[Form Descriptor (Tropical Freeze)|Form Descriptor]]
| 1
| {{unknown|'''Unknown Descriptor'''}}
| Data type is <code>GSRP</code>. Often has a size of 0.
|-
| [[Form Descriptor (Tropical Freeze)|Form Descriptor]]
| 1
| '''Script Descriptor'''
| Data type is <code>SRIP</code>
|-
| [[#Game Object Component|Game Object Component]]
| Varies
| '''Components'''
| Unsure if there is a layer component count.
|}
|}


=== COMP ===
===== Game Object Component =====


{| class="wikitable"
{| class="wikitable"
! Type
! Type
! Size
! Count
! Description
! Name
! Notes
|-
|-
| [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]]
| [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]]
| 0x18
| 1
| '''COMP chunk descriptor'''
| '''Component Descriptor'''
| Data type is <code>COMP</code>
|-
|-
| u32
| u32
| 4
| 1
| '''Object type'''
| '''[[#Component Types|Component Type]]'''
| This appears to be a hash of the component name.
|-
|-
| u128
| GUID
| 0x10
| 1
| '''Instance ID'''
| '''Instance ID'''
|
|-
|-
| u32
| u32
| 4
| 1
| '''Instance name length'''
| '''Name Length'''
|
|-
|-
| string
| char
| -
| ''Name Length''
| '''Instance name''' (not zero-terminated)
| '''Instance Name'''
|
|}
 
The remaining data seems to have two structures; one that's used by most objects and one that's specific to GameObject components.
 
'''Regular structure:'''
 
{| class="wikitable"
! Type
! Count
! Name
! Notes
|-
|-
| u16
| u16
| 2
| 1
| '''Connection count'''
| '''Connection Count'''
|
|-
| [[#Connection|Connection]]
| ''Connection Count''
| '''Connection Array'''
| These establish links to other components to allow them to interact
|-
| u32
| 1
| '''Property Count'''
|
|-
| [[#Property|Property]]
| ''Property Count''
| '''Object Properties'''
|
|}
 
'''GameObject structure:'''
 
{| class="wikitable"
! Type
! Count
! Name
! Notes
|-
| u32
| 1
| '''Sub-Component Count'''
|
|-
| [[#Sub-Component|Sub-Component]]
| ''Sub-Component Count''
| '''Sub-Component Array'''
| Seems to describe other script components that are children of this one.
|-
| bool
| 1
| {{unknown|'''Unknown'''}}
| This is likely the Active flag that appears on every object in the previous games.
|-
| vector3
| 1
| '''Position'''
|
|-
| vector3
| 1
| '''Rotation'''
| Euler XYZ angles in degrees (presumably in ZYX order like the previous games).
|-
| vector3
| 1
| '''Scale'''
|
|}
|}


Each connection is structured as:
====== Connection ======


{| class="wikitable"
{| class="wikitable"
! Offset
! Type
! Type
! Size
! Count
! Description
! Name
! Notes
|-
|-
| 0x0
| char
| char[4]
| 4
| 4
| '''State'''
| '''Event'''
| This is the event that causes the connection to trigger. (These are what were called States in the previous games.)
|-
|-
| 0x4
| char
| char[4]
| 4
| 4
| '''Message'''
| '''Action'''
| Action that the connected object should execute when the connection triggers. (These are what were called Messages in the previous games.)
|-
|-
| 0x8
| GUID
| u128
| 1
| 0x10
| '''Target Instance ID'''
| '''Target Instance ID'''
| Instance ID of the target object that
|-
|-
| 0x18
| u32
| u32
| 1
| {{unknown|'''Unknown'''}}
|
|}
====== Property ======
{| class="wikitable"
! Type
! Count
! Name
! Notes
|-
| u32
| 1
| '''Property ID'''
| 32-bit hash of the property name.
|-
| u16
| 1
| '''Property Size'''
|
|-
| {{unknown|}}
| {{unknown|}}
| '''Property Data'''
| Varies depending on the type of the property (which is hardcoded depending on the property ID).
|}
====== Sub-Component ======
This structure is used to define sub-components that are attached to GameObject components.
{| class="wikitable"
! Type
! Count
! Name
! Notes
|-
| char
| 4
| 4
| '''Type'''
| Usually <code>COMP</code>, but sometimes other things like <code>IL00</code>. Not sure what it means.
|-
| GUID
| 1
| '''Component ID'''
|
|-
| bool
| 1
| {{unknown|'''Unknown'''}}
| {{unknown|'''Unknown'''}}
| Might be an Active/Enabled flag.
|}
|}


Following is property data; size and contents vary by object type.
== Component Types ==
 
==== Component Types ====


{| class="wikitable"
{| class="wikitable"
Anonymous user