public void WriteParameterMetadata(BinaryStream writer, List <SDEFBase> metadataList, SDEFBase sdefBase)
        {
            for (int j = 0; j < sdefBase.ChildParameters.Count; j++)
            {
                SDEFBase entry = sdefBase.ChildParameters[j];
                writer.WriteInt32(entry.Name.Length + 1);
                writer.WriteString(entry.Name, StringCoding.ZeroTerminated);

                if (entry is SDEFParamArray)
                {
                    writer.WriteInt16((short)ValueType.Array);
                }
                else
                {
                    SDEFParam param = entry as SDEFParam;
                    if (entry.NodeType == NodeType.RawValue)
                    {
                        writer.WriteInt16((short)param.RawValue.Type);
                    }
                    else if (entry.NodeType == NodeType.CustomType)
                    {
                        int typeIndex = metadataList.FindIndex(metaType => metaType.CustomTypeName == entry.CustomTypeName);
                        writer.WriteInt16((short)typeIndex);
                    }
                }

                writer.WriteBoolean(entry.NodeType == NodeType.CustomType, BooleanCoding.Word);

                if (entry is SDEFParamArray array)
                {
                    if (entry.NodeType == NodeType.RawValueArray)
                    {
                        writer.WriteInt16((short)array.RawValuesArray[0].Type);
                    }
                    else
                    {
                        int typeIndex = metadataList.FindIndex(metaType => metaType.CustomTypeName == entry.CustomTypeName);
                        writer.WriteInt16((short)typeIndex);
                    }

                    writer.WriteBoolean(entry.NodeType == NodeType.CustomTypeArray, BooleanCoding.Word);

                    if (entry.NodeType == NodeType.CustomTypeArray)
                    {
                        if (Version == 0)
                        {
                            writer.WriteInt32(0);
                        }
                        else
                        {
                            writer.WriteInt32((short)array.Values.Count);
                        }
                    }
                    else
                    {
                        if (Version == 0)
                        {
                            writer.WriteInt32(0);
                        }
                        else
                        {
                            writer.WriteInt32((short)array.RawValuesArray.Length);
                        }
                    }
                }
            }
        }
        public static void Traverse(BinaryStream reader, int version, PseudoReflectionObject sdef, SDEFBase parentNode, SDEFMetaData sdefMetadata, SDEFMetaDataCategory nodeCategory, ref int depth)
        {
            depth++;
            foreach (var entry in nodeCategory.Entries)
            {
                SDEFBase current;
                if (!entry.HasCustomType && (ValueType)entry.TypeOrIndex == ValueType.Array)
                {
                    current = new SDEFParamArray(); // Param is a param array
                }
                else
                {
                    current = new SDEFParam(); // Param is regular parameter, but if its a custom type it may have children parameters
                }
                current.Name = entry.Name;
                parentNode.ChildParameters.Add(current);

                sdef.ParameterList.Add(current);
                if (entry.HasCustomType)
                {
                    current.CustomTypeName = sdefMetadata.Categories[entry.TypeOrIndex].Name;
                    current.NodeType       = NodeType.CustomType;

                    // Traverse children parameter for this basic type
                    Traverse(reader, version, sdef, current, sdefMetadata, sdefMetadata.Categories[entry.TypeOrIndex], ref depth);
                }
                else if ((ValueType)entry.TypeOrIndex == ValueType.Array)
                {
                    if (entry.ArrayHasCustomType)
                    {
                        current.NodeType       = NodeType.CustomTypeArray;
                        current.CustomTypeName = sdefMetadata.Categories[entry.ArrayCategoryIndex].Name;
                        if (version == 0)
                        {
                            entry.ArrayLength = reader.ReadUInt32();
                        }

                        for (int i = 0; i < entry.ArrayLength; i++)
                        {
                            // Create the element for the array to add later
                            var arrayElement = new SDEFParam();
                            arrayElement.CustomTypeName = current.CustomTypeName;
                            arrayElement.NodeType       = NodeType.CustomType;
                            arrayElement.Name           = $"[{i}]";
                            Traverse(reader, version, sdef, arrayElement, sdefMetadata, sdefMetadata.Categories[entry.ArrayCategoryIndex], ref depth);

                            // Don't forget to add our array element to the global parameter list
                            sdef.ParameterList.Add(arrayElement);
                            (current as SDEFParamArray).Values.Add(arrayElement);
                        }
                    }
                    else
                    {
                        current.CustomTypeName = nodeCategory.Name;
                        current.NodeType       = NodeType.RawValueArray;
                        if (version == 0)
                        {
                            entry.ArrayLength = reader.ReadUInt32();
                        }

                        (current as SDEFParamArray).RawValuesArray = new SDEFVariant[entry.ArrayLength];
                        for (int i = 0; i < entry.ArrayLength; i++)
                        {
                            var val = ReadData(reader, entry, (ValueType)entry.ArrayCategoryIndex);
                            (current as SDEFParamArray).RawValuesArray[i] = val;
                        }
                    }
                }
                else
                {
                    current.NodeType = NodeType.RawValue;
                    var variant = ReadData(reader, entry, (ValueType)entry.TypeOrIndex);
                    (current as SDEFParam).RawValue = variant;
                }

                current.Depth = depth;
            }
            depth--;
        }