diff --git a/.gitignore b/.gitignore index ac9c49142..811814afa 100644 --- a/.gitignore +++ b/.gitignore @@ -94,7 +94,7 @@ crashlytics-build.properties Packages/packages-lock.json GameData/run.cc GameData/player.cc -GameData/RemovedMods/ +Vault/Aetheria/.obsidian/plugins/copilot/data.json # Agent scratch, sandboxed toolchain caches, and throwaway checkouts. These had # grown to 47 untracked entries; the worktree must stay legible, so they never diff --git a/.lfsconfig b/.lfsconfig deleted file mode 100644 index d9ce439fc..000000000 --- a/.lfsconfig +++ /dev/null @@ -1,2 +0,0 @@ -[lfs] - url = https://eureka.gamecult.org/forge/GameCult/Aetheria.git/info/lfs diff --git a/Assets/Content/Prefabs/Mine.prefab b/Assets/Content/Prefabs/Mine.prefab index 912986ee7..dbc1e0915 100644 --- a/Assets/Content/Prefabs/Mine.prefab +++ b/Assets/Content/Prefabs/Mine.prefab @@ -146,5 +146,6 @@ MonoBehaviour: ActiveEmission: 100 ArmedEmission: 1000 RotationSpeed: 1 + GridOffset: 0 HitEffect: {fileID: 1121192042590650, guid: e1b08032bec16ba4eb1ae23cbd572664, type: 3} HitEffectScale: 10 diff --git a/Assets/Content/Prefabs/Stations/PlanetOutpost.prefab b/Assets/Content/Prefabs/Stations/PlanetOutpost.prefab index e3d20ceb7..6ce31f34f 100644 --- a/Assets/Content/Prefabs/Stations/PlanetOutpost.prefab +++ b/Assets/Content/Prefabs/Stations/PlanetOutpost.prefab @@ -81,6 +81,87 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} +--- !u!1 &7783244517717541194 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7783244517717541195} + - component: {fileID: 7783244517717541175} + - component: {fileID: 7783244517717541174} + m_Layer: 9 + m_Name: Gravity Well + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &7783244517717541195 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7783244517717541194} + m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 7783244518521719148} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!33 &7783244517717541175 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7783244517717541194} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &7783244517717541174 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7783244517717541194} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 44a8bbb89acb4e34c9f41a9da5842bb4, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &7783244518317531027 GameObject: m_ObjectHideFlags: 0 @@ -208,6 +289,7 @@ Transform: m_Children: - {fileID: 589192530128514016} - {fileID: 7783244518317531036} + - {fileID: 7783244517717541195} - {fileID: 7783244516809707565} m_Father: {fileID: 0} m_RootOrder: 0 @@ -225,6 +307,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: Body: {fileID: 7783244518317531038} + GravityWell: {fileID: 7783244517717541174} Icon: {fileID: 7783244516809707566} Generator: {fileID: 741236912059895623} --- !u!114 &741236912059895623 diff --git a/Assets/Editor/AetheriaBuild.cs b/Assets/Editor/AetheriaBuild.cs index 3cf434ee4..7d3c891d2 100644 --- a/Assets/Editor/AetheriaBuild.cs +++ b/Assets/Editor/AetheriaBuild.cs @@ -8,12 +8,12 @@ using UnityEditor.AddressableAssets.Settings; using UnityEditor.Build.Reporting; using Debug = UnityEngine.Debug; -// The one way to make a player directory, for Windows or Linux. Owns what the directory contains: the player and its data, +// The one way to make a Win64 player directory. Owns what the directory contains: Aetheria.exe and its data, // GameData/Aetheria.cc, GameData/Narrative/**, GameData/Mods/** and ModTools/AetherDb. Manual builds, smokes and // release cuts all call this and stage nothing themselves. // // Unity -batchmode -quit -projectPath -executeMethod AetheriaBuild.Build -// -aetheriaVersion -aetheriaOut [-aetheriaTarget win64|linux64] -logFile +// -aetheriaVersion -aetheriaOut -logFile // // AetherDb is published from tools/AetherDb, so the headless build's CULTLIB_ROOT / CULTMATH_ROOT (Directory.Build.props) // must be set for dotnet when the defaults do not hold the pinned revisions. @@ -22,14 +22,6 @@ public static class AetheriaBuild { private static readonly Regex SemVer = new Regex(@"^\d+\.\d+\.\d+([-+][0-9A-Za-z.-]+)?$"); - // A target: the player Unity builds, its executable, and the runtime AetherDb is published for. - private static (BuildTarget target, string player, string runtime, string aetherDb) Target(string name) => name switch - { - "win64" => (BuildTarget.StandaloneWindows64, "Aetheria.exe", "win-x64", "AetherDb.exe"), - "linux64" => (BuildTarget.StandaloneLinux64, "Aetheria.x86_64", "linux-x64", "AetherDb"), - _ => throw new InvalidOperationException($"-aetheriaTarget {name}: expected win64 or linux64"), - }; - public static void Build() { var step = "arguments"; @@ -38,7 +30,6 @@ public static class AetheriaBuild var version = Argument("-aetheriaVersion"); if (!SemVer.IsMatch(version)) throw new InvalidOperationException("-aetheriaVersion is not a semver"); var output = Path.GetFullPath(Argument("-aetheriaOut")); - var target = Target(Argument("-aetheriaTarget", "win64")); var repoRoot = Directory.GetParent(UnityEngine.Application.dataPath).FullName; step = "version"; @@ -55,8 +46,8 @@ public static class AetheriaBuild var report = BuildPipeline.BuildPlayer(new BuildPlayerOptions { scenes = scenes, - locationPathName = Path.Combine(output, target.player), - target = target.target, + locationPathName = Path.Combine(output, "Aetheria.exe"), + target = BuildTarget.StandaloneWindows64, options = BuildOptions.None, }); if (report.summary.result != BuildResult.Succeeded || report.summary.totalErrors != 0) @@ -66,7 +57,7 @@ public static class AetheriaBuild PlayerStaging.Stage(repoRoot, output); step = "aetherdb"; - Publish(repoRoot, Path.Combine(output, "ModTools"), target.runtime, target.aetherDb); + Publish(repoRoot, Path.Combine(output, "ModTools")); step = "burst"; var burst = Path.Combine(output, "Aetheria_BurstDebugInformation_DoNotShip"); @@ -83,11 +74,11 @@ public static class AetheriaBuild EditorApplication.Exit(0); } - private static void Publish(string repoRoot, string modTools, string runtime, string aetherDb) + private static void Publish(string repoRoot, string modTools) { var info = new ProcessStartInfo("dotnet") { - Arguments = $"publish tools/AetherDb -c Release -r {runtime} --self-contained -p:PublishSingleFile=true -o \"{modTools}\"", + Arguments = $"publish tools/AetherDb -c Release -r win-x64 --self-contained -p:PublishSingleFile=true -o \"{modTools}\"", WorkingDirectory = repoRoot, UseShellExecute = false, RedirectStandardOutput = true, @@ -101,16 +92,15 @@ public static class AetheriaBuild if (process.ExitCode != 0) throw new InvalidOperationException($"dotnet publish exited {process.ExitCode}:\n{text}\n{errors.Result}"); } - if (!File.Exists(Path.Combine(modTools, aetherDb))) - throw new InvalidOperationException($"dotnet publish produced no ModTools/{aetherDb}"); + if (!File.Exists(Path.Combine(modTools, "AetherDb.exe"))) + throw new InvalidOperationException("dotnet publish produced no ModTools/AetherDb.exe"); } - private static string Argument(string name, string fallback = null) + private static string Argument(string name) { var args = Environment.GetCommandLineArgs(); var at = Array.IndexOf(args, name); - if (at < 0 || at + 1 >= args.Length) - return fallback ?? throw new InvalidOperationException(name + " is required"); + if (at < 0 || at + 1 >= args.Length) throw new InvalidOperationException(name + " is required"); return args[at + 1]; } } diff --git a/Assets/Editor/PlayerStaging.cs b/Assets/Editor/PlayerStaging.cs index 6f48daaa0..4698130f6 100644 --- a/Assets/Editor/PlayerStaging.cs +++ b/Assets/Editor/PlayerStaging.cs @@ -2,8 +2,9 @@ using System; using System.IO; // What a player directory holds beside the executable's data: GameData/Aetheria.cc, GameData/Narrative/** and, when -// the repo has one, GameData/Mods/**. Nothing else under GameData ships (run.cc and player.cc are the player's own). -// Unity-free so the headless suite can prove the rules; AetheriaBuild is the only caller. +// the repo has one, GameData/Mods/**. Nothing else under GameData ships (run.cc and player.cc are the player's own; +// SoundbanksInfo.json is read by no code). Unity-free so the headless suite can prove the rules; AetheriaBuild is the +// only caller. internal static class PlayerStaging { public const string Catalog = "Aetheria.cc"; diff --git a/Assets/Materials/Brushes/Gravity Waves.mat b/Assets/Materials/Brushes/Gravity Waves.mat new file mode 100644 index 000000000..a45dfed21 --- /dev/null +++ b/Assets/Materials/Brushes/Gravity Waves.mat @@ -0,0 +1,83 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Gravity Waves + m_Shader: {fileID: 4800000, guid: 8a8e593b17063b54ea02f7ea5363b59d, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _Depth: 3.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _Frequency: 27.43 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _Phase: 0 + - _Power: 8 + - _SinePower: 1.25 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/UI/MapAsteroid.mat.meta b/Assets/Materials/Brushes/Gravity Waves.mat.meta similarity index 79% rename from Assets/Materials/UI/MapAsteroid.mat.meta rename to Assets/Materials/Brushes/Gravity Waves.mat.meta index 2c044e9e9..f4e2f41d4 100644 --- a/Assets/Materials/UI/MapAsteroid.mat.meta +++ b/Assets/Materials/Brushes/Gravity Waves.mat.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c1012d5466454651b7279be93ef9af88 +guid: 11fbaa87dcc7a3743a6bd3aa5c86e5ae NativeFormatImporter: externalObjects: {} mainObjectFileID: 2100000 diff --git a/Assets/Materials/Brushes/Gravity Field.mat b/Assets/Materials/Brushes/Gravity Well.mat similarity index 92% rename from Assets/Materials/Brushes/Gravity Field.mat rename to Assets/Materials/Brushes/Gravity Well.mat index d912917c9..e0bd9f79d 100644 --- a/Assets/Materials/Brushes/Gravity Field.mat +++ b/Assets/Materials/Brushes/Gravity Well.mat @@ -7,8 +7,8 @@ Material: m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_Name: Gravity Field - m_Shader: {fileID: 4800000, guid: 08d8efa80af84065b54c9bfed784e435, type: 3} + m_Name: Gravity Well + m_Shader: {fileID: 4800000, guid: 268da230635cfb34ab4ed6ad39503fa0, type: 3} m_ShaderKeywords: m_LightmapFlags: 4 m_EnableInstancingVariants: 0 @@ -57,6 +57,8 @@ Material: m_Offset: {x: 0, y: 0} m_Floats: - _BumpScale: 1 + - _Cutoff: 1 + - _Depth: 80 - _DetailNormalMapScale: 1 - _DstBlend: 0 - _GlossMapScale: 1 @@ -66,6 +68,7 @@ Material: - _Mode: 0 - _OcclusionStrength: 1 - _Parallax: 0.02 + - _Power: 16 - _SmoothnessTextureChannel: 0 - _SpecularHighlights: 1 - _SrcBlend: 1 diff --git a/Assets/Materials/Brushes/Gravity Field.mat.meta b/Assets/Materials/Brushes/Gravity Well.mat.meta similarity index 100% rename from Assets/Materials/Brushes/Gravity Field.mat.meta rename to Assets/Materials/Brushes/Gravity Well.mat.meta diff --git a/Assets/Materials/Brushes/Sector Tint.mat b/Assets/Materials/Brushes/Sector Tint.mat index 84e252ad3..3e5e00f24 100644 --- a/Assets/Materials/Brushes/Sector Tint.mat +++ b/Assets/Materials/Brushes/Sector Tint.mat @@ -8,7 +8,7 @@ Material: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: Sector Tint - m_Shader: {fileID: 4800000, guid: 782740c1a3d7455ea75dc87fafdc8432, type: 3} + m_Shader: {fileID: 4800000, guid: 268da230635cfb34ab4ed6ad39503fa0, type: 3} m_ValidKeywords: [] m_InvalidKeywords: [] m_LightmapFlags: 4 @@ -59,8 +59,8 @@ Material: m_Ints: [] m_Floats: - _BumpScale: 1 + - _Cutoff: 1 - _Depth: 0.025 - - _EdgeBrightness: 0.12 - _DetailNormalMapScale: 1 - _DstBlend: 0 - _Frequency: 6.2832 @@ -72,6 +72,7 @@ Material: - _OcclusionStrength: 1 - _Parallax: 0.02 - _Phase: 0 + - _Power: 2 - _SinePower: 1.25 - _SmoothnessTextureChannel: 0 - _SpecularHighlights: 1 diff --git a/Assets/Materials/Brushes/Wormhole Gravity 1.mat b/Assets/Materials/Brushes/Wormhole Gravity 1.mat new file mode 100644 index 000000000..3ae24d6ee --- /dev/null +++ b/Assets/Materials/Brushes/Wormhole Gravity 1.mat @@ -0,0 +1,80 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Wormhole Gravity 1 + m_Shader: {fileID: 4800000, guid: 268da230635cfb34ab4ed6ad39503fa0, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 1 + - _Depth: 54 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _Power: 4 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/Brushes/Wormhole Gravity 1.mat.meta b/Assets/Materials/Brushes/Wormhole Gravity 1.mat.meta new file mode 100644 index 000000000..7d40d0332 --- /dev/null +++ b/Assets/Materials/Brushes/Wormhole Gravity 1.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 244f3e4c0c030a24b8d7aa944895bdcf +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/Brushes/Wormhole Gravity 2.mat b/Assets/Materials/Brushes/Wormhole Gravity 2.mat new file mode 100644 index 000000000..3ae24d6ee --- /dev/null +++ b/Assets/Materials/Brushes/Wormhole Gravity 2.mat @@ -0,0 +1,80 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Wormhole Gravity 1 + m_Shader: {fileID: 4800000, guid: 268da230635cfb34ab4ed6ad39503fa0, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 1 + - _Depth: 54 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _Power: 4 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/Brushes/Wormhole Gravity 2.mat.meta b/Assets/Materials/Brushes/Wormhole Gravity 2.mat.meta new file mode 100644 index 000000000..fb6f1270d --- /dev/null +++ b/Assets/Materials/Brushes/Wormhole Gravity 2.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0ec0689c58b99c64297b3e429e1d9112 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/Brushes/Wormhole Gravity.mat b/Assets/Materials/Brushes/Wormhole Gravity.mat new file mode 100644 index 000000000..fb6f52b20 --- /dev/null +++ b/Assets/Materials/Brushes/Wormhole Gravity.mat @@ -0,0 +1,82 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Wormhole Gravity + m_Shader: {fileID: 4800000, guid: 268da230635cfb34ab4ed6ad39503fa0, type: 3} + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.15 + - _Depth: 2000 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _Power: 64 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/Brushes/Wormhole Gravity.mat.meta b/Assets/Materials/Brushes/Wormhole Gravity.mat.meta new file mode 100644 index 000000000..30ec9b01d --- /dev/null +++ b/Assets/Materials/Brushes/Wormhole Gravity.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a9ef17c902709ce41a837c54b809184b +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/Brushes/Wormhole Waves.mat b/Assets/Materials/Brushes/Wormhole Waves.mat new file mode 100644 index 000000000..7902c5c36 --- /dev/null +++ b/Assets/Materials/Brushes/Wormhole Waves.mat @@ -0,0 +1,84 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Wormhole Waves + m_Shader: {fileID: 4800000, guid: 8681ac064d59d15458d16cc9b884262c, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _Depth: 33.9 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _Frequency: 2 + - _FrequencyDist: 60 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _Power: 2 + - _SinePower: 1.25 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _Speed: 15 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/Brushes/Wormhole Waves.mat.meta b/Assets/Materials/Brushes/Wormhole Waves.mat.meta new file mode 100644 index 000000000..1e5f35dd3 --- /dev/null +++ b/Assets/Materials/Brushes/Wormhole Waves.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ef2f6090d5cc14a4e9ce38def3bed9ac +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/Fog Marching 1.mat b/Assets/Materials/Fog Marching 1.mat new file mode 100644 index 000000000..20290c785 --- /dev/null +++ b/Assets/Materials/Fog Marching 1.mat @@ -0,0 +1,73 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Fog Marching 1 + m_Shader: {fileID: 4800000, guid: 7a890b6ceccf53c44bfc54b18b5daa58, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _Displacement: + m_Texture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Patch: + m_Texture: {fileID: 8400000, guid: c618a6b20b3c7394590c59a9fa467e86, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Surface: + m_Texture: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TintTexture: + m_Texture: {fileID: 8400000, guid: d196505464047f04a97f28689041209b, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _AlphaFloor: 0.01 + - _DepthBlend: 512 + - _DepthCeiling: 4096 + - _FlowSpeed: 2 + - _Gamma: 0.5 + - _GridCeilingBlend: -300 + - _GridCeilingDensity: 0.01 + - _GridCeilingFollow: 0 + - _GridCeilingOffset: 0 + - _GridFillDensity: 0.001 + - _GridFloorBlend: 100 + - _GridFloorDensity: 2 + - _GridFloorOffset: 20 + - _GridPatchBlend: 50 + - _GridPatchDensity: 2 + - _NoiseExponent: 2.25 + - _NoiseFrequency: 0.015 + - _NoiseSpeed: 0 + - _NoiseStrength: 500 + - _SafetyDistance: 20 + - _Scattering: 0 + - _ScatteringDensityExponent: 0.5 + - _ScatteringDistExponent: 0.5 + - _ScatteringMinDist: 500 + - _StepExponent: 2 + - _TintExponent: 0.1 + - _TurbulenceAmplitude: 100 + - _TurbulenceScale: 100 + m_Colors: + - _Tint: {r: 0.0627451, g: 0.0627451, b: 0.0627451, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/Fog Marching 1.mat.meta b/Assets/Materials/Fog Marching 1.mat.meta new file mode 100644 index 000000000..00e039020 --- /dev/null +++ b/Assets/Materials/Fog Marching 1.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a72896cb7097bfa46a1a8f4092e47c72 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/Fog Marching Main Menu.mat b/Assets/Materials/Fog Marching Main Menu.mat new file mode 100644 index 000000000..b22522a2d --- /dev/null +++ b/Assets/Materials/Fog Marching Main Menu.mat @@ -0,0 +1,99 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Fog Marching Main Menu + m_Shader: {fileID: 4800000, guid: 7a890b6ceccf53c44bfc54b18b5daa58, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _Displacement: + m_Texture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NebulaPatch: + m_Texture: {fileID: 8400000, guid: c618a6b20b3c7394590c59a9fa467e86, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NebulaPatchHeight: + m_Texture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NebulaSurfaceHeight: + m_Texture: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NebulaTint: + m_Texture: {fileID: 8400000, guid: d196505464047f04a97f28689041209b, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Patch: + m_Texture: {fileID: 8400000, guid: c618a6b20b3c7394590c59a9fa467e86, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Surface: + m_Texture: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TintTexture: + m_Texture: {fileID: 8400000, guid: d196505464047f04a97f28689041209b, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _AlphaFloor: 0 + - _DepthBlend: 512 + - _DepthCeiling: 1024 + - _Exposure: 100 + - _FlowAmplitude: 1 + - _FlowScale: 1 + - _FlowScroll: 1 + - _FlowSpeed: 5 + - _Gamma: 0.3 + - _GridCeilingBlend: -300 + - _GridCeilingDensity: 0.01 + - _GridCeilingFollow: 0 + - _GridCeilingOffset: 0 + - _GridFillDensity: 0.001 + - _GridFloorBlend: 50 + - _GridFloorDensity: 1 + - _GridFloorOffset: 100 + - _GridPatchBlend: 50 + - _GridPatchDensity: 1 + - _NebulaFillDensity: 0.00075 + - _NebulaFloorBlend: 50 + - _NebulaFloorDensity: 1 + - _NebulaFloorOffset: 80 + - _NebulaPatchBlend: 25 + - _NebulaPatchDensity: 0.1 + - _NoiseExponent: 2 + - _NoiseFrequency: 0.02 + - _NoiseSpeed: 0.00001 + - _NoiseStrength: 200 + - _SafetyDistance: 50 + - _Scattering: 0 + - _ScatteringDensityExponent: 8 + - _ScatteringDistExponent: 0.5 + - _ScatteringMinDist: 1 + - _StepExponent: 2 + - _TintExponent: 1.2 + - _TurbulenceAmplitude: 20 + - _TurbulenceScale: 30 + m_Colors: + - _Tint: {r: 0.09411765, g: 0.09411765, b: 0.09411765, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/Fog Marching Main Menu.mat.meta b/Assets/Materials/Fog Marching Main Menu.mat.meta new file mode 100644 index 000000000..6a5cdb35e --- /dev/null +++ b/Assets/Materials/Fog Marching Main Menu.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e21702a5e6e98b7409d6913663ceab7e +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/Fog Marching Test.mat b/Assets/Materials/Fog Marching Test.mat new file mode 100644 index 000000000..91b56761e --- /dev/null +++ b/Assets/Materials/Fog Marching Test.mat @@ -0,0 +1,65 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Fog Marching Test + m_Shader: {fileID: 4800000, guid: 7a890b6ceccf53c44bfc54b18b5daa58, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _Displacement: + m_Texture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Patch: + m_Texture: {fileID: 8400000, guid: c618a6b20b3c7394590c59a9fa467e86, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Surface: + m_Texture: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TintTexture: + m_Texture: {fileID: 8400000, guid: d196505464047f04a97f28689041209b, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _AlphaFloor: 0 + - _DepthBlend: 512 + - _DepthCeiling: 4096 + - _Gamma: 0.66 + - _GridCeilingBlend: -300 + - _GridCeilingDensity: 0.01 + - _GridCeilingFollow: 0 + - _GridCeilingOffset: 0 + - _GridFillDensity: 0.000025 + - _GridFloorBlend: 100 + - _GridFloorDensity: 4 + - _GridFloorOffset: 0 + - _GridPatchBlend: 5 + - _GridPatchDensity: 0.1 + - _NoiseFrequency: 0.01 + - _NoiseSpeed: 0.02 + - _NoiseStrength: 50 + - _SafetyDistance: 0 + - _StepExponent: 2 + - _TintExponent: 8 + m_Colors: + - _Tint: {r: 2.0078435, g: 2.0078435, b: 2.0078435, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/Fog Marching Test.mat.meta b/Assets/Materials/Fog Marching Test.mat.meta new file mode 100644 index 000000000..9f0e3d586 --- /dev/null +++ b/Assets/Materials/Fog Marching Test.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ad63650ae6d6cc542a5aad16694b3c46 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/Fog Marching.mat b/Assets/Materials/Fog Marching.mat new file mode 100644 index 000000000..52dc13c19 --- /dev/null +++ b/Assets/Materials/Fog Marching.mat @@ -0,0 +1,99 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Fog Marching + m_Shader: {fileID: 4800000, guid: 7a890b6ceccf53c44bfc54b18b5daa58, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _Displacement: + m_Texture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NebulaPatch: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NebulaPatchHeight: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NebulaSurfaceHeight: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NebulaTint: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Patch: + m_Texture: {fileID: 8400000, guid: c618a6b20b3c7394590c59a9fa467e86, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Surface: + m_Texture: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TintTexture: + m_Texture: {fileID: 8400000, guid: d196505464047f04a97f28689041209b, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _AlphaFloor: 0.01 + - _DepthBlend: 512 + - _DepthCeiling: 4096 + - _Exposure: 10 + - _FlowAmplitude: 512 + - _FlowScale: 1024 + - _FlowScroll: 0 + - _FlowSpeed: 1 + - _Gamma: 0.3 + - _GridCeilingBlend: -300 + - _GridCeilingDensity: 0.01 + - _GridCeilingFollow: 0 + - _GridCeilingOffset: 0 + - _GridFillDensity: 0.0005 + - _GridFloorBlend: 50 + - _GridFloorDensity: 1 + - _GridFloorOffset: 10 + - _GridPatchBlend: 150 + - _GridPatchDensity: 1 + - _NebulaFillDensity: 0.00075 + - _NebulaFloorBlend: 150 + - _NebulaFloorDensity: 1 + - _NebulaFloorOffset: 0 + - _NebulaPatchBlend: 51.47 + - _NebulaPatchDensity: 0.25 + - _NoiseExponent: 3 + - _NoiseFrequency: 0.005 + - _NoiseSpeed: 0 + - _NoiseStrength: -400 + - _SafetyDistance: 200 + - _Scattering: 50 + - _ScatteringDensityExponent: 1 + - _ScatteringDistExponent: 1.5 + - _ScatteringMinDist: 10 + - _StepExponent: 2 + - _TintExponent: 2 + - _TurbulenceAmplitude: 20 + - _TurbulenceScale: 60 + m_Colors: + - _Tint: {r: 0.01, g: 0.01, b: 0.01, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/Fog Marching.mat.meta b/Assets/Materials/Fog Marching.mat.meta new file mode 100644 index 000000000..04c6076f8 --- /dev/null +++ b/Assets/Materials/Fog Marching.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2ff39f5d101241043ba1dcde19d92f77 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Materials/UI/MapAsteroid.mat b/Assets/Materials/UI/MapAsteroid.mat deleted file mode 100644 index a0dbbdb1f..000000000 --- a/Assets/Materials/UI/MapAsteroid.mat +++ /dev/null @@ -1,31 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: MapAsteroid - m_Shader: {fileID: 4800000, guid: 22e2fc798f044a3aa2f6cd71f1df09a7, type: 3} - m_ValidKeywords: [] - m_InvalidKeywords: [] - m_LightmapFlags: 0 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: 3000 - stringTagMap: {} - disabledShaderPasses: [] - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _MainTex: - m_Texture: {fileID: 2800000, guid: 060aefd5a3d5ced4dabd9190a140e76e, type: 3} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Ints: [] - m_Floats: [] - m_Colors: - - _Color: {r: 1, g: 1, b: 1, a: 1} - m_BuildTextureStacks: [] diff --git a/Assets/Prefabs/RPG/Pickups/Dodecahedron.prefab b/Assets/Prefabs/RPG/Pickups/Dodecahedron.prefab index 7a65a0864..5d4f837d1 100644 --- a/Assets/Prefabs/RPG/Pickups/Dodecahedron.prefab +++ b/Assets/Prefabs/RPG/Pickups/Dodecahedron.prefab @@ -189,6 +189,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: RotationSpeed: 1 + GridOffset: 0 LabelFadeDuration: 0.5 LabelPersistDuration: 3 LabelDisplayAngle: 15 diff --git a/Assets/Prefabs/RPG/Pickups/Hexahedron.prefab b/Assets/Prefabs/RPG/Pickups/Hexahedron.prefab index f9a477cda..91f1c2ad3 100644 --- a/Assets/Prefabs/RPG/Pickups/Hexahedron.prefab +++ b/Assets/Prefabs/RPG/Pickups/Hexahedron.prefab @@ -162,6 +162,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: RotationSpeed: 1 + GridOffset: 0 LabelFadeDuration: 0.5 LabelPersistDuration: 3 LabelDisplayAngle: 15 diff --git a/Assets/Prefabs/RPG/Pickups/Icosahedron.prefab b/Assets/Prefabs/RPG/Pickups/Icosahedron.prefab index 4252e74cc..95973ba56 100644 --- a/Assets/Prefabs/RPG/Pickups/Icosahedron.prefab +++ b/Assets/Prefabs/RPG/Pickups/Icosahedron.prefab @@ -162,6 +162,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: RotationSpeed: 1 + GridOffset: 0 LabelFadeDuration: 0.5 LabelPersistDuration: 3 LabelDisplayAngle: 15 diff --git a/Assets/Prefabs/RPG/Pickups/Octahedron.prefab b/Assets/Prefabs/RPG/Pickups/Octahedron.prefab index 099083195..5957a7295 100644 --- a/Assets/Prefabs/RPG/Pickups/Octahedron.prefab +++ b/Assets/Prefabs/RPG/Pickups/Octahedron.prefab @@ -162,6 +162,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: RotationSpeed: 1 + GridOffset: 0 LabelFadeDuration: 0.5 LabelPersistDuration: 3 LabelDisplayAngle: 15 diff --git a/Assets/Prefabs/RPG/Pickups/Tetrahedron.prefab b/Assets/Prefabs/RPG/Pickups/Tetrahedron.prefab index 6dad19967..8688b6a3b 100644 --- a/Assets/Prefabs/RPG/Pickups/Tetrahedron.prefab +++ b/Assets/Prefabs/RPG/Pickups/Tetrahedron.prefab @@ -162,6 +162,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: RotationSpeed: 1 + GridOffset: 0 LabelFadeDuration: 0.5 LabelPersistDuration: 3 LabelDisplayAngle: 15 diff --git a/Assets/Prefabs/RPG/Planets/Gas Giant.prefab b/Assets/Prefabs/RPG/Planets/Gas Giant.prefab index de87b2a13..46ae7a3b1 100644 --- a/Assets/Prefabs/RPG/Planets/Gas Giant.prefab +++ b/Assets/Prefabs/RPG/Planets/Gas Giant.prefab @@ -30,6 +30,8 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 3973935122748960680} + - {fileID: 3973935121058605868} + - {fileID: 3973935122114073483} - {fileID: 3973935121358855036} m_Father: {fileID: 0} m_RootOrder: 0 @@ -47,9 +49,94 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: Body: {fileID: 3973935122748960683} + GravityWell: {fileID: 3973935121058605871} Icon: {fileID: 3973935121358855037} Generator: {fileID: 0} SunMaterial: {fileID: 3973935122748960685} + GravityWaves: {fileID: 3973935122114073485} +--- !u!1 &3973935121058605867 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3973935121058605868} + - component: {fileID: 3973935121058605856} + - component: {fileID: 3973935121058605871} + m_Layer: 9 + m_Name: Gravity Well + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3973935121058605868 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3973935121058605867} + m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3973935120991099173} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!33 &3973935121058605856 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3973935121058605867} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &3973935121058605871 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3973935121058605867} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 44a8bbb89acb4e34c9f41a9da5842bb4, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &3973935121358855035 GameObject: m_ObjectHideFlags: 0 @@ -133,6 +220,89 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} +--- !u!1 &3973935122114073482 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3973935122114073483} + - component: {fileID: 3973935122114073486} + - component: {fileID: 3973935122114073485} + m_Layer: 10 + m_Name: Gravity Waves + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3973935122114073483 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3973935122114073482} + m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3973935120991099173} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!33 &3973935122114073486 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3973935122114073482} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &3973935122114073485 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3973935122114073482} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 11fbaa87dcc7a3743a6bd3aa5c86e5ae, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &3973935122748960663 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Prefabs/RPG/Planets/Planet.prefab b/Assets/Prefabs/RPG/Planets/Planet.prefab index afffe73c4..336b3430b 100644 --- a/Assets/Prefabs/RPG/Planets/Planet.prefab +++ b/Assets/Prefabs/RPG/Planets/Planet.prefab @@ -83,6 +83,89 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} +--- !u!1 &8859079004671924238 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8859079004671924239} + - component: {fileID: 8859079004671924339} + - component: {fileID: 8859079004671924338} + m_Layer: 9 + m_Name: Gravity Well + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8859079004671924239 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8859079004671924238} + m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8859079004937162792} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!33 &8859079004671924339 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8859079004671924238} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &8859079004671924338 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8859079004671924238} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 44a8bbb89acb4e34c9f41a9da5842bb4, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &8859079004937162791 GameObject: m_ObjectHideFlags: 0 @@ -114,6 +197,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 8859079005270853336} + - {fileID: 8859079004671924239} - {fileID: 8859079003226229097} m_Father: {fileID: 0} m_RootOrder: 0 @@ -131,6 +215,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: Body: {fileID: 8859079005270853338} + GravityWell: {fileID: 8859079004671924338} Icon: {fileID: 8859079003226229098} Generator: {fileID: -7153121627769399805} --- !u!114 &-7153121627769399805 diff --git a/Assets/Prefabs/RPG/Planets/Sun.prefab b/Assets/Prefabs/RPG/Planets/Sun.prefab index ebe0fa72f..a7950f448 100644 --- a/Assets/Prefabs/RPG/Planets/Sun.prefab +++ b/Assets/Prefabs/RPG/Planets/Sun.prefab @@ -30,6 +30,8 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 7852221720971737233} + - {fileID: 7852221720969441490} + - {fileID: 7852221720741322892} - {fileID: 7852221720816817928} - {fileID: 7852221720964551245} m_Father: {fileID: 0} @@ -48,11 +50,96 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: Body: {fileID: 7852221720971737229} + GravityWell: {fileID: 7852221720969441484} Icon: {fileID: 7852221720964551246} Generator: {fileID: 0} SunMaterial: {fileID: 7852221720971737234} + GravityWaves: {fileID: 7852221720741322894} FogTint: {fileID: 7852221720816817929} Light: {fileID: 8064377225639657765} +--- !u!1 &7852221720741322899 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7852221720741322892} + - component: {fileID: 7852221720741322895} + - component: {fileID: 7852221720741322894} + m_Layer: 10 + m_Name: Gravity Waves + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &7852221720741322892 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7852221720741322899} + m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7852221720480299767} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!33 &7852221720741322895 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7852221720741322899} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &7852221720741322894 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7852221720741322899} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 11fbaa87dcc7a3743a6bd3aa5c86e5ae, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &7852221720816817935 GameObject: m_ObjectHideFlags: 0 @@ -219,6 +306,89 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} +--- !u!1 &7852221720969441489 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7852221720969441490} + - component: {fileID: 7852221720969441485} + - component: {fileID: 7852221720969441484} + m_Layer: 9 + m_Name: Gravity Well + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &7852221720969441490 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7852221720969441489} + m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7852221720480299767} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!33 &7852221720969441485 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7852221720969441489} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &7852221720969441484 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7852221720969441489} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 44a8bbb89acb4e34c9f41a9da5842bb4, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &7852221720971737232 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Prefabs/RPG/Wormhole 1.prefab b/Assets/Prefabs/RPG/Wormhole 1.prefab index e1ca93be7..b03d01009 100644 --- a/Assets/Prefabs/RPG/Wormhole 1.prefab +++ b/Assets/Prefabs/RPG/Wormhole 1.prefab @@ -1,5 +1,167 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: +--- !u!1 &1826894967093516808 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1030590306481442051} + - component: {fileID: 3216580199816124320} + - component: {fileID: 3211969211988968959} + m_Layer: 9 + m_Name: Gravity Well + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1030590306481442051 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1826894967093516808} + m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1024, y: 1024, z: 1024} + m_Children: [] + m_Father: {fileID: 463084220523011477} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!33 &3216580199816124320 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1826894967093516808} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &3211969211988968959 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1826894967093516808} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 244f3e4c0c030a24b8d7aa944895bdcf, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!1 &3908760799087214860 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 581261949390603689} + - component: {fileID: 987447324816385543} + - component: {fileID: 3959510878930752720} + m_Layer: 9 + m_Name: Gravity Waves + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &581261949390603689 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3908760799087214860} + m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 512, y: 512, z: 512} + m_Children: [] + m_Father: {fileID: 463084220523011477} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!33 &987447324816385543 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3908760799087214860} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &3959510878930752720 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3908760799087214860} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: ef2f6090d5cc14a4e9ce38def3bed9ac, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!1 &4837153162502999620 GameObject: m_ObjectHideFlags: 0 @@ -27,6 +189,9 @@ Transform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: + - {fileID: 8222188360457572195} + - {fileID: 1030590306481442051} + - {fileID: 581261949390603689} - {fileID: 8249320701965103923} m_Father: {fileID: 0} m_RootOrder: 0 @@ -112,3 +277,84 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} +--- !u!1 &7647029665738834910 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8222188360457572195} + - component: {fileID: 2468954688819198096} + - component: {fileID: 8290522694236574882} + m_Layer: 9 + m_Name: Gravity Pit + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8222188360457572195 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7647029665738834910} + m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 512, y: 512, z: 512} + m_Children: [] + m_Father: {fileID: 463084220523011477} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!33 &2468954688819198096 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7647029665738834910} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &8290522694236574882 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7647029665738834910} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: a9ef17c902709ce41a837c54b809184b, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} diff --git a/Assets/Prefabs/RTS/Asteroid Belt.prefab b/Assets/Prefabs/RTS/Asteroid Belt.prefab new file mode 100644 index 000000000..38df4e9e3 --- /dev/null +++ b/Assets/Prefabs/RTS/Asteroid Belt.prefab @@ -0,0 +1,111 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &992254348637625916 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1779911639310264026} + - component: {fileID: 349597964696402918} + - component: {fileID: 2844878085845264008} + - component: {fileID: 917803079556930035} + - component: {fileID: 4397878771830533054} + m_Layer: 14 + m_Name: Asteroid Belt + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1779911639310264026 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 992254348637625916} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &349597964696402918 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 992254348637625916} + m_Mesh: {fileID: 0} +--- !u!23 &2844878085845264008 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 992254348637625916} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: c018d99199afeca448c64b9022ac7270, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!64 &917803079556930035 +MeshCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 992254348637625916} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 4 + m_Convex: 0 + m_CookingOptions: 30 + m_Mesh: {fileID: 0} +--- !u!114 &4397878771830533054 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 992254348637625916} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 52538a3309c36fc4583c964a1c0b705f, type: 3} + m_Name: + m_EditorClassIdentifier: diff --git a/Assets/Prefabs/RTS/Asteroid Belt.prefab.meta b/Assets/Prefabs/RTS/Asteroid Belt.prefab.meta new file mode 100644 index 000000000..f1298ae38 --- /dev/null +++ b/Assets/Prefabs/RTS/Asteroid Belt.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1f1bfa2175a13b647888e2949e0cb138 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/RTS/Planet.prefab b/Assets/Prefabs/RTS/Planet.prefab index b288f30c5..dc8300809 100644 --- a/Assets/Prefabs/RTS/Planet.prefab +++ b/Assets/Prefabs/RTS/Planet.prefab @@ -223,6 +223,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: + - {fileID: 5321404120083801960} - {fileID: 5321404118931821940} - {fileID: 5321404119494867799} - {fileID: 1093865191529778971} @@ -244,7 +245,7 @@ MonoBehaviour: Label: {fileID: 5321404119494867796} Message: {fileID: 6196070888394201391} Children: [] - GravityMesh: {fileID: 0} + GravityMesh: {fileID: 5321404120083801962} --- !u!1 &5321404118931821943 GameObject: m_ObjectHideFlags: 0 @@ -563,3 +564,93 @@ MonoBehaviour: m_hasFontAssetChanged: 0 m_renderer: {fileID: 5321404119494867795} m_maskType: 0 +--- !u!1 &5321404120083801964 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5321404120083801960} + - component: {fileID: 5321404120083801963} + - component: {fileID: 5321404120083801962} + m_Layer: 8 + m_Name: Gravity Well + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &5321404120083801960 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5321404120083801964} + serializedVersion: 2 + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 10, y: 10, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5321404118521994135} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &5321404120083801963 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5321404120083801964} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &5321404120083801962 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5321404120083801964} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 44a8bbb89acb4e34c9f41a9da5842bb4, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} diff --git a/Assets/Resources/Geonames.meta b/Assets/Resources/Geonames.meta new file mode 100644 index 000000000..64c8c9a19 --- /dev/null +++ b/Assets/Resources/Geonames.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0f3e518a4c9bcc2469abe6cebdcb3691 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Geonames/Australia.csv b/Assets/Resources/Geonames/Australia.csv new file mode 100644 index 000000000..05587efaa --- /dev/null +++ b/Assets/Resources/Geonames/Australia.csv @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01bb478f4433dc42d5533e5030ef103ad163deca6bc40fb412025acd12e35c73 +size 442795 diff --git a/Assets/Resources/Geonames/Australia.csv.meta b/Assets/Resources/Geonames/Australia.csv.meta new file mode 100644 index 000000000..33d8c7dbe --- /dev/null +++ b/Assets/Resources/Geonames/Australia.csv.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 8ba25d5d0ecee31408c7ce7460b4e015 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Geonames/Congo.csv b/Assets/Resources/Geonames/Congo.csv new file mode 100644 index 000000000..5d0f0b66e --- /dev/null +++ b/Assets/Resources/Geonames/Congo.csv @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c84ff44083e4f0d9d9314e7b7095ed4ce2955905f26e7926faa09ed222655729 +size 506722 diff --git a/Assets/Resources/Geonames/Congo.csv.meta b/Assets/Resources/Geonames/Congo.csv.meta new file mode 100644 index 000000000..6147d0a96 --- /dev/null +++ b/Assets/Resources/Geonames/Congo.csv.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1e43b383bf860524986a6947496776d0 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Geonames/Germany.csv b/Assets/Resources/Geonames/Germany.csv new file mode 100644 index 000000000..beb35d1d0 --- /dev/null +++ b/Assets/Resources/Geonames/Germany.csv @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73e4e7231d448879d0a6d8524b3200be75fc8f5011a70cfd670b0897d07eca10 +size 1284208 diff --git a/Assets/Resources/Geonames/Germany.csv.meta b/Assets/Resources/Geonames/Germany.csv.meta new file mode 100644 index 000000000..244e41eda --- /dev/null +++ b/Assets/Resources/Geonames/Germany.csv.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ed470b8eb6cc68c4485ddc05d5a17ca1 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Geonames/India.csv b/Assets/Resources/Geonames/India.csv new file mode 100644 index 000000000..6b4eab5c6 --- /dev/null +++ b/Assets/Resources/Geonames/India.csv @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96c66414822c43a5451ce1910c1e545dedb224b0f3e79bc54f945dd484afc6a2 +size 3229324 diff --git a/Assets/Resources/Geonames/India.csv.meta b/Assets/Resources/Geonames/India.csv.meta new file mode 100644 index 000000000..3f8c176b4 --- /dev/null +++ b/Assets/Resources/Geonames/India.csv.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ca62f6d649360184aaa975c2716dfb27 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Geonames/Iran.csv b/Assets/Resources/Geonames/Iran.csv new file mode 100644 index 000000000..8d2754642 --- /dev/null +++ b/Assets/Resources/Geonames/Iran.csv @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b70fbbe6b4832eb1a3f35844bd87c0eb479fc77b6e59d6600b64cbbe7cc1bf16 +size 1073119 diff --git a/Assets/Resources/Geonames/Iran.csv.meta b/Assets/Resources/Geonames/Iran.csv.meta new file mode 100644 index 000000000..507664280 --- /dev/null +++ b/Assets/Resources/Geonames/Iran.csv.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e2d60c7158f6a01418d78e46c5845729 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Geonames/Japan.csv b/Assets/Resources/Geonames/Japan.csv new file mode 100644 index 000000000..d106ec364 --- /dev/null +++ b/Assets/Resources/Geonames/Japan.csv @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d58dc0227cc6e3b7622726c155031467b6d7314623c7e3a33aad8ce1462b2c5b +size 1031132 diff --git a/Assets/Resources/Geonames/Japan.csv.meta b/Assets/Resources/Geonames/Japan.csv.meta new file mode 100644 index 000000000..f46c1022d --- /dev/null +++ b/Assets/Resources/Geonames/Japan.csv.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5dd450a6f5ec92d49871674b33509135 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Geonames/Mexico.csv b/Assets/Resources/Geonames/Mexico.csv new file mode 100644 index 000000000..517228e8f --- /dev/null +++ b/Assets/Resources/Geonames/Mexico.csv @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a654b8451a08a0c769712f4fb1d96c3c661457a88bb57ec4288eab36eab7ec1 +size 633432 diff --git a/Assets/Resources/Geonames/Mexico.csv.meta b/Assets/Resources/Geonames/Mexico.csv.meta new file mode 100644 index 000000000..2b0283e78 --- /dev/null +++ b/Assets/Resources/Geonames/Mexico.csv.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b75e17ea31f6a62488628bf9605bd48c +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Geonames/Russia.csv b/Assets/Resources/Geonames/Russia.csv new file mode 100644 index 000000000..6344ff571 --- /dev/null +++ b/Assets/Resources/Geonames/Russia.csv @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4ed581eef681e5357a14efe4e6a1fc52370def7ada6565f4b953e410fa7f39e +size 2375319 diff --git a/Assets/Resources/Geonames/Russia.csv.meta b/Assets/Resources/Geonames/Russia.csv.meta new file mode 100644 index 000000000..7794294e9 --- /dev/null +++ b/Assets/Resources/Geonames/Russia.csv.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5c1aee30ccf3a1e44bddeb4d550edbf0 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Geonames/Swahili.csv b/Assets/Resources/Geonames/Swahili.csv new file mode 100644 index 000000000..678065eed --- /dev/null +++ b/Assets/Resources/Geonames/Swahili.csv @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb0f44e7948c637a2b0f9e0ca098b2f4689d065fe6484723acf0bfa34a26d0a5 +size 501002 diff --git a/Assets/Resources/Geonames/Swahili.csv.meta b/Assets/Resources/Geonames/Swahili.csv.meta new file mode 100644 index 000000000..94bfbb4f8 --- /dev/null +++ b/Assets/Resources/Geonames/Swahili.csv.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 63e21276398c8b0449e01d97a088add1 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Geonames/Thailand.csv b/Assets/Resources/Geonames/Thailand.csv new file mode 100644 index 000000000..400b8f1a9 --- /dev/null +++ b/Assets/Resources/Geonames/Thailand.csv @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:888c929f0e29728369448e6981bb8a043c49610f4c4390a2cb549bf6b494d3dc +size 143084 diff --git a/Assets/Resources/Geonames/Thailand.csv.meta b/Assets/Resources/Geonames/Thailand.csv.meta new file mode 100644 index 000000000..fd5bd346a --- /dev/null +++ b/Assets/Resources/Geonames/Thailand.csv.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2923f8bd3a2f0fb4084f64138e6d793d +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Geonames/USA.csv b/Assets/Resources/Geonames/USA.csv new file mode 100644 index 000000000..05bd91140 --- /dev/null +++ b/Assets/Resources/Geonames/USA.csv @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:314a30df2033795f04738589c660991e4310f1bfe0578c71bda2a9a72d8a617f +size 954928 diff --git a/Assets/Resources/Geonames/USA.csv.meta b/Assets/Resources/Geonames/USA.csv.meta new file mode 100644 index 000000000..b59cdf567 --- /dev/null +++ b/Assets/Resources/Geonames/USA.csv.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a06c0e26f73d51f489303deadad77030 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Geonames/bad-words.txt b/Assets/Resources/Geonames/bad-words.txt new file mode 100644 index 000000000..5013fea9d --- /dev/null +++ b/Assets/Resources/Geonames/bad-words.txt @@ -0,0 +1,1384 @@ + +abbo +abo +abortion +abuse +addict +addicts +adult +africa +african +alla +allah +alligatorbait +amateur +american +anal +analannie +analsex +angie +angry +anus +arab +arabs +areola +argie +aroused +arse +arsehole +asian +ass +assassin +assassinate +assassination +assault +assbagger +assblaster +assclown +asscowboy +asses +assfuck +assfucker +asshat +asshole +assholes +asshore +assjockey +asskiss +asskisser +assklown +asslick +asslicker +asslover +assman +assmonkey +assmunch +assmuncher +asspacker +asspirate +asspuppies +assranger +asswhore +asswipe +athletesfoot +attack +australian +babe +babies +backdoor +backdoorman +backseat +badfuck +balllicker +balls +ballsack +banging +baptist +barelylegal +barf +barface +barfface +bast +bastard +bazongas +bazooms +beaner +beast +beastality +beastial +beastiality +beatoff +beat-off +beatyourmeat +beaver +bestial +bestiality +bi +biatch +bible +bicurious +bigass +bigbastard +bigbutt +bigger +bisexual +bi-sexual +bitch +bitcher +bitches +bitchez +bitchin +bitching +bitchslap +bitchy +biteme +black +blackman +blackout +blacks +blind +blow +blowjob +boang +bogan +bohunk +bollick +bollock +bomb +bombers +bombing +bombs +bomd +bondage +boner +bong +boob +boobies +boobs +booby +boody +boom +boong +boonga +boonie +booty +bootycall +bountybar +bra +brea5t +breast +breastjob +breastlover +breastman +brothel +bugger +buggered +buggery +bullcrap +bulldike +bulldyke +bullshit +bumblefuck +bumfuck +bunga +bunghole +buried +burn +butchbabes +butchdike +butchdyke +butt +buttbang +butt-bang +buttface +buttfuck +butt-fuck +buttfucker +butt-fucker +buttfuckers +butt-fuckers +butthead +buttman +buttmunch +buttmuncher +buttpirate +buttplug +buttstain +byatch +cacker +cameljockey +cameltoe +canadian +cancer +carpetmuncher +carruth +catholic +catholics +cemetery +chav +cherrypopper +chickslick +children's +chin +chinaman +chinamen +chinese +chink +chinky +choad +chode +christ +christian +church +cigarette +cigs +clamdigger +clamdiver +clit +clitoris +clogwog +cocaine +cock +cockblock +cockblocker +cockcowboy +cockfight +cockhead +cockknob +cocklicker +cocklover +cocknob +cockqueen +cockrider +cocksman +cocksmith +cocksmoker +cocksucer +cocksuck +cocksucked +cocksucker +cocksucking +cocktail +cocktease +cocky +cohee +coitus +color +colored +coloured +commie +communist +condom +conservative +conspiracy +coolie +cooly +coon +coondog +copulate +cornhole +corruption +cra5h +crabs +crack +crackpipe +crackwhore +crack-whore +crap +crapola +crapper +crappy +crash +creamy +crime +crimes +criminal +criminals +crotch +crotchjockey +crotchmonkey +crotchrot +cum +cumbubble +cumfest +cumjockey +cumm +cummer +cumming +cumquat +cumqueen +cumshot +cunilingus +cunillingus +cunn +cunnilingus +cunntt +cunt +cunteyed +cuntfuck +cuntfucker +cuntlick +cuntlicker +cuntlicking +cuntsucker +cybersex +cyberslimer +dago +dahmer +dammit +damn +damnation +damnit +darkie +darky +datnigga +dead +deapthroat +death +deepthroat +defecate +dego +demon +deposit +desire +destroy +deth +devil +devilworshipper +dick +dickbrain +dickforbrains +dickhead +dickless +dicklick +dicklicker +dickman +dickwad +dickweed +diddle +die +died +dies +dike +dildo +dingleberry +dink +dipshit +dipstick +dirty +disease +diseases +disturbed +dive +dix +dixiedike +dixiedyke +doggiestyle +doggystyle +dong +doodoo +doo-doo +doom +dope +dragqueen +dragqween +dripdick +drug +drunk +drunken +dumb +dumbass +dumbbitch +dumbfuck +dyefly +dyke +easyslut +eatballs +eatme +eatpussy +ecstacy +ejaculate +ejaculated +ejaculating +ejaculation +enema +enemy +erect +erection +ero +escort +ethiopian +ethnic +european +evl +excrement +execute +executed +execution +executioner +explosion +facefucker +faeces +fag +fagging +faggot +fagot +failed +failure +fairies +fairy +faith +fannyfucker +fart +farted +farting +farty +fastfuck +fat +fatah +fatass +fatfuck +fatfucker +fatso +fckcum +fear +feces +felatio +felch +felcher +felching +fellatio +feltch +feltcher +feltching +fetish +fight +filipina +filipino +fingerfood +fingerfuck +fingerfucked +fingerfucker +fingerfuckers +fingerfucking +fire +firing +fister +fistfuck +fistfucked +fistfucker +fistfucking +fisting +flange +flasher +flatulence +floo +flydie +flydye +fok +fondle +footaction +footfuck +footfucker +footlicker +footstar +fore +foreskin +forni +fornicate +foursome +fourtwenty +fraud +freakfuck +freakyfucker +freefuck +fu +fubar +fuc +fucck +fuck +fucka +fuckable +fuckbag +fuckbuddy +fucked +fuckedup +fucker +fuckers +fuckface +fuckfest +fuckfreak +fuckfriend +fuckhead +fuckher +fuckin +fuckina +fucking +fuckingbitch +fuckinnuts +fuckinright +fuckit +fuckknob +fuckme +fuckmehard +fuckmonkey +fuckoff +fuckpig +fucks +fucktard +fuckwhore +fuckyou +fudgepacker +fugly +fuk +fuks +funeral +funfuck +fungus +fuuck +gangbang +gangbanged +gangbanger +gangsta +gatorbait +gay +gaymuthafuckinwhore +gaysex +geez +geezer +geni +genital +german +getiton +gin +ginzo +gipp +girls +givehead +glazeddonut +gob +god +godammit +goddamit +goddammit +goddamn +goddamned +goddamnes +goddamnit +goddamnmuthafucker +goldenshower +gonorrehea +gonzagas +gook +gotohell +goy +goyim +greaseball +gringo +groe +gross +grostulation +gubba +gummer +gun +gyp +gypo +gypp +gyppie +gyppo +gyppy +hamas +handjob +hapa +harder +hardon +harem +headfuck +headlights +hebe +heeb +hell +henhouse +heroin +herpes +heterosexual +hijack +hijacker +hijacking +hillbillies +hindoo +hiscock +hitler +hitlerism +hitlerist +hiv +ho +hobo +hodgie +hoes +hole +holestuffer +homicide +homo +homobangers +homosexual +honger +honk +honkers +honkey +honky +hook +hooker +hookers +hooters +hore +hork +horn +horney +horniest +horny +horseshit +hosejob +hoser +hostage +hotdamn +hotpussy +hottotrot +hummer +husky +hussy +hustler +hymen +hymie +iblowu +idiot +ikey +illegal +incest +insest +intercourse +interracial +intheass +inthebuff +israel +israeli +israel's +italiano +itch +jackass +jackoff +jackshit +jacktheripper +jade +jap +japanese +japcrap +jebus +jeez +jerkoff +jesus +jesuschrist +jew +jewish +jiga +jigaboo +jigg +jigga +jiggabo +jigger +jiggy +jihad +jijjiboo +jimfish +jism +jiz +jizim +jizjuice +jizm +jizz +jizzim +jizzum +joint +juggalo +jugs +junglebunny +kaffer +kaffir +kaffre +kafir +kanake +kid +kigger +kike +kill +killed +killer +killing +kills +kink +kinky +kissass +kkk +knife +knockers +kock +kondum +koon +kotex +krap +krappy +kraut +kum +kumbubble +kumbullbe +kummer +kumming +kumquat +kums +kunilingus +kunnilingus +kunt +ky +kyke +lactate +laid +lapdance +latin +lesbain +lesbayn +lesbian +lesbin +lesbo +lez +lezbe +lezbefriends +lezbo +lezz +lezzo +liberal +libido +licker +lickme +lies +limey +limpdick +limy +lingerie +liquor +livesex +loadedgun +lolita +looser +loser +lotion +lovebone +lovegoo +lovegun +lovejuice +lovemuscle +lovepistol +loverocket +lowlife +lsd +lubejob +lucifer +luckycammeltoe +lugan +lynch +macaca +mad +mafia +magicwand +mams +manhater +manpaste +marijuana +mastabate +mastabater +masterbate +masterblaster +mastrabator +masturbate +masturbating +mattressprincess +meatbeatter +meatrack +meth +mexican +mgger +mggor +mickeyfinn +mideast +milf +minority +mockey +mockie +mocky +mofo +moky +moles +molest +molestation +molester +molestor +moneyshot +mooncricket +mormon +moron +moslem +mosshead +mothafuck +mothafucka +mothafuckaz +mothafucked +mothafucker +mothafuckin +mothafucking +mothafuckings +motherfuck +motherfucked +motherfucker +motherfuckin +motherfucking +motherfuckings +motherlovebone +muff +muffdive +muffdiver +muffindiver +mufflikcer +mulatto +muncher +munt +murder +murderer +muslim +naked +narcotic +nasty +nastybitch +nastyho +nastyslut +nastywhore +nazi +necro +negro +negroes +negroid +negro's +nig +niger +nigerian +nigerians +nigg +nigga +niggah +niggaracci +niggard +niggarded +niggarding +niggardliness +niggardliness's +niggardly +niggards +niggard's +niggaz +nigger +niggerhead +niggerhole +niggers +nigger's +niggle +niggled +niggles +niggling +nigglings +niggor +niggur +niglet +nignog +nigr +nigra +nigre +nip +nipple +nipplering +nittit +nlgger +nlggor +nofuckingway +nook +nookey +nookie +noonan +nooner +nude +nudger +nuke +nutfucker +nymph +ontherag +oral +orga +orgasim +orgasm +orgies +orgy +osama +paki +palesimian +palestinian +pansies +pansy +panti +panties +payo +pearlnecklace +peck +pecker +peckerwood +pee +peehole +pee-pee +peepshow +peepshpw +pendy +penetration +peni5 +penile +penis +penises +penthouse +period +perv +phonesex +phuk +phuked +phuking +phukked +phukking +phungky +phuq +pi55 +picaninny +piccaninny +pickaninny +piker +pikey +piky +pimp +pimped +pimper +pimpjuic +pimpjuice +pimpsimp +pindick +piss +pissed +pisser +pisses +pisshead +pissin +pissing +pissoff +pistol +pixie +pixy +playboy +playgirl +pocha +pocho +pocketpool +pohm +polack +pom +pommie +pommy +poo +poon +poontang +poop +pooper +pooperscooper +pooping +poorwhitetrash +popimp +porchmonkey +porn +pornflick +pornking +porno +pornography +pornprincess +pot +poverty +premature +pric +prick +prickhead +primetime +propaganda +pros +prostitute +protestant +pu55i +pu55y +pube +pubic +pubiclice +pud +pudboy +pudd +puddboy +puke +puntang +purinapricness +puss +pussie +pussies +pussy +pussycat +pussyeater +pussyfucker +pussylicker +pussylips +pussylover +pussypounder +pusy +quashie +queef +queer +quickie +quim +ra8s +rabbi +racial +racist +radical +radicals +raghead +randy +rape +raped +raper +rapist +rearend +rearentry +rectum +redlight +redneck +reefer +reestie +refugee +reject +remains +rentafuck +republican +rere +retard +retarded +ribbed +rigger +rimjob +rimming +roach +robber +roundeye +rump +russki +russkie +sadis +sadom +samckdaddy +sandm +sandnigger +satan +scag +scallywag +scat +schlong +screw +screwyou +scrotum +scum +semen +seppo +servant +sex +sexed +sexfarm +sexhound +sexhouse +sexing +sexkitten +sexpot +sexslave +sextogo +sextoy +sextoys +sexual +sexually +sexwhore +sexy +sexymoma +sexy-slim +shag +shaggin +shagging +shat +shav +shawtypimp +sheeney +shhit +shinola +shit +shitcan +shitdick +shite +shiteater +shited +shitface +shitfaced +shitfit +shitforbrains +shitfuck +shitfucker +shitfull +shithapens +shithappens +shithead +shithouse +shiting +shitlist +shitola +shitoutofluck +shits +shitstain +shitted +shitter +shitting +shitty +shoot +shooting +shortfuck +showtime +sick +sissy +sixsixsix +sixtynine +sixtyniner +skank +skankbitch +skankfuck +skankwhore +skanky +skankybitch +skankywhore +skinflute +skum +skumbag +slant +slanteye +slapper +slaughter +slav +slave +slavedriver +sleezebag +sleezeball +slideitin +slime +slimeball +slimebucket +slopehead +slopey +slopy +slut +sluts +slutt +slutting +slutty +slutwear +slutwhore +smack +smackthemonkey +smut +snatch +snatchpatch +snigger +sniggered +sniggering +sniggers +snigger's +sniper +snot +snowback +snownigger +sob +sodom +sodomise +sodomite +sodomize +sodomy +sonofabitch +sonofbitch +sooty +sos +soviet +spaghettibender +spaghettinigger +spank +spankthemonkey +sperm +spermacide +spermbag +spermhearder +spermherder +spic +spick +spig +spigotty +spik +spit +spitter +splittail +spooge +spreadeagle +spunk +spunky +squaw +stagg +stiffy +strapon +stringer +stripclub +stroke +stroking +stupid +stupidfuck +stupidfucker +suck +suckdick +sucker +suckme +suckmyass +suckmydick +suckmytit +suckoff +suicide +swallow +swallower +swalow +swastika +sweetness +syphilis +taboo +taff +tampon +tang +tantra +tarbaby +tard +teat +terror +terrorist +teste +testicle +testicles +thicklips +thirdeye +thirdleg +threesome +threeway +timbernigger +tinkle +tit +titbitnipply +titfuck +titfucker +titfuckin +titjob +titlicker +titlover +tits +tittie +titties +titty +tnt +toilet +tongethruster +tongue +tonguethrust +tonguetramp +tortur +torture +tosser +towelhead +trailertrash +tramp +trannie +tranny +transexual +transsexual +transvestite +triplex +trisexual +trojan +trots +tuckahoe +tunneloflove +turd +turnon +twat +twink +twinkie +twobitwhore +uck +uk +unfuckable +upskirt +uptheass +upthebutt +urinary +urinate +urine +usama +uterus +vagina +vaginal +vatican +vibr +vibrater +vibrator +vietcong +violence +virgin +virginbreaker +vomit +vulva +wab +wank +wanker +wanking +waysted +weapon +weenie +weewee +welcher +welfare +wetb +wetback +wetspot +whacker +whash +whigger +whiskey +whiskeydick +whiskydick +whit +whitenigger +whites +whitetrash +whitey +whiz +whop +whore +whorefucker +whorehouse +wigger +willie +williewanker +willy +wn +wog +women's +wop +wtf +wuss +wuzzie +xtc +xxx +yankee +yellowman +zigabo +zipperhead diff --git a/Assets/Resources/Geonames/bad-words.txt.meta b/Assets/Resources/Geonames/bad-words.txt.meta new file mode 100644 index 000000000..ff605e0c5 --- /dev/null +++ b/Assets/Resources/Geonames/bad-words.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 790ef350f8658b04480e0645919a21fa +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Geonames/pleiades.csv b/Assets/Resources/Geonames/pleiades.csv new file mode 100644 index 000000000..581d44ff7 --- /dev/null +++ b/Assets/Resources/Geonames/pleiades.csv @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45b0dbc07d492958b26de3695427076d270bdd0525ab45c415be72560ebccb5f +size 400944 diff --git a/Assets/Resources/Geonames/pleiades.csv.meta b/Assets/Resources/Geonames/pleiades.csv.meta new file mode 100644 index 000000000..dc0edb8f1 --- /dev/null +++ b/Assets/Resources/Geonames/pleiades.csv.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b532694a5ec3cc6458d42aa2835537b5 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Settings.asset b/Assets/Resources/Settings.asset index 46bee7272..032d8c898 100644 --- a/Assets/Resources/Settings.asset +++ b/Assets/Resources/Settings.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7f09c54dfdb87dffd76fa92365d62c53ce333457b89ccf8ead09093ffffedc42 -size 12525 +oid sha256:667368f42385152984589abb3803aa88a51937286ac2450d890970710ec38e37 +size 13039 diff --git a/Assets/Scenes/ARPG.unity b/Assets/Scenes/ARPG.unity index 4d5b15473..b93a7b909 100644 --- a/Assets/Scenes/ARPG.unity +++ b/Assets/Scenes/ARPG.unity @@ -409,13 +409,13 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 23420356} serializedVersion: 2 - m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} - m_LocalPosition: {x: 0, y: -5, z: 0} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] - m_Father: {fileID: 0} - m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} + m_Father: {fileID: 1037490739} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &23420359 MeshRenderer: m_ObjectHideFlags: 0 @@ -8037,7 +8037,7 @@ Camera: m_Depth: 0 m_CullingMask: serializedVersion: 2 - m_Bits: 5120 + m_Bits: 5632 m_RenderingPath: 1 m_TargetTexture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} m_TargetDisplay: 0 @@ -16322,7 +16322,7 @@ MonoBehaviour: Settings: {fileID: 11400000, guid: cd2344e2001a37544aab0960c164d4ff, type: 2} ZoneRoot: {fileID: 2095699057} SectorBrushes: {fileID: 1037490739} - AmbientLight: {fileID: 23420357} + SectorBoundaryBrush: {fileID: 1476765550} SceneCamera: {fileID: 887677622} FogCameras: - {fileID: 559840917} @@ -16333,98 +16333,70 @@ MonoBehaviour: - {fileID: 488792362} - {fileID: 970624071} - {fileID: 2095741464} + FogMaterial: {fileID: 2100000, guid: 2ff39f5d101241043ba1dcde19d92f77, type: 2} + FogFarFadeFraction: 0.125 FarPlaneDistanceMultiplier: 1 AsteroidMeshes: - Mesh: {fileID: 4300004, guid: bdb4c719a85f3f2419f6c573dd1daf15, type: 3} Material: {fileID: 2100000, guid: ce975d2d2ccd0914b9260b7d66319aaa, type: 2} - Radius: 1.5022775 - Mesh: {fileID: 4300004, guid: 19fa9aa3b5fee244fb007d58c351be01, type: 3} Material: {fileID: 2100000, guid: 443981befe15f604aba2b04eef2f0de2, type: 2} - Radius: 1.0907339 - Mesh: {fileID: 4300004, guid: 693c11c21d8f22240ae2b6c576bf923a, type: 3} Material: {fileID: 2100000, guid: 818a00140c1abb047be1d65d1c20b52a, type: 2} - Radius: 1.345119 - Mesh: {fileID: 4300004, guid: 73f7fb37d1925f246919650feda3df71, type: 3} Material: {fileID: 2100000, guid: 60bb3870b22a23b458c2bc94e4403bda, type: 2} - Radius: 0.9581426 - Mesh: {fileID: 4300004, guid: 13503d5cc77421a4384053d90e12610f, type: 3} Material: {fileID: 2100000, guid: 3175592343a31774b872b32ae89a7ee8, type: 2} - Radius: 1.3620772 - Mesh: {fileID: 4300004, guid: 7c93e75f8f4cde14d82932c65389f566, type: 3} Material: {fileID: 2100000, guid: edee875c32d24154688acf645e314864, type: 2} - Radius: 1.1282945 - Mesh: {fileID: 4300004, guid: b2e60056527750e4c87bd4f6de85ec32, type: 3} Material: {fileID: 2100000, guid: c3d0e5db17690724b89cff9a71876aa6, type: 2} - Radius: 1.5490558 - Mesh: {fileID: 4300004, guid: 87ef785989ec82b498488e651b61b2c6, type: 3} Material: {fileID: 2100000, guid: 5686a9131ca8350448768971c9e21da0, type: 2} - Radius: 1.4786077 - Mesh: {fileID: 4300004, guid: a0f93e74d454f5046908a26ecbbc31cf, type: 3} Material: {fileID: 2100000, guid: 85e9ac4c62af0fb4a94bc35ac5e24254, type: 2} - Radius: 1.1443666 - Mesh: {fileID: 4300004, guid: 4a9e0d7ffd8f8e94abf7a800653c0b4e, type: 3} Material: {fileID: 2100000, guid: 27b1a299ede684d499133b9a0dc85bda, type: 2} - Radius: 1.1114912 - Mesh: {fileID: 4300004, guid: 232b4a71860923049890d661dee4aff7, type: 3} Material: {fileID: 2100000, guid: d9e9ebabc89054f4495754372a7b4d8f, type: 2} - Radius: 1.5410137 - Mesh: {fileID: 4300004, guid: 335c54d8095aa3f44bab46ca5fa5bd4c, type: 3} Material: {fileID: 2100000, guid: 71cd479bb26cd7140ba9d3753f49ffbc, type: 2} - Radius: 1.3792597 - Mesh: {fileID: 4300004, guid: 8942a135422bd014bb3451fe02d656f2, type: 3} Material: {fileID: 2100000, guid: 0f7035043b158484995ff86e9371b141, type: 2} - Radius: 1.2433527 - Mesh: {fileID: 4300004, guid: 47e8c832aa7d46e4ba06961fddf3cc06, type: 3} Material: {fileID: 2100000, guid: d5788bb4b0d2d93429d9c6462034e470, type: 2} - Radius: 1.3664026 - Mesh: {fileID: 4300004, guid: 7c1227bb235e0f74aa9a6cdb9e7ccac5, type: 3} Material: {fileID: 2100000, guid: 060b5e360701d5146adc3d1c65c7a3df, type: 2} - Radius: 1.2458941 - Mesh: {fileID: 4300004, guid: 77a272b796d88344eacf56a79372b45e, type: 3} Material: {fileID: 2100000, guid: 3cd15eb9c358aa547bcd223ee3c1edde, type: 2} - Radius: 2.157539 - Mesh: {fileID: 4300004, guid: bafc829a0712b174d9485c5bcbc1b529, type: 3} Material: {fileID: 2100000, guid: b58fd84189173114d8708fb50b43f2d7, type: 2} - Radius: 1.5399581 - Mesh: {fileID: 4300004, guid: 47fa308b6b417034ea47809cb08bccfb, type: 3} Material: {fileID: 2100000, guid: f56b0896907ac9e41b6fd9dca05f1fa2, type: 2} - Radius: 1.8855069 - Mesh: {fileID: 4300004, guid: fb03a3e40b409db44a810641e0a6c493, type: 3} Material: {fileID: 2100000, guid: 78859c2284122944493cc283967036db, type: 2} - Radius: 1.2214345 - Mesh: {fileID: 4300004, guid: de7739fee205f4a4f9ae290126a36b61, type: 3} Material: {fileID: 2100000, guid: 89b312038af5203469d447f7ff01105f, type: 2} - Radius: 1.8183402 - Mesh: {fileID: 4300004, guid: a966f9aba651bf34da1bb6e3e7f26301, type: 3} Material: {fileID: 2100000, guid: 3326bc3e2b8ada34c9bfd44cf8cf1a1c, type: 2} - Radius: 1.5686527 - Mesh: {fileID: 4300004, guid: 0d55ec2b68453b7418abcd63378eed69, type: 3} Material: {fileID: 2100000, guid: 12b1f515279281a42b2bd53cdb174488, type: 2} - Radius: 1.9112675 - Mesh: {fileID: 4300004, guid: e5dc38d7ffa6ed242831255d93657aaa, type: 3} Material: {fileID: 2100000, guid: 5a06a4f6d5df32b4dae76c13939d3ce9, type: 2} - Radius: 1.9507759 - Mesh: {fileID: 4300004, guid: 9f36793bd68d3d84d8116485bf933992, type: 3} Material: {fileID: 2100000, guid: decc37f956dfc244b956de2d6f5375c2, type: 2} - Radius: 1.5778105 - Mesh: {fileID: 4300004, guid: 214c1534cdd5b3a4a80927e9d879290f, type: 3} Material: {fileID: 2100000, guid: a20b424628f81de4e8cf080a503b66af, type: 2} - Radius: 1.4580269 - Mesh: {fileID: 4300004, guid: 7db51bba443e10f4f9a597a296ceb0c6, type: 3} Material: {fileID: 2100000, guid: f96d19f3fe978b044972d1360d2e7707, type: 2} - Radius: 2.430305 - Mesh: {fileID: 4300004, guid: 6116ec4d9786d04408c3b26d0c525407, type: 3} Material: {fileID: 2100000, guid: 1788de6db766a4444a09dc0c80e1bcb2, type: 2} - Radius: 1.7872484 - Mesh: {fileID: 4300004, guid: 3d6e611c9ebead04b9d6d7d490977ddc, type: 3} Material: {fileID: 2100000, guid: 0fab294fd86e3b84394a967642904d55, type: 2} - Radius: 1.9273407 - Mesh: {fileID: 4300004, guid: 76b1f709ca820234bbf6c03507333b7e, type: 3} Material: {fileID: 2100000, guid: 63a8a57976371814689d7fb222e635e9, type: 2} - Radius: 1.70707 - Mesh: {fileID: 4300004, guid: d3c9f05eabff9e24ca9521e0b8dffd50, type: 3} Material: {fileID: 2100000, guid: 9be65d82397829b46894243c2d91a06d, type: 2} - Radius: 1.6336656 AsteroidSpritesheetWidth: 4 AsteroidSpritesheetHeight: 4 LODHandler: {fileID: 1009503736} @@ -16445,13 +16417,13 @@ MonoBehaviour: MapGravityMaterials: - {fileID: 2100000, guid: 841e4091d19548347bd59115047b4e49, type: 2} - {fileID: 2100000, guid: a92fc6d958edb9f46b6e58134f609cc0, type: 2} - GravityField: {fileID: 2100000, guid: 44a8bbb89acb4e34c9f41a9da5842bb4, type: 2} Tour: 0 TourSwitchTime: 10 TourFollowDistance: 100 TourHeightOffset: 50 TourFollowOffsetDegrees: 55 - MapAsteroidMaterial: {fileID: 2100000, guid: c1012d5466454651b7279be93ef9af88, type: 2} + AsteroidBeltUI: {fileID: 349597964696402918, guid: 1f1bfa2175a13b647888e2949e0cb138, + type: 3} Planet: {fileID: 8287217960984982033, guid: 88ace6073e3db1a46bd3aaf4f971acb9, type: 3} GasGiant: {fileID: 3250623180916197132, guid: 85753b4a7c762274385af384abed7a04, type: 3} @@ -16491,6 +16463,7 @@ MonoBehaviour: NebulaTint: {fileID: 8400000, guid: d196505464047f04a97f28689041209b, type: 2} Heightmap: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} ParticleColors: {fileID: 2800000, guid: 56db63da398b2d04394ddbccedce943c, type: 3} + GravityCamera: {fileID: 1537342003} --- !u!114 &1009503736 MonoBehaviour: m_ObjectHideFlags: 0 @@ -16891,6 +16864,8 @@ Transform: m_LocalScale: {x: 3000, y: 3000, z: 3000} m_ConstrainProportionsScale: 0 m_Children: + - {fileID: 1476765548} + - {fileID: 23420357} - {fileID: 1108843909} - {fileID: 1647230682} - {fileID: 1254851255} @@ -22664,6 +22639,96 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &1476765547 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1476765548} + - component: {fileID: 1476765551} + - component: {fileID: 1476765550} + m_Layer: 9 + m_Name: Boundary + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1476765548 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1476765547} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1037490739} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!23 &1476765550 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1476765547} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 0 + m_StaticShadowCaster: 0 + m_MotionVectors: 2 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 8f45fb3a0f420d5428f1528827d55fa2, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_MaskInteraction: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1476765551 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1476765547} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} --- !u!1 &1485884351 GameObject: m_ObjectHideFlags: 0 @@ -23500,7 +23565,7 @@ Camera: m_Depth: 0 m_CullingMask: serializedVersion: 2 - m_Bits: 512 + m_Bits: 1536 m_RenderingPath: 1 m_TargetTexture: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} m_TargetDisplay: 0 @@ -38421,7 +38486,6 @@ SceneRoots: - {fileID: 906767442} - {fileID: 1009503730} - {fileID: 1037490739} - - {fileID: 23420357} - {fileID: 2095699057} - {fileID: 134113271} - {fileID: 666227432} diff --git a/Assets/Scenes/Main Menu.unity b/Assets/Scenes/Main Menu.unity index 4fafe8336..a37cfffba 100644 --- a/Assets/Scenes/Main Menu.unity +++ b/Assets/Scenes/Main Menu.unity @@ -892,6 +892,7 @@ MonoBehaviour: NebulaTint: {fileID: 8400000, guid: d196505464047f04a97f28689041209b, type: 2} Heightmap: {fileID: 8400000, guid: 2fc21a9d3e9647948b56e384cd9378b3, type: 2} ParticleColors: {fileID: 2800000, guid: 56db63da398b2d04394ddbccedce943c, type: 3} + GravityCamera: {fileID: 2103364771} --- !u!114 &750375536 MonoBehaviour: m_ObjectHideFlags: 0 @@ -981,7 +982,7 @@ Camera: m_Depth: 0 m_CullingMask: serializedVersion: 2 - m_Bits: 5120 + m_Bits: 5632 m_RenderingPath: 1 m_TargetTexture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} m_TargetDisplay: 0 @@ -1060,6 +1061,16 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.x + value: 512 + objectReference: {fileID: 0} + - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.y + value: 512 + objectReference: {fileID: 0} - target: {fileID: 7852221720816817928, guid: 046dde0f4600bce41ad33c476f99b309, type: 3} propertyPath: m_LocalScale.x @@ -1075,6 +1086,16 @@ PrefabInstance: propertyPath: m_Materials.Array.data[0] value: objectReference: {fileID: 2100000, guid: b9f52544f98f47146b486fb6e27179bb, type: 2} + - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.x + value: 512 + objectReference: {fileID: 0} + - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.y + value: 512 + objectReference: {fileID: 0} - target: {fileID: 7852221720971737233, guid: 046dde0f4600bce41ad33c476f99b309, type: 3} propertyPath: m_LocalScale.x diff --git a/Assets/Scenes/TestScene.unity b/Assets/Scenes/TestScene.unity index 45c73ee85..5288b6845 100644 --- a/Assets/Scenes/TestScene.unity +++ b/Assets/Scenes/TestScene.unity @@ -911,6 +911,26 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.x + value: 40 + objectReference: {fileID: 0} + - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.y + value: 40 + objectReference: {fileID: 0} + - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.x + value: 20 + objectReference: {fileID: 0} + - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.y + value: 20 + objectReference: {fileID: 0} - target: {fileID: 7852221720971737233, guid: 046dde0f4600bce41ad33c476f99b309, type: 3} propertyPath: m_LocalPosition.y @@ -1758,6 +1778,26 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.x + value: 40 + objectReference: {fileID: 0} + - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.y + value: 40 + objectReference: {fileID: 0} + - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.x + value: 20 + objectReference: {fileID: 0} + - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.y + value: 20 + objectReference: {fileID: 0} - target: {fileID: 7852221720971737233, guid: 046dde0f4600bce41ad33c476f99b309, type: 3} propertyPath: m_LocalPosition.y @@ -3769,7 +3809,7 @@ Camera: m_Depth: 0 m_CullingMask: serializedVersion: 2 - m_Bits: 5120 + m_Bits: 5632 m_RenderingPath: 1 m_TargetTexture: {fileID: 8400000, guid: 06ec5ef8a5830fc44b1ac1a6e123add5, type: 2} m_TargetDisplay: 0 @@ -5257,6 +5297,26 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.x + value: 40 + objectReference: {fileID: 0} + - target: {fileID: 7852221720741322892, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.y + value: 40 + objectReference: {fileID: 0} + - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.x + value: 20 + objectReference: {fileID: 0} + - target: {fileID: 7852221720969441490, guid: 046dde0f4600bce41ad33c476f99b309, + type: 3} + propertyPath: m_LocalScale.y + value: 20 + objectReference: {fileID: 0} - target: {fileID: 7852221720971737233, guid: 046dde0f4600bce41ad33c476f99b309, type: 3} propertyPath: m_LocalPosition.y diff --git a/Assets/Scripts/Editor/AmbientEdgeVerify.cs b/Assets/Scripts/Editor/AmbientEdgeVerify.cs deleted file mode 100644 index 4a56b6ea9..000000000 --- a/Assets/Scripts/Editor/AmbientEdgeVerify.cs +++ /dev/null @@ -1,244 +0,0 @@ -using System; -using System.IO; -using GameCult.Caching; -using UnityEditor; -using UnityEditor.SceneManagement; -using UnityEngine; -using UnityEngine.Experimental.Rendering; -using UnityEngine.Rendering; - -namespace Aetheria.EditorTools -{ - /// - /// Batchmode check for campaign aetheria-gravity, cut ambient-follows-populated-area: the ambient tint falls softly to - /// dark and never hits an edge (ruling dark-beyond-populated-area). It opens ARPG.unity, takes the Ambient Fog Light the - /// scene wires into ZoneRenderer, sizes it for a generated zone with ZoneRenderer.FitAmbientLight (the call LoadZone - /// makes, not a copy), renders it through an orthographic camera that culls its layer into a target built from the descriptor of the production - /// Fog Tint render texture (B10G11R11_UFloatPack32, the format the Tint cameras write), and checks the - /// radial profile against exp(-(r/P)^2 ln(1/_EdgeBrightness)) times the centre, to within what that format stores (a - /// 5-bit mantissa) wherever the gaussian is at least a few ZoneRenderer.AmbientFloor (P is Zone.PopulatedRadius), that it - /// is lit at Pack.Radius, that the quad's rim and every lit texel beside a dark one are - /// at most two floors, and that no two lit texels are more than half a decade apart. - /// - /// Renders, so it needs a graphics device: run WITHOUT -nographics. - /// Unity -batchmode -projectPath <repo> -executeMethod Aetheria.EditorTools.AmbientEdgeVerify.Run -logFile <path> - /// Do not pass -quit: Run exits the Editor itself, 0 on success and 1 on any failure. - /// - public static class AmbientEdgeVerify - { - const string Tag = "[AmbientEdgeVerify]"; - const int Size = 512; - const int AmbientLayer = 13; - const string FogTintPath = "Assets/Resources/Fog Tint.renderTexture"; - // A float with a 5-bit mantissa (Fog Tint's blue) steps by 2^-5 of its value, and the target truncates to a step. - const float FormatRelativeError = 1f / 32f; - // The profile is held to the gaussian where it is at least this many floors; below that the format's tail is measured, not held. - const float FaithfulFloors = 8f; - // The rim and every lit texel beside a dark one hold at most this many floors, 2^-14 (the smallest normal of the format's - // floats): the one step to dark is the format's last value. Measured on the Fog Tint format it is 1.5 floors at most. - const float StepToDarkFloors = 2f; - static bool _ok = true; - - static void OnLog(string message, string stack, LogType type) - { - if ((type == LogType.Error || type == LogType.Exception || type == LogType.Assert) && !message.StartsWith(Tag)) - Fail("logged-error", message.Split('\n')[0]); - } - - static void Fail(string check, string detail) - { - Debug.LogError($"{Tag} FAIL {check}: {detail}"); - _ok = false; - } - - public static void Run() - { - if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null) - { - Debug.LogError($"{Tag} FAIL: no graphics device in this session; rerun batchmode without -nographics."); - EditorApplication.Exit(1); - return; - } - Application.logMessageReceived += OnLog; - var work = Path.Combine(Path.GetTempPath(), "ambient-edge-" + Guid.NewGuid().ToString("N")); - Directory.CreateDirectory(Path.Combine(work, "probe")); - try - { - var settings = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset") - ?? throw new InvalidOperationException("No Settings.asset."); - // Generated zones have the populated radius at about .78 of the pack radius (p50 over 1500 zones): this one's - // pack radius is set so, which puts Pack.Radius where it sits in play, inside the quad's reach. - var probe = GravityFieldParityVerify.BuildZone(settings, Path.Combine(work, "probe"), out _); - var zone = GravityFieldParityVerify.BuildZone(settings, work, out _, probe.PopulatedRadius / .78f); - EditorSceneManager.OpenScene("Assets/Scenes/ARPG.unity", OpenSceneMode.Single); - try - { - var renderer = UnityEngine.Object.FindFirstObjectByType(FindObjectsInactive.Include); - if (renderer == null || renderer.AmbientLight == null) throw new InvalidOperationException("ARPG.unity wires no ZoneRenderer.AmbientLight."); - Check(renderer, zone); - } - finally - { - EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); - } - Debug.Log(_ok ? $"{Tag} PASS" : $"{Tag} FAIL: see errors above"); - } - catch (Exception e) - { - Debug.LogError($"{Tag} FAIL exception: {e}"); - _ok = false; - } - finally - { - Application.logMessageReceived -= OnLog; - try { Directory.Delete(work, true); } catch { } - } - EditorApplication.Exit(_ok ? 0 : 1); - } - - // A bare ambient quad for the verifies that run LoadZone on a renderer built in code: the scene's material, no scene. - public static Transform NewAmbientLight() - { - var quad = new GameObject("Ambient Fog Light") { layer = AmbientLayer }; - quad.AddComponent().sharedMesh = Resources.GetBuiltinResource("Quad.fbx"); - quad.AddComponent().sharedMaterial = AssetDatabase.LoadAssetAtPath("Assets/Materials/Brushes/Sector Tint.mat"); - return quad.transform; - } - - static void Check(ZoneRenderer renderer, Zone zone) - { - var production = AssetDatabase.LoadAssetAtPath(FogTintPath); - if (production == null || production.graphicsFormat != GraphicsFormat.B10G11R11_UFloatPack32) - Fail("format", $"Fog Tint is {(production == null ? "missing" : production.graphicsFormat.ToString())}, not the B10G11R11_UFloatPack32 that AmbientFloor and FormatRelativeError describe"); - var light = renderer.AmbientLight; - if (light.parent != null) Fail("wiring", $"the ambient quad sits under {light.parent.name}, whose scale is the pack radius's"); - if (light.gameObject.layer != AmbientLayer) Fail("wiring", $"the ambient quad is on layer {light.gameObject.layer}, not {AmbientLayer}"); - - ZoneRenderer.FitAmbientLight(light, zone); - var meshRenderer = light.GetComponent(); - var material = meshRenderer.sharedMaterial; - var edge = material.GetFloat("_EdgeBrightness"); - var tint = material.GetColor("_Color").linear; - var centre = material.GetFloat("_Depth") * Mathf.Max(tint.r, Mathf.Max(tint.g, tint.b)); - var populated = zone.PopulatedRadius; - var half = light.localScale.x / 2f; - Debug.Log($"{Tag} populated radius {populated:F1} u, pack radius {zone.Pack.Radius:F1} u, quad half-extent {half:F1} u, edge brightness {edge:G3}, centre {centre:G4}"); - if (!(populated > 0f) || !(half > populated)) { Fail("sizing", $"the quad half-extent {half:F1} u does not reach beyond the populated radius {populated:F1} u"); return; } - - Render(light, half * 1.05f, out var value, out var world); - var floor = ZoneRenderer.AmbientFloor; - Debug.Log($"{Tag} format floor {floor:E2} = {floor / centre:E2} of the centre; tail (drawn / floor): " - + string.Join(" ", System.Linq.Enumerable.Select(new[] { 1.5f, 1.75f, 1.9f, 2f, 2.05f, 2.1f, 2.15f, 2.2f }, - k => $"{k}P:{Sample(value, world, new Vector2(k * populated, 0f)) / floor:G3}"))); - var logFall = Mathf.Log(1f / edge); - foreach (var k in new[] { 0f, .5f, 1f, 1.5f, 2f }) - { - var drawn = Sample(value, world, new Vector2(k * populated, 0f)); - Debug.Log($"{Tag} r = {k} P: drawn {drawn:G5}, expected {centre * Mathf.Exp(-k * k * logFall):G5}"); - } - var worstProfile = 0f; - var compared = 0; - var rim = 0f; - for (var i = 0; i < value.Length; i++) - { - if (float.IsNaN(value[i])) { Fail("texels", $"texel {i}: NaN"); return; } - var r = world[i].magnitude; - var expected = centre * Mathf.Exp(-(r / populated) * (r / populated) * logFall); - if (r <= half && expected >= FaithfulFloors * floor) - { - var error = Mathf.Abs(value[i] - expected) / (FormatRelativeError * expected); - worstProfile = Mathf.Max(worstProfile, error); - compared++; - if (error > 1f) { Fail("profile", $"at r = {r / populated:F3} P: expected {expected:G5}, drawn {value[i]:G5}, off by {error:F2} times the format's step"); return; } - } - // The rim: the texels in the quad's outermost ring (within two texels of its edge). - var edgeDistance = half - Mathf.Max(Mathf.Abs(world[i].x), Mathf.Abs(world[i].y)); - if (edgeDistance >= 0f && edgeDistance < 2f * (half * 1.05f * 2f / Size)) rim = Mathf.Max(rim, value[i]); - } - Debug.Log($"{Tag} profile: {compared} texels held to the gaussian, worst error {worstProfile:F3} of the format's step; rim {rim / centre:E2} of the centre"); - if (compared < Size * Size / 16) Fail("profile", $"only {compared} texels were held to the gaussian; the check is vacuous"); - if (rim > floor * StepToDarkFloors) Fail("rim", $"the quad's rim is {rim / floor:G3} times the format floor"); - - var atPack = Sample(value, world, new Vector2(zone.Pack.Radius, 0f)); - Debug.Log($"{Tag} at Pack.Radius: {atPack / centre:E2} of the centre"); - if (!(atPack > 0f)) Fail("pack-radius", "the ambient is zero at Pack.Radius"); - - var worstJump = 0f; - for (var y = 0; y < Size; y++) - for (var x = 0; x < Size; x++) - { - var here = value[y * Size + x]; - if (here <= 0f) continue; - foreach (var next in new[] { x + 1 < Size ? value[y * Size + x + 1] : 0f, y + 1 < Size ? value[(y + 1) * Size + x] : 0f }) - { - if (next <= 0f) { if (here > floor * StepToDarkFloors) Fail("last-step", $"a lit texel of {here / floor:G3} floors sits beside a dark one"); continue; } - worstJump = Mathf.Max(worstJump, Mathf.Abs(Mathf.Log10(here / next))); - } - } - Debug.Log($"{Tag} largest jump between neighbouring lit texels: {worstJump:F3} decades (limit 0.5)"); - if (worstJump > .5f) Fail("jump", $"neighbouring texels differ by {worstJump:F2} decades"); - var lit = 0; - foreach (var v in value) if (v > 0f) lit++; - if (lit < Size * Size / 2) Fail("jump", $"only {lit} texels are lit; the check is vacuous"); - } - - static float Sample(float[] value, Vector2[] world, Vector2 at) - { - var best = 0; - for (var i = 1; i < world.Length; i++) - if ((world[i] - at).sqrMagnitude < (world[best] - at).sqrMagnitude) best = i; - return value[best]; - } - - // Renders the ambient layer through a downward orthographic camera centred on the origin, as the Tint cameras see it, - // and returns the brightest channel of every texel with the world xz of its centre, which is asked of the camera. - static void Render(Transform light, float half, out float[] value, out Vector2[] world) - { - var production = AssetDatabase.LoadAssetAtPath(FogTintPath) ?? throw new InvalidOperationException("No Fog Tint render texture."); - var rt = new RenderTexture(production.descriptor) { filterMode = FilterMode.Point }; - var cameraObject = new GameObject("Ambient Edge Camera"); - var read = new Texture2D(Size, Size, TextureFormat.RGBAFloat, false); - var previous = RenderTexture.active; - try - { - var camera = cameraObject.AddComponent(); - camera.orthographic = true; - camera.orthographicSize = half; - camera.aspect = 1f; - camera.nearClipPlane = .3f; - camera.farClipPlane = 1000f; - camera.cullingMask = 1 << light.gameObject.layer; - camera.clearFlags = CameraClearFlags.SolidColor; - camera.backgroundColor = Color.black; - camera.allowHDR = false; - camera.allowMSAA = false; - camera.targetTexture = rt; - cameraObject.transform.SetPositionAndRotation(new Vector3(0f, 100f, 0f), Quaternion.Euler(90f, 0f, 0f)); - camera.Render(); - - RenderTexture.active = rt; - read.ReadPixels(new Rect(0, 0, Size, Size), 0, 0); - read.Apply(); - var pixels = read.GetPixelData(0); - value = new float[Size * Size]; - for (var i = 0; i < value.Length; i++) - value[i] = Mathf.Max(pixels[4 * i], Mathf.Max(pixels[4 * i + 1], pixels[4 * i + 2])); - world = new Vector2[Size * Size]; - for (var y = 0; y < Size; y++) - for (var x = 0; x < Size; x++) - { - var p = camera.ViewportToWorldPoint(new Vector3((x + .5f) / Size, (y + .5f) / Size, 100f)); - world[y * Size + x] = new Vector2(p.x, p.z); - } - } - finally - { - RenderTexture.active = previous; - UnityEngine.Object.DestroyImmediate(cameraObject); - UnityEngine.Object.DestroyImmediate(read); - rt.Release(); - UnityEngine.Object.DestroyImmediate(rt); - } - } - } -} diff --git a/Assets/Scripts/Editor/AmbientEdgeVerify.cs.meta b/Assets/Scripts/Editor/AmbientEdgeVerify.cs.meta deleted file mode 100644 index 0962854de..000000000 --- a/Assets/Scripts/Editor/AmbientEdgeVerify.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 63b03af05dfdae44c89e21ca7ebec892 \ No newline at end of file diff --git a/Assets/Scripts/Editor/BeltFloaterLayerVerify.cs b/Assets/Scripts/Editor/BeltFloaterLayerVerify.cs deleted file mode 100644 index 500ae1cea..000000000 --- a/Assets/Scripts/Editor/BeltFloaterLayerVerify.cs +++ /dev/null @@ -1,265 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using GameCult.Caching; -using UnityEditor; -using UnityEditor.SceneManagement; -using UnityEngine; -using float2 = CultMath.float2; -using float4 = CultMath.float4; - -// End-to-end proof of the belt draw (rulings asteroid-tops-at-layer, rock-meshes-by-size), measured where it fails: two belts are loaded -// into a ZoneRenderer carrying ARPG.unity's real AsteroidMeshes (meshes, stored radii) and Settings.asset, over a zone whose wells make the -// field differ rock to rock, and ZoneRenderer.DrawBelts runs as Update runs it. Every instanced matrix it hands to the GPU is read back with the -// mesh it is drawn with (ZoneRenderer.DrawInstanced), and for each drawn rock the verify measures, from the mesh's real vertices: -// - the farthest vertex from the rock's centre after the matrix (the reach, a bound on the rock's top under any rotation) is the rock's -// gameplay radius, and centre y + reach is the floater layer over the field at the rock's xz and the drawn time; -// - the rock is drawn exactly once, on exactly one matrix of a real pose (no spare instance in a batch); -// - within a belt a bigger rock never takes a smaller mesh (by the mesh's own farthest vertex), and the belt keeps min(AsteroidMeshCount, meshes) meshes. -// The arguments the renderer hands the draw list (radius field, belt, batch size, kept count) are not inspected: their consequence is. -// -// Reached: ZoneRenderer.LoadPlanet for each belt, DrawBelts. Not reached: LoadZone's other planets (their prefabs), the GPU draw itself. -// Needs a GPU device for MapPresenter's belt buffer: run without -nographics. -// -// Unity -batchmode -projectPath -executeMethod Aetheria.EditorTools.BeltFloaterLayerVerify.Run -logFile -// -// Do not pass -quit: Run enters play mode (a domain reload), the check runs there, and the Editor exits itself, 0 on success and 1 on any failure. -namespace Aetheria.EditorTools -{ - [InitializeOnLoad] - public static class BeltFloaterLayerVerify - { - private const string Tag = "[BeltFloaterLayerVerify]"; - private const string Flag = "BeltFloaterLayerVerify.running"; - private const string Wiring = "BeltFloaterLayerVerify.wiring"; - private const double Budget = 300; // real seconds - private const float Lead = .008f, Layer = -1.5f, Tolerance = .02f; - private static IEnumerator _check; - private static double _started; - private static string _work; - - static BeltFloaterLayerVerify() - { - if (SessionState.GetBool(Flag, false)) EditorApplication.playModeStateChanged += OnPlayMode; - } - - public static void Run() - { - try - { - SessionState.SetString(Wiring, ReadWiring()); - SessionState.SetBool(Flag, true); - EditorApplication.EnterPlaymode(); - } - catch (Exception exception) - { - Debug.LogException(exception); - EditorApplication.Exit(1); - } - } - - private static void OnPlayMode(PlayModeStateChange change) - { - if (change != PlayModeStateChange.EnteredPlayMode) return; - _work = Path.Combine(Path.GetTempPath(), $"belt-floater-{Guid.NewGuid():N}"); - Directory.CreateDirectory(_work); - _started = Time.realtimeSinceStartupAsDouble; - _check = Check(); - EditorApplication.update += Step; - } - - private static void Step() - { - try - { - if (Time.realtimeSinceStartupAsDouble - _started > Budget) throw new InvalidOperationException($"The check did not finish in {Budget} seconds."); - if (_check.MoveNext()) return; - Finish(0); - } - catch (Exception exception) - { - Debug.LogException(exception); - Finish(1); - } - } - - private static void Finish(int code) - { - EditorApplication.update -= Step; - SessionState.SetBool(Flag, false); - try { if (Directory.Exists(_work)) Directory.Delete(_work, true); } catch (Exception) { /* a temp directory */ } - EditorApplication.Exit(code); - } - - private static void Require(bool condition, string what) - { - if (!condition) throw new InvalidOperationException(what); - } - - // A belt of rocks of every size, its sizes in the given order, round an orbit about the planet. - private static Asteroid[] Rocks(int count, Func size, float start) => Enumerable.Range(0, count).Select(i => new Asteroid - { - Distance = start + i * 9.7f, Phase = Mathf.Repeat(i * .6180339887f, 1f), Size = size(i), RotationSpeed = .1f + i * .013f - }).ToArray(); - - private static IEnumerator Check() - { - var game = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset") ?? throw new InvalidOperationException("No Settings.asset."); - var settings = game.GameplaySettings; - settings.FloaterLayerHeight = Layer; // in memory, never saved back to the asset: a draw that drops the layer fails - - var meshes = SessionState.GetString(Wiring, "").Split('|').Select(entry => entry.Split('~')).Select(p => new InstancedMesh - { - Mesh = AssetDatabase.LoadAllAssetsAtPath(p[0]).OfType().First(m => m.name == p[1]), - Material = p[2] == "" ? null : AssetDatabase.LoadAssetAtPath(p[2]), - Radius = float.Parse(p[3], System.Globalization.CultureInfo.InvariantCulture) - }).ToArray(); - Require(meshes.Length > game.AsteroidMeshCount, $"ARPG.unity has {meshes.Length} rock meshes for a kept count of {game.AsteroidMeshCount}: nothing to prune."); - - var cache = AetheriaStores.Open(Path.Combine(_work, "belts.cc"), Path.Combine(_work, "belts-run.cc"), catalogWritable: true); - cache.Upsert(new VerseGrammar { Revision = 1 }); - cache.FlushAsync().Wait(); - var items = new ItemManager(1u, cache, new ProvenanceLedger(), settings, _ => { }); - - CultRecordKey Orbit(CultRecordKey parent, float distance, float phase, float2 fixedPosition = default) - { - var data = new OrbitData { Distance = distance, Phase = phase, FixedPosition = fixedPosition }; - if (parent.IsSet()) data.Parent = new CultRecordRef(parent); - return cache.Upsert(data).Key; - } - - // A heavy sun and a planet on a moving rail, the belts round the planet: the field under a rock differs from rock to rock. - var sunOrbit = Orbit(default, 0f, 0f, new float2(700f, -300f)); - var planetOrbit = Orbit(sunOrbit, 600f, .3f); - var beltOrbitA = Orbit(planetOrbit, 150f, .1f); - var beltOrbitB = Orbit(planetOrbit, 300f, .6f); - var beltA = cache.Upsert(new AsteroidBeltData { Orbit = new CultRecordRef(beltOrbitA), Asteroids = Rocks(24, i => (i * 7 % 24) / 23f, 40f) }).Key; - var beltB = cache.Upsert(new AsteroidBeltData { Orbit = new CultRecordRef(beltOrbitB), Asteroids = Rocks(24, i => (i * 5 % 24) / 23f, 60f) }).Key; - var pack = new ZonePack { Radius = 5000f, Mass = 10000f }; - foreach (var orbit in new[] { sunOrbit, planetOrbit, beltOrbitA, beltOrbitB }) pack.Orbits.Add(new CultRecordRef(orbit)); - pack.Planets.Add(new CultRecordRef(cache.Upsert(new PlanetData { Name = "Belt Sun", Orbit = new CultRecordRef(sunOrbit), Mass = 400f }).Key)); - pack.Planets.Add(new CultRecordRef(cache.Upsert(new PlanetData { Name = "Belt Planet", Orbit = new CultRecordRef(planetOrbit), Mass = 400f }).Key)); - pack.Planets.Add(new CultRecordRef(beltA)); - pack.Planets.Add(new CultRecordRef(beltB)); - var curves = new PlanetSettings - { - BodyRadius = new ExponentialCurve(), - WellStrength = new ExponentialCurve { Multiplier = 1f, Exponent = 1f }, - RocheLimit = new ExponentialCurve { Constant = 10f }, - AsteroidSize = new ExponentialLerp { Minimum = 2f, Maximum = 9f, Exponent = 1.7f }, - AsteroidHitpoints = new ExponentialLerp { Minimum = 10f, Maximum = 300f, Exponent = 2f }, - AsteroidRespawnTime = new ExponentialLerp { Minimum = 5f, Maximum = 60f, Exponent = 1f } - }; - var zone = new Zone(items, curves, pack, null, null); - zone.Update(.5f); - - // The renderer, configured as the scene configures it for belts: Awake builds the map, LoadPlanet reads Zone, Settings and AsteroidMeshes. - var rendererObject = new GameObject("Belt Zone Renderer"); - rendererObject.SetActive(false); - var renderer = rendererObject.AddComponent(); - renderer.Settings = game; - renderer.AsteroidMeshes = meshes; - renderer.ItemManager = items; - renderer.LODHandler = new GameObject("Belt LOD").AddComponent(); - const BindingFlags Any = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; - typeof(ZoneRenderer).GetProperty("Zone").GetSetMethod(true).Invoke(renderer, new object[] { zone }); - typeof(ZoneRenderer).GetMethod("Awake", Any).Invoke(renderer, null); - var load = typeof(ZoneRenderer).GetMethod("LoadPlanet", Any); - foreach (var belt in new[] { beltA, beltB }) load.Invoke(renderer, new object[] { belt, zone.Planets[belt] }); - - var planetAt = DrawAhead.Orbit(zone, planetOrbit, Lead); - var camera = new GameObject("Belt Camera").AddComponent(); - camera.transform.position = new Vector3(planetAt.x, 4000f, planetAt.y); - camera.transform.rotation = Quaternion.Euler(90, 0, 0); - camera.farClipPlane = 20000f; - renderer.MainCamera = camera; - yield return null; - - ActionGameManager.Clock.Reset(); - ActionGameManager.Clock.Advance(Lead, _ => throw new InvalidOperationException("a step ran")); - var lead = ActionGameManager.Clock.Lead; - Require(Mathf.Abs(lead - Lead) < 1e-6f, $"The clock's lead is {lead}, not {Lead}."); - - var drawn = new List<(Mesh mesh, Matrix4x4[] matrices)>(); - renderer.DrawInstanced = (mesh, _, matrices) => drawn.Add((mesh, (Matrix4x4[]) matrices.Clone())); - renderer.DrawBelts(lead); - - // The poses the sim defines at the drawn time: every rock of both belts. - var rocks = new List<(CultRecordKey belt, int index, float4 pose)>(); - foreach (var belt in new[] { beltA, beltB }) - { - var poses = new float4[((AsteroidBeltData) zone.Planets[belt]).Asteroids.Length]; - zone.EvaluateBelt(belt, poses, DrawAhead.Time(zone, lead)); - for (var i = 0; i < poses.Length; i++) rocks.Add((belt, i, poses[i])); - } - Require(drawn.Count > 0, "DrawBelts drew nothing: the belts are out of the camera or have no rocks."); - - // The field differs between rocks, so a draw that drops it or samples it at the wrong place fails. - var layers = rocks.Select(r => DrawAhead.FloaterHeight(zone, settings, r.pose.xy, lead)).ToArray(); - Require(layers.Max() - layers.Min() > 1f, $"The fixture's field is flat under the rocks: layer heights span {layers.Max() - layers.Min()}."); - - var seen = new Dictionary<(CultRecordKey, int), float>(); // rock -> its mesh's own farthest vertex - var vertices = new Dictionary(); - foreach (var (mesh, matrices) in drawn) - { - if (!vertices.TryGetValue(mesh, out var v)) vertices[mesh] = v = mesh.vertices; - var own = Mathf.Sqrt(v.Max(x => x.sqrMagnitude)); - foreach (var matrix in matrices) - { - var centre = (Vector3) matrix.GetColumn(3); - var at = rocks.Where(r => Mathf.Abs(r.pose.x - centre.x) < .01f && Mathf.Abs(r.pose.y - centre.z) < .01f).ToArray(); - Require(at.Length == 1, $"An instance of {mesh.name} sits at {centre.x},{centre.z}, where {at.Length} rocks are (a spare or misplaced instance)."); - var rock = at[0]; - Require(seen.TryAdd((rock.belt, rock.index), own), $"Rock {rock.index} of {rock.belt} is drawn twice."); - var reach = v.Max(x => (matrix.MultiplyPoint3x4(x) - centre).magnitude); - Require(Mathf.Abs(reach - rock.pose.w) < Tolerance * Mathf.Max(1f, rock.pose.w), - $"Rock {rock.index} of {rock.belt} on {mesh.name}: its farthest vertex is {reach} from its centre, its gameplay radius {rock.pose.w}."); - var top = centre.y + reach; - var want = DrawAhead.FloaterHeight(zone, settings, rock.pose.xy, lead); - Require(Mathf.Abs(top - want) < Tolerance, - $"Rock {rock.index} of {rock.belt} on {mesh.name}: its top is {top}, the floater layer over the field there {want}."); - } - } - Require(seen.Count == rocks.Count, $"{seen.Count} of {rocks.Count} rocks were drawn."); - - foreach (var belt in new[] { beltA, beltB }) - { - var mine = rocks.Where(r => r.belt.Equals(belt)).ToArray(); - var radii = mine.Select(r => seen[(belt, r.index)]).Distinct().OrderBy(x => x).ToArray(); - Require(radii.Length >= 2, $"Belt {belt} is drawn on {radii.Length} distinct mesh radii: the size match is not exercised."); - var kept = drawn.Where(d => d.matrices.Any(m => mine.Any(r => Mathf.Abs(r.pose.x - m.m03) < .01f && Mathf.Abs(r.pose.y - m.m23) < .01f))).Select(d => d.mesh).Distinct().Count(); - Require(kept == Mathf.Min(game.AsteroidMeshCount, meshes.Length), $"Belt {belt} is drawn on {kept} meshes, not the kept count {game.AsteroidMeshCount}."); - var size = mine.ToDictionary(r => r.index, r => zone.AsteroidBelts[belt].UndamagedSize(r.index, zone.Settings)); - foreach (var a in mine) - foreach (var b in mine) - if (size[a.index] < size[b.index]) - Require(seen[(belt, a.index)] <= seen[(belt, b.index)], - $"Belt {belt}: rock {a.index} (size {size[a.index]}) is smaller than rock {b.index} ({size[b.index]}) and takes a bigger mesh ({seen[(belt, a.index)]} against {seen[(belt, b.index)]})."); - var biggest = mine.OrderByDescending(r => size[r.index]).First(); - Require(Mathf.Approximately(seen[(belt, biggest.index)], radii[^1]), $"Belt {belt}: its biggest rock is not on its biggest mesh."); - } - ActionGameManager.Clock.Reset(); - Debug.Log($"{Tag} ok: {rocks.Count} rocks of 2 belts drawn at the floater layer, big rocks on big meshes ({drawn.Count} batches)"); - } - - // The AsteroidMeshes ARPG.unity's ZoneRenderer names, read before the play session (a scene cannot be opened inside one) and carried across the - // domain reload as asset paths: mesh path, mesh name, material path, stored radius. - private static string ReadWiring() - { - var scene = EditorSceneManager.OpenScene("Assets/Scenes/ARPG.unity", OpenSceneMode.Additive); - try - { - var found = UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None) - .Where(r => r.gameObject.scene == scene).ToArray(); - Require(found.Length == 1, $"ARPG.unity has {found.Length} ZoneRenderers."); - var meshes = found[0].AsteroidMeshes ?? throw new InvalidOperationException("ARPG.unity's ZoneRenderer has no AsteroidMeshes."); - return string.Join("|", meshes.Select(m => string.Join("~", AssetDatabase.GetAssetPath(m.Mesh), m.Mesh.name, - m.Material == null ? "" : AssetDatabase.GetAssetPath(m.Material), m.Radius.ToString("R", System.Globalization.CultureInfo.InvariantCulture)))); - } - finally { EditorSceneManager.CloseScene(scene, true); } - } - } -} diff --git a/Assets/Scripts/Editor/BeltFloaterLayerVerify.cs.meta b/Assets/Scripts/Editor/BeltFloaterLayerVerify.cs.meta deleted file mode 100644 index a383593c7..000000000 --- a/Assets/Scripts/Editor/BeltFloaterLayerVerify.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 7d25a93db1972324fa5460b2415c1e4a \ No newline at end of file diff --git a/Assets/Scripts/Editor/CapabilityPresentationSmoke.cs b/Assets/Scripts/Editor/CapabilityPresentationSmoke.cs index 135163e24..75d97c63f 100644 --- a/Assets/Scripts/Editor/CapabilityPresentationSmoke.cs +++ b/Assets/Scripts/Editor/CapabilityPresentationSmoke.cs @@ -62,7 +62,7 @@ public static class CapabilityPresentationSmoke cache.FlushAsync().Wait(); var ledger = new ProvenanceLedger(); for (var i = 1; i <= 8; i++) ledger.Lots[i] = new Lot { Origin = new Attributed(), Quality = 1 }; - var items = new ItemManager(1u, cache, ledger, settings, _ => { }); + var items = new ItemManager(cache, ledger, settings, _ => { }); var zone = new Zone(items, new PlanetSettings(), new ZonePack(), new GalaxyZone { Name = "Smoke", Owner = null }, null); var hullRef = items.ItemData.RefOf(items.ItemData.GetByName("Smoke Hull")); var ship = new Ship(items, zone, new EquippableItem { Data = hullRef, Durability = 1000, Lot = 1 }, new EntitySettings()); @@ -85,11 +85,6 @@ public static class CapabilityPresentationSmoke ?? throw new InvalidOperationException("No Tractor Beam prefab."); // An entity's instance as the game builds it: the beam is a child before SetEntity on both ship paths, so the // binder finds it as the game does. - // The scene's map: an entity registers its icon with the ZoneRenderer's presenter, so each instance carries a quad. - var mapRenderer = new GameObject("Smoke Zone Renderer").AddComponent(); - mapRenderer.Settings = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset"); - mapRenderer.MapGravityMaterials = new Material[0]; - Awaken(mapRenderer); (GameObject Object, EntityInstance Instance, TractorBeam Beam) Bound(string name, Entity entity) { var go = new GameObject(name); @@ -103,11 +98,7 @@ public static class CapabilityPresentationSmoke var tractor = ((GameObject)PrefabUtility.InstantiatePrefab(beamPrefab, go.transform)).GetComponent(); tractor.Power = .8f; tractor.Direction = Vector3.forward; - var icon = GameObject.CreatePrimitive(PrimitiveType.Quad); - icon.transform.SetParent(go.transform); - bound.MapIcon = icon.GetComponent(); - bound.MapIcon.sharedMaterial = new Material(Shader.Find("Unlit/Color")); - bound.SetEntity(mapRenderer, entity); + bound.SetEntity(null, entity); return (go, bound, tractor); } var (instanceObject, instance, beam) = Bound("Smoke Entity Instance", ship); diff --git a/Assets/Scripts/Editor/CultCacheDrawers.cs b/Assets/Scripts/Editor/CultCacheDrawers.cs index 27d21afec..c446212db 100644 --- a/Assets/Scripts/Editor/CultCacheDrawers.cs +++ b/Assets/Scripts/Editor/CultCacheDrawers.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System; using System.Linq; using System.Reflection; @@ -88,13 +87,14 @@ public sealed class InspectableTemperatureDrawer : ICultInspectorDrawer } } -// A size and a toggle per cell. The underlay (the item's schematic texture, or a hull's line art stretched to the Shape's -// Width x Height) is drawn by HullUnderlay; the height follows a texture's aspect. A hull's hardpoint cells are tinted. -// Both read the owning record through +// A size and a toggle per cell. When the owning item has a schematic texture, the texture lies under the grid and the +// height follows its aspect; a hull's hardpoint cells are tinted. Both read the owning record through // inspector.Record, which is a read-only copy: nothing here writes to it. [CultInspectorDrawer(typeof(InspectableSchematicShapeAttribute))] public sealed class InspectableSchematicShapeDrawer : ICultInspectorDrawer { + private static Material _schematicMaterial; + public object Draw(CultInspector inspector, string label, Type type, object value, MemberInfo member) { if (type != typeof(Shape)) return inspector.DrawDefault(label, type, value, member); @@ -122,13 +122,18 @@ public sealed class InspectableSchematicShapeDrawer : ICultInspectorDrawer { using (var grid = new EditorGUILayout.VerticalScope()) { - HullUnderlay.Draw(grid.rect, item, inspector.Records); + if (schematic != null && Event.current.type == EventType.Repaint) + { + _schematicMaterial ??= new Material(Shader.Find("Legacy Shaders/Particles/Additive")); + EditorGUI.DrawPreviewTexture(grid.rect, schematic, _schematicMaterial); + } for (var y = shape.Height - 1; y >= 0; y--) using (new EditorGUILayout.HorizontalScope()) for (var x = 0; x < shape.Width; x++) { - var hardpoint = hull?.Hardpoints.FirstOrDefault(hp => HullFootprint.Cells(hp).Contains(int2(x, y))); + var hardpoint = hull?.Hardpoints.FirstOrDefault(hp => hp.Shape.Coordinates + .Any(v => v.x + hp.Position.x == x && v.y + hp.Position.y == y)); var previous = GUI.backgroundColor; if (hardpoint != null) GUI.backgroundColor = hardpoint.TintColor.ToColor(); shape[int2(x, y)] = GUILayout.Toggle(shape[int2(x, y)], GUIContent.none, GUILayout.Width(16)); @@ -140,93 +145,3 @@ public sealed class InspectableSchematicShapeDrawer : ICultInspectorDrawer return shape; } } - -// The underlay under a hull's cell grids, drawn on Repaint only. A shipped hull's schematic texture is stretched over -// the grid rect; a mod hull's line art (its ShipAuthoring, found in the open cache at hull.Visual) is placed by -// SchematicUnderlay.Fit in cell units and mapped to the rect here, the one site that maps cells to a grid's screen -// rect. The hull Shape grid and the footprint painter both draw through it. No lookup found: no line underlay. -public static class HullUnderlay -{ - private static Material _schematicMaterial; - - public static void Draw(Rect grid, EquippableItemData item, IReadOnlyList records) - { - if (item == null || Event.current.type != EventType.Repaint) return; - var texture = string.IsNullOrEmpty(item.Schematic) ? null : AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(item.Schematic)); - if (texture != null) - { - _schematicMaterial ??= new Material(Shader.Find("Legacy Shaders/Particles/Additive")); - EditorGUI.DrawPreviewTexture(grid, texture, _schematicMaterial); - } - - if (!(item is HullData hull) || hull.Shape == null || hull.Shape.Width == 0 || hull.Shape.Height == 0) return; - var key = CultInspectorModel.RecordKey(hull.Visual); - var authoring = records?.FirstOrDefault(record => record.Key.Value == key && record.Document is ShipAuthoring)?.Document as ShipAuthoring; - if (authoring == null) return; - - var lines = authoring.SchematicLines; - var fit = SchematicUnderlay.Fit(lines, hull.Shape); - for (var i = 0; i < fit.Length; i++) - { - var rgba = lines[i].Color; - var color = rgba == null ? Color.white : new Color(rgba[0], rgba[1], rgba[2], rgba[3]); - var points = fit[i].Select(p => new Vector3( - grid.x + p.x / hull.Shape.Width * grid.width, - grid.yMax - p.y / hull.Shape.Height * grid.height)).ToList(); - if (lines[i].Cyclic && points.Count > 2) points.Add(points[0]); - using (new Handles.DrawingScope(color)) Handles.DrawAAPolyLine(2f, points.ToArray()); - } - } -} - -// A hardpoint's schematic footprint over its hull's cells: the hull's occupied cells shaded, this hardpoint's cells lit -// in its tint, other hardpoints' cells tinted and disabled. A click edits Position and Shape together through -// HullFootprint.Toggle, which owns the rule so a Thing host reads the same one. The footprint is authored for gameplay, -// never derived from the model. Read-only on inspector.Record; only the HardpointData it is given changes. -[CultInspectorDrawer(typeof(HardpointData))] -public sealed class HardpointFootprintDrawer : ICultInspectorDrawer -{ - public object Draw(CultInspector inspector, string label, Type type, object value, MemberInfo member) - { - var hardpoint = value as HardpointData; - if (type != typeof(HardpointData) || hardpoint == null) return inspector.DrawDefault(label, type, value, member); - var hull = inspector.Record as HullData; - var own = hull?.Hardpoints.FirstOrDefault(hp => hp.Type == hardpoint.Type && hp.Position.Equals(hardpoint.Position) - && HullFootprint.Cells(hp).SequenceEqual(HullFootprint.Cells(hardpoint))); - var drawn = (HardpointData) inspector.DrawDefault(label, type, value, member); - if (hull?.Shape == null) return drawn; - - var others = hull.Hardpoints.Where(hp => hp != own).ToArray(); - EditorGUILayout.LabelField("Footprint"); - using (new EditorGUILayout.HorizontalScope()) - { - using (var grid = new EditorGUILayout.VerticalScope()) - { - HullUnderlay.Draw(grid.rect, hull, inspector.Records); - for (var y = hull.Shape.Height - 1; y >= 0; y--) - using (new EditorGUILayout.HorizontalScope()) - for (var x = 0; x < hull.Shape.Width; x++) - { - var cell = int2(x, y); - var other = others.FirstOrDefault(hp => HullFootprint.Cells(hp).Contains(cell)); - var on = HullFootprint.Cells(drawn).Contains(cell); - var previous = GUI.backgroundColor; - GUI.backgroundColor = on ? drawn.TintColor.ToColor() : other != null ? other.TintColor.ToColor() - : hull.Shape[cell] ? Color.gray : previous; - EditorGUI.BeginChangeCheck(); - using (new EditorGUI.DisabledScope(other != null && !on)) - GUILayout.Toggle(on || other != null, GUIContent.none, GUILayout.Width(16)); - if (EditorGUI.EndChangeCheck() && HullFootprint.Toggle(drawn.Shape, drawn.Position, cell, out var shape, out var position)) - { - drawn.Shape = shape; - drawn.Position = position; - GUI.changed = true; - } - GUI.backgroundColor = previous; - } - } - GUILayout.FlexibleSpace(); - } - return drawn; - } -} diff --git a/Assets/Scripts/Editor/DrawnPoseWiringVerify.cs b/Assets/Scripts/Editor/DrawnPoseWiringVerify.cs deleted file mode 100644 index 69109a622..000000000 --- a/Assets/Scripts/Editor/DrawnPoseWiringVerify.cs +++ /dev/null @@ -1,232 +0,0 @@ -using System; -using System.Collections; -using System.IO; -using System.Linq; -using GameCult.Caching; -using UnityEditor; -using UnityEditor.SceneManagement; -using UnityEngine; -using float2 = CultMath.float2; -using float3 = CultMath.float3; - -// Batch proof that the presenters read the drawn pose through the clock: DrawnPoseTests pins the pose maths headlessly, -// and this is what pins that each presenter passes ActionGameManager.Clock.Lead into it. A zone with a sun and a planet on a moving rail -// is built and the pickup and mine prefabs ARPG.unity's ZoneRenderer names are bound to it as the renderer binds them; a loose Projectile is launched on the -// zone. The zone is stepped once, then the clock is set to leads 0, 0.008 and 0.015 s with no step, and each presenter's -// own Update places its transform. A body is drawn at its last step plus its step velocity times the lead, spelled here -// from the body's fields, so a presenter that reads lead 0 (or half the lead) sits on the step and fails. -// -// Reached: ItemPickup, MineInstance, Projectile.Draw. Not reached: ZoneRenderer.Update (Lower needs a ComputeBuffer, a -// GPU device) and the ActionGameManager markers (they need the ARPG scene running); a Lower split so its record fill is -// pure, or a run with a GPU and ARPG.unity in play mode, would reach them. -// -// Unity -batchmode -nographics -projectPath -executeMethod Aetheria.EditorTools.DrawnPoseWiringVerify.Run -logFile -// -// Do not pass -quit: Run enters play mode (a domain reload), the check runs there, and the Editor exits itself, 0 on -// success and 1 on any failure. -namespace Aetheria.EditorTools -{ - [InitializeOnLoad] - public static class DrawnPoseWiringVerify - { - private const string Tag = "[DrawnPoseWiringVerify]"; - private const string Flag = "DrawnPoseWiringVerify.running"; - private const string Wiring = "DrawnPoseWiringVerify.wiring"; - private const double Budget = 300; // real seconds - private const float RoundSpeed = 100f, Tolerance = 1e-3f; - private static IEnumerator _check; - private static double _started; - private static string _work; - - static DrawnPoseWiringVerify() - { - if (SessionState.GetBool(Flag, false)) EditorApplication.playModeStateChanged += OnPlayMode; - } - - public static void Run() - { - try - { - SessionState.SetString(Wiring, ReadWiring()); - SessionState.SetBool(Flag, true); - EditorApplication.EnterPlaymode(); - } - catch (Exception exception) - { - Debug.LogException(exception); - EditorApplication.Exit(1); - } - } - - private static void OnPlayMode(PlayModeStateChange change) - { - if (change != PlayModeStateChange.EnteredPlayMode) return; - _work = Path.Combine(Path.GetTempPath(), $"drawn-pose-wiring-{Guid.NewGuid():N}"); - Directory.CreateDirectory(_work); - _started = Time.realtimeSinceStartupAsDouble; - _check = Check(); - EditorApplication.update += Step; - } - - private static void Step() - { - try - { - if (Time.realtimeSinceStartupAsDouble - _started > Budget) throw new InvalidOperationException($"The check did not finish in {Budget} seconds."); - if (_check.MoveNext()) return; - Finish(0); - } - catch (Exception exception) - { - Debug.LogException(exception); - Finish(1); - } - } - - private static void Finish(int code) - { - EditorApplication.update -= Step; - SessionState.SetBool(Flag, false); - try { if (Directory.Exists(_work)) Directory.Delete(_work, true); } catch (Exception) { /* a temp directory */ } - EditorApplication.Exit(code); - } - - private static void Require(bool condition, string what) - { - if (!condition) throw new InvalidOperationException(what); - } - - private static IEnumerator Check() - { - var settings = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset")?.GameplaySettings - ?? throw new InvalidOperationException("No Settings.asset."); - settings.FloaterLayerHeight = -1.5f; // nonzero, so a presenter that drops the floater layer fails - - var wired = SessionState.GetString(Wiring, "").Split('|').Select(entry => entry.Split('=')).ToDictionary(pair => pair[0], pair => pair[1]); - var pickupPrefab = AssetDatabase.LoadAssetAtPath(wired["SimpleCommodityPickup"])?.GetComponent(); - var minePrefab = AssetDatabase.LoadAssetAtPath(wired["MinePrefab"])?.GetComponent(); - Require(pickupPrefab != null, "ZoneRenderer.SimpleCommodityPickup is not an ItemPickup in ARPG.unity."); - Require(minePrefab != null, "ZoneRenderer.MinePrefab is not a MineInstance in ARPG.unity."); - - var oneCell = new Shape(1, 1); - oneCell[new CultMath.int2(0, 0)] = true; - var cache = AetheriaStores.Open(Path.Combine(_work, "wiring.cc"), Path.Combine(_work, "wiring-run.cc"), catalogWritable: true); - cache.Upsert(new VerseGrammar { Revision = 1 }); - cache.Upsert(new SimpleCommodityData { Name = "Wiring Ore", Shape = oneCell, MaxStack = 100 }); - cache.FlushAsync().Wait(); - var ledger = new ProvenanceLedger(); - var items = new ItemManager(1u, cache, ledger, settings, _ => { }); - - // A sun and a planet on a moving rail round it, both near the bodies below: the field under a floater changes with the - // drawn time, so a presenter that samples it at the step's time, drops it, or reads lead 0 for the height draws a different y. - var sunOrbit = cache.Upsert(new OrbitData { FixedPosition = new float2(-55, -.5f) }).Key; - var planetOrbit = cache.Upsert(new OrbitData { Parent = new CultRecordRef(sunOrbit), Distance = 40f, Phase = 0f }).Key; - var pack = new ZonePack { Radius = 5000f, Mass = 10000f }; - pack.Orbits.Add(new CultRecordRef(sunOrbit)); - pack.Orbits.Add(new CultRecordRef(planetOrbit)); - pack.Planets.Add(new CultRecordRef(cache.Upsert(new PlanetData { Name = "Wiring Sun", Orbit = new CultRecordRef(sunOrbit), Mass = 400f }).Key)); - pack.Planets.Add(new CultRecordRef(cache.Upsert(new PlanetData { Name = "Wiring Planet", Orbit = new CultRecordRef(planetOrbit), Mass = 400f }).Key)); - var curves = new PlanetSettings - { - BodyRadius = new ExponentialCurve(), - WellStrength = new ExponentialCurve { Multiplier = 1f, Exponent = 1f }, - RocheLimit = new ExponentialCurve { Constant = 10f } - }; - var zone = new Zone(items, curves, pack, null, null); - - var rootObject = new GameObject("Wiring Zone Root"); - - var ore = new SimpleCommodity { Data = items.ItemData.RefOf(items.ItemData.GetByName("Wiring Ore")), Quantity = 7 }; - var floating = zone.Release(ore, new float2(-17, 4), new float2(10, 0)); - var mine = new Mine - { - Body = new KinematicBody { Position = new float2(-20, 8), Velocity = new float2(0, 14) }, - ArmingDelay = 1e6f, FuseDelay = 1f, Lifetime = 1e6f, BlastRadius = 1f - }; - zone.Lay(mine); - - // Bound the way ZoneRenderer.LoadFloatingItem and LoadMine bind them: the prefab ARPG.unity names, Bind(zone, body, settings). - // (A ZoneRenderer would load this zone's sun and planet too, and that needs the planet prefab, the map and a GPU.) - var pickup = UnityEngine.Object.Instantiate(pickupPrefab, rootObject.transform); - pickup.Bind(zone, floating, settings); - var mineInstance = UnityEngine.Object.Instantiate(minePrefab, rootObject.transform); - mineInstance.Bind(zone, mine, settings); - - // A round on its frozen line, no target and no outcome known: drawn at FireOrigin + direction * speed * (T - FireTime). - var shot = new PendingShot - { - ShotId = 1, FireOrigin = new float3(0, 0, 0), FireTime = 0f, TravelDirection = new float2(1, 0), Speed = RoundSpeed, - MaxRange = 1e6f, FireRange = 1e6f, CommitTime = 1e5f, ArrivalTime = 2e5f - }; - var projectile = new GameObject("Wiring Round").AddComponent(); - projectile.Launch(null, zone, shot, new Vector3(0, 0, 0)); - yield return null; - - zone.Update(.5f); - - - var pickupVelocity = floating.Body.TotalVelocity; - var mineVelocity = mine.Body.TotalVelocity; - Require(Mathf.Abs(pickupVelocity.x) > 1f && Mathf.Abs(mineVelocity.y) > 1f, "The fixture's bodies stopped: a lead would not move them."); - - // The field under each floater really is a function of the drawn time here, by more than the tolerance at the largest lead. - const float LargestLead = .015f; - foreach (var at in new[] { floating.Body.Position + pickupVelocity * LargestLead, mine.Body.Position + mineVelocity * LargestLead }) - Require(Mathf.Abs(DrawAhead.Height(zone, at, LargestLead) - zone.GetHeight(at, zone.ExactTime)) > 5 * Tolerance, - $"The fixture's field is flat under a floater: height {DrawAhead.Height(zone, at, LargestLead)} at the drawn time, {zone.GetHeight(at, zone.ExactTime)} at the step, planet at {zone.OrbitPositionAt(planetOrbit, zone.ExactTime)}, floater at {at}."); - - Vector2 baseline = default; - foreach (var leadSeconds in new[] { 0f, .008f, .015f }) - { - ActionGameManager.Clock.Reset(); - if (leadSeconds > 0) ActionGameManager.Clock.Advance(leadSeconds, _ => throw new InvalidOperationException("a step ran")); - var lead = ActionGameManager.Clock.Lead; - Require(Mathf.Abs(lead - leadSeconds) < 1e-6f, $"The clock's lead is {lead}, not {leadSeconds}."); - yield return null; - - var seen = pickup.transform.position; - var want = floating.Body.Position + pickupVelocity * lead; - Require(Mathf.Abs(seen.x - want.x) < Tolerance && Mathf.Abs(seen.z - want.y) < Tolerance, - $"ItemPickup at lead {lead}: drawn x/z {seen.x},{seen.z}, the step plus velocity times lead {want.x},{want.y}."); - - Require(Mathf.Abs(seen.y - DrawAhead.FloaterHeight(zone, settings, new float2(want.x, want.y), lead)) < Tolerance, - $"ItemPickup y {seen.y} is not on the floater layer."); - - seen = mineInstance.transform.position; - want = mine.Body.Position + mineVelocity * lead; - Require(Mathf.Abs(seen.x - want.x) < Tolerance && Mathf.Abs(seen.z - want.y) < Tolerance, - $"MineInstance at lead {lead}: drawn x/z {seen.x},{seen.z}, the step plus velocity times lead {want.x},{want.y}."); - Require(Mathf.Abs(seen.y - DrawAhead.FloaterHeight(zone, settings, new float2(want.x, want.y), lead)) < Tolerance, - $"MineInstance y {seen.y} is not on the floater layer."); - - // The round's line is a function of the drawn time: it moves RoundSpeed * lead along its direction between leads. - seen = projectile.transform.position; - if (leadSeconds == 0f) baseline = new Vector2(seen.x, seen.z); - var moved = new Vector2(seen.x, seen.z) - baseline; - Require(Mathf.Abs(moved.x - RoundSpeed * lead) < Tolerance && Mathf.Abs(moved.y) < Tolerance, - $"Projectile at lead {lead}: drawn {moved.x},{moved.y} past its lead-0 pose, expected {RoundSpeed * lead},0."); - } - ActionGameManager.Clock.Reset(); - Debug.Log($"{Tag} ok: ItemPickup, MineInstance and Projectile draw at the clock's lead (0, 0.008, 0.015 s)"); - } - - // What ARPG.unity's ZoneRenderer names in the pickup and mine fields, read from the saved scene before the play session - // (a scene cannot be opened inside one) and carried across the domain reload as asset paths. - private static string ReadWiring() - { - var scene = EditorSceneManager.OpenScene("Assets/Scenes/ARPG.unity", OpenSceneMode.Additive); - try - { - var found = UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None) - .Where(r => r.gameObject.scene == scene).ToArray(); - Require(found.Length == 1, $"ARPG.unity has {found.Length} ZoneRenderers."); - var wired = found[0]; - return string.Join("|", new (string, UnityEngine.Object)[] - { - ("SimpleCommodityPickup", wired.SimpleCommodityPickup), ("MinePrefab", wired.MinePrefab) - }.Select(f => f.Item1 + "=" + (f.Item2 == null ? "" : AssetDatabase.GetAssetPath(f.Item2)))); - } - finally { EditorSceneManager.CloseScene(scene, true); } - } - } -} diff --git a/Assets/Scripts/Editor/DrawnPoseWiringVerify.cs.meta b/Assets/Scripts/Editor/DrawnPoseWiringVerify.cs.meta deleted file mode 100644 index 534bebdb6..000000000 --- a/Assets/Scripts/Editor/DrawnPoseWiringVerify.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: c2270cf68a4af384eb715c8b5a55f5e8 \ No newline at end of file diff --git a/Assets/Scripts/Editor/FloatingItemsDrawnSmoke.cs b/Assets/Scripts/Editor/FloatingItemsDrawnSmoke.cs index 742e8aa9d..50f6fcb94 100644 --- a/Assets/Scripts/Editor/FloatingItemsDrawnSmoke.cs +++ b/Assets/Scripts/Editor/FloatingItemsDrawnSmoke.cs @@ -24,8 +24,7 @@ public static class FloatingItemsDrawnSmoke private const string Flag = "FloatingItemsDrawnSmoke.running"; private const string Wiring = "FloatingItemsDrawnSmoke.wiring"; private static IEnumerator _check; - private const double Budget = 300; // real seconds: batch frames can be far shorter than a game second - private static double _started; + private static int _frames; private static string _work; static FloatingItemsDrawnSmoke() @@ -53,7 +52,6 @@ public static class FloatingItemsDrawnSmoke if (change != PlayModeStateChange.EnteredPlayMode) return; _work = Path.Combine(Path.GetTempPath(), $"floating-items-smoke-{Guid.NewGuid():N}"); Directory.CreateDirectory(_work); - _started = Time.realtimeSinceStartupAsDouble; _check = Check(); EditorApplication.update += Step; } @@ -62,7 +60,7 @@ public static class FloatingItemsDrawnSmoke { try { - if (Time.realtimeSinceStartupAsDouble - _started > Budget) throw new InvalidOperationException($"The check did not finish in {Budget} seconds."); + if (++_frames > 3000) throw new InvalidOperationException("The check did not finish in 3000 frames."); if (_check.MoveNext()) return; Finish(0); } @@ -90,8 +88,6 @@ public static class FloatingItemsDrawnSmoke { var settings = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset")?.GameplaySettings ?? throw new InvalidOperationException("No Settings.asset."); - // A floater rides its own layer: a nonzero one (never saved back to the asset), so a presenter that drops it fails. - settings.FloaterLayerHeight = -1.5f; // The wiring: the scene's ZoneRenderer names an ItemPickup prefab in each of the four fields, and none of those // prefabs keeps a script that no longer exists. @@ -124,7 +120,7 @@ public static class FloatingItemsDrawnSmoke cache.FlushAsync().Wait(); var ledger = new ProvenanceLedger(); for (var i = 1; i <= 8; i++) ledger.Lots[i] = new Lot { Origin = new Attributed(), Quality = 1 }; - var items = new ItemManager(1u, cache, ledger, settings, _ => { }); + var items = new ItemManager(cache, ledger, settings, _ => { }); var zone = new Zone(items, new PlanetSettings(), new ZonePack(), null, null); EquippableItem Make(string name, int lot) => new EquippableItem { @@ -149,7 +145,6 @@ public static class FloatingItemsDrawnSmoke typeof(ZoneRenderer).GetField(name).SetValue(renderer, pickup); renderer.ItemManager = items; renderer.SectorBrushes = new GameObject("Smoke Brushes").transform; - renderer.AmbientLight = Aetheria.EditorTools.AmbientEdgeVerify.NewAmbientLight(); renderer.SlimeGravityCamera = new GameObject("Smoke Gravity Camera").AddComponent(); var slimeObject = new GameObject("Smoke Slime"); slimeObject.SetActive(false); // the real Slime needs its compute shader; LoadZone only sets its radius @@ -160,9 +155,8 @@ public static class FloatingItemsDrawnSmoke ItemPickup[] Pickups() => rootObject.GetComponentsInChildren(true).Where(p => p != null).ToArray(); void At(ItemPickup pickup, FloatingItem floating, string what) { - var lead = ActionGameManager.Clock.Lead; - var at = DrawAhead.Position(floating.Body, lead); - var want = new Vector3(at.x, DrawAhead.FloaterHeight(zone, settings, at, lead), at.y); + var at = floating.Body.Position; + var want = new Vector3(at.x, zone.GetHeight(at), at.y); Require(Vector3.Distance(pickup.transform.position, want) < 1e-3f, $"{what}: the pickup is at {pickup.transform.position}, the body at {want}."); } @@ -191,13 +185,10 @@ public static class FloatingItemsDrawnSmoke var earlyPickup = Pickups().Single(p => p.Item == early.Item); earlyPickup.LabelPersistDuration = 1; earlyPickup.LabelFadeDuration = .2f; - // Game time, not frames: batch frames can be far shorter than a game second, so a frame count can run out before the fade. - var labelUntil = Time.time + earlyPickup.LabelPersistDuration + earlyPickup.LabelFadeDuration + 1f; - while (Time.time < labelUntil && earlyPickup.ScanLabel.color.a > .05f) yield return null; + for (var i = 0; i < 1200 && earlyPickup.ScanLabel.color.a > .05f; i++) yield return null; Require(earlyPickup.ScanLabel.color.a <= .05f, "label: an unviewed, unheld label did not go dark."); Require(zone.TryHold(taker, early.Id), "label: the zone refused to hold the item."); - labelUntil = Time.time + earlyPickup.LabelPersistDuration + earlyPickup.LabelFadeDuration + 1f; - while (Time.time < labelUntil && earlyPickup.ScanLabel.color.a < .95f) yield return null; + for (var i = 0; i < 1200 && earlyPickup.ScanLabel.color.a < .95f; i++) yield return null; Require(earlyPickup.ScanLabel.color.a >= .95f, "label: a held item's label is not lit."); // The test scene's stand-in sim and tendril ride the zone's own held-pose curve: its pose at each point of a grab diff --git a/Assets/Scripts/Editor/FlowFieldParityVerify.cs b/Assets/Scripts/Editor/FlowFieldParityVerify.cs index 2fa3e5fda..90979f7e8 100644 --- a/Assets/Scripts/Editor/FlowFieldParityVerify.cs +++ b/Assets/Scripts/Editor/FlowFieldParityVerify.cs @@ -106,7 +106,7 @@ namespace Aetheria.EditorTools var cache = AetheriaStores.Open(Path.Combine(work, Guid.NewGuid().ToString("N") + ".cc"), catalogWritable: true); cache.Upsert(new VerseGrammar { Revision = 1 }); cache.FlushAsync().Wait(); - var items = new ItemManager(1u, cache, new ProvenanceLedger(), settings.GameplaySettings, _ => { }); + var items = new ItemManager(cache, new ProvenanceLedger(), settings.GameplaySettings, _ => { }); return new Zone(items, new PlanetSettings { Flow = flow }, new ZonePack { Time = time }, new GalaxyZone { Name = "Parity", Owner = null }, null); } diff --git a/Assets/Scripts/Editor/FlowFieldSceneVerify.cs b/Assets/Scripts/Editor/FlowFieldSceneVerify.cs index d39874f33..80d9a4e31 100644 --- a/Assets/Scripts/Editor/FlowFieldSceneVerify.cs +++ b/Assets/Scripts/Editor/FlowFieldSceneVerify.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Linq; using System.Reflection; @@ -140,9 +140,6 @@ namespace Aetheria.EditorTools Call(volume, "Update"); if (Differing(flowing, Frame()) == 0) Fail("scene-stardust-run", "the particle buffer did not move while the zone ran"); if (Shader.GetGlobalFloat("_NebulaNoiseTime") == noiseTime) Fail("scene-noise-clock", "_NebulaNoiseTime did not move while the zone ran"); - - CheckStardustUncullable(dust, bufferField); - CheckStardustUnderFog(dust, bufferField); } finally { @@ -150,214 +147,6 @@ namespace Aetheria.EditorTools } } - // The event Stardust itself attaches its draw at, read from the class so the verifier cannot agree with a copy of it. - static CameraEvent DrawEvent() => - (CameraEvent) typeof(Stardust).GetField("DrawEvent", BindingFlags.NonPublic | BindingFlags.Static).GetRawConstantValue(); - - // The dust is a command buffer on the target camera, which no culling sees: with every particle 10000 below the - // camera (far past any box a hand could inflate round it) a render still shows dust, and shows none when the - // same particles have no size. - static void CheckStardustUncullable(Stardust dust, FieldInfo bufferField) - { - var camera = dust.TargetCamera; - if (camera == null) { Fail("scene-stardust-uncullable", "Stardust has no TargetCamera"); return; } - var drawEvent = DrawEvent(); - var attached = camera.GetCommandBuffers(drawEvent).Count(buffer => buffer.name == "Stardust"); - if (attached != 1) Fail("scene-stardust-uncullable", $"{attached} Stardust command buffers at {drawEvent} on the target camera, expected 1"); - foreach (var other in Enum.GetValues(typeof(CameraEvent)).Cast().Where(other => other != drawEvent)) - { - var stray = camera.GetCommandBuffers(other).Count(buffer => buffer.name == "Stardust"); - if (stray != 0) Fail("scene-stardust-uncullable", $"{stray} Stardust command buffers at {other}, expected 0"); - } - - var particles = (ComputeBuffer) bufferField.GetValue(dust); - float[] Layout(float size, Vector3 centre, float below) => DustLayout(particles.count, size, centre, below); - - var transform = camera.transform; - var (position, rotation) = (transform.position, transform.rotation); - var (far, flags, background, mask, target) = (camera.farClipPlane, camera.clearFlags, camera.backgroundColor, camera.cullingMask, camera.targetTexture); - var texture = RenderTexture.GetTemporary(64, 64, 24, RenderTextureFormat.ARGB32); - var readback = new Texture2D(64, 64, TextureFormat.RGBA32, false); - var previous = RenderTexture.active; - // Image effects on the camera would write their own frame over the dust; only the dust draw is under test. - var effects = camera.GetComponents().Where(behaviour => behaviour.enabled).ToArray(); - Color32[] Render(float size, Vector3 centre, float below) - { - Call(dust, "Update"); // on a bounded draw this queues the draw for the camera; here it dispatches the compute - particles.SetData(Layout(size, centre, below)); - camera.Render(); - RenderTexture.active = texture; - readback.ReadPixels(new Rect(0, 0, 64, 64), 0, 0); - readback.Apply(); - return readback.GetPixels32(); - } - try - { - foreach (var effect in effects) effect.enabled = false; - camera.clearFlags = CameraClearFlags.SolidColor; - camera.backgroundColor = Color.black; - camera.cullingMask = 1; - camera.targetTexture = texture; - // control: the camera where the scene put it, dust 100 below, inside any box a hand-set extent would give - transform.SetPositionAndRotation(position, Quaternion.Euler(90f, 0f, 0f)); - camera.farClipPlane = 1000f; - var nearWith = Render(5f, position, 100f); var nearWithout = Render(0f, position, 100f); - var nearDiff = 0; for (var i = 0; i < nearWith.Length; i++) if (!nearWith[i].Equals(nearWithout[i])) nearDiff++; - Debug.Log($"{Tag} stardust near-control differing pixels={nearDiff}"); - if (nearDiff == 0) Fail("scene-stardust-uncullable", "control: dust 100 below the camera drew no pixels"); - transform.SetPositionAndRotation(new Vector3(0f, -40000f, 0f), Quaternion.Euler(90f, 0f, 0f)); - camera.farClipPlane = 30000f; - var withDust = Render(400f, transform.position, 10000f); // the material scales a quad by distance^.33, so at this range it needs this size to cover pixels - var without = Render(0f, transform.position, 10000f); - var differing = 0; - for (var i = 0; i < withDust.Length; i++) - if (!withDust[i].Equals(without[i])) differing++; - if (differing == 0) Fail("scene-stardust-uncullable", "the dust 10000 below the camera drew no pixels"); - } - finally - { - RenderTexture.active = previous; - foreach (var effect in effects) effect.enabled = true; - camera.targetTexture = target; - camera.cullingMask = mask; - camera.backgroundColor = background; - camera.clearFlags = flags; - camera.farClipPlane = far; - transform.SetPositionAndRotation(position, rotation); - RenderTexture.ReleaseTemporary(texture); - UnityEngine.Object.DestroyImmediate(readback); - } - } - - // The nebula is an [ImageEffectOpaque] that fogs the whole ray to a depth the dust never writes (B49): dust drawn - // before it is attenuated by the fog, dust drawn after it sits on top at full strength. The dust's contribution to a - // pixel (render with dust minus render without) is read with the cloud renderer off and on, in an HDR target. - static void CheckStardustUnderFog(Stardust dust, FieldInfo bufferField) - { - const int Size = 128; - var camera = dust.TargetCamera; - var cloud = camera == null ? null : camera.GetComponent(); - if (cloud == null) { Fail("scene-stardust-under-fog", "the target camera has no VolumeCloudRenderer"); return; } - var particles = (ComputeBuffer) bufferField.GetValue(dust); - - var transform = camera.transform; - var (position, rotation) = (transform.position, transform.rotation); - var (far, flags, background, mask, target, hdr) = (camera.farClipPlane, camera.clearFlags, camera.backgroundColor, camera.cullingMask, camera.targetTexture, camera.allowHDR); - var texture = RenderTexture.GetTemporary(Size, Size, 24, RenderTextureFormat.ARGBHalf); - var readback = new Texture2D(Size, Size, TextureFormat.RGBAHalf, false); - var previous = RenderTexture.active; - var effects = camera.GetComponents().Where(behaviour => behaviour.enabled).ToArray(); - var fields = new System.Collections.Generic.List(); - GameObject floor = null; - float[] Render(bool fog, float size) - { - cloud.enabled = fog; - for (var frame = 0; frame < 2; frame++) // the cloud's first frame forces ULTRA and fills its history; the second is the settled one - { - Call(dust, "Update"); - particles.SetData(DustLayout(particles.count, size, position, 100f)); - camera.Render(); - } - RenderTexture.active = texture; - readback.ReadPixels(new Rect(0, 0, Size, Size), 0, 0); - readback.Apply(); - return readback.GetPixels().Select(pixel => pixel.r * .2126f + pixel.g * .7152f + pixel.b * .0722f).ToArray(); - } - try - { - foreach (var effect in effects) effect.enabled = false; - camera.allowHDR = true; - camera.clearFlags = CameraClearFlags.SolidColor; - camera.backgroundColor = Color.black; - camera.cullingMask = 1; - camera.targetTexture = texture; - camera.farClipPlane = 1000f; - transform.SetPositionAndRotation(position, Quaternion.Euler(90f, 0f, 0f)); - // The fog only measures a partial density where depth is written: a pixel with no depth is fogged whole (CloudShader sets - // density 1 past the far plane). A floor under the dust gives the march a finite ray. - floor = GameObject.CreatePrimitive(PrimitiveType.Plane); - floor.transform.position = position + Vector3.down * 200f; - floor.transform.localScale = Vector3.one * 100f; - UnityEngine.Object.DestroyImmediate(floor.GetComponent()); - - // The scene's own nebula fields are textures the game renders; here a uniform fill of white fog stands in for them. - foreach (var (name, format) in new[] { ("_NebulaSurfaceHeight", TextureFormat.RFloat), ("_NebulaPatchHeight", TextureFormat.RHalf), ("_NebulaPatch", TextureFormat.RHalf) }) - Shader.SetGlobalTexture(name, Uniform(format, Color.black, fields)); - Shader.SetGlobalTexture("_NebulaTint", Uniform(TextureFormat.RGBA32, Color.white, fields)); - Shader.DisableKeyword("NOISE_SLOPE"); - Shader.SetGlobalFloat("_NebulaFillDensity", .01f); - Shader.SetGlobalFloat("_NebulaFillDistance", 120f); - Shader.SetGlobalFloat("_NebulaFillExponent", 0f); - Shader.SetGlobalFloat("_NebulaFillOffset", 0f); - Shader.SetGlobalFloat("_NebulaPatchDensity", 0f); - Shader.SetGlobalFloat("_NebulaLuminance", .01f); // a fog dimmer than the dust: dust drawn over it would otherwise read as a negative contribution - Shader.SetGlobalFloat("_ExtinctionCoefficient", .25f); // with the fill density, about 40% of the light to the floor is fogged away - Shader.SetGlobalFloat("_SafetyDistance", -1e6f); // below every sample: only the uniform fill, none of the zone's noise - Shader.SetGlobalFloat("_TintLodExponent", 0f); - - var clearBare = Render(false, 0f); - var clearDust = Render(false, 5f); - var fogBare = Render(true, 0f); - var fogDust = Render(true, 5f); - - var fogShown = 0f; - var (clearSum, fogSum, drawn) = (0f, 0f, 0); - for (var i = 0; i < clearBare.Length; i++) - { - fogShown += Mathf.Abs(fogBare[i] - clearBare[i]) / clearBare.Length; - if (clearDust[i] == clearBare[i]) continue; - drawn++; clearSum += clearDust[i] - clearBare[i]; fogSum += fogDust[i] - fogBare[i]; - } - var (clearMean, fogMean) = (drawn == 0 ? 0f : clearSum / drawn, drawn == 0 ? 0f : fogSum / drawn); - Debug.Log($"{Tag} stardust under fog: fog control mean |difference|={fogShown}, dust pixels={drawn}, dust contribution cloud off={clearMean}, cloud on={fogMean}, ratio={(clearMean == 0f ? 0f : fogMean / clearMean)}"); - if (drawn == 0 || clearMean <= 0f) Fail("scene-stardust-under-fog", "control: the dust drew no pixels with the cloud renderer off"); - else if (fogShown < 1e-3f) Fail("scene-stardust-under-fog", "control: the cloud renderer changed no pixels, so no fog is in view"); - else if (fogMean > .9f * clearMean) Fail("scene-stardust-under-fog", "the dust is not attenuated by the fog in front of it: it was drawn after the nebula composites"); - else if (fogMean < .1f * clearMean) Fail("scene-stardust-under-fog", "the dust is erased, not dimmed, by a partial fog"); - } - finally - { - RenderTexture.active = previous; - foreach (var effect in effects) effect.enabled = true; - camera.allowHDR = hdr; - camera.targetTexture = target; - camera.cullingMask = mask; - camera.backgroundColor = background; - camera.clearFlags = flags; - camera.farClipPlane = far; - transform.SetPositionAndRotation(position, rotation); - RenderTexture.ReleaseTemporary(texture); - UnityEngine.Object.DestroyImmediate(readback); - foreach (var field in fields) UnityEngine.Object.DestroyImmediate(field); - if (floor != null) UnityEngine.Object.DestroyImmediate(floor); - } - } - - static Texture2D Uniform(TextureFormat format, Color colour, System.Collections.Generic.List owner) - { - var texture = new Texture2D(1, 1, format, false) { wrapMode = TextureWrapMode.Clamp }; - texture.SetPixel(0, 0, colour); - texture.Apply(); - owner.Add(texture); - return texture; - } - - // A square patch of particles 4 apart, `below` under `centre`. - static float[] DustLayout(int count, float size, Vector3 centre, float below) - { - var side = Mathf.RoundToInt(Mathf.Sqrt(count)); - var data = new float[count * 7]; - for (var i = 0; i < count; i++) - { - data[i * 7 + 0] = centre.x + ((i % side) - side / 2f) * 4f; - data[i * 7 + 1] = centre.y - below; - data[i * 7 + 2] = centre.z + ((i / side) - side / 2f) * 4f; - data[i * 7 + 3] = data[i * 7 + 4] = data[i * 7 + 5] = 1f; - data[i * 7 + 6] = size; - } - return data; - } - // CloudShader's pass 0 compiles with the flow keywords (it must #include_with_pragmas the shared include). static void CheckCloudKeywords() { diff --git a/Assets/Scripts/Editor/GravityFieldParityVerify.cs b/Assets/Scripts/Editor/GravityFieldParityVerify.cs deleted file mode 100644 index d996d3227..000000000 --- a/Assets/Scripts/Editor/GravityFieldParityVerify.cs +++ /dev/null @@ -1,428 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using GameCult.Caching; -using UnityEditor; -using UnityEditor.SceneManagement; -using UnityEngine; -using UnityEngine.Rendering; -using CultMath; - -namespace Aetheria.EditorTools -{ - /// - /// Batchmode check for campaign aetheria-gravity, cut grid-lowering: what the Gravity Field pass draws is the sim's - /// height. It builds a zone from Settings.asset's PlanetSettings with three bodies, runs the real lowering - /// (GravityLowering.Lower and CreateField), renders the field through an orthographic camera that culls layer 9 into - /// a float target, and compares every texel with -Zone.GetHeight at the texel centre's world position. It then checks - /// that the texture's gradient points where Zone.GetForce does, and that ARPG.unity and the body prefabs are wired - /// the way the cut leaves them (the gravity cameras cull layer 9 alone, nothing but the run-time field sits on it). - /// - /// Renders, so it needs a graphics device: run WITHOUT -nographics (as FlowFieldParityVerify). - /// Unity -batchmode -projectPath <repo> -executeMethod Aetheria.EditorTools.GravityFieldParityVerify.Run -logFile <path> - /// Do not pass -quit: Run exits the Editor itself, 0 on success and 1 on any failure. - /// - public static class GravityFieldParityVerify - { - const string Tag = "[GravityFieldParityVerify]"; - const int Size = 256; - // Measured on this tree (the "max error" line this run prints): the largest |texel + GetHeight| over the windows of the three - // frames is 0.0103 u, in the moved-again frame's sun window (float32 on both sides, the GPU's log and the closed form's - // single-precision floor of 1.5e-5 per unit strength against the CPU's, the quad's interpolated world position). The - // tolerance is 2.9x that. A band whose terms were drawn from the wrong edge (reference, inner or outer) moves the - // drawn height by whole units. - const float Tolerance = 0.03f; - // The worst angle between the texture's central difference and GetForce (B28: 1.0 degrees median zone, 2.9 worst). - const float GradientDegrees = 3f; - // Below this force (u/s^2) the drawn height differs between neighbouring texels by less than float32 resolves. - const float FlatForce = 1e-3f; - static float _maxError, _maxAngle, _maxTau; - static bool _ok = true; - - static void OnLog(string message, string stack, LogType type) - { - if ((type == LogType.Error || type == LogType.Exception || type == LogType.Assert) && !message.StartsWith(Tag)) - Fail("logged-error", message.Split('\n')[0]); - } - - static void Fail(string check, string detail) - { - Debug.LogError($"{Tag} FAIL {check}: {detail}"); - _ok = false; - } - - public static void Run() - { - if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null) - { - Debug.LogError($"{Tag} FAIL: no graphics device in this session; rerun batchmode without -nographics."); - EditorApplication.Exit(1); - return; - } - - Application.logMessageReceived += OnLog; - var work = Path.Combine(Path.GetTempPath(), "gravity-parity-" + Guid.NewGuid().ToString("N")); - Directory.CreateDirectory(work); - ComputeBuffer wells = null; - GameObject field = null; - try - { - var settings = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset") - ?? throw new InvalidOperationException("No Settings.asset."); - var material = AssetDatabase.LoadAssetAtPath("Assets/Materials/Brushes/Gravity Field.mat") - ?? throw new InvalidOperationException("No Gravity Field.mat."); - - var zone = BuildZone(settings, work, out var orbits, multiRoot: true); - GravityLowering.Lower(zone, 0f, ref wells); - field = GravityLowering.CreateField(material); - - // Three frames through the one buffer, as ZoneRenderer.Update runs it: the bodies as built, then two moves (an - // orbit's Position is what Zone.GetHeight reads). A move keeps the tree's geometry, since a rail never leaves - // its parent's distance and the walk skips a subtree outside its reach: the sun is the root, the planet is - // its Distance from the sun, the planetoid its Distance from the planet. A lowering that mirrors an axis or - // stops refreshing the upload agrees with the sim in the first frame only where it is symmetric. - CheckFrame("built", zone, orbits); - orbits[1].Position = Around(orbits[0], orbits[1], .31f); - orbits[2].Position = Around(orbits[1], orbits[2], .77f); - orbits[5].Position = Around(orbits[1], orbits[5], .41f); - GravityLowering.Lower(zone, 0f, ref wells); - CheckFrame("moved", zone, orbits); - orbits[0].Position = new float2(210f, -95f); - orbits[1].Position = Around(orbits[0], orbits[1], .52f); - orbits[2].Position = Around(orbits[1], orbits[2], .05f); - orbits[5].Position = Around(orbits[1], orbits[5], .93f); - GravityLowering.Lower(zone, 0f, ref wells); - CheckFrame("moved-again", zone, orbits); - if (_maxTau <= 1f) Fail("series-branch", $"the largest tau over the drawn bounded terms is {_maxTau:G4}; no window draws the series branch"); - Debug.Log($"{Tag} largest drawn tau {_maxTau:G4}"); - Debug.Log($"{Tag} max error {_maxError:G4} u (tolerance {Tolerance:G4}); max gradient angle {_maxAngle:F2} degrees (limit {GradientDegrees:F0})"); - - CheckWiring(settings); - Debug.Log(_ok ? $"{Tag} PASS" : $"{Tag} FAIL: see errors above"); - } - catch (Exception e) - { - Debug.LogError($"{Tag} FAIL exception: {e}"); - _ok = false; - } - finally - { - Application.logMessageReceived -= OnLog; - if (field != null) UnityEngine.Object.DestroyImmediate(field); - wells?.Release(); - try { Directory.Delete(work, true); } catch { } - } - EditorApplication.Exit(_ok ? 0 : 1); - } - - static float Core(Zone zone, float mass) => zone.Settings.RocheLimit.Evaluate(mass); - - // Where an orbit lies when it stands `turns` round its parent at its Distance. - static float2 Around(Orbit parent, Orbit child, float turns) => parent.Position + child.Data.Distance * OrbitData.Evaluate(turns); - - static Vector2 At(Orbit orbit) => new Vector2(orbit.Position.x, orbit.Position.y); - - // Orbits 0-2 are the sun, the planet and the planetoid, each window centred where the body is now; orbit 3 is the - // body of no strength, orbit 4 the second sun and orbit 5 the planet's moon inside its Roche limit (whose band has - // tau above 1: the series branch of the shader). The zone window holds all of them; the far window is centred on the - // zone node, so its band (nothing inside A, the zone's mass beyond Beta A) is drawn. A window draws a term when - // the term's disc reaches it; the largest tau over the drawn terms must exceed 1 or the series branch went unchecked. - static void CheckFrame(string frame, Zone zone, Orbit[] orbits) - { - CheckTexels(frame + "-planetoid", zone, At(orbits[2]), 4f * Core(zone, 29.2f)); - CheckTexels(frame + "-planet", zone, At(orbits[1]), 4f * Core(zone, 273.9f)); - CheckTexels(frame + "-sun", zone, At(orbits[0]), 4f * Core(zone, 14152f)); - CheckTexels(frame + "-zone", zone, Vector2.zero, 1.05f * zone.Pack.Radius); - var centre = new Vector2(zone.Wells.Centre.x, zone.Wells.Centre.y); - var span = 0f; - foreach (var root in new[] { orbits[0], orbits[4] }) - span = Math.Max(span, (At(root) - centre).magnitude + zone.Wells.Reach(zone.Orbits.First(o => o.Value == root).Key)); - // The wells have their own windows: out here a texel is 40 u wide, so only the ring from 0.9 A outward, where the - // zone node's band rises and the zone becomes one body, is measured. - CheckTexels(frame + "-far", zone, centre, 1.6f * span, .9f * span); - CheckGradient(zone, orbits.Select(At).ToArray()); - } - - // A sun (14152 at (-130, 85)), its planet (273.9, placed at (610, -240) at the pack's time), the planet's planetoid - // (29.2, placed at (670, -270)) and a body of mass 0, whose well has no strength (a legal body; its curves give - // c = 0 and R = 0), at (1700, 300): a family, so the band terms are drawn (the planet's and the sun's cusps and - // fades), off both axes and asymmetric, so the zone's wells sit where the verify says before any Update and a - // mirrored or swapped axis cannot agree with the sim. The sun and the zero-mass body are fixed roots. - internal static Zone BuildZone(GameSettings settings, string work, out Orbit[] orbits, float radius = 4182f, bool multiRoot = false) - { - var cache = AetheriaStores.Open(Path.Combine(work, "catalog.cc"), Path.Combine(work, "run.cc"), catalogWritable: true); - cache.Upsert(new VerseGrammar { Revision = 1 }); - cache.FlushAsync().Wait(); - var items = new ItemManager(1u, cache, new ProvenanceLedger(), settings.GameplaySettings, _ => { }); - var positions = new List { new Vector2(-130f, 85f), new Vector2(610f, -240f), new Vector2(670f, -270f), new Vector2(1700f, 300f) }; - var masses = new List { 14152f, 273.9f, 29.2f, 0f }; - var parents = new List { -1, 0, 1, -1 }; - if (multiRoot) - { - // A second sun (a second subzone, so the zone node exists) and a moon of the planet 0.6 of its Roche limit away. - positions.Add(new Vector2(-2400f, -1900f)); - masses.Add(3000f); - parents.Add(-1); - positions.Add(positions[1] + new Vector2(-.6f * settings.PlanetSettings.RocheLimit.Evaluate(273.9f), 0f)); - masses.Add(1f); - parents.Add(1); - } - var keys = new CultRecordKey[positions.Count]; - var pack = new ZonePack { Radius = radius }; - for (var i = 0; i < positions.Count; i++) - { - var data = new OrbitData { FixedPosition = new float2(positions[i].x, positions[i].y) }; - if (parents[i] >= 0) - { - var offset = positions[i] - positions[parents[i]]; - data.Parent = new CultRecordRef(keys[parents[i]]); - data.Distance = offset.magnitude; - data.Phase = Mathf.Atan2(offset.y, offset.x) / (2f * Mathf.PI); - } - var orbit = keys[i] = cache.Upsert(data).Key; - var body = cache.Upsert(new PlanetData - { Name = "Body " + i, Orbit = new CultRecordRef(orbit), Mass = masses[i] }).Key; - pack.Orbits.Add(new CultRecordRef(orbit)); - pack.Planets.Add(new CultRecordRef(body)); - } - var zone = new Zone(items, settings.PlanetSettings, pack, new GalaxyZone { Name = "Gravity Parity", Owner = null }, null); - orbits = keys.Select(k => zone.Orbits[k]).ToArray(); - return zone; - } - - // Renders the field through a downward orthographic camera that culls layer 9 only, centred on `centre` with - // half-size `half`, and returns the depth of every texel with the world xz of the texel's centre, which is asked - // of the camera rather than assumed. - static void Render(Vector2 centre, float half, out float[] depth, out Vector2[] world) - { - var rt = new RenderTexture(Size, Size, 0, RenderTextureFormat.RFloat) { filterMode = FilterMode.Point }; - var cameraObject = new GameObject("Gravity Parity Camera"); - var read = new Texture2D(Size, Size, TextureFormat.RFloat, false); - var previous = RenderTexture.active; - try - { - var camera = cameraObject.AddComponent(); - camera.orthographic = true; - camera.orthographicSize = half; - camera.aspect = 1f; - camera.nearClipPlane = .3f; - camera.farClipPlane = 1000f; - camera.cullingMask = 1 << GravityLowering.FieldLayer; - camera.clearFlags = CameraClearFlags.SolidColor; - camera.backgroundColor = Color.black; - camera.allowHDR = false; - camera.allowMSAA = false; - camera.targetTexture = rt; - cameraObject.transform.SetPositionAndRotation(new Vector3(centre.x, 100f, centre.y), Quaternion.Euler(90f, 0f, 0f)); - camera.Render(); - - RenderTexture.active = rt; - read.ReadPixels(new Rect(0, 0, Size, Size), 0, 0); - read.Apply(); - depth = read.GetPixelData(0).ToArray(); - world = new Vector2[Size * Size]; - for (var y = 0; y < Size; y++) - for (var x = 0; x < Size; x++) - { - var p = camera.ViewportToWorldPoint(new Vector3((x + .5f) / Size, (y + .5f) / Size, 100f)); - world[y * Size + x] = new Vector2(p.x, p.z); - } - } - finally - { - RenderTexture.active = previous; - UnityEngine.Object.DestroyImmediate(cameraObject); - UnityEngine.Object.DestroyImmediate(read); - rt.Release(); - UnityEngine.Object.DestroyImmediate(rt); - } - } - - // The largest tau = (a^2 + eps^2) / (b^2 - a^2) over the bounded terms whose disc reaches the window's square. - static void NoteTau(Zone zone, Vector2 centre, float half) - { - foreach (var term in zone.Wells.Terms) - { - if (float.IsPositiveInfinity(term.Outer)) continue; - var at = term.Node.IsSet() ? zone.Orbits[term.Node].Position : zone.Wells.Centre; - if (Math.Abs(at.x - centre.x) > half + term.Outer || Math.Abs(at.y - centre.y) > half + term.Outer) continue; - _maxTau = Math.Max(_maxTau, (term.Inner * term.Inner + term.Softening * term.Softening) / (term.Outer * term.Outer - term.Inner * term.Inner)); - } - } - - static void CheckTexels(string window, Zone zone, Vector2 centre, float half, float ringFrom = 0f) - { - Render(centre, half, out var depth, out var world); - NoteTau(zone, centre, half); - var worst = 0f; - var live = 0; - var measured = 0; - for (var i = 0; i < depth.Length; i++) - { - if ((world[i] - centre).magnitude < ringFrom) continue; - measured++; - var expected = -zone.GetHeight(new float2(world[i].x, world[i].y)); - if (float.IsNaN(depth[i])) { Fail($"{window}-texels", $"texel {i}: NaN"); return; } - var error = Math.Abs(depth[i] - expected); - worst = Math.Max(worst, error); - if (Math.Abs(expected) > 1f) live++; - if (error > Tolerance) - { - Fail($"{window}-texels", $"texel {i} at ({world[i].x:F2}, {world[i].y:F2}): expected {expected:G6}, drawn {depth[i]:G6}, error {error:G4} > {Tolerance:G4}"); - return; - } - } - _maxError = Math.Max(_maxError, worst); - // A window that draws nothing agrees with a zone that is flat: the check must be live. - if (live < measured / 2) Fail($"{window}-texels", $"only {live} of {measured} texels are deeper than 1 u; the check is vacuous"); - Debug.Log($"{Tag} {window}: {depth.Length} texels, max error {worst:G4} u"); - } - - // The texture's central difference (over two 4 u texels, mid-zone) points where GetForce does: depth = -h, so its - // gradient is the force over the exaggeration. This is what the slope readers (the shader's slopeFlow, the nebula - // surface normal, the drawn grid) take from the texture. - static void CheckGradient(Zone zone, Vector2[] bodies) - { - Render(new Vector2(1500f, 0f), 512f, out var depth, out var world); - var compared = 0; - for (var y = 1; y < Size - 1; y++) - for (var x = 1; x < Size - 1; x++) - { - var here = world[y * Size + x]; - if (bodies.Any(b => (b - here).magnitude < 16f)) continue; - // The world step of each texel axis is read from the camera, so a flipped or rotated target is still measured. - var au = world[y * Size + x + 1] - world[y * Size + x - 1]; - var av = world[(y + 1) * Size + x] - world[(y - 1) * Size + x]; - var du = depth[y * Size + x + 1] - depth[y * Size + x - 1]; - var dv = depth[(y + 1) * Size + x] - depth[(y - 1) * Size + x]; - var det = au.x * av.y - au.y * av.x; - var g = new Vector2((du * av.y - dv * au.y) / det, (dv * au.x - du * av.x) / det); - var f = zone.GetForce(new float2(here.x, here.y)); - if (CultMath.math.length(f) < FlatForce) continue; // between the subzones the ground is flat: no direction to compare - var angle = Vector2.Angle(g, new Vector2(f.x, f.y)); - if (float.IsNaN(angle) || angle > GradientDegrees) - { - Fail("gradient", $"at ({here.x:F1}, {here.y:F1}) the drawn slope points {angle:F2} degrees from the force (limit {GradientDegrees:F0})"); - return; - } - _maxAngle = Math.Max(_maxAngle, angle); - compared++; - } - if (compared < Size * Size / 2) Fail("gradient", $"only {compared} texels were compared"); - } - - // Main Menu.unity has no ZoneRenderer, so no Gravity Field and no lowered potential: its gravity cameras draw the - // menu's own brush objects (Boundary on layer 9, the Waves on layer 10) and are presentation by spec (follow-up - // menu-grid-brushes), not a reader of the potential. This pins that: a ZoneRenderer in the menu would make its - // cameras readers of the field, and they would have to cull layer 9 alone like ARPG's. - static void CheckTestSceneWiring() - { - EditorSceneManager.OpenScene("Assets/Scenes/TestScene.unity", OpenSceneMode.Single); - try - { - if (CheckPatchCameras("TestScene.unity") < 1) Fail("wiring", "no Fog Patch Displacement camera in TestScene.unity"); - } - finally - { - EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); - } - } - - static void CheckMenuWiring() - { - var scene = EditorSceneManager.OpenScene("Assets/Scenes/Main Menu.unity", OpenSceneMode.Single); - try - { - if (UnityEngine.Object.FindFirstObjectByType(FindObjectsInactive.Include) != null) - Fail("wiring", "Main Menu.unity has a ZoneRenderer: its gravity cameras now read the Gravity Field and must cull layer 9 alone"); - var seen = 0; - foreach (var camera in UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None)) - { - if (camera.targetTexture == null || camera.targetTexture.name != "Fog Surface Displacement") continue; - seen++; - const int menuBrushLayers = (1 << 9) | (1 << 10); - if (camera.cullingMask != menuBrushLayers) - Fail("wiring", $"Main Menu camera {camera.name} culls mask {camera.cullingMask}, not the menu brush layers 9 and 10"); - } - if (seen != 1) Fail("wiring", $"{seen} Fog Surface Displacement cameras in Main Menu.unity, expected 1"); - if (CheckPatchCameras("Main Menu.unity") < 1) Fail("wiring", "no Fog Patch Displacement camera in Main Menu.unity"); - } - finally - { - EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); - } - } - - // Every scene's Fog Patch Displacement camera: cloudDensity adds the R32 gravity height to the patch texture, so - // a patch camera that culls the gravity layer counts the field twice. Returns how many it found in the open scene. - static int CheckPatchCameras(string sceneName) - { - var found = 0; - foreach (var camera in UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None)) - { - if (camera.targetTexture == null || camera.targetTexture.name != "Fog Patch Displacement") continue; - found++; - if ((camera.cullingMask & 1 << GravityLowering.FieldLayer) != 0) - Fail("wiring", $"camera {camera.name} (target Fog Patch Displacement) in {sceneName} culls layer {GravityLowering.FieldLayer}, the gravity layer"); - } - return found; - } - - static void CheckWiring(GameSettings settings) - { - var scene = EditorSceneManager.OpenScene("Assets/Scenes/ARPG.unity", OpenSceneMode.Single); - try - { - var gravityTargets = new[] { "Fog Surface Displacement", "Slime Gravity", "MinimapGravity" }; - var seen = 0; - foreach (var camera in UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None)) - { - if (camera.targetTexture == null || !gravityTargets.Contains(camera.targetTexture.name)) continue; - seen++; - if (camera.cullingMask != 1 << GravityLowering.FieldLayer) - Fail("wiring", $"camera {camera.name} (target {camera.targetTexture.name}) culls mask {camera.cullingMask}, not layer {GravityLowering.FieldLayer} alone"); - } - if (seen < gravityTargets.Length) Fail("wiring", $"only {seen} gravity cameras found in ARPG.unity"); - - // The patch texture is half-float: it holds the patch layers only, the nebula reads gravity from the R32 surface. - if (CheckPatchCameras("ARPG.unity") != 1) Fail("wiring", "ARPG.unity does not have exactly 1 Fog Patch Displacement camera"); - - // The map screen's gravity camera has no target until MapRenderer gives it one at run time. - var map = UnityEngine.Object.FindFirstObjectByType(FindObjectsInactive.Include); - if (map == null || map.GravityCamera == null) Fail("wiring", "no MapRenderer.GravityCamera in ARPG.unity"); - else if (map.GravityCamera.cullingMask != 1 << GravityLowering.FieldLayer) - Fail("wiring", $"MapRenderer.GravityCamera culls mask {map.GravityCamera.cullingMask}, not layer {GravityLowering.FieldLayer} alone"); - - var renderer = UnityEngine.Object.FindFirstObjectByType(FindObjectsInactive.Include); - if (renderer == null) Fail("wiring", "no ZoneRenderer in ARPG.unity"); - else if (renderer.GravityField == null || renderer.GravityField.shader.name != "Brushes/Gravity Field") - Fail("wiring", "ZoneRenderer.GravityField is not a Brushes/Gravity Field material"); - - foreach (var r in UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None)) - if (r.gameObject.layer == GravityLowering.FieldLayer) - Fail("wiring", $"renderer {r.name} in ARPG.unity sits on layer {GravityLowering.FieldLayer}"); - } - finally - { - EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); - } - - CheckMenuWiring(); - CheckTestSceneWiring(); - - foreach (var path in new[] - { - "Assets/Prefabs/RPG/Planets/Planet.prefab", "Assets/Prefabs/RPG/Planets/Gas Giant.prefab", - "Assets/Prefabs/RPG/Planets/Sun.prefab", "Assets/Prefabs/RPG/Wormhole 1.prefab" - }) - { - var prefab = AssetDatabase.LoadAssetAtPath(path); - if (prefab == null) { Fail("wiring", $"no prefab at {path}"); continue; } - foreach (var r in prefab.GetComponentsInChildren(true)) - if (r.gameObject.layer == GravityLowering.FieldLayer) - Fail("wiring", $"renderer {r.name} in {path} sits on layer {GravityLowering.FieldLayer}"); - } - } - } -} diff --git a/Assets/Scripts/Editor/MapBeltPerf.cs b/Assets/Scripts/Editor/MapBeltPerf.cs deleted file mode 100644 index ea3eac5c0..000000000 --- a/Assets/Scripts/Editor/MapBeltPerf.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Linq; -using GameCult.Caching; -using UnityEditor; -using CultMath; -using UnityEngine; -using float4 = CultMath.float4; -using Debug = UnityEngine.Debug; - -// The map's belt cost per frame, CPU milliseconds and managed allocation, for belts of 1000, 2250 (the generated -// maximum, Settings.asset) and 4000 asteroids: the base revision's AsteroidBeltUI.Update (MapBeltPerfBase, a verbatim copy) -// and MapPresenter's belt upload and draw, each as the median and interquartile range of 21 runs of 300 frames after -// a warm-up, in this one Unity job. CPU time only: GPU cost is not covered. Needs a GPU device. -// -// Unity -batchmode -projectPath -executeMethod MapBeltPerf.Run -logFile -public static class MapBeltPerf -{ - private const int Warmup = 60, Frames = 300, RunCount = 21; - - public static void Run() - { - var work = Path.Combine(Path.GetTempPath(), $"map-belt-perf-{Guid.NewGuid():N}"); - try - { - Directory.CreateDirectory(work); - foreach (var count in new[] { 1000, 2250, 4000 }) Measure(work, count); - EditorApplication.Exit(0); - } - catch (Exception exception) - { - Debug.LogException(exception); - EditorApplication.Exit(1); - } - } - - private static void Measure(string work, int count) - { - var settings = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset"); - var cache = AetheriaStores.Open(Path.Combine(work, $"c{count}.cc"), Path.Combine(work, $"r{count}.cc"), catalogWritable: true); - cache.Upsert(new VerseGrammar { Revision = 1 }); - var sunOrbit = cache.Upsert(new OrbitData()).Key; - var sunKey = cache.Upsert(new PlanetData { Name = "Sun", Orbit = new CultRecordRef(sunOrbit), Mass = 400f }).Key; - var beltOrbit = cache.Upsert(new OrbitData { Parent = new CultRecordRef(sunOrbit), Distance = 900f, Phase = .42f }).Key; - var asteroids = Enumerable.Range(0, count).Select(i => new Asteroid - { Distance = 120f + i * .01f, Phase = CultMath.math.frac(i * .618f), Size = CultMath.math.frac(i * .37f + .1f), RotationSpeed = .15f + i * 1e-4f }).ToArray(); - var beltKey = cache.Upsert(new AsteroidBeltData { Orbit = new CultRecordRef(beltOrbit), Asteroids = asteroids }).Key; - var pack = new ZonePack - { - Orbits = { new CultRecordRef(sunOrbit), new CultRecordRef(beltOrbit) }, - Planets = { new CultRecordRef(sunKey), new CultRecordRef(beltKey) }, - Radius = 5000f, Mass = 10000f, Time = 0 - }; - var items = new ItemManager(1u, cache, new ProvenanceLedger(), settings.GameplaySettings, _ => { }); - var zone = new Zone(items, new PlanetSettings - { - BodyRadius = new ExponentialCurve(), WellStrength = new ExponentialCurve { Multiplier = 1f, Exponent = 1f }, - RocheLimit = new ExponentialCurve { Constant = 2f }, - AsteroidSize = new ExponentialLerp { Minimum = 2f, Maximum = 9f, Exponent = 1.7f }, - AsteroidHitpoints = new ExponentialLerp { Minimum = 10f, Maximum = 300f, Exponent = 2f }, - AsteroidRespawnTime = new ExponentialLerp { Minimum = 5f, Maximum = 60f, Exponent = 1f } - }, pack, new GalaxyZone { Name = "Perf", Owner = null }, null); - - var transforms = new float4[count]; - var presenter = new MapPresenter(new Material[0], AssetDatabase.LoadAssetAtPath("Assets/Materials/UI/MapAsteroid.mat"), 4, 4, 3f); - presenter.RegisterBelt(beltKey, transforms); - var baseBelt = new MapBeltPerfBase(zone, zone.AsteroidBelts[beltKey], 4, 4, 3f); - - Report("base", count, Runs(zone, beltKey, transforms, () => baseBelt.Update(transforms, 0f))); - Report("head", count, Runs(zone, beltKey, transforms, () => presenter.Draw(zone, 0))); - presenter.Clear(); - } - - // Each run is Frames frames after Warmup frames; the figure is one run's CPU ms per frame and managed bytes per frame. - private static (double ms, long bytes)[] Runs(Zone zone, CultRecordKey beltKey, float4[] transforms, Action frame) - { - var results = new (double, long)[RunCount]; - var stopwatch = new Stopwatch(); - var time = 0.0; - for (var run = -1; run < RunCount; run++) - { - stopwatch.Reset(); - long allocated = 0; - for (var i = 0; i < Warmup + Frames; i++) - { - zone.EvaluateBelt(beltKey, transforms, time += 0.016); - var bytes = GC.GetAllocatedBytesForCurrentThread(); - if (i >= Warmup) stopwatch.Start(); - frame(); - if (i >= Warmup) stopwatch.Stop(); - if (i >= Warmup) allocated += GC.GetAllocatedBytesForCurrentThread() - bytes; - } - if (run >= 0) results[run] = (stopwatch.Elapsed.TotalMilliseconds / Frames, allocated / Frames); - } - return results; - } - - private static double Quantile(double[] sorted, double q) - { - var at = q * (sorted.Length - 1); - var low = (int)Math.Floor(at); - var high = Math.Min(low + 1, sorted.Length - 1); - return sorted[low] + (sorted[high] - sorted[low]) * (at - low); - } - - private static void Report(string revision, int count, (double ms, long bytes)[] runs) - { - var ms = runs.Select(r => r.ms).OrderBy(v => v).ToArray(); - var bytes = runs.Select(r => (double)r.bytes).OrderBy(v => v).ToArray(); - var units = Process.GetProcessesByName("Unity").Length; - Debug.Log($"[MapBeltPerf] revision={revision} asteroids={count} runs={runs.Length} frames_per_run={Frames} " + - $"cpu_ms_median={Quantile(ms, .5):F4} iqr={Quantile(ms, .25):F4}-{Quantile(ms, .75):F4} " + - $"gc_bytes_median={Quantile(bytes, .5):F0} unity_processes={units} cpus={Environment.ProcessorCount}"); - } -} diff --git a/Assets/Scripts/Editor/MapBeltPerf.cs.meta b/Assets/Scripts/Editor/MapBeltPerf.cs.meta deleted file mode 100644 index 5a06251b4..000000000 --- a/Assets/Scripts/Editor/MapBeltPerf.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 2bf3d3dcd7e3dd940add2640db93e3fe \ No newline at end of file diff --git a/Assets/Scripts/Editor/MapBeltPerfBase.cs b/Assets/Scripts/Editor/MapBeltPerfBase.cs deleted file mode 100644 index 6470b9c9a..000000000 --- a/Assets/Scripts/Editor/MapBeltPerfBase.cs +++ /dev/null @@ -1,88 +0,0 @@ -using GameCult.Caching; -using CultMath; -using UnityEngine; -using static CultMath.math; -using float2 = CultMath.float2; -using float4 = CultMath.float4; -using Random = UnityEngine.Random; - -// The base revision's per-frame belt map path, copied from ZoneRenderer.cs at da6fe033 (class AsteroidBeltUI) so that -// MapBeltPerf can measure it beside MapPresenter in one job. Only the lead it read from ActionGameManager.Clock is -// fixed at zero. Not used by the game. -public class MapBeltPerfBase -{ - private Vector3[] _vertices; - private Vector3[] _normals; - private Vector2[] _uvs; - private int[] _indices; - private CultRecordKey _orbitParent; - private Mesh _mesh; - private float _size; - private Zone _zone; - private AsteroidBelt _belt; - private float _scale; - - public MapBeltPerfBase(Zone zone, AsteroidBelt belt, int spritesheetWidth, int spritesheetHeight, float scale) - { - _belt = belt; - _zone = zone; - var orbit = zone.Orbits[belt.Data.Orbit.Key]; - _orbitParent = orbit.Data.Parent.Key; - _vertices = new Vector3[_belt.Data.Asteroids.Length * 4]; - _normals = new Vector3[_belt.Data.Asteroids.Length * 4]; - _uvs = new Vector2[_belt.Data.Asteroids.Length * 4]; - _indices = new int[_belt.Data.Asteroids.Length * 6]; - _scale = scale; - - var maxDist = 0f; - var spriteSize = float2(1f / spritesheetWidth, 1f / spritesheetHeight); - // vertex order: bottom left, top left, top right, bottom right - for (var i = 0; i < belt.Data.Asteroids.Length; i++) - { - if (belt.Data.Asteroids[i].Distance > maxDist) - maxDist = belt.Data.Asteroids[i].Distance; - var spriteX = Random.Range(0, spritesheetWidth); - var spriteY = Random.Range(0, spritesheetHeight); - - _uvs[i * 4] = new Vector2(spriteX * spriteSize.x, spriteY * spriteSize.y); - _uvs[i * 4 + 1] = new Vector2(spriteX * spriteSize.x, spriteY * spriteSize.y + spriteSize.y); - _uvs[i * 4 + 2] = new Vector2(spriteX * spriteSize.x + spriteSize.x, spriteY * spriteSize.y + spriteSize.y); - _uvs[i * 4 + 3] = new Vector2(spriteX * spriteSize.x + spriteSize.x, spriteY * spriteSize.y); - - _indices[i * 6] = i * 4; - _indices[i * 6 + 1] = i * 4 + 1; - _indices[i * 6 + 2] = i * 4 + 3; - _indices[i * 6 + 3] = i * 4 + 3; - _indices[i * 6 + 4] = i * 4 + 1; - _indices[i * 6 + 5] = i * 4 + 2; - } - - for (var i = 0; i < _normals.Length; i++) _normals[i] = -Vector3.forward; - - _mesh = new Mesh(); - _mesh.vertices = _vertices; - _mesh.uv = _uvs; - _mesh.triangles = _indices; - _mesh.normals = _normals; - _mesh.bounds = new Bounds(Vector3.zero, Vector3.one * maxDist); - _size = maxDist; - } - - public void Update(float4[] transforms, float height) - { - var parentPosition = DrawAhead.Orbit(_zone, _orbitParent, 0f); - for (var i = 0; i < transforms.Length; i++) - { - var transform = transforms[i]; - var rotation = Quaternion.Euler(90, transform.z, 0); - var position = new Vector3(transform.x, height, transform.y); - _vertices[i * 4] = rotation * new Vector3(-transform.w * _scale, -transform.w * _scale, 0) + position; - _vertices[i * 4 + 1] = rotation * new Vector3(-transform.w * _scale, transform.w * _scale, 0) + position; - _vertices[i * 4 + 2] = rotation * new Vector3(transform.w * _scale, transform.w * _scale, 0) + position; - _vertices[i * 4 + 3] = rotation * new Vector3(transform.w * _scale, -transform.w * _scale, 0) + position; - } - - _mesh.bounds = new Bounds(new Vector3(parentPosition.x, 0, parentPosition.y), Vector3.one * (_size * 2)); - _mesh.vertices = _vertices; - } -} diff --git a/Assets/Scripts/Editor/MapBeltPerfBase.cs.meta b/Assets/Scripts/Editor/MapBeltPerfBase.cs.meta deleted file mode 100644 index 662341fb1..000000000 --- a/Assets/Scripts/Editor/MapBeltPerfBase.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: c3e6b631c94f2384c87cf1906907af9f \ No newline at end of file diff --git a/Assets/Scripts/Editor/MapPresenterCapture.cs b/Assets/Scripts/Editor/MapPresenterCapture.cs deleted file mode 100644 index 1e0a727f0..000000000 --- a/Assets/Scripts/Editor/MapPresenterCapture.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System; -using System.IO; -using UnityEditor; -using UnityEditor.SceneManagement; -using UnityEngine; - -// Proof that a planet icon and a ping tint reach the pixels of the real map cameras when the planet's well is deeper -// than 1000 below the camera. The ARPG scene's own "Map Overlays" and "Map Tint" cameras (position, orthographic size, -// clip planes and culling mask as authored) render into a render texture on a solid black background. For each, in -// order: a control render with nothing drawn; a render with the thing placed 1100 below the camera (a plain quad, and the -// PingEffect prefab), which must equal the control because the far plane clips it; then MapPresenter's draw of the sun -// (well deeper than 2000) or the PingEffect prefab placed where EntityInstance places it, which must differ from the -// control at its pixel. A capture that draws nothing fails the last check, and one that cannot tell drawn from clipped -// fails the middle one. -// -// Unity -batchmode -projectPath -executeMethod MapPresenterCapture.Run -logFile -// -// Needs a GPU device; do not pass -nographics or -quit: Run exits the Editor itself, 0 on success and 1 on any failure. -public static class MapPresenterCapture -{ - private const int Size = 64; - - public static void Run() - { - var work = Path.Combine(Path.GetTempPath(), $"map-presenter-capture-{Guid.NewGuid():N}"); - try - { - Directory.CreateDirectory(work); - Check(work); - Debug.Log("[MapPresenterCapture] ok"); - EditorApplication.Exit(0); - } - catch (Exception exception) - { - Debug.LogException(exception); - EditorApplication.Exit(1); - } - } - - private static void Require(bool condition, string what) - { - if (!condition) throw new InvalidOperationException(what); - } - - private static Camera SceneCamera(string name) - { - foreach (var camera in UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None)) - if (camera.name == name) return camera; - throw new InvalidOperationException($"No camera named {name} in the scene."); - } - - private static Color Render(Camera camera, RenderTexture target, Vector3 at) - { - camera.targetTexture = target; - camera.clearFlags = CameraClearFlags.SolidColor; - camera.backgroundColor = Color.black; - camera.Render(); - var viewport = camera.WorldToViewportPoint(new Vector3(at.x, 0, at.z)); - var previous = RenderTexture.active; - RenderTexture.active = target; - var read = new Texture2D(Size, Size, TextureFormat.RGBA32, false); - read.ReadPixels(new Rect(0, 0, Size, Size), 0, 0); - RenderTexture.active = previous; - var pixel = read.GetPixel(Mathf.Clamp((int)(viewport.x * Size), 0, Size - 1), Mathf.Clamp((int)(viewport.y * Size), 0, Size - 1)); - UnityEngine.Object.DestroyImmediate(read); - return pixel; - } - - private static float Distance(Color a, Color b) => Mathf.Abs(a.r - b.r) + Mathf.Abs(a.g - b.g) + Mathf.Abs(a.b - b.b); - - private static void Check(string work) - { - EditorSceneManager.OpenScene("Assets/Scenes/ARPG.unity", OpenSceneMode.Single); - var f = MapPresenterSmoke.Build(work, flatIcons: true); - f.Map.SetMinimapScale(300f); - var target = new RenderTexture(Size, Size, 24, RenderTextureFormat.ARGB32); - var layer = LayerMask.NameToLayer("Minimap"); - - // Planet: the sun's icon through the map overlays camera. - var overlays = SceneCamera("Map Overlays"); - Require((overlays.cullingMask & (1 << layer)) != 0, "The Map Overlays camera does not see the Minimap layer."); - var well = f.Zone.GetHeight(DrawAhead.Orbit(f.Zone, f.Zone.PlanetInstances[f.SunKey].BodyData.Orbit.Key, 0), 0); - Require(well < -1000f, $"The fixture sun's well is {well}, not deeper than 1000."); - Require(f.Map.TryDrawn(f.SunKey, out var sun), "The sun registered no icon."); - var sunAt = sun.GetPosition(); - // Control: the pixel with nothing queued. Then a quad 1100 below the camera, deeper than the far plane, which must - // leave the pixel as it was. Then the presenter's draw, which must change it. Draws queue for the cameras that - // render after them, so the order is empty, deep, drawn. - var empty = Render(overlays, target, sunAt); - var quad = GameObject.CreatePrimitive(PrimitiveType.Quad); - var deepMesh = quad.GetComponent().sharedMesh; - var deepMaterial = new Material(Shader.Find("Unlit/Color")) { color = Color.white }; - UnityEngine.Object.DestroyImmediate(quad); - Graphics.RenderMesh(new RenderParams(deepMaterial) { layer = layer }, deepMesh, 0, - Matrix4x4.TRS(new Vector3(sunAt.x, -1100f, sunAt.z), Quaternion.Euler(90, 0, 0), Vector3.one * 300f)); - var deep = Render(overlays, target, sunAt); - Require(Distance(deep, empty) < .01f, $"A mesh 1100 below the camera drew: {deep} against {empty}."); - f.Map.Draw(f.Zone, 0); - var drawn = Render(overlays, target, sunAt); - Require(Distance(drawn, empty) > .3f, $"The sun's icon is not in the pixels: drawn {drawn}, empty {empty}."); - - // Ping tint: the PingEffect prefab where EntityInstance places it, through the map tint camera. - var tint = SceneCamera("Map Tint"); - var ping = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath("Assets/Content/Prefabs/PingEffect.prefab")); - ping.transform.localScale = Vector3.one * 300f; - var pingAt = new Vector3(sunAt.x, MapPresenter.PlaneY, sunAt.z); - ping.transform.position = pingAt; - ping.SetActive(false); - var untinted = Render(tint, target, pingAt); - ping.SetActive(true); - ping.transform.position = new Vector3(sunAt.x, -1100f, sunAt.z); - var deepPing = Render(tint, target, pingAt); - Require(Distance(deepPing, untinted) < .01f, $"A ping 1100 below the camera drew: {deepPing} against {untinted}."); - ping.transform.position = pingAt; - var tinted = Render(tint, target, pingAt); - Require(Distance(tinted, untinted) > .02f, $"The ping tint is not in the pixels: with {tinted}, without {untinted}."); - Debug.Log($"[MapPresenterCapture] well={well} sun drawn={drawn} empty={empty} deep={deep}; ping tinted={tinted} untinted={untinted} deep={deepPing}"); - } -} diff --git a/Assets/Scripts/Editor/MapPresenterCapture.cs.meta b/Assets/Scripts/Editor/MapPresenterCapture.cs.meta deleted file mode 100644 index 53caa5ee1..000000000 --- a/Assets/Scripts/Editor/MapPresenterCapture.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: cfa012aaae63b5044bdfd1b6b44ca9da \ No newline at end of file diff --git a/Assets/Scripts/Editor/MapPresenterSmoke.cs b/Assets/Scripts/Editor/MapPresenterSmoke.cs deleted file mode 100644 index cccc4883c..000000000 --- a/Assets/Scripts/Editor/MapPresenterSmoke.cs +++ /dev/null @@ -1,233 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Reflection; -using GameCult.Caching; -using UnityEditor; -using UnityEngine; -using CultMath; -using CultMath.UnityBridge; -using static CultMath.math; -using float2 = CultMath.float2; -using float3 = CultMath.float3; -using float4 = CultMath.float4; - -// Batch proof of MapPresenter's contract on a real Zone, without a scene: a sun with a very deep well, a belt, and ships -// registered through EntityInstance.SetEntity as the game does. Planet icons draw at the map plane inside both map -// cameras' clip range however deep the well, a rolled and pitched hull's icon turns by yaw alone, every kind registers one -// draw and leaves no icon child behind, a belt is one instanced draw of every asteroid, and an entity's fade reaches its -// icon the frame it is set. Not reached: prefab, mod ship, station and turret instances (they register through the same -// call), and the rendered pixels (a GPU capture). -// -// Unity -batchmode -projectPath -executeMethod MapPresenterSmoke.Run -logFile -// -// Do not pass -quit: Run exits the Editor itself, 0 on success and 1 on any failure. -public static class MapPresenterSmoke -{ - private const BindingFlags Any = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; - private const int Asteroids = 24; - - public static void Run() - { - var work = Path.Combine(Path.GetTempPath(), $"map-presenter-smoke-{Guid.NewGuid():N}"); - try - { - Directory.CreateDirectory(work); - Check(work); - Debug.Log("[MapPresenterSmoke] ok"); - EditorApplication.Exit(0); - } - catch (Exception exception) - { - Debug.LogException(exception); - EditorApplication.Exit(1); - } - } - - private static void Require(bool condition, string what) - { - if (!condition) throw new InvalidOperationException(what); - } - - private static void Awaken(Component component) => component.GetType().GetMethod("Awake", Any)?.Invoke(component, null); - - // flat: authored lying on the map plane (facing up), as a real icon is; the smoke's own icons are authored upright - // so that their rotation is exactly the yaw. - private static MeshRenderer NewIcon(Transform parent, bool flat) - { - var icon = GameObject.CreatePrimitive(PrimitiveType.Quad); - icon.layer = LayerMask.NameToLayer("Minimap"); - icon.transform.SetParent(parent, false); - if (flat) icon.transform.localRotation = Quaternion.Euler(90, 0, 0); - var renderer = icon.GetComponent(); - renderer.sharedMaterial = new Material(Shader.Find("Unlit/Color")) { color = new Color(1, 1, 1, .8f) }; - return renderer; - } - - // What Build leaves registered with a presenter, for the checks here and for MapPresenterCapture. - internal sealed class Fixture - { - public Zone Zone; - public MapPresenter Map; - public Ship Ship, Other; - public EntityInstance ShipInstance, OtherInstance; - public CultRecordKey SunKey, BeltKey; - public float4[] Belt; - public Transform Roots; - } - - private static void Check(string work) - { - var f = Build(work, flatIcons: false); - Checks(f); - } - - internal static Fixture Build(string work, bool flatIcons) - { - var settings = AssetDatabase.LoadAssetAtPath("Assets/Resources/Settings.asset") - ?? throw new InvalidOperationException("No Settings.asset."); - var planetSettings = new PlanetSettings - { - BodyRadius = new ExponentialCurve(), - WellStrength = new ExponentialCurve { Multiplier = 1f, Exponent = 1f }, - RocheLimit = new ExponentialCurve { Constant = 2f }, - AsteroidSize = new ExponentialLerp { Minimum = 2f, Maximum = 9f, Exponent = 1.7f }, - AsteroidHitpoints = new ExponentialLerp { Minimum = 10f, Maximum = 300f, Exponent = 2f }, - AsteroidRespawnTime = new ExponentialLerp { Minimum = 5f, Maximum = 60f, Exponent = 1f } - }; - var cache = AetheriaStores.Open(Path.Combine(work, "c.cc"), Path.Combine(work, "r.cc"), catalogWritable: true); - cache.Upsert(new VerseGrammar { Revision = 1 }); - var shape = new Shape(5, 4); - foreach (var cell in shape.AllCoordinates) shape[cell] = true; - cache.Upsert(new HullData { Name = "Smoke Hull", HullType = HullType.Ship, Shape = shape, Durability = 1000, Mass = 1000, Armor = 0 }); - var sunOrbit = cache.Upsert(new OrbitData()).Key; - var sunKey = cache.Upsert(new PlanetData { Name = "Sun", Orbit = new CultRecordRef(sunOrbit), Mass = 1e6f }).Key; - var rootOrbit = cache.Upsert(new OrbitData { Parent = new CultRecordRef(sunOrbit), Distance = 4000f, Phase = .17f }).Key; - var beltOrbit = cache.Upsert(new OrbitData { Parent = new CultRecordRef(rootOrbit), Distance = 900f, Phase = .42f }).Key; - var asteroids = Enumerable.Range(0, Asteroids).Select(i => new Asteroid - { Distance = 120f + i * 11.3f, Phase = frac(i * .618f), Size = frac(i * .37f + .1f), RotationSpeed = .15f + i * .037f }).ToArray(); - var beltKey = cache.Upsert(new AsteroidBeltData { Orbit = new CultRecordRef(beltOrbit), Asteroids = asteroids }).Key; - var pack = new ZonePack - { - Orbits = { new CultRecordRef(sunOrbit), new CultRecordRef(rootOrbit), new CultRecordRef(beltOrbit) }, - Planets = { new CultRecordRef(sunKey), new CultRecordRef(beltKey) }, - Radius = 5000f, Mass = 10000f, Time = 0 - }; - var ledger = new ProvenanceLedger(); - for (var i = 1; i <= 8; i++) ledger.Lots[i] = new Lot { Origin = new Attributed(), Quality = 1 }; - var items = new ItemManager(1u, cache, ledger, settings.GameplaySettings, _ => { }); - var zone = new Zone(items, planetSettings, pack, new GalaxyZone { Name = "Smoke", Owner = null }, null); - var hullRef = items.ItemData.RefOf(items.ItemData.GetByName("Smoke Hull")); - var ship = new Ship(items, zone, new EquippableItem { Data = hullRef, Durability = 1000, Lot = 1 }, new EntitySettings()); - var other = new Ship(items, zone, new EquippableItem { Data = hullRef, Durability = 1000, Lot = 2 }, new EntitySettings()); - ship.Position = float3(300, 50, 200); - other.Position = float3(-300, -90, 100); - zone.Admit(ship, piloted: false); - zone.Admit(other, piloted: false); - - // A hull heading 40 degrees from +z, pitched up 89.9 and rolled 30: its forward is almost vertical, where the pose's - // eulerAngles.y is the gimbal decomposition (yaw and roll folded together), not the heading. The heading is the - // forward projected onto the map plane, 40. The fixture asserts the two differ, so a yaw read from eulerAngles - // cannot pass. - var pose = Quaternion.Euler(0, 40, 0) * Quaternion.Euler(-89.9f, 0, 30); - var flatForward = pose * Vector3.forward; - Require(Mathf.Abs(Mathf.DeltaAngle(Mathf.Atan2(flatForward.x, flatForward.z) * Mathf.Rad2Deg, 40f)) < .5f, "The fixture's forward does not head 40."); - Require(Mathf.Abs(Mathf.DeltaAngle(pose.eulerAngles.y, 40f)) > 10f, $"The fixture's eulerAngles.y {pose.eulerAngles.y} is aligned with its heading."); - ship.Direction = float2(Mathf.Sin(40 * Mathf.Deg2Rad), Mathf.Cos(40 * Mathf.Deg2Rad)); - typeof(Ship).GetProperty("Rotation", Any).GetSetMethod(true).Invoke(ship, new object[] { new CultMath.quaternion(pose.x, pose.y, pose.z, pose.w) }); - - var map = new MapPresenter(new Material[0], AssetDatabase.LoadAssetAtPath("Assets/Materials/UI/MapAsteroid.mat"), 4, 4, 3f); - var roots = new GameObject("Smoke Roots").transform; - EntityInstance Bound(Entity entity) - { - var body = new GameObject(entity.Name); - body.transform.SetParent(roots); - var instance = body.AddComponent(); - Awaken(instance); - instance.HullColliders = new HullCollider[0]; - instance.RadiatorHardpoints = new RadiatorHardpoint[0]; - instance.ThrusterHardpoints = new ThrusterHardpoint[0]; - instance.WeaponHardpoints = new WeaponHardpoint[0]; - instance.ArticulationPoints = new ArticulationPoint[0]; - instance.MapIcon = NewIcon(body.transform, flatIcons); - var zoneRenderer = new GameObject("Smoke Zone Renderer").AddComponent(); - zoneRenderer.Settings = settings; - zoneRenderer.MapGravityMaterials = new Material[0]; - Awaken(zoneRenderer); - typeof(ZoneRenderer).GetProperty("Map").GetSetMethod(true).Invoke(zoneRenderer, new object[] { map }); - instance.SetEntity(zoneRenderer, entity); - return instance; - } - var shipInstance = Bound(ship); - var otherInstance = Bound(other); - var sunRoot = new GameObject("Smoke Sun").transform; - sunRoot.SetParent(roots); - map.RegisterPlanet(sunKey, NewIcon(sunRoot, flatIcons), sunRoot); - var belt = new float4[Asteroids]; - map.RegisterBelt(beltKey, belt); - zone.EvaluateBelt(beltKey, belt, DrawAhead.Time(zone, 0)); - map.SetFade(ship, 1f); - map.SetFade(other, 1f); - map.SetMinimapScale(2f); - map.Draw(zone, 0); - return new Fixture { Zone = zone, Map = map, Ship = ship, Other = other, ShipInstance = shipInstance, - OtherInstance = otherInstance, SunKey = sunKey, BeltKey = beltKey, Belt = belt, Roots = roots }; - } - - private static void Checks(Fixture f) - { - var (zone, map, ship, other, sunKey, beltKey, belt, roots) = (f.Zone, f.Map, f.Ship, f.Other, f.SunKey, f.BeltKey, f.Belt, f.Roots); - // Deep planet: the sun's field is deeper than 2000 below the plane, and its icon sits on the map plane inside both - // map cameras' clip range (minimap at y 10, map screen at y 1; near 0.3, far 1000, looking down). - var well = zone.GetHeight(DrawAhead.Orbit(zone, zone.PlanetInstances[sunKey].BodyData.Orbit.Key, 0), 0); - Require(well < -2000f, $"The fixture sun's well is {well}, not below -2000."); - Require(map.TryDrawn(sunKey, out var sunIcon), "The sun registered no icon."); - var y = sunIcon.GetPosition().y; - Require(y < 1f - .3f && y > 10f - 1000f && Mathf.Abs(y - MapPresenter.PlaneY) < .5f, $"The sun's icon is drawn at y {y}, not on the map plane."); - - // Axes: each icon sits at its sim position's planar x and z (a ship at (300, 200), the other at (-300, 100), the sun at - // its orbit), never swapped, and never at the 3D height (the ships ride at y 50 and -90, the sun's well is below -2000). - var shipAt = DrawAhead.Position(ship, 0); - Require(Mathf.Abs(shipAt.x - 300f) < 1e-3f && Mathf.Abs(shipAt.z - 200f) < 1e-3f, $"The ship's sim position is ({shipAt.x}, {shipAt.z}), not (300, 200)."); - var sunAt = DrawAhead.Orbit(zone, zone.PlanetInstances[sunKey].BodyData.Orbit.Key, 0); - Require(map.TryDrawn(ship, out var shipIcon, out _), "The ship registered no icon."); - Require(Mathf.Abs(shipIcon.GetPosition().x - 300f) < 1e-3f && Mathf.Abs(shipIcon.GetPosition().z - 200f) < 1e-3f, - $"The ship's icon is at ({shipIcon.GetPosition().x}, {shipIcon.GetPosition().z}), not its sim position (300, 200)."); - Require(map.TryDrawn(other, out var otherIcon, out _), "The second ship registered no icon."); - Require(Mathf.Abs(otherIcon.GetPosition().x + 300f) < 1e-3f && Mathf.Abs(otherIcon.GetPosition().z - 100f) < 1e-3f, - $"The second ship's icon is at ({otherIcon.GetPosition().x}, {otherIcon.GetPosition().z}), not (-300, 100)."); - Require(Mathf.Abs(sunIcon.GetPosition().x - sunAt.x) < 1e-3f && Mathf.Abs(sunIcon.GetPosition().z - sunAt.y) < 1e-3f, - $"The sun's icon is at ({sunIcon.GetPosition().x}, {sunIcon.GetPosition().z}), not its orbit ({sunAt.x}, {sunAt.y})."); - Require(Mathf.Abs(otherIcon.GetPosition().y - (MapPresenter.PlaneY + MapPresenter.ShipOffset)) < 1e-4f, "The second ship's icon took the 3D height."); - - // Tilted hull: the icon turns by the heading projected onto the map plane (40) times its authored rotation (identity here), with no roll or pitch. - var want = Quaternion.Euler(0, 40, 0); - Require(Quaternion.Angle(shipIcon.rotation, want) < .1f, $"The icon is rotated {shipIcon.rotation.eulerAngles}, not yaw 40 alone."); - Require(Vector3.Angle(shipIcon.rotation * Vector3.up, Vector3.up) < .1f, "The icon's up axis tilted with the hull."); - Require(Mathf.Abs(shipIcon.GetPosition().y - (MapPresenter.PlaneY + MapPresenter.ShipOffset)) < 1e-4f, "The ship's icon left the map plane."); - - // Every kind registers once: three icons drew, and no icon child remains under any registered transform. - Require(map.IconCount == 3 && map.IconDraws == 3, $"{map.IconCount} icons, {map.IconDraws} drawn; expected 3 and 3."); - Require(roots.GetComponentsInChildren(true).Length == 0, "An icon child remains under an entity or planet transform."); - - // A belt is one instanced draw of every asteroid, and its buffer holds this frame's floats. - Require(map.BeltDraws == 1 && map.LastBeltInstances == belt.Length, $"{map.BeltDraws} belt draws of {map.LastBeltInstances} instances; expected 1 of {belt.Length}."); - var read = new float4[belt.Length]; - map.ReadBelt(beltKey, read); - for (var i = 0; i < belt.Length; i++) - Require(read[i].x == belt[i].x && read[i].y == belt[i].y && read[i].z == belt[i].z && read[i].w == belt[i].w, $"Belt buffer differs from the frame's floats at {i}."); - - // Belts draw on the minimap with the map screen closed. - map.OpenMapScreen(false); - map.Draw(zone, 0); - Require(map.BeltDraws == 1, "A belt did not draw on the minimap with the map screen closed."); - - // Fade: half faded reaches the icon's colour alpha on the next draw; faded out draws nothing. - map.SetFade(ship, .5f); - map.Draw(zone, 0); - Require(map.TryDrawn(ship, out _, out var alpha) && Mathf.Abs(alpha - .4f) < 1e-3f, $"Icon alpha {alpha}, expected 0.8 * 0.5."); - map.SetFade(ship, 0f); - map.Draw(zone, 0); - Require(map.IconDraws == 2, $"{map.IconDraws} icons drew with one fully faded out; expected 2."); - } -} diff --git a/Assets/Scripts/Editor/MapPresenterSmoke.cs.meta b/Assets/Scripts/Editor/MapPresenterSmoke.cs.meta deleted file mode 100644 index 2fff0ea86..000000000 --- a/Assets/Scripts/Editor/MapPresenterSmoke.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 58982a1c397cc2f4d9706fd103af6654 \ No newline at end of file diff --git a/Assets/Scripts/Editor/NameTools.cs b/Assets/Scripts/Editor/NameTools.cs new file mode 100644 index 000000000..a048dce89 --- /dev/null +++ b/Assets/Scripts/Editor/NameTools.cs @@ -0,0 +1,93 @@ +using System.Buffers.Text; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using MessagePack; +using CultMath; +using UnityEngine; +using UnityEditor; +using Random = CultMath.Random; + +public class NameTools : EditorWindow +{ + public int NameGeneratorMinLength = 5; + public int NameGeneratorMaxLength = 10; + public int NameGeneratorOrder = 4; + private int minWordLength = 4; + private TextAsset nameFile; + private MarkovNameGenerator _nameGenerator; + private bool _stripNumberTokens; + + + // Add menu named "My Window" to the Window menu + [MenuItem("Window/Aetheria/Name Tools")] + static void Init() + { + // Get existing open window or if none, make a new one: + NameTools window = (NameTools)EditorWindow.GetWindow(typeof(NameTools)); + window.Show(); + } + + bool HasNonASCIIChars(string str) + { + return (System.Text.Encoding.UTF8.GetByteCount(str) != str.Length); + } + + void OnGUI() + { + + nameFile = (TextAsset) EditorGUILayout.ObjectField("Name File", nameFile, typeof(TextAsset), false); + minWordLength = EditorGUILayout.IntField("Minimum File Word Length", minWordLength); + NameGeneratorMinLength = EditorGUILayout.IntField("Generated Minimum Word Length", NameGeneratorMinLength); + NameGeneratorMaxLength = EditorGUILayout.IntField("Generated Maximum Word Length", NameGeneratorMaxLength); + NameGeneratorOrder = EditorGUILayout.IntField("Generator Order", NameGeneratorOrder); + _stripNumberTokens = GUILayout.Toggle(_stripNumberTokens, "Strip Number Tokens"); + + if (GUILayout.Button("Clean Name File")) + { + var lines = nameFile.text.Split('\n'); + using StreamWriter outputFile = new StreamWriter(Path.Combine(Application.dataPath, nameFile.name + ".csv")); + var names = new HashSet(); + foreach (var line in lines) + { + var tokens = line.Split(',', ' '); + foreach (var t in tokens) + { + if (!HasNonASCIIChars(t)) + { + var s = new string(t.Where(c => char.IsLetter(c) || c == '-' || c == '`' || c == '\'').ToArray()).Trim().Trim('`','-'); + if(s.Length >= minWordLength && !names.Contains(s)) + { + names.Add(s); + outputFile.WriteLine(s); + } + } + } + } + } + + if (GUILayout.Button("Process Name File") && nameFile != null) + { + var names = new HashSet(); + var lines = nameFile.text.Split('\n'); + foreach (var line in lines) + { + foreach(var word in line.ToUpperInvariant().Split(' ', ',', '.', '"')) + if (word.Length >= minWordLength && !names.Contains(word)) + names.Add(word); + } + Debug.Log($"Found {lines.Length} lines, with {names.Count} unique names!"); + var random = new Random(1337); + _nameGenerator = new MarkovNameGenerator(ref random, names, NameGeneratorOrder, NameGeneratorMinLength, NameGeneratorMaxLength); + } + + if (_nameGenerator != null) + { + if (GUILayout.Button("Generate Name")) + { + Debug.Log(_nameGenerator.NextName); + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Editor/GravityFieldParityVerify.cs.meta b/Assets/Scripts/Editor/NameTools.cs.meta similarity index 83% rename from Assets/Scripts/Editor/GravityFieldParityVerify.cs.meta rename to Assets/Scripts/Editor/NameTools.cs.meta index 50646bcbb..e0022b308 100644 --- a/Assets/Scripts/Editor/GravityFieldParityVerify.cs.meta +++ b/Assets/Scripts/Editor/NameTools.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1ceb2bdab0804463b1998471d47e82fa +guid: 88b5f578fe63a904b997331630e61416 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/Editor/RockMeshRadius.cs b/Assets/Scripts/Editor/RockMeshRadius.cs deleted file mode 100644 index 971284924..000000000 --- a/Assets/Scripts/Editor/RockMeshRadius.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Linq; -using UnityEditor; -using UnityEditor.Build; -using UnityEditor.Build.Reporting; -using UnityEditor.SceneManagement; -using UnityEngine; - -// The radius of each rock mesh ZoneRenderer draws (ruling rock-meshes-by-size): the farthest vertex from the mesh origin, which bounds the -// mesh's top under any rotation. DrawAhead.RockScale divides the gameplay radius by it, so the drawn rock is the gameplay rock. It is stored on -// InstancedMesh.Radius in ARPG.unity, because a build cannot read vertices of a mesh without Read/Write import. -// -// Unity -batchmode -nographics -projectPath -executeMethod Aetheria.EditorTools.RockMeshRadius.Fill -logFile -// Unity -batchmode -nographics -projectPath -executeMethod Aetheria.EditorTools.RockMeshRadius.Verify -logFile -// -// Fill measures every AsteroidMeshes entry and saves the scene; Verify fails (exit 1) when any stored radius is not the measured one. -// RockMeshRadiusBuildGate runs the same check before every player build and fails the build, so a mesh with no filled radius cannot ship; -// Gate runs that gate in batch mode. -// Unity -batchmode -nographics -projectPath -executeMethod Aetheria.EditorTools.RockMeshRadius.Gate -logFile -namespace Aetheria.EditorTools -{ - public static class RockMeshRadius - { - private const string Scene = "Assets/Scenes/ARPG.unity"; - private const float Tolerance = 1e-4f; - - public static float Measure(Mesh mesh) => Mathf.Sqrt(mesh.vertices.Max(v => v.sqrMagnitude)); - - public static void Fill() => Batch(() => - { - var scene = EditorSceneManager.OpenScene(Scene, OpenSceneMode.Single); - var (renderer, meshes, measured) = Load(scene); - for (var i = 0; i < meshes.Length; i++) meshes[i].Radius = measured[i]; - EditorUtility.SetDirty(renderer); - EditorSceneManager.MarkSceneDirty(scene); - if (!EditorSceneManager.SaveScene(scene)) throw new InvalidOperationException("The scene did not save."); - return Summary("filled", measured); - }); - - public static void Verify() => Batch(() => Check(OpenSceneMode.Single)); - - // The build gate's own entry in batch mode: exit 1 exactly when a build would fail (RockMeshRadiusBuildGate). - public static void Gate() => Batch(() => - { - try { new RockMeshRadiusBuildGate().OnPreprocessBuild(null); } - catch (BuildFailedException failure) { throw new InvalidOperationException(failure.Message); } - return "the build gate passes"; - }); - - // Throws unless every AsteroidMeshes entry of ARPG.unity has a stored radius equal to its mesh's measured one (a zero radius never does). - public static string Check(OpenSceneMode mode) - { - var scene = EditorSceneManager.OpenScene(Scene, mode); - try - { - var (_, meshes, measured) = Load(scene); - var failures = meshes.Select((m, i) => (m, i)).Where(p => !(measured[p.i] > 0f) || Mathf.Abs(p.m.Radius - measured[p.i]) > Tolerance).ToArray(); - if (failures.Length > 0) - throw new InvalidOperationException("InstancedMesh.Radius differs from the measured one, or is unset, on mesh (run RockMeshRadius.Fill): " + string.Join(", ", - failures.Select(f => f.m.Mesh.name))); - return Summary("ok", measured); - } - finally - { - if (mode == OpenSceneMode.Additive) EditorSceneManager.CloseScene(scene, true); - } - } - - private static (ZoneRenderer renderer, InstancedMesh[] meshes, float[] measured) Load(UnityEngine.SceneManagement.Scene scene) - { - var renderer = UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None) - .Single(r => r.gameObject.scene == scene); - var meshes = renderer.AsteroidMeshes; - if (meshes == null || meshes.Length == 0) throw new InvalidOperationException("ARPG.unity's ZoneRenderer has no AsteroidMeshes."); - var bad = meshes.Where(m => m.Mesh == null).ToArray(); - if (bad.Length > 0) throw new InvalidOperationException($"{bad.Length} AsteroidMeshes entries have no mesh."); - return (renderer, meshes, meshes.Select(m => Measure(m.Mesh)).ToArray()); - } - - private static string Summary(string what, float[] measured) - { - var sorted = measured.OrderBy(r => r).ToArray(); - return $"{what}: {sorted.Length} meshes, radius min {sorted[0]:F3} median {sorted[sorted.Length / 2]:F3} max {sorted[^1]:F3}"; - } - - private static void Batch(Func run) - { - try - { - Debug.Log($"[RockMeshRadius] {run()}"); - EditorApplication.Exit(0); - } - catch (Exception exception) - { - Debug.LogException(exception); - EditorApplication.Exit(1); - } - } - } - - // A mesh in AsteroidMeshes with no filled radius must not ship: the build fails, naming the field. - public class RockMeshRadiusBuildGate : IPreprocessBuildWithReport - { - public int callbackOrder => 0; - - public void OnPreprocessBuild(BuildReport report) - { - try { RockMeshRadius.Check(OpenSceneMode.Additive); } - catch (InvalidOperationException failure) { throw new BuildFailedException(failure.Message); } - } - } -} diff --git a/Assets/Scripts/Editor/RockMeshRadius.cs.meta b/Assets/Scripts/Editor/RockMeshRadius.cs.meta deleted file mode 100644 index f95fec963..000000000 --- a/Assets/Scripts/Editor/RockMeshRadius.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 9ea93f3d164825c4b99a0d07f24d5cf6 \ No newline at end of file diff --git a/Assets/Scripts/Editor/ScenarioPickerCapture.cs b/Assets/Scripts/Editor/ScenarioPickerCapture.cs deleted file mode 100644 index b39dd7a1b..000000000 --- a/Assets/Scripts/Editor/ScenarioPickerCapture.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using UnityEditor; -using UnityEditor.SceneManagement; -using UnityEngine; -using UnityEngine.UI; - -// A render of the New Game screen as the game builds it: the real Main Menu scene's panel prototype, docked and filled -// by ScenarioPicker.Dock and ScenarioPicker.Show with every scenario group, on a plain dark background (the cloud -// backdrop is a play-mode renderer). Writes /Temp/scenario-picker.png at 1920x1080, or the path after -pngOut (Unity empties Temp on exit). -// -// Unity -batchmode -projectPath -executeMethod ScenarioPickerCapture.Run [-pngOut ] -logFile -// -// Needs a GPU device; do not pass -nographics or -quit: Run exits the Editor itself, 0 on success and 1 on any failure. -public static class ScenarioPickerCapture -{ - private const int Width = 1920, Height = 1080; - - public static void Run() - { - try - { - Capture(); - EditorApplication.Exit(0); - } - catch (Exception exception) - { - Debug.LogException(exception); - EditorApplication.Exit(1); - } - } - - // The menu's two panes built the way MainMenu.Start builds them, against the Main Menu scene. - internal static (MainMenu menu, PropertiesPanel list, PropertiesPanel detail) Build() - { - EditorSceneManager.OpenScene("Assets/Scenes/Main Menu.unity", OpenSceneMode.Single); - var menu = UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None)[0]; - menu.PanelPrototype.gameObject.SetActive(false); - var list = menu.PanelPrototype.Instantiate(); - var detail = menu.PanelPrototype.Instantiate(); - // Edit mode runs no Awake, which is what activates each row a panel adds. - list.Awake(); - detail.Awake(); - ScenarioPicker.Dock(detail, list); - return (menu, list, detail); - } - - internal static List<(string label, Scenario[] scenarios)> AllGroups() => new List<(string label, Scenario[] scenarios)> - { - ("modes", Scenarios.Modes), ("development", Scenarios.Development), ("test arenas", Scenarios.Tests) - }; - - private static void Capture() - { - var (menu, list, detail) = Build(); - menu.Dialog.gameObject.SetActive(false); - list.Title.text = MainMenu.TitleSubtitle("new game", "scenarios"); - ScenarioPicker.Show(list, detail, AllGroups(), _ => { }, () => { }, menu.Dialog.Confirm); - list.RefreshValues(); - detail.RefreshValues(); - - var canvas = menu.GetComponentInParent(true).rootCanvas; - var target = new RenderTexture(Width, Height, 24, RenderTextureFormat.ARGB32); - var cameraObject = new GameObject("ScenarioPickerCapture camera"); - var camera = cameraObject.AddComponent(); - camera.orthographic = true; - camera.orthographicSize = 5; - camera.clearFlags = CameraClearFlags.SolidColor; - camera.backgroundColor = new Color(.04f, .05f, .08f); - camera.cullingMask = 1 << LayerMask.NameToLayer("UI"); - camera.targetTexture = target; - canvas.renderMode = RenderMode.ScreenSpaceCamera; - canvas.worldCamera = camera; - canvas.planeDistance = 10; - canvas.gameObject.SetActive(true); - Canvas.ForceUpdateCanvases(); - LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform) list.transform); - LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform) detail.transform); - foreach (var text in list.transform.GetComponentsInChildren()) - text.ForceMeshUpdate(); - Canvas.ForceUpdateCanvases(); - list.Content.GetComponentInParent().onValueChanged.Invoke(Vector2.zero); - camera.Render(); - - var previous = RenderTexture.active; - RenderTexture.active = target; - var read = new Texture2D(Width, Height, TextureFormat.RGBA32, false); - read.ReadPixels(new Rect(0, 0, Width, Height), 0, 0); - RenderTexture.active = previous; - - var background = read.GetPixel(0, 0); - var differing = 0; - foreach (var pixel in read.GetPixels32()) - if (Mathf.Abs(pixel.r / 255f - background.r) + Mathf.Abs(pixel.g / 255f - background.g) + Mathf.Abs(pixel.b / 255f - background.b) > .05f) - differing++; - if (differing < Width * Height / 100) - throw new InvalidOperationException($"The capture is uniform: only {differing} pixels differ from the background."); - - var path = Path.GetFullPath(Path.Combine(Application.dataPath, "..", "Temp", "scenario-picker.png")); - var args = Environment.GetCommandLineArgs(); - var outIndex = Array.IndexOf(args, "-pngOut"); - if (outIndex >= 0) path = Path.GetFullPath(args[outIndex + 1]); - Directory.CreateDirectory(Path.GetDirectoryName(path)); - File.WriteAllBytes(path, read.EncodeToPNG()); - Debug.Log($"[ScenarioPickerCapture] {path} ({differing} of {Width * Height} pixels differ from the background)"); - } -} diff --git a/Assets/Scripts/Editor/ScenarioPickerCapture.cs.meta b/Assets/Scripts/Editor/ScenarioPickerCapture.cs.meta deleted file mode 100644 index ebeb742e8..000000000 --- a/Assets/Scripts/Editor/ScenarioPickerCapture.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 2e79f280179150e4080250c45e07cd69 \ No newline at end of file diff --git a/Assets/Scripts/Editor/ScenarioPickerVerify.cs b/Assets/Scripts/Editor/ScenarioPickerVerify.cs deleted file mode 100644 index 6816cafc9..000000000 --- a/Assets/Scripts/Editor/ScenarioPickerVerify.cs +++ /dev/null @@ -1,265 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using TMPro; -using UnityEditor; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; - -// The picker's selection and keyboard rules, driven through the events the game delivers: Move and Cancel reach the -// focused Launch button through ExecuteEvents, as the Input System UI module sends them, and a click is Button.onClick. -// -// Unity -batchmode -projectPath -executeMethod ScenarioPickerVerify.Run -logFile -// -// Exits the Editor itself, 0 when every rule holds and 1 on the first that does not. -public static class ScenarioPickerVerify -{ - private sealed class Fake : Scenario - { - private readonly uint _seed; - private readonly bool _ambient; - public Fake(string name, uint seed = 0, bool ambient = true) { Name = name; _seed = seed; _ambient = ambient; } - public override string Name { get; } - public override string Id => Name.ToLowerInvariant(); - public override string Brief => $"brief of {Name}"; - public override uint Seed => _seed; - public override bool Ambient => _ambient; - public override Galaxy Generate(GalaxyStage stage) => throw new NotSupportedException(); - public override void Stage(ScenarioStage stage) => throw new NotSupportedException(); - } - - private sealed class Screen - { - public ScenarioPicker Picker; - public PropertiesPanel List, Detail; - public Button[] Rows; - public Button Back, Launch; - public readonly List Launched = new List(); - public int Backs; - public Scenario[] A, B, C; - } - - public static void Run() - { - try - { - SelectionFollowsClicksAndArrows(); - ArrowsStopAtTheEnds(); - LeftAndRightAreIgnored(); - LaunchIsOnePathAndFocusClears(); - CancelAndBackAreOnePath(); - DetailPaneFollowsSelection(); - OneGroupHasNoSectionLabel(); - LaunchesOnceHoweverItIsReached(); - ArrowingThroughTheRealListKeepsTheSelectionVisible(); - Debug.Log("[ScenarioPickerVerify] ok"); - EditorApplication.Exit(0); - } - catch (Exception exception) - { - Debug.LogException(exception); - EditorApplication.Exit(1); - } - } - - private static void Require(bool condition, string what) - { - if (!condition) throw new InvalidOperationException(what); - } - - private static Screen Build(bool oneGroup = false, bool real = false) - { - var (menu, list, detail) = ScenarioPickerCapture.Build(); - // Build opens the scene afresh, which destroys the previous EventSystem. - var events = new GameObject("verify EventSystem").AddComponent(); - // Edit mode never calls OnEnable, which is what registers an EventSystem as current. - typeof(EventSystem).GetMethod("OnEnable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(events, null); - var screen = new Screen - { - List = list, Detail = detail, - A = new Scenario[] { new Fake("Alpha", 7), new Fake("Beta") }, - B = new Scenario[] { new Fake("Gamma", ambient: false) }, - C = new Scenario[] { new Fake("Delta"), new Fake("Echo") } - }; - var groups = real ? ScenarioPickerCapture.AllGroups() : oneGroup - ? new List<(string label, Scenario[] scenarios)> { ("modes", screen.A) } - : new List<(string label, Scenario[] scenarios)> { ("modes", screen.A), ("development", screen.B), ("test arenas", screen.C) }; - // The menu builds a panel while it is inactive and shows it afterwards; the picker must find its scroll all the same. - if (real) list.gameObject.SetActive(false); - screen.Picker = ScenarioPicker.Show(list, detail, groups, screen.Launched.Add, () => screen.Backs++, menu.Dialog.Confirm); - var buttons = list.GetComponentsInChildren(false).Where(button => !button.transform.IsChildOf(detail.transform)).Select(button => button.Button).ToArray(); - screen.Rows = buttons.Take(buttons.Length - 1).ToArray(); - screen.Back = buttons.Last(); - screen.Launch = detail.GetComponentsInChildren