Add CultCache geometry documents
This commit is contained in:
parent
6f31c332f4
commit
69ac7b5b4b
7 changed files with 752 additions and 13 deletions
148
CultLib.sln
148
CultLib.sln
|
|
@ -25,61 +25,167 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameCult.Networking.Tests",
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameCult.Caching.Tests", "tests\GameCult.Caching.Tests\GameCult.Caching.Tests.csproj", "{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameCult.Geometry", "src\GameCult.Geometry\GameCult.Geometry.csproj", "{94C086DA-3359-424B-9688-29A198806481}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameCult.Geometry.Tests", "tests\GameCult.Geometry.Tests\GameCult.Geometry.Tests.csproj", "{C95A9A21-34FA-4D82-BE5B-88FBDA836D31}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{72AEDD42-E881-4EB7-99A8-FD3B9667189C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{72AEDD42-E881-4EB7-99A8-FD3B9667189C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{72AEDD42-E881-4EB7-99A8-FD3B9667189C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{72AEDD42-E881-4EB7-99A8-FD3B9667189C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{72AEDD42-E881-4EB7-99A8-FD3B9667189C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{72AEDD42-E881-4EB7-99A8-FD3B9667189C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{72AEDD42-E881-4EB7-99A8-FD3B9667189C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{72AEDD42-E881-4EB7-99A8-FD3B9667189C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{72AEDD42-E881-4EB7-99A8-FD3B9667189C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{72AEDD42-E881-4EB7-99A8-FD3B9667189C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{72AEDD42-E881-4EB7-99A8-FD3B9667189C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{72AEDD42-E881-4EB7-99A8-FD3B9667189C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{9DDA917D-B4DB-4AC1-9B9A-4ECF06A5ABA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9DDA917D-B4DB-4AC1-9B9A-4ECF06A5ABA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9DDA917D-B4DB-4AC1-9B9A-4ECF06A5ABA1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{9DDA917D-B4DB-4AC1-9B9A-4ECF06A5ABA1}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{9DDA917D-B4DB-4AC1-9B9A-4ECF06A5ABA1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{9DDA917D-B4DB-4AC1-9B9A-4ECF06A5ABA1}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{9DDA917D-B4DB-4AC1-9B9A-4ECF06A5ABA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9DDA917D-B4DB-4AC1-9B9A-4ECF06A5ABA1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9DDA917D-B4DB-4AC1-9B9A-4ECF06A5ABA1}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{9DDA917D-B4DB-4AC1-9B9A-4ECF06A5ABA1}.Release|x64.Build.0 = Release|Any CPU
|
||||
{9DDA917D-B4DB-4AC1-9B9A-4ECF06A5ABA1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{9DDA917D-B4DB-4AC1-9B9A-4ECF06A5ABA1}.Release|x86.Build.0 = Release|Any CPU
|
||||
{26EE4C38-F06E-4E7A-A89C-908318BCB0DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{26EE4C38-F06E-4E7A-A89C-908318BCB0DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{26EE4C38-F06E-4E7A-A89C-908318BCB0DB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{26EE4C38-F06E-4E7A-A89C-908318BCB0DB}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{26EE4C38-F06E-4E7A-A89C-908318BCB0DB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{26EE4C38-F06E-4E7A-A89C-908318BCB0DB}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{26EE4C38-F06E-4E7A-A89C-908318BCB0DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{26EE4C38-F06E-4E7A-A89C-908318BCB0DB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{26EE4C38-F06E-4E7A-A89C-908318BCB0DB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{26EE4C38-F06E-4E7A-A89C-908318BCB0DB}.Release|x64.Build.0 = Release|Any CPU
|
||||
{26EE4C38-F06E-4E7A-A89C-908318BCB0DB}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{26EE4C38-F06E-4E7A-A89C-908318BCB0DB}.Release|x86.Build.0 = Release|Any CPU
|
||||
{0E990C96-3808-450E-9349-A0C3262195ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0E990C96-3808-450E-9349-A0C3262195ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0E990C96-3808-450E-9349-A0C3262195ED}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{0E990C96-3808-450E-9349-A0C3262195ED}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{0E990C96-3808-450E-9349-A0C3262195ED}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0E990C96-3808-450E-9349-A0C3262195ED}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{0E990C96-3808-450E-9349-A0C3262195ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0E990C96-3808-450E-9349-A0C3262195ED}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0E990C96-3808-450E-9349-A0C3262195ED}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{0E990C96-3808-450E-9349-A0C3262195ED}.Release|x64.Build.0 = Release|Any CPU
|
||||
{0E990C96-3808-450E-9349-A0C3262195ED}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{0E990C96-3808-450E-9349-A0C3262195ED}.Release|x86.Build.0 = Release|Any CPU
|
||||
{DBE06954-EC85-4034-9049-72C7D27556DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DBE06954-EC85-4034-9049-72C7D27556DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DBE06954-EC85-4034-9049-72C7D27556DF}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{DBE06954-EC85-4034-9049-72C7D27556DF}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{DBE06954-EC85-4034-9049-72C7D27556DF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{DBE06954-EC85-4034-9049-72C7D27556DF}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{DBE06954-EC85-4034-9049-72C7D27556DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DBE06954-EC85-4034-9049-72C7D27556DF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DBE06954-EC85-4034-9049-72C7D27556DF}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{DBE06954-EC85-4034-9049-72C7D27556DF}.Release|x64.Build.0 = Release|Any CPU
|
||||
{DBE06954-EC85-4034-9049-72C7D27556DF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{DBE06954-EC85-4034-9049-72C7D27556DF}.Release|x86.Build.0 = Release|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Release|x64.Build.0 = Release|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F}.Release|x86.Build.0 = Release|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Release|x64.Build.0 = Release|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42}.Release|x86.Build.0 = Release|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81}.Release|x86.Build.0 = Release|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Release|x64.Build.0 = Release|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5}.Release|x86.Build.0 = Release|Any CPU
|
||||
{94C086DA-3359-424B-9688-29A198806481}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{94C086DA-3359-424B-9688-29A198806481}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{94C086DA-3359-424B-9688-29A198806481}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{94C086DA-3359-424B-9688-29A198806481}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{94C086DA-3359-424B-9688-29A198806481}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{94C086DA-3359-424B-9688-29A198806481}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{94C086DA-3359-424B-9688-29A198806481}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{94C086DA-3359-424B-9688-29A198806481}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{94C086DA-3359-424B-9688-29A198806481}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{94C086DA-3359-424B-9688-29A198806481}.Release|x64.Build.0 = Release|Any CPU
|
||||
{94C086DA-3359-424B-9688-29A198806481}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{94C086DA-3359-424B-9688-29A198806481}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C95A9A21-34FA-4D82-BE5B-88FBDA836D31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C95A9A21-34FA-4D82-BE5B-88FBDA836D31}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C95A9A21-34FA-4D82-BE5B-88FBDA836D31}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C95A9A21-34FA-4D82-BE5B-88FBDA836D31}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C95A9A21-34FA-4D82-BE5B-88FBDA836D31}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C95A9A21-34FA-4D82-BE5B-88FBDA836D31}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C95A9A21-34FA-4D82-BE5B-88FBDA836D31}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C95A9A21-34FA-4D82-BE5B-88FBDA836D31}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C95A9A21-34FA-4D82-BE5B-88FBDA836D31}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C95A9A21-34FA-4D82-BE5B-88FBDA836D31}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C95A9A21-34FA-4D82-BE5B-88FBDA836D31}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C95A9A21-34FA-4D82-BE5B-88FBDA836D31}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{72AEDD42-E881-4EB7-99A8-FD3B9667189C} = {E733CBFF-42AE-4B6A-B5B9-0071ECFB45F1}
|
||||
{9DDA917D-B4DB-4AC1-9B9A-4ECF06A5ABA1} = {E733CBFF-42AE-4B6A-B5B9-0071ECFB45F1}
|
||||
{26EE4C38-F06E-4E7A-A89C-908318BCB0DB} = {E733CBFF-42AE-4B6A-B5B9-0071ECFB45F1}
|
||||
{0E990C96-3808-450E-9349-A0C3262195ED} = {E733CBFF-42AE-4B6A-B5B9-0071ECFB45F1}
|
||||
{DBE06954-EC85-4034-9049-72C7D27556DF} = {E733CBFF-42AE-4B6A-B5B9-0071ECFB45F1}
|
||||
{67383F6C-C9C3-4C5B-95D4-5C50C20EDD4F} = {E733CBFF-42AE-4B6A-B5B9-0071ECFB45F1}
|
||||
{8D1B01A7-BF9E-44E6-88E1-B17255728B42} = {E733CBFF-42AE-4B6A-B5B9-0071ECFB45F1}
|
||||
{E2DC8FF6-D39E-4FCA-9549-1F7681F0AA81} = {39D316AB-ABB5-49A2-8E83-CAF4C75B48F4}
|
||||
{EB15435B-7147-4BD9-BB9C-B0A14318D3D5} = {39D316AB-ABB5-49A2-8E83-CAF4C75B48F4}
|
||||
{0E990C96-3808-450E-9349-A0C3262195ED} = {E733CBFF-42AE-4B6A-B5B9-0071ECFB45F1}
|
||||
{DBE06954-EC85-4034-9049-72C7D27556DF} = {E733CBFF-42AE-4B6A-B5B9-0071ECFB45F1}
|
||||
{94C086DA-3359-424B-9688-29A198806481} = {E733CBFF-42AE-4B6A-B5B9-0071ECFB45F1}
|
||||
{C95A9A21-34FA-4D82-BE5B-88FBDA836D31} = {39D316AB-ABB5-49A2-8E83-CAF4C75B48F4}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ The libraries cover three main areas:
|
|||
- a typed in-memory cache with pluggable persistence
|
||||
- LiteNetLib-based networking with encrypted credential exchange and signed session tokens
|
||||
- CultMesh distributed realtime database and simulation-consensus primitives
|
||||
- typed geometry domain/chunk documents for distributed CSG and LOD streaming
|
||||
- declarative Unity UI composition and reflective runtime inspector tooling
|
||||
|
||||
## Which Package Do I Want?
|
||||
|
|
@ -18,12 +19,15 @@ and pretending the label makes it furniture.
|
|||
| Job | Start With | Owns | Use When | Do Not Use It For |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Local typed state | `GameCult.Caching` / CultCache | Document identity, schema compatibility, record keys, indexes, globals, and local persistence | You need a typed cache, file-compatible save data, local reactive reads, or a stable domain document model | Peer discovery, transport security, shard routing, or mesh consensus |
|
||||
| Procedural geometry state | `GameCult.Geometry` | CultCache-native domain trees, LOD build requests, selected-cut diagnostics, and chunk artifact payloads | Rust, Unity, or remote workers need to share CSG/LOD geometry and graph metadata as typed state | Transport policy, peer discovery, or gameplay authority |
|
||||
| Network transport and database plumbing | `GameCult.Networking` / CultNet | LiteNetLib transport, authentication, schema-v0 wire contracts, shard authority, raw document replication, snapshots, and subscriptions | You need a client/server pipe, login/session flow, schema discovery, or a low-level distributed CultCache lane | Gameplay-facing mesh ergonomics, Verse policy, mod branches, or simulation consensus composition |
|
||||
| Distributed realtime gameplay state | `GameCult.Mesh` / CultMesh | Public mesh entrypoints, Verse discovery, peer exchange, shard replication defaults, authority leases, client prediction, and witness consensus | You want the game to treat clients and servers as one reactive database for persistent state, input state, and simulation facts | A tiny local-only tool, a bare transport client, or a storage format contract |
|
||||
|
||||
Quick rule:
|
||||
|
||||
- Choose CultCache when the problem is "how do I model and persist typed state?"
|
||||
- Choose GameCult.Geometry when the problem is "how do geometry workers share
|
||||
domain trees, LOD build requests, and mesh chunks as typed state?"
|
||||
- Choose CultNet when the problem is "how do peers exchange authenticated,
|
||||
schema-aware database messages?"
|
||||
- Choose CultMesh when the problem is "how does a game join a Verse and share
|
||||
|
|
@ -51,6 +55,7 @@ The solution includes:
|
|||
- `GameCult.Caching.NewtonsoftJson`: Newtonsoft.Json-backed persistence for the cache
|
||||
- `GameCult.Caching.MessagePack.Generator`: source generator for MessagePack formatters for cache models
|
||||
- `GameCult.Caching.MessagePack.Analyzers`: packaging project that delivers the generator to consuming projects
|
||||
- `GameCult.Geometry`: CultCache-native geometry domain, selected-cut, and chunk artifact documents for VibeGeometry/Fensalir-style pipelines
|
||||
- `GameCult.Networking`: encrypted login/register/verify flows and message dispatch over LiteNetLib
|
||||
- `GameCult.Mesh`: CultMesh package home for distributed realtime database, shard replication, client prediction, Verse discovery, and mesh witness consensus
|
||||
- `GameCult.Caching.Tests`: NUnit tests for cache and backing-store behavior
|
||||
|
|
@ -67,11 +72,13 @@ src/
|
|||
GameCult.Caching.NewtonsoftJson/
|
||||
GameCult.Caching.MessagePack.Generator/
|
||||
GameCult.Caching.MessagePack.Analyzers/
|
||||
GameCult.Geometry/
|
||||
GameCult.Networking/
|
||||
GameCult.Mesh/
|
||||
GameCult.Unity/
|
||||
tests/
|
||||
GameCult.Caching.Tests/
|
||||
GameCult.Geometry.Tests/
|
||||
GameCult.Networking.Tests/
|
||||
```
|
||||
|
||||
|
|
|
|||
435
src/GameCult.Geometry/CultGeometryDocuments.cs
Normal file
435
src/GameCult.Geometry/CultGeometryDocuments.cs
Normal file
|
|
@ -0,0 +1,435 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using GameCult.Caching;
|
||||
using MessagePack;
|
||||
using static GameCult.Geometry.CultGeometryDocuments;
|
||||
|
||||
namespace GameCult.Geometry
|
||||
{
|
||||
/// <summary>
|
||||
/// Schema versions for CultCache-native geometry pipeline documents.
|
||||
/// </summary>
|
||||
public static class CultGeometrySchemaVersions
|
||||
{
|
||||
public const string Domain = "gamecult.geometry.domain.v1";
|
||||
public const string BuildRequest = "gamecult.geometry.build_request.v1";
|
||||
public const string SelectedCut = "gamecult.geometry.selected_cut.v1";
|
||||
public const string ChunkArtifact = "gamecult.geometry.chunk_artifact.v1";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CultCache document containing a hierarchical geometry domain tree.
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
[CultDocument("gamecult.geometry.domain", CultGeometrySchemaVersions.Domain)]
|
||||
public sealed class CultGeometryDomainDocument
|
||||
{
|
||||
[Key(0)]
|
||||
[CultName]
|
||||
public string DomainId { get; set; } = string.Empty;
|
||||
|
||||
[Key(1)]
|
||||
[CultIndex]
|
||||
public string RootKey { get; set; } = string.Empty;
|
||||
|
||||
[Key(2)]
|
||||
public string SourceRuntime { get; set; } = string.Empty;
|
||||
|
||||
[Key(3)]
|
||||
public CultGeometryDomainNode Root { get; set; } = new CultGeometryDomainNode();
|
||||
|
||||
[Key(4)]
|
||||
public string CreatedAt { get; set; } = string.Empty;
|
||||
|
||||
public static CultRecordKey CreateRecordKey(CultGeometryDomainDocument domain)
|
||||
{
|
||||
if (domain == null) throw new ArgumentNullException(nameof(domain));
|
||||
return new CultRecordKey("geometry:domain:" + StableHash(
|
||||
domain.RootKey,
|
||||
domain.SourceRuntime,
|
||||
domain.Root.StableFingerprint()));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// One node in a geometry domain tree.
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public sealed class CultGeometryDomainNode
|
||||
{
|
||||
[Key(0)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[Key(1)]
|
||||
public string Kind { get; set; } = string.Empty;
|
||||
|
||||
[Key(2)]
|
||||
public float[] Translation { get; set; } = Array.Empty<float>();
|
||||
|
||||
[Key(3)]
|
||||
public float[] RotationXyzw { get; set; } = Array.Empty<float>();
|
||||
|
||||
[Key(4)]
|
||||
public ulong Seed { get; set; }
|
||||
|
||||
[Key(5)]
|
||||
public CultGeometryFeatureClaim[] Claims { get; set; } = Array.Empty<CultGeometryFeatureClaim>();
|
||||
|
||||
[Key(6)]
|
||||
public CultGeometryDomainNode[] Children { get; set; } = Array.Empty<CultGeometryDomainNode>();
|
||||
|
||||
public string StableFingerprint()
|
||||
{
|
||||
var builder = new StringBuilder()
|
||||
.Append(Name).Append('\u001f')
|
||||
.Append(Kind).Append('\u001f')
|
||||
.Append(Seed.ToString(CultureInfo.InvariantCulture)).Append('\u001f')
|
||||
.AppendVector(Translation).Append('\u001f')
|
||||
.AppendVector(RotationXyzw);
|
||||
foreach (var claim in Claims)
|
||||
{
|
||||
builder.Append('\u001e').Append(claim.StableFingerprint());
|
||||
}
|
||||
|
||||
foreach (var child in Children)
|
||||
{
|
||||
builder.Append('\u001d').Append(child.StableFingerprint());
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A domain feature claim before CSG lowering.
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public sealed class CultGeometryFeatureClaim
|
||||
{
|
||||
[Key(0)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[Key(1)]
|
||||
public float[] Translation { get; set; } = Array.Empty<float>();
|
||||
|
||||
[Key(2)]
|
||||
public float[] RotationXyzw { get; set; } = Array.Empty<float>();
|
||||
|
||||
[Key(3)]
|
||||
public float[] SupportCenter { get; set; } = Array.Empty<float>();
|
||||
|
||||
[Key(4)]
|
||||
public float[] SupportSize { get; set; } = Array.Empty<float>();
|
||||
|
||||
[Key(5)]
|
||||
public string Kind { get; set; } = string.Empty;
|
||||
|
||||
[Key(6)]
|
||||
public uint Material { get; set; }
|
||||
|
||||
[Key(7)]
|
||||
public string LoweringPolicy { get; set; } = string.Empty;
|
||||
|
||||
public string StableFingerprint() => new StringBuilder()
|
||||
.Append(Name).Append('\u001f')
|
||||
.Append(Kind).Append('\u001f')
|
||||
.Append(Material.ToString(CultureInfo.InvariantCulture)).Append('\u001f')
|
||||
.Append(LoweringPolicy).Append('\u001f')
|
||||
.AppendVector(Translation).Append('\u001f')
|
||||
.AppendVector(RotationXyzw).Append('\u001f')
|
||||
.AppendVector(SupportCenter).Append('\u001f')
|
||||
.AppendVector(SupportSize)
|
||||
.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CultCache document requesting one geometry LOD build.
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
[CultDocument("gamecult.geometry.build_request", CultGeometrySchemaVersions.BuildRequest)]
|
||||
public sealed class CultGeometryBuildRequest
|
||||
{
|
||||
[Key(0)]
|
||||
[CultName]
|
||||
public string RequestId { get; set; } = string.Empty;
|
||||
|
||||
[Key(1)]
|
||||
[CultReference(typeof(CultGeometryDomainDocument))]
|
||||
public string DomainKey { get; set; } = string.Empty;
|
||||
|
||||
[Key(2)]
|
||||
[CultIndex]
|
||||
public string WorkerGroup { get; set; } = string.Empty;
|
||||
|
||||
[Key(3)]
|
||||
public float[] CameraPosition { get; set; } = Array.Empty<float>();
|
||||
|
||||
[Key(4)]
|
||||
public float[] FrustumMin { get; set; } = Array.Empty<float>();
|
||||
|
||||
[Key(5)]
|
||||
public float[] FrustumMax { get; set; } = Array.Empty<float>();
|
||||
|
||||
[Key(6)]
|
||||
public float ViewportHeightPixels { get; set; }
|
||||
|
||||
[Key(7)]
|
||||
public float VerticalFovRadians { get; set; }
|
||||
|
||||
[Key(8)]
|
||||
public float TargetError { get; set; }
|
||||
|
||||
[Key(9)]
|
||||
public int TriangleBudget { get; set; }
|
||||
|
||||
[Key(10)]
|
||||
public int ColliderBudget { get; set; }
|
||||
|
||||
[Key(11)]
|
||||
public string[] SemanticFilter { get; set; } = Array.Empty<string>();
|
||||
|
||||
[Key(12)]
|
||||
public string[] RequestedChunkKeys { get; set; } = Array.Empty<string>();
|
||||
|
||||
[Key(13)]
|
||||
public string[] DirtyDomainKeys { get; set; } = Array.Empty<string>();
|
||||
|
||||
[Key(14)]
|
||||
public string CreatedAt { get; set; } = string.Empty;
|
||||
|
||||
public static CultRecordKey CreateRecordKey(CultGeometryBuildRequest request)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
return new CultRecordKey("geometry:request:" + StableHash(
|
||||
request.DomainKey,
|
||||
request.WorkerGroup,
|
||||
StableVector(request.CameraPosition),
|
||||
StableVector(request.FrustumMin),
|
||||
StableVector(request.FrustumMax),
|
||||
request.ViewportHeightPixels.ToString("R", CultureInfo.InvariantCulture),
|
||||
request.VerticalFovRadians.ToString("R", CultureInfo.InvariantCulture),
|
||||
request.TargetError.ToString("R", CultureInfo.InvariantCulture),
|
||||
request.TriangleBudget.ToString(CultureInfo.InvariantCulture),
|
||||
request.ColliderBudget.ToString(CultureInfo.InvariantCulture),
|
||||
StableArray(request.SemanticFilter),
|
||||
StableArray(request.RequestedChunkKeys),
|
||||
StableArray(request.DirtyDomainKeys)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CultCache document describing the selected domain cut produced for one build request.
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
[CultDocument("gamecult.geometry.selected_cut", CultGeometrySchemaVersions.SelectedCut)]
|
||||
public sealed class CultGeometrySelectedCutManifest
|
||||
{
|
||||
[Key(0)]
|
||||
[CultName]
|
||||
public string CutId { get; set; } = string.Empty;
|
||||
|
||||
[Key(1)]
|
||||
[CultReference(typeof(CultGeometryBuildRequest))]
|
||||
public string RequestKey { get; set; } = string.Empty;
|
||||
|
||||
[Key(2)]
|
||||
public string[] SelectedNodes { get; set; } = Array.Empty<string>();
|
||||
|
||||
[Key(3)]
|
||||
public string[] DeferredChildRequests { get; set; } = Array.Empty<string>();
|
||||
|
||||
[Key(4)]
|
||||
public string[] ParentFallbackNodes { get; set; } = Array.Empty<string>();
|
||||
|
||||
[Key(5)]
|
||||
public CultGeometryContributionRow[] Diagnostics { get; set; } = Array.Empty<CultGeometryContributionRow>();
|
||||
|
||||
public static CultRecordKey CreateRecordKey(CultGeometrySelectedCutManifest cut)
|
||||
{
|
||||
if (cut == null) throw new ArgumentNullException(nameof(cut));
|
||||
return new CultRecordKey("geometry:cut:" + StableHash(
|
||||
cut.RequestKey,
|
||||
cut.CutId,
|
||||
StableArray(cut.SelectedNodes),
|
||||
StableArray(cut.DeferredChildRequests),
|
||||
StableArray(cut.ParentFallbackNodes)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// One diagnostic row explaining selected-cut pressure.
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public sealed class CultGeometryContributionRow
|
||||
{
|
||||
[Key(0)]
|
||||
public string DomainKey { get; set; } = string.Empty;
|
||||
|
||||
[Key(1)]
|
||||
public string Kind { get; set; } = string.Empty;
|
||||
|
||||
[Key(2)]
|
||||
public float Contribution { get; set; }
|
||||
|
||||
[Key(3)]
|
||||
public float ProjectedScreenError { get; set; }
|
||||
|
||||
[Key(4)]
|
||||
public float SemanticPriority { get; set; }
|
||||
|
||||
[Key(5)]
|
||||
public int EstimatedTriangleCost { get; set; }
|
||||
|
||||
[Key(6)]
|
||||
public int ChildCost { get; set; }
|
||||
|
||||
[Key(7)]
|
||||
public int RemainingTriangleBudget { get; set; }
|
||||
|
||||
[Key(8)]
|
||||
public bool Requested { get; set; }
|
||||
|
||||
[Key(9)]
|
||||
public bool Dirty { get; set; }
|
||||
|
||||
[Key(10)]
|
||||
public bool Selected { get; set; }
|
||||
|
||||
[Key(11)]
|
||||
public bool UsedFallback { get; set; }
|
||||
|
||||
[Key(12)]
|
||||
public bool DeferredByBudget { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CultCache document carrying one emitted geometry chunk and its collider payload.
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
[CultDocument("gamecult.geometry.chunk_artifact", CultGeometrySchemaVersions.ChunkArtifact)]
|
||||
public sealed class CultGeometryChunkArtifact
|
||||
{
|
||||
[Key(0)]
|
||||
[CultName]
|
||||
public string ChunkId { get; set; } = string.Empty;
|
||||
|
||||
[Key(1)]
|
||||
[CultReference(typeof(CultGeometrySelectedCutManifest))]
|
||||
public string CutKey { get; set; } = string.Empty;
|
||||
|
||||
[Key(2)]
|
||||
[CultIndex]
|
||||
public string SelectedCutId { get; set; } = string.Empty;
|
||||
|
||||
[Key(3)]
|
||||
public float[] BoundsMin { get; set; } = Array.Empty<float>();
|
||||
|
||||
[Key(4)]
|
||||
public float[] BoundsMax { get; set; } = Array.Empty<float>();
|
||||
|
||||
[Key(5)]
|
||||
public string[] SourceDomainKeys { get; set; } = Array.Empty<string>();
|
||||
|
||||
[Key(6)]
|
||||
public string[] SourceClaimKeys { get; set; } = Array.Empty<string>();
|
||||
|
||||
[Key(7)]
|
||||
public CultGeometryTriangleMesh RenderMesh { get; set; } = new CultGeometryTriangleMesh();
|
||||
|
||||
[Key(8)]
|
||||
public CultGeometryTriangleMesh? ColliderMesh { get; set; }
|
||||
|
||||
[Key(9)]
|
||||
public int InputBrushes { get; set; }
|
||||
|
||||
[Key(10)]
|
||||
public int CandidatePairs { get; set; }
|
||||
|
||||
[Key(11)]
|
||||
public int RejectedPairs { get; set; }
|
||||
|
||||
[Key(12)]
|
||||
public ulong StableClipSeed { get; set; }
|
||||
|
||||
[Key(13)]
|
||||
public bool SupportsParentChildCoexistence { get; set; }
|
||||
|
||||
public static CultRecordKey CreateRecordKey(CultGeometryChunkArtifact chunk)
|
||||
{
|
||||
if (chunk == null) throw new ArgumentNullException(nameof(chunk));
|
||||
return new CultRecordKey("geometry:chunk:" + StableHash(
|
||||
chunk.CutKey,
|
||||
chunk.ChunkId,
|
||||
chunk.SelectedCutId,
|
||||
StableArray(chunk.SourceDomainKeys),
|
||||
StableArray(chunk.SourceClaimKeys),
|
||||
chunk.RenderMesh.StableFingerprint(),
|
||||
chunk.ColliderMesh?.StableFingerprint() ?? string.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Packed triangle mesh payload for CultCache persistence and CultNet replication.
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public sealed class CultGeometryTriangleMesh
|
||||
{
|
||||
[Key(0)]
|
||||
public float[] Positions { get; set; } = Array.Empty<float>();
|
||||
|
||||
[Key(1)]
|
||||
public float[] Normals { get; set; } = Array.Empty<float>();
|
||||
|
||||
[Key(2)]
|
||||
public float[] Uvs { get; set; } = Array.Empty<float>();
|
||||
|
||||
[Key(3)]
|
||||
public uint[] Indices { get; set; } = Array.Empty<uint>();
|
||||
|
||||
[Key(4)]
|
||||
public uint[] TriangleMaterials { get; set; } = Array.Empty<uint>();
|
||||
|
||||
[IgnoreMember]
|
||||
public int TriangleCount => Indices.Length / 3;
|
||||
|
||||
public string StableFingerprint() => StableHash(
|
||||
StableVector(Positions),
|
||||
StableVector(Normals),
|
||||
StableVector(Uvs),
|
||||
string.Join(",", Indices.Select(value => value.ToString(CultureInfo.InvariantCulture))),
|
||||
string.Join(",", TriangleMaterials.Select(value => value.ToString(CultureInfo.InvariantCulture))));
|
||||
}
|
||||
|
||||
internal static class CultGeometryDocuments
|
||||
{
|
||||
public static string StableHash(params string[] parts)
|
||||
{
|
||||
using var sha = SHA256.Create();
|
||||
var canonical = string.Join("\u001f", parts);
|
||||
var bytes = sha.ComputeHash(Encoding.UTF8.GetBytes(canonical));
|
||||
return string.Concat(bytes.Select(value => value.ToString("x2")));
|
||||
}
|
||||
|
||||
public static string StableVector(float[] values)
|
||||
{
|
||||
return string.Join(",", values.Select(value => value.ToString("R", CultureInfo.InvariantCulture)));
|
||||
}
|
||||
|
||||
public static string StableArray(string[] values)
|
||||
{
|
||||
return string.Join("\u001e", values);
|
||||
}
|
||||
}
|
||||
|
||||
internal static class CultGeometryStringBuilderExtensions
|
||||
{
|
||||
public static StringBuilder AppendVector(this StringBuilder builder, float[] values)
|
||||
{
|
||||
builder.Append(StableVector(values));
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/GameCult.Geometry/GameCult.Geometry.csproj
Normal file
18
src/GameCult.Geometry/GameCult.Geometry.csproj
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Description>Typed CultCache geometry domain and chunk artifact documents for VibeGeometry and Fensalir</Description>
|
||||
<PackageId>GameCult.Geometry</PackageId>
|
||||
<PackageTags>game;geometry;csg;lod;cultcache;cultmesh;vibegeometry;fensalir</PackageTags>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GameCult.Caching\GameCult.Caching.csproj" />
|
||||
<PackageReference Include="MessagePack" Version="3.1.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="README.md" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
16
src/GameCult.Geometry/README.md
Normal file
16
src/GameCult.Geometry/README.md
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# GameCult.Geometry
|
||||
|
||||
`GameCult.Geometry` defines CultCache-native documents for procedural geometry
|
||||
domains, LOD build requests, selected-cut manifests, and mesh chunk artifacts.
|
||||
|
||||
The package is deliberately substrate-shaped:
|
||||
|
||||
- CultCache owns document identity, schema compatibility, references, and local
|
||||
persistence.
|
||||
- CultNet can distribute these documents through the normal raw document lane.
|
||||
- CultMesh can use them as worker-visible shared state for simulation and
|
||||
geometry pipelines.
|
||||
- JSON is not a runtime transport here. It may publish schema descriptions at
|
||||
the xeno boundary, but the live machine eats and emits typed CultCache
|
||||
documents.
|
||||
|
||||
19
tests/GameCult.Geometry.Tests/GameCult.Geometry.Tests.csproj
Normal file
19
tests/GameCult.Geometry.Tests/GameCult.Geometry.Tests.csproj
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<RootNamespace>GameCult.Geometry.Tests</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\GameCult.Caching.MessagePack\GameCult.Caching.MessagePack.csproj" />
|
||||
<ProjectReference Include="..\..\src\GameCult.Geometry\GameCult.Geometry.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NUnit" Version="4.*" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="6.2.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.4.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="8.9.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
138
tests/GameCult.Geometry.Tests/GeometryDocumentTests.cs
Normal file
138
tests/GameCult.Geometry.Tests/GeometryDocumentTests.cs
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
using FluentAssertions;
|
||||
using GameCult.Caching;
|
||||
using GameCult.Caching.MessagePack;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GameCult.Geometry.Tests
|
||||
{
|
||||
public sealed class GeometryDocumentTests
|
||||
{
|
||||
[Test]
|
||||
public void GeometryDocuments_Register_AsCultCacheSchemas()
|
||||
{
|
||||
var cache = new CultCache();
|
||||
|
||||
cache.Registry.GetRequired<CultGeometryDomainDocument>().SchemaVersion
|
||||
.Should().Be(CultGeometrySchemaVersions.Domain);
|
||||
cache.Registry.GetRequired<CultGeometryBuildRequest>().SchemaVersion
|
||||
.Should().Be(CultGeometrySchemaVersions.BuildRequest);
|
||||
cache.Registry.GetRequired<CultGeometrySelectedCutManifest>().SchemaVersion
|
||||
.Should().Be(CultGeometrySchemaVersions.SelectedCut);
|
||||
cache.Registry.GetRequired<CultGeometryChunkArtifact>().SchemaVersion
|
||||
.Should().Be(CultGeometrySchemaVersions.ChunkArtifact);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GeometryBuildRequest_UsesStableCultCacheKey()
|
||||
{
|
||||
var domain = SampleDomain();
|
||||
var domainKey = CultGeometryDomainDocument.CreateRecordKey(domain);
|
||||
var request = new CultGeometryBuildRequest
|
||||
{
|
||||
DomainKey = domainKey.Value,
|
||||
WorkerGroup = "ragnarok-column-workers",
|
||||
CameraPosition = [36f, -42f, 30f],
|
||||
FrustumMin = [-75f, -75f, -30f],
|
||||
FrustumMax = [75f, 75f, 120f],
|
||||
ViewportHeightPixels = 1080f,
|
||||
VerticalFovRadians = 1.0471976f,
|
||||
TargetError = 0.01f,
|
||||
TriangleBudget = 10_000,
|
||||
ColliderBudget = 10_000,
|
||||
SemanticFilter = [],
|
||||
RequestedChunkKeys = [],
|
||||
DirtyDomainKeys = []
|
||||
};
|
||||
|
||||
var first = CultGeometryBuildRequest.CreateRecordKey(request);
|
||||
var second = CultGeometryBuildRequest.CreateRecordKey(request);
|
||||
request.TriangleBudget++;
|
||||
var changed = CultGeometryBuildRequest.CreateRecordKey(request);
|
||||
|
||||
second.Should().Be(first);
|
||||
changed.Should().NotBe(first);
|
||||
first.Value.Should().StartWith("geometry:request:");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ChunkArtifact_RoundTrips_ThroughCultCacheMessagePack()
|
||||
{
|
||||
var chunk = new CultGeometryChunkArtifact
|
||||
{
|
||||
ChunkId = "chunk/ragnarok-column/column-00",
|
||||
CutKey = "geometry:cut:test",
|
||||
SelectedCutId = "cut-test",
|
||||
BoundsMin = [-1f, -1f, 0f],
|
||||
BoundsMax = [1f, 1f, 1f],
|
||||
SourceDomainKeys = ["ragnarok-column/stellarator-column-00"],
|
||||
SourceClaimKeys = ["ragnarok-column/stellarator-column-00/claim/support"],
|
||||
RenderMesh = new CultGeometryTriangleMesh
|
||||
{
|
||||
Positions = [0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f, 0f],
|
||||
Normals = [0f, 0f, 1f, 0f, 0f, 1f, 0f, 0f, 1f],
|
||||
Uvs = [0f, 0f, 1f, 0f, 0f, 1f],
|
||||
Indices = [0u, 1u, 2u],
|
||||
TriangleMaterials = [20u]
|
||||
},
|
||||
ColliderMesh = null,
|
||||
InputBrushes = 1,
|
||||
StableClipSeed = 1234,
|
||||
SupportsParentChildCoexistence = true
|
||||
};
|
||||
|
||||
var payload = CultDocumentMessagePackSerialization.Serialize(chunk);
|
||||
var decoded = CultDocumentMessagePackSerialization.Deserialize<CultGeometryChunkArtifact>(payload);
|
||||
|
||||
decoded.ChunkId.Should().Be(chunk.ChunkId);
|
||||
decoded.RenderMesh.TriangleCount.Should().Be(1);
|
||||
CultGeometryChunkArtifact.CreateRecordKey(decoded)
|
||||
.Should().Be(CultGeometryChunkArtifact.CreateRecordKey(chunk));
|
||||
}
|
||||
|
||||
private static CultGeometryDomainDocument SampleDomain()
|
||||
{
|
||||
return new CultGeometryDomainDocument
|
||||
{
|
||||
DomainId = "ragnarok-column",
|
||||
RootKey = "ragnarok-column",
|
||||
SourceRuntime = "vg-csg",
|
||||
CreatedAt = "2026-05-29T00:00:00.0000000Z",
|
||||
Root = new CultGeometryDomainNode
|
||||
{
|
||||
Name = "ragnarok-column",
|
||||
Kind = "Root",
|
||||
Translation = [0f, 0f, 0f],
|
||||
RotationXyzw = [0f, 0f, 0f, 1f],
|
||||
Seed = 0x5EED,
|
||||
Claims = [],
|
||||
Children =
|
||||
[
|
||||
new CultGeometryDomainNode
|
||||
{
|
||||
Name = "stellarator-column-00",
|
||||
Kind = "Column",
|
||||
Translation = [0f, 0f, 0f],
|
||||
RotationXyzw = [0f, 0f, 0f, 1f],
|
||||
Seed = 0xC0110000,
|
||||
Claims =
|
||||
[
|
||||
new CultGeometryFeatureClaim
|
||||
{
|
||||
Name = "column-support-shell",
|
||||
Translation = [0f, 0f, 0f],
|
||||
RotationXyzw = [0f, 0f, 0f, 1f],
|
||||
SupportCenter = [0f, 0f, 45f],
|
||||
SupportSize = [18f, 18f, 96f],
|
||||
Kind = "SupportShell",
|
||||
Material = 10,
|
||||
LoweringPolicy = "RenderAndCollider"
|
||||
}
|
||||
],
|
||||
Children = []
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue