User Tools

Site Tools


kirby64_the_crystal_shards:level_settings_blocks

This is an old revision of the document!


Level Settings Block

Every Area has its own Level Settings Block defined inside the Main Stage Table (see: Levels). The level settings block defines the camera, collision, and entities spawned inside the stage. The Basic Structure of the Level Settings Block is as follows.

Level Settings Layout

  1. Main Header
  2. Vertices
  3. Triangles
  4. Surface Normals
  5. Triangle Groups/Cells
  6. Surface Normals Groups/Cells
  7. Dynamic Geometry Lists
  8. Dynamic Geometry Groups
  9. Water Data
  10. Water Normals
  11. Collision Header (referred to by Main Header[0])
  12. Pathing Nodes
  13. Kirby Node Params & Camera Nodes
  14. Node Connections
  15. Unk Bytes
  16. Unk Floats
  17. Path Node Headers
  18. Node Header (referred to by Main Header[1])
  19. Entity List (referred to by Main Header[2])

Main Header

The main header contains references to the three main sections of the level settings block: Collision, Camera and the Entity List.

struct Main_Header
{
/*0x00*/    struct Collision_Header    *Collision_Header;
/*0x04*/    struct Node_Header    *Node_Header;
/*0x08*/    struct Entities    (*Entity_IDs)[];
};

Collision

Collision is handled by several different lists that combine to create the level geometry.

Vertices

Vertices are made up of unsorted s16 tripets of x, y and z position.

The vertex array starts with a 0x270F triplet and ends with a single 0x9999.

Triangles

Triangles are made by connecting 3 vertices referenced by their index. (e.g. 0,1,2 is made up of vertices 0,1 and 2 in the list). Every Triangle has a struct that has additional parameters telling the game how to handle collision.

struct Col_Triangle
{
/*0x0*/ 	u16        Vertex[3];
/*0x6*/ 	u16	   Polygon_Number;
/*0x8*/ 	u16        Solidity_Type; //(1 forward norm, 2 back norm, 4 no shadow, 8 non solid)
/*0xA*/ 	u16	   Destructable_Group_Index;
/*0xC*/ 	u16	   Break_Particle; //(seen in DEDEDE hammer break)
/*0xE*/ 	u16	   Halt_Movement; //warp related? Maybe dest (kirby cant move while on top of this if 1)
/*0x10*/	s16	   Col_Param1; //Amount to move kirby while on certain col types or Break Condition
/*0x12*/	u16	   Collision_Type; //see col type list
};

The following is a list of Collision_Type values known.

  • 0x1 - wall ladder
  • 0x2 - rope
  • 0x3 - death floor
  • 0x4 - Platform you can jump through/Fall Through
  • 0x8 - warp
  • 0x9 - STAR BLOCK/Breakable Blocks
  • 0xD - Breakable Ceiling/Breaks when launched through
  • 0x10 - DEDEDE hammer break
  • 0x12 - move kirby backwards while on top
  • 0x13 - move kirby forwards while on top
  • 0x14 - Platform with custom movement (seems to be in some sort of object list separate from normal level geometry)

The triangle list begins with a placeholder struct of (0,1,2,3,4,5,6,7,8,9)

Triangle Normals

Triangle normals are stored as a F32 array of 4 values. The first three values are the surface normals while the last is the origin offset. Together the normals should solve the plane equation (see:link).

The list of normals always starts with (-1,-2,-3,-4) and is used to refer to walls, only floor and ceilings have their normals listed. The actual value of the first set of normal is not known to have any significance. Redundant normals are not repeated, but are just referenced multiple times (e.g. two triangles with norm Y==1 and offset==0 share their normal).

struct Normal
{
/*0x0*/    Vec3f    Surface_Normals;
/*0xC*/    f32      Origin_Offset;
};

Triangle Groups

The triangle groups is a list of triangles used to make collision sorting more efficient.

The triangle group list begins with a flag of 0x8192 and ends with 0x9999. Each triangle group is a u16 list of indices to the triangle struct array.

Each triangle group represents one polygon index (0x6 in tri struct). The groups are defined by setting the msb at the last triangle in that group. This means any coplanar, connected N-gon will be a single polygon group. Triangle groups are searched in reverse order.

There should be an equal amount of items in the triangle list and triangle group list.

Normal Groups

The normal groups is a list that matches each normal to a triangle. It is formed in pairs with the first item being the index of the normal, and the second item being the index of the triangle.

Normal groups are sorted by polygon index. Only floors & ceilings are referenced by the normal groups, walls are given the first index of the normals list (-1,-2,-3,-4).

struct Norm_Group
{
/*0x0*/  u16  Normal_Index;
/*0x2*/  u16  Triangle_Index;
};

Dynamic Geometry Lists

A DynGeo list is referenced by certain collision types using 0xA inside the col tri struct. This is so instead of destroying one triangle, all connected geometry is edited as a single rigid body.

When a triangle is going to be edited, 0xA of the tri struct references the index into this list. This list will then tell the game the index to the array of dynamic geo groups and the number of members in that array.

struct DynGeo_List
{
/*0x0*/  u16  Num_Dynamic_Geo_Group_Members; //Number of connected triangles
/*0x2*/  u16  Index_To_Dynamic_Geo_Group; //(0x30 in col header)
/*0x4*/  u16  Unk_Index; //Gets stored to unk struct
};

The dynamic geo list usually ends with 0x9999, but it is not necessary. The dynamic geo list can also be null, in that case the col header will have a null ptr to match.

Dynamic Geometry Groups

Dynamic geometry groups are an array of u16 indices that reference the tri struct array.

When a triangle is being edited, 0xA in the tri struct points to the dynamic geometry list. From there an index to this dynamic geometry group list is given, and the number of members in that list.

The dynamic geomtry group only has the references to triangles. The transformation (usually destruction) is applied based on col type or specific code.

The dynamic geo geoup array usually ends with 0x9999, but its not necessary. This list can also be null, and will have a null ptr in the col header to match.

Water Data

Water data is an array of water structs that will determine how kirby collides with water. Normals and a bounding box are used instead of polygons to determine collision. First kirby has to be inside the bounding box inside the water data struct. Then the normals are used. Normals are different than collision triangle geometry in that they define an infinite plane. The normal planes intersect to create a closed surface which is used as the collision check.

The bytes inside the water data struct act as bools.

struct Water_Data
{
/*0x0*/    u16    Num_Normals;
/*0x2*/    u16    Norm_Array_Index;
/*0x4*/    u8     Water_Box_Active;
/*0x5*/    u8     Activate_Water_Flow;
/*0x6*/    u8     Water_Flow_Direction;
/*0x7*/    u8     Water_Flow_Speed;
/*0x8*/    f32    Pos1;
/*0xC*/    f32    Pos2;
/*0x10*/   f32    Pos3;
/*0x14*/   f32    Pos4;
};

Water Floats

Works exactly like floats for other collision triangles. Lead by a (1,2,3,4) the followed by (3*norms,origin offset). Follows all the conventions for normals that you'd expect, including n * r = -offset.

This list is only accessed by being pointed to by the water data struct.

Collision Header

The collision header is referred to by the first index inside the main header. The collision header has the following format.

struct Collision_Header
{
/*0x0*/    struct Col_Triangle    *Triangles;
/*0x4*/    u32       Len_Triangles;
/*0x8*/    s16       (*Vertices)[][3];
/*0xC*/    u32       Len_Vertices;
/*0x10*/   struct Normal          (*Triangle_Normals)[];
/*0x14*/   u32       Len_Tiangle_Normals;
/*0x18*/   u16       (*Triangle_Cells)[][2];
/*0x1C*/   u32       Len_Triangle_Cells;
/*0x20*/   u16       (*Triangle_Norm_Cells)[][2];
/*0x24*/   u32       Len_Triangle_Norm_Cells;
/*0x28*/   u32       Num_Floor_Norms; //Should be tri norm cells minus 1
/*0x2C*/   struct DynGeo_List     (*Destructable_Groups)[];
/*0x30*/   u16       (*Destructable Indices)[];
/*0x34*/   struct Water_Data      (*Water_Data)[];
/*0x38*/   u32       Len_Water_Data;
/*0x3C*/   struct Normal          (*Water_Normals)[];
/*0x40*/   u32       Len_Water_Normals;
};

Node_Header

The level nodes are referred to by the second index in the main header. This section tells the game how to move kirby as you progress through the level and how the camera should act.

struct Node_Header
{
/*0x0*/    u32    Num_Path_Nodes;
/*0x4*/    struct Path_Node_Header   (*Path_Node_Header)[];
/*0x8*/    u8     (*Unk_Bytes)[];
/*0xC*/    f32    (*Unk_Floats)[];
};

Path Node Headers

Pathing nodes are sections of the level that have a defined path and camera movement for kirby as he progresses through the level.

Each node has several parts which are pointed to by the path node header array.

struct Path_Node_Header
{
/*0x0*/    struct Kirby_Node	  *Kirby_Node;
/*0x4*/	   struct Path_Node_Footer    *Path_Node_Footer;
/*0x8*/	   struct Node_Connecters     (*Node_Connections)[];
/*0xC*/	   u16		Num_Connections;
/*0xE*/	   u16		Self_Connected;
};

Path Nodes

Path nodes are made up of 3 parts. A footer, a position matrix, and a boundary matrix.

The path node footer contains pointers to the other sections, as well as important data for those sections.

The boundary matrix is a N×1 matrix that has percentage completion for the positional matrix. This matrix tells the game how much each position in the position matrix contributes towards one node.

The position matrix is a 3×N matrix which tells the game the absolute positioning of kirby as you progress through the level. This matrix is how kirby moves in both X and Z when you push to the right.

All together these sections create a path which kirby will walk along when you push right/left. Theyre ordered in the rom as: Position matrix, boundary matrix, path node footer.

struct Path_Node_Footer
{
/*0x00*/    u32    FlagUnk; //0x200 if *Unk should be used
/*0x04*/    u32    Num_Node_Sections;
/*0x08*/    Vec3f  (*Position_Matrix)[];
/*0x0C*/    f32    Inverse_H_Speed;
/*0x10*/    f32    (*Boundary_Matrix)[];
/*0x14*/    f32    (*Unk)[][5];
};

The unknown section is almost always null. All that is known is that it follows the boundary matrix and is an areay of 5 floats, with length of Num_Node_Sections-1.

Camera&Kirby Nodes

These nodes tell the game how to move the camera with respect to the path nodes. There are settings for kirby's graphics (possibly lots of other things aswell) as he progresses through the level, as well as camera movement.

Thr flag in 0xE of Kirby_Node determines if 0x10 or 0x4 is read. A value of 0x10 reads unused3, and a value of 0x1 reads the warp.

The unused3 and unused4 code is read by the game, but seems to do nothing. Its possibly code that was removed after a beta. Opt_1 and opt_2 are used only in 5-5-1.

struct Kirby_Node
{
/*0x00*/	u8      Node_Number;
/*0x01*/        u8      Padding;
/*0x02*/        u16     unk2;
/*0x04*/	struct Level    Warps;
/*0x08*/	u8	unused;
/*0x09*/	u8	Shade_Left;
/*0x0A*/	u8	Shade_Center;
/*0x0B*/	u8	Shade_Right;
/*0x0C*/	u16	unused2;
/*0x0E*/	u16	Unkflag;
/*0x10*/	s16     unused3;
/*0x12*/        s16     unused4;
/*0x14*/	f32     opt_1;
/*0x18*/	f32     opt_2;
/*0x1C*/	u32     unused5;
/*0x20*/        struct Camera_Node    Camera;
};
struct Camera_Node
{
/*0x00*/   u16    Camera_Type;
/*0x02*/   u8     Lock_X_pos;
/*0x03*/   u8     Lock_Y_pos;
/*0x04*/   u8     Lock_Z_pos;
/*0x05*/   u8     unused;
/*0x06*/   u8     unk1;
/*0x07*/   u8     unk2;
/*0x08*/   u8     Follow_X_Angle;
/*0x09*/   u8     unk4;
/*0x0A*/   u8     unk5;
/*0x0C*/   f32    X_Focus_Pos;
/*0x10*/   f32    Y_Focus_Pos;
/*0x14*/   f32    Flag; //always 9999?
/*0x18*/   f32    Near_Clip_Plane;
/*0x1C*/   f32    Far_Clip_Plane;
/*0x20*/   f32[2] Cam_Y_Pos;
/*0x28*/   f32[2] Cam_X_Pos;
/*0x30*/   f32[2] Cam_Z_Pos;
/*0x38*/   f32[2] FOV_Pair;
/*0x40*/   f32[2] Lateral_Y_Pos;
/*0x48*/   f32    Unk6;
/*0x4C*/   f32    Cam_X_Offset_Locked;
/*0x50*/   f32    Unk7;
/*0x54*/   f32    Cam_Y_Pos_Locked;
/*0x58*/   f32[2] Flag2; //a 9999 pair
/*0x60*/   f32    Focus_Y_Above; //while 0x6 is true
/*0x64*/   f32    Focus_Y_Below; //while 0x6 is true
/*0x68*/   f32    Focus_X_Left; //while 0x6 is true
/*0x6C*/   f32    Focus_X_Right; //while 0x6 is true
};

Node Connectors

Node connectors tell the game which nodes to use as kirby hits the boundaries of a node. The number of connections for each node is listed in the path node header.

struct Node_Connectors
{
/*0x00*/    u16     Unused;  //Not entirely sure
/*0x02*/    u16     Current_Node;
/*0x04*/    u16     Unused2; //Not sure
/*0x06*/    u16     Connected_Node;
};

Entity List

The entity list is an array of structs ehich spawn objects as kirby gets in range. It is terminated by an 0x99999999 marker. See Entity IDs for more info

kirby64_the_crystal_shards/level_settings_blocks.1589154314.txt.gz · Last modified: 2020/05/10 23:45 by jesusyoshi54