From 6c8b5798ce9a436e6c2dcb323bc606a081db2dee Mon Sep 17 00:00:00 2001 From: Passive <20432486+PassiveModding@users.noreply.github.com> Date: Thu, 30 Apr 2026 08:43:14 +1000 Subject: [PATCH 1/5] Initial patch 7.5 updates --- Meddle/Meddle.Plugin/Meddle.Plugin.csproj | 3 ++- Meddle/Meddle.Plugin/Services/LayoutService.cs | 10 +++++----- Meddle/Meddle.Plugin/UI/CommonUI.cs | 2 +- Meddle/Meddle.Plugin/UI/LiveCharacterTab.cs | 6 +++--- Meddle/Meddle.Plugin/UI/Windows/DebugWindow.cs | 1 + Meddle/Meddle.Plugin/UI/Windows/MainWindow.cs | 1 + Meddle/Meddle.Plugin/Utils/OnRenderMaterialUtil.cs | 4 ++-- Meddle/Meddle.Plugin/Utils/ParseMaterialUtil.cs | 4 ++-- Meddle/Meddle.Plugin/packages.lock.json | 6 +++--- 9 files changed, 20 insertions(+), 17 deletions(-) diff --git a/Meddle/Meddle.Plugin/Meddle.Plugin.csproj b/Meddle/Meddle.Plugin/Meddle.Plugin.csproj index 1c256ef..cd3ebef 100644 --- a/Meddle/Meddle.Plugin/Meddle.Plugin.csproj +++ b/Meddle/Meddle.Plugin/Meddle.Plugin.csproj @@ -1,4 +1,4 @@ - + 0.0.1 enable @@ -15,6 +15,7 @@ ..\Meddle.Utils\Lib\OtterTex.dll + diff --git a/Meddle/Meddle.Plugin/Services/LayoutService.cs b/Meddle/Meddle.Plugin/Services/LayoutService.cs index a34e3cd..5cffebb 100644 --- a/Meddle/Meddle.Plugin/Services/LayoutService.cs +++ b/Meddle/Meddle.Plugin/Services/LayoutService.cs @@ -250,7 +250,7 @@ private unsafe ParsedInstanceSet[] ParseLayout(LayoutManager* activeLayout) string? path = null; if (primaryPath.HasValue) { - path = primaryPath; + path = primaryPath.ToString(); } return new ParsedUnsupportedInstance((nint)instanceLayout, @@ -387,7 +387,7 @@ private unsafe ParsedInstanceSet[] ParseLayout(LayoutManager* activeLayout) } var primaryPath = sharedGroup->GetPrimaryPath(); - string path = primaryPath.HasValue ? primaryPath : throw new Exception("SharedGroup has no primary path"); + string path = primaryPath.HasValue ? primaryPath.ToString() : throw new Exception("SharedGroup has no primary path"); var furnitureMatch = context.Housing.Furniture.FirstOrDefault(item => item.LayoutInstance == sharedGroupPtr); if (furnitureMatch is not null) @@ -441,7 +441,7 @@ private unsafe ParsedInstanceSet[] ParseLayout(LayoutManager* activeLayout) } var primaryPath = bgPart->GetPrimaryPath(); - string path = primaryPath.HasValue ? primaryPath : throw new Exception("BgPart has no primary path"); + string path = primaryPath.HasValue ? primaryPath.ToString() : throw new Exception("BgPart has no primary path"); var bgChangeHandle = graphics->GetBgChangeMaterial(); (int BgChangeMaterialIndex, string Path)? bgChangeMaterial = null; @@ -640,13 +640,13 @@ private unsafe HousingTerritoryData ParseTerritoryFurniture(LayoutManager* activ var furniture = type switch { HousingTerritoryType.Indoor => ((IndoorTerritory*)territory)->FurnitureManager.FurnitureMemory, - HousingTerritoryType.Outdoor => ((OutdoorTerritory*)territory)->FurnitureStruct.FurnitureMemory, + HousingTerritoryType.Outdoor => ((OutdoorTerritory*)territory)->FurnitureManager.FurnitureMemory, _ => [] }; var objectManager = type switch { HousingTerritoryType.Indoor => &((IndoorTerritory*)territory)->FurnitureManager.ObjectManager, - HousingTerritoryType.Outdoor => &((OutdoorTerritory*)territory)->FurnitureStruct.ObjectManager, + HousingTerritoryType.Outdoor => &((OutdoorTerritory*)territory)->FurnitureManager.ObjectManager, _ => null }; diff --git a/Meddle/Meddle.Plugin/UI/CommonUI.cs b/Meddle/Meddle.Plugin/UI/CommonUI.cs index 921e612..575947d 100644 --- a/Meddle/Meddle.Plugin/UI/CommonUI.cs +++ b/Meddle/Meddle.Plugin/UI/CommonUI.cs @@ -193,7 +193,7 @@ public unsafe string GetCharacterDisplayText(IGameObject obj, bool includeDistan var modelType = ((CharacterBase*)drawObject)->GetModelType(); var name = obj.Name.TextValue; - if (obj.ObjectKind == ObjectKind.Player && !string.IsNullOrWhiteSpace(config.PlayerNameOverride)) + if (obj.ObjectKind == ObjectKind.Pc && !string.IsNullOrWhiteSpace(config.PlayerNameOverride)) { name = config.PlayerNameOverride; } diff --git a/Meddle/Meddle.Plugin/UI/LiveCharacterTab.cs b/Meddle/Meddle.Plugin/UI/LiveCharacterTab.cs index 4513f51..2f168dd 100644 --- a/Meddle/Meddle.Plugin/UI/LiveCharacterTab.cs +++ b/Meddle/Meddle.Plugin/UI/LiveCharacterTab.cs @@ -775,7 +775,7 @@ private void DrawMaterial(Pointer mtPtr, int materialIdx, LazyMaterialResourceHandle->TextureCount) { - var textureName = material->MaterialResourceHandle->TexturePath(i); + var textureName = material->MaterialResourceHandle->TexturePath(i).ToString(); var gpuTex = DxHelper.ExportTextureResource(textureEntry.Texture->Texture); var textureData = gpuTex.Resource.ToTexture(); textureBuffer[textureName] = textureData; @@ -814,7 +814,7 @@ private void DrawMaterial(Pointer mtPtr, int materialIdx, LazyTextureCount}"); ImGui.Text($"Ref Count: {material->RefCount}"); - var shpkName = material->MaterialResourceHandle->ShpkName; + var shpkName = material->MaterialResourceHandle->ShpkName.ToString(); UiUtil.Text($"Shader Package: {shpkName}", shpkName); ImGui.Text($"Shader Flags: 0x{material->ShaderFlags:X8}"); @@ -851,7 +851,7 @@ private void DrawTexture(CSMaterial* material, CSMaterial.TextureEntry textureEn using var textureId = ImRaii.PushId($"{(nint)textureEntry.Texture}"); string? textureName = null; if (texIdx < material->MaterialResourceHandle->TextureCount) - textureName = material->MaterialResourceHandle->TexturePath(texIdx); + textureName = material->MaterialResourceHandle->TexturePath(texIdx).ToString(); var textureFileName = textureEntry.Texture->FileName.ParseString(); ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); diff --git a/Meddle/Meddle.Plugin/UI/Windows/DebugWindow.cs b/Meddle/Meddle.Plugin/UI/Windows/DebugWindow.cs index f877f4f..5ecbd14 100644 --- a/Meddle/Meddle.Plugin/UI/Windows/DebugWindow.cs +++ b/Meddle/Meddle.Plugin/UI/Windows/DebugWindow.cs @@ -1,5 +1,6 @@ using System.Numerics; using Dalamud.Bindings.ImGui; +using Dalamud.Interface.Windowing; using Meddle.Plugin.Models; using Microsoft.Extensions.Logging; diff --git a/Meddle/Meddle.Plugin/UI/Windows/MainWindow.cs b/Meddle/Meddle.Plugin/UI/Windows/MainWindow.cs index 0f8596d..42f1c47 100644 --- a/Meddle/Meddle.Plugin/UI/Windows/MainWindow.cs +++ b/Meddle/Meddle.Plugin/UI/Windows/MainWindow.cs @@ -3,6 +3,7 @@ using Dalamud.Interface; using Dalamud.Interface.Utility.Raii; using Dalamud.Bindings.ImGui; +using Dalamud.Interface.Windowing; using Meddle.Plugin.Models; using Meddle.Plugin.UI.Layout; using Microsoft.Extensions.Logging; diff --git a/Meddle/Meddle.Plugin/Utils/OnRenderMaterialUtil.cs b/Meddle/Meddle.Plugin/Utils/OnRenderMaterialUtil.cs index b4789d1..bb536cd 100644 --- a/Meddle/Meddle.Plugin/Utils/OnRenderMaterialUtil.cs +++ b/Meddle/Meddle.Plugin/Utils/OnRenderMaterialUtil.cs @@ -185,7 +185,7 @@ private static void ApplySkinMaterialTextures(ref OnRenderMaterialOutput renderM */ var slotShpk = materialAtIndex.Value->MaterialResourceHandle->ShpkName; - if (slotShpk != "characterstockings.shpk") + if (slotShpk.ToString() != "characterstockings.shpk") { return; } @@ -228,7 +228,7 @@ private static void CopySkinMaterialTextures(ref OnRenderMaterialOutput renderMa } string? path = null; - string? pathFromMaterial = skinMaterialHandle->TextureCount > i ? skinMaterialHandle->TexturePath(i) : null; + string? pathFromMaterial = skinMaterialHandle->TextureCount > i ? skinMaterialHandle->TexturePath(i).ToString() : null; if (entry.Texture != null && entry.Texture->Texture != null) { path = entry.Texture->FileName.ToString(); diff --git a/Meddle/Meddle.Plugin/Utils/ParseMaterialUtil.cs b/Meddle/Meddle.Plugin/Utils/ParseMaterialUtil.cs index 8c48b0c..a77d0f9 100644 --- a/Meddle/Meddle.Plugin/Utils/ParseMaterialUtil.cs +++ b/Meddle/Meddle.Plugin/Utils/ParseMaterialUtil.cs @@ -92,7 +92,7 @@ public static class ParseMaterialUtil string? materialPathFromModel; if (model != null) { - materialPathFromModel = modelPtr.Value->ModelResourceHandle->GetMaterialFileNameBySlot((uint)materialIndex); + materialPathFromModel = modelPtr.Value->ModelResourceHandle->GetMaterialFileNameBySlot((uint)materialIndex).ToString(); } else { @@ -109,7 +109,7 @@ public static class ParseMaterialUtil var texturePath = texturePtr.TextureResourceHandle->FileName.ParseString(); if (texIdx < material->TextureCount) { - var texturePathFromMaterial = material->MaterialResourceHandle->TexturePath(texIdx); + var texturePathFromMaterial = material->MaterialResourceHandle->TexturePath(texIdx).ToString(); var (resource, _) = DxHelper.ExportTextureResource(texturePtr.TextureResourceHandle->Texture); var textureInfo = new ParsedTextureInfo(texturePath, texturePathFromMaterial, resource); textures.Add(textureInfo); diff --git a/Meddle/Meddle.Plugin/packages.lock.json b/Meddle/Meddle.Plugin/packages.lock.json index d504e7f..6722369 100644 --- a/Meddle/Meddle.Plugin/packages.lock.json +++ b/Meddle/Meddle.Plugin/packages.lock.json @@ -4,9 +4,9 @@ "net10.0-windows7.0": { "DalamudPackager": { "type": "Direct", - "requested": "[14.0.1, )", - "resolved": "14.0.1", - "contentHash": "y0WWyUE6dhpGdolK3iKgwys05/nZaVf4ZPtIjpLhJBZvHxkkiE23zYRo7K7uqAgoK/QvK5cqF6l3VG5AbgC6KA==" + "requested": "[15.0.0, )", + "resolved": "15.0.0", + "contentHash": "411vwC8/X8Z/sQ2TI6v3SvOn66xFPeOjFn3Zn+h0d3Ox2t1kFm66AhDvmx/qcMwVrR+Hidxj0dadpQ2dgyXMBQ==" }, "DotNet.ReproducibleBuilds": { "type": "Direct", From 8dcdd989697002a91becb0fce1c985b89776cc2a Mon Sep 17 00:00:00 2001 From: Passive <20432486+PassiveModding@users.noreply.github.com> Date: Thu, 30 Apr 2026 09:20:54 +1000 Subject: [PATCH 2/5] Remove obsolete CustomizeParameter fields --- .../Models/Structs/CustomizeParameter.cs | 29 +++++++------------ .../Meddle.Plugin/UI/MaterialParameterTab.cs | 24 +-------------- .../Meddle.Plugin/Utils/ParseMaterialUtil.cs | 2 -- .../Meddle.Utils/Export/CustomizeParameter.cs | 4 --- 4 files changed, 11 insertions(+), 48 deletions(-) diff --git a/Meddle/Meddle.Plugin/Models/Structs/CustomizeParameter.cs b/Meddle/Meddle.Plugin/Models/Structs/CustomizeParameter.cs index 000c987..df63171 100644 --- a/Meddle/Meddle.Plugin/Models/Structs/CustomizeParameter.cs +++ b/Meddle/Meddle.Plugin/Models/Structs/CustomizeParameter.cs @@ -3,7 +3,7 @@ namespace Meddle.Plugin.Models.Structs; -[StructLayout(LayoutKind.Explicit, Size = 0x90)] +[StructLayout(LayoutKind.Explicit, Size = 0x70)] public struct CustomizeParameter { /// @@ -15,60 +15,51 @@ public struct CustomizeParameter [FieldOffset(0xC)] public float MuscleTone; - [FieldOffset(0x10)] - public Vector4 SkinFresnelValue0; - /// /// XYZ : Lip diffuse color, as squared RGB. /// W : Lip opacity. /// - [FieldOffset(0x20)] + [FieldOffset(0x10)] public Vector4 LipColor; /// /// XYZ : Hair primary color, as squared RGB. /// - [FieldOffset(0x30)] + [FieldOffset(0x20)] public Vector3 MainColor; - [FieldOffset(0x3C)] + [FieldOffset(0x2C)] public float FacePaintUVMultiplier; - [FieldOffset(0x40)] - public Vector3 HairFresnelValue0; - - [FieldOffset(0x4C)] - public float Unk0; - /// /// XYZ : Hair highlight color, as squared RGB. /// - [FieldOffset(0x50)] + [FieldOffset(0x30)] public Vector3 MeshColor; - [FieldOffset(0x5C)] + [FieldOffset(0x3C)] public float FacePaintUVOffset; /// /// XYZ : Left eye color, as squared RGB. /// W : Left Eye Limbal Ring Intensity /// - [FieldOffset(0x60)] + [FieldOffset(0x40)] public Vector4 LeftColor; /// /// XYZ : Right eye color, as squared RGB. /// W : Right Eye Limbal Ring Intensity /// - [FieldOffset(0x70)] + [FieldOffset(0x50)] public Vector4 RightColor; /// /// XYZ : Race feature color, as squared RGB. /// - [FieldOffset(0x80)] + [FieldOffset(0x60)] public Vector3 OptionColor; - [FieldOffset(0x8C)] + [FieldOffset(0x6C)] public float Unk1; } diff --git a/Meddle/Meddle.Plugin/UI/MaterialParameterTab.cs b/Meddle/Meddle.Plugin/UI/MaterialParameterTab.cs index e96c021..e8ba66a 100644 --- a/Meddle/Meddle.Plugin/UI/MaterialParameterTab.cs +++ b/Meddle/Meddle.Plugin/UI/MaterialParameterTab.cs @@ -126,14 +126,7 @@ public unsafe void DrawCustomizeParams(CharacterBase* cbase) { parameter.MuscleTone = customizeParameters!.Value.MuscleTone; } - - ImGui.ColorEdit4("Skin Fresnel", ref parameter.SkinFresnelValue0); - ImGui.SameLine(); - if (ImGui.Button("Restore##SkinFresnel")) - { - parameter.SkinFresnelValue0 = customizeParameters!.Value.SkinFresnelValue0; - } - + ImGui.ColorEdit4("Lip Color", ref parameter.LipColor); ImGui.SameLine(); if (ImGui.Button("Restore##LipColor")) @@ -154,21 +147,6 @@ public unsafe void DrawCustomizeParams(CharacterBase* cbase) { parameter.FacePaintUVMultiplier = customizeParameters!.Value.FacePaintUVMultiplier; } - - ImGui.ColorEdit3("Hair Fresnel", ref parameter.HairFresnelValue0); - ImGui.SameLine(); - if (ImGui.Button("Restore##HairFresnel")) - { - parameter.HairFresnelValue0 = customizeParameters!.Value.HairFresnelValue0; - } - - ImGui.DragFloat("Unk0", ref parameter.Unk0, 0.01f, -10.0f, 10.0f, "%.2f"); - ImGui.SameLine(); - if (ImGui.Button("Restore##Unk0")) - { - parameter.Unk0 = customizeParameters!.Value.Unk0; - } - ImGui.ColorEdit3("Mesh Color", ref parameter.MeshColor); ImGui.SameLine(); if (ImGui.Button("Restore##MeshColor")) diff --git a/Meddle/Meddle.Plugin/Utils/ParseMaterialUtil.cs b/Meddle/Meddle.Plugin/Utils/ParseMaterialUtil.cs index a77d0f9..92bf20c 100644 --- a/Meddle/Meddle.Plugin/Utils/ParseMaterialUtil.cs +++ b/Meddle/Meddle.Plugin/Utils/ParseMaterialUtil.cs @@ -172,11 +172,9 @@ public static unsafe ParsedHumanInfo ParseHuman(Pointer character { SkinColor = customizeCBuf.SkinColor, MuscleTone = customizeCBuf.MuscleTone, - SkinFresnelValue0 = customizeCBuf.SkinFresnelValue0, LipColor = customizeCBuf.LipColor, MainColor = customizeCBuf.MainColor, FacePaintUvMultiplier = customizeCBuf.FacePaintUVMultiplier, - HairFresnelValue0 = customizeCBuf.HairFresnelValue0, MeshColor = customizeCBuf.MeshColor, FacePaintUvOffset = customizeCBuf.FacePaintUVOffset, LeftColor = customizeCBuf.LeftColor, diff --git a/Meddle/Meddle.Utils/Export/CustomizeParameter.cs b/Meddle/Meddle.Utils/Export/CustomizeParameter.cs index 2887fa6..f2af0cd 100644 --- a/Meddle/Meddle.Utils/Export/CustomizeParameter.cs +++ b/Meddle/Meddle.Utils/Export/CustomizeParameter.cs @@ -17,8 +17,6 @@ public class CustomizeParameter { public float MuscleTone; - public Vector4 SkinFresnelValue0; - /// /// XYZ : Lip diffuse color, as squared RGB. /// W : Lip opacity. @@ -30,8 +28,6 @@ public class CustomizeParameter { /// public Vector3 MainColor; public float FacePaintUvMultiplier; - - public Vector3 HairFresnelValue0; /// /// XYZ : Hair highlight color, as squared RGB. From c7a032398fae6ca1f4bd59b8317480c7d7a61532 Mon Sep 17 00:00:00 2001 From: Passive <20432486+PassiveModding@users.noreply.github.com> Date: Thu, 30 Apr 2026 14:06:42 +1000 Subject: [PATCH 3/5] Update ShpkFile parsing to v14.1 --- Meddle/Meddle.Utils/Files/ShpkFile.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Meddle/Meddle.Utils/Files/ShpkFile.cs b/Meddle/Meddle.Utils/Files/ShpkFile.cs index 8d6e271..79c6484 100644 --- a/Meddle/Meddle.Utils/Files/ShpkFile.cs +++ b/Meddle/Meddle.Utils/Files/ShpkFile.cs @@ -12,6 +12,7 @@ public class ShpkFile private const uint Dx11Magic = 0x31315844u; // bytes of DX11 private const uint Shpk13_1 = 0x0D01; + private const uint Shpk14_1 = 0x0E01; public const uint MaterialParamsConstantId = 0x64D12851u; // g_MaterialParameter is a cbuffer filled from the ad hoc section of the mtrl @@ -24,6 +25,8 @@ public ShpkFile(byte[] data) : this(new Span(data)) public uint? Unk131A; public uint? Unk131B; public uint? Unk131C; + + public uint? Unk141A; //public byte[] Blobs; //public byte[] Strings; public Shader[] VertexShaders; @@ -71,6 +74,10 @@ public ShpkFile(ReadOnlySpan data) Unk131B = reader.ReadUInt32(); Unk131C = reader.ReadUInt32(); } + if (FileHeader.Version >= Shpk14_1) + { + Unk141A = reader.ReadUInt32(); + } // var blobs = data[(int)FileHeader.BlobsOffset..(int)FileHeader.StringsOffset]; // var strings = data[(int)FileHeader.StringsOffset..]; From 2e3b8104bd44f0706b3beb035b7b38f1989222a7 Mon Sep 17 00:00:00 2001 From: Passive <20432486+PassiveModding@users.noreply.github.com> Date: Thu, 30 Apr 2026 14:32:35 +1000 Subject: [PATCH 4/5] Fix enum naming not displaying as string --- Meddle/Meddle.Plugin/UI/Layout/Config.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Meddle/Meddle.Plugin/UI/Layout/Config.cs b/Meddle/Meddle.Plugin/UI/Layout/Config.cs index 0708bc9..fc87ca0 100644 --- a/Meddle/Meddle.Plugin/UI/Layout/Config.cs +++ b/Meddle/Meddle.Plugin/UI/Layout/Config.cs @@ -113,7 +113,7 @@ private void DrawOptions() } var drawTypes = config.LayoutConfig.DrawTypes; - if (ImGui.BeginCombo("Draw Types", drawTypes.ToString())) + if (ImGui.BeginCombo("Draw Types", drawTypes.GetDescription())) { foreach (var type in Enum.GetValues()) { From 5fcd4584d97cf8a30d069fcfa6e1ad1ebca177f8 Mon Sep 17 00:00:00 2001 From: Passive <20432486+PassiveModding@users.noreply.github.com> Date: Thu, 30 Apr 2026 14:36:27 +1000 Subject: [PATCH 5/5] Update names for unnamed shpk 13.1 fields --- Meddle/Meddle.Utils/Files/ShpkFile.cs | 36 +++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Meddle/Meddle.Utils/Files/ShpkFile.cs b/Meddle/Meddle.Utils/Files/ShpkFile.cs index 79c6484..c5f9aa7 100644 --- a/Meddle/Meddle.Utils/Files/ShpkFile.cs +++ b/Meddle/Meddle.Utils/Files/ShpkFile.cs @@ -22,9 +22,9 @@ public ShpkFile(byte[] data) : this(new Span(data)) public ShpkHeader FileHeader; - public uint? Unk131A; - public uint? Unk131B; - public uint? Unk131C; + public uint? HullShaderCount; + public uint? DomainShaderCount; + public uint? GeometryShaderCount; public uint? Unk141A; //public byte[] Blobs; @@ -70,9 +70,9 @@ public ShpkFile(ReadOnlySpan data) if (FileHeader.Version >= Shpk13_1) { - Unk131A = reader.ReadUInt32(); - Unk131B = reader.ReadUInt32(); - Unk131C = reader.ReadUInt32(); + HullShaderCount = reader.ReadUInt32(); + DomainShaderCount = reader.ReadUInt32(); + GeometryShaderCount = reader.ReadUInt32(); } if (FileHeader.Version >= Shpk14_1) { @@ -171,14 +171,14 @@ public Pass ReadPass(ref SpanBinaryReader r) var id = r.ReadUInt32(); var vertexShader = r.ReadUInt32(); var pixelShader = r.ReadUInt32(); - uint? unk131G = null; - uint? unk131H = null; - uint? unk131I = null; + uint? hullShader = null; + uint? domainShader = null; + uint? geometryShader = null; if (FileHeader.Version >= Shpk13_1) { - unk131G = r.ReadUInt32(); - unk131H = r.ReadUInt32(); - unk131I = r.ReadUInt32(); + hullShader = r.ReadUInt32(); + domainShader = r.ReadUInt32(); + geometryShader = r.ReadUInt32(); } return new Pass @@ -186,9 +186,9 @@ public Pass ReadPass(ref SpanBinaryReader r) Id = id, VertexShader = vertexShader, PixelShader = pixelShader, - Unk131G = unk131G, - Unk131H = unk131H, - Unk131I = unk131I + HullShader = hullShader, + DomainShader = domainShader, + GeometryShader = geometryShader }; } @@ -244,9 +244,9 @@ public struct Pass public uint Id; public uint VertexShader; public uint PixelShader; - public uint? Unk131G; - public uint? Unk131H; - public uint? Unk131I; + public uint? HullShader; + public uint? DomainShader; + public uint? GeometryShader; } public struct Key