app.hypergames.hypersdk 1.4.12 → 1.4.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## [1.4.14](https://github.com/mvmhyper/hyper-sdk/compare/v1.4.13...v1.4.14) (2026-01-06)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * migrate final submit to websockets; refresh CSRF on freeze-resume ([8b445e7](https://github.com/mvmhyper/hyper-sdk/commit/8b445e78d677507cc2ef7bce54d815df0ee0f58b))
7
+ * Minor Bug fixes and improvements. ([a5004b5](https://github.com/mvmhyper/hyper-sdk/commit/a5004b5d054be4e5a432f30a6abcfad4287f70b7))
8
+
9
+ ## [1.4.13](https://github.com/mvmhyper/hyper-sdk/compare/v1.4.12...v1.4.13) (2026-01-01)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * Add HyperRandom usage check and scene menu utility ([4e8bad9](https://github.com/mvmhyper/hyper-sdk/commit/4e8bad9a56dc3007c1303ee095b8bfc6cb09903a))
15
+
1
16
  ## [1.4.12](https://github.com/mvmhyper/hyper-sdk/compare/v1.4.11...v1.4.12) (2025-12-23)
2
17
 
3
18
 
@@ -55,35 +55,58 @@ namespace Hyper.Editor
55
55
  return;
56
56
  }
57
57
 
58
+ var currentVersion = packageInfo.version;
58
59
  var previousVersion = EditorPrefs.GetString(InstallerPrefsKey, string.Empty);
59
60
  var sceneExists = File.Exists(HyperLoaderSceneDestination);
60
61
  var templateExists = Directory.Exists(WebGLTemplateDestination);
61
62
  var configExists = File.Exists(HyperGameContentConfigDestination);
62
63
  var settingsExists = File.Exists(HyperSDKSettingsDestination);
63
64
 
64
- // Only run if version changed or files are missing
65
- if (previousVersion == packageInfo.version &&
66
- sceneExists &&
67
- templateExists &&
68
- configExists &&
69
- settingsExists)
70
- {
71
- return;
72
- }
73
-
65
+ // Check what kind of version change we are dealing with
66
+ bool isMajorVersionChange = HasMajorVersionChanged(previousVersion, currentVersion);
67
+ bool isMajorOrMinorVersionChange = HasMajorOrMinorVersionChanged(previousVersion, currentVersion);
68
+
74
69
  var packageRoot = packageInfo.resolvedPath;
75
70
  var hyperLoaderSource = Path.Combine(packageRoot, HyperLoaderSceneRelativePath);
76
71
  var templateSource = Path.Combine(packageRoot, WebGLTemplateRelativePath);
77
72
  var hyperGameContentConfigSource = Path.Combine(packageRoot, HyperGameContentConfigRelativePath);
78
73
  var hyperSDKSettingsSource = Path.Combine(packageRoot, HyperSDKSettingsRelativePath);
79
74
 
80
- CopyFileWithoutMeta(hyperLoaderSource, HyperLoaderSceneDestination);
81
- CopyTemplate(templateSource);
82
- CopyFileWithoutMeta(hyperGameContentConfigSource, HyperGameContentConfigDestination);
83
- CopyFileWithoutMeta(hyperSDKSettingsSource, HyperSDKSettingsDestination);
75
+ bool anyFileCopied = false;
76
+
77
+ if (!sceneExists || isMajorVersionChange)
78
+ {
79
+ CopyFileWithoutMeta(hyperLoaderSource, HyperLoaderSceneDestination);
80
+ anyFileCopied = true;
81
+ }
82
+
83
+ if (!templateExists || isMajorOrMinorVersionChange)
84
+ {
85
+ CopyTemplate(templateSource);
86
+ anyFileCopied = true;
87
+ }
88
+
89
+ if (!configExists || isMajorOrMinorVersionChange)
90
+ {
91
+ CopyFileWithoutMeta(hyperGameContentConfigSource, HyperGameContentConfigDestination);
92
+ anyFileCopied = true;
93
+ }
84
94
 
85
- EditorPrefs.SetString(InstallerPrefsKey, packageInfo.version);
86
- AssetDatabase.Refresh();
95
+ if (!settingsExists || isMajorOrMinorVersionChange)
96
+ {
97
+ CopyFileWithoutMeta(hyperSDKSettingsSource, HyperSDKSettingsDestination);
98
+ anyFileCopied = true;
99
+ }
100
+
101
+ // Always update the stored version, even if no files were copied
102
+ if (previousVersion != currentVersion)
103
+ {
104
+ EditorPrefs.SetString(InstallerPrefsKey, currentVersion);
105
+ if (anyFileCopied)
106
+ {
107
+ AssetDatabase.Refresh();
108
+ }
109
+ }
87
110
  }
88
111
 
89
112
  private static void CopyFileWithoutMeta(string sourcePath, string destinationPath)
@@ -143,6 +166,82 @@ namespace Hyper.Editor
143
166
  FileUtil.DeleteFileOrDirectory(meta);
144
167
  }
145
168
  }
169
+
170
+ /// <summary>
171
+ /// Parses a semantic version string (e.g., "1.4.5") and returns major, minor, patch components.
172
+ /// Returns (0, 0, 0) if version string is invalid or empty.
173
+ /// </summary>
174
+ private static (int major, int minor, int patch) ParseVersion(string version)
175
+ {
176
+ if (string.IsNullOrEmpty(version))
177
+ {
178
+ return (0, 0, 0);
179
+ }
180
+
181
+ // Remove any pre-release or build metadata (e.g., "1.4.5-preview.1" -> "1.4.5")
182
+ var cleanVersion = version.Split('-')[0].Split('+')[0];
183
+
184
+ var parts = cleanVersion.Split('.');
185
+ if (parts.Length < 2)
186
+ {
187
+ return (0, 0, 0);
188
+ }
189
+
190
+ int major = int.TryParse(parts[0], out int m) ? m : 0;
191
+ int minor = int.TryParse(parts[1], out int mi) ? mi : 0;
192
+ int patch = parts.Length > 2 && int.TryParse(parts[2], out int p) ? p : 0;
193
+
194
+ return (major, minor, patch);
195
+ }
196
+
197
+ /// <summary>
198
+ /// Returns true if the version change represents a major or minor version change (not just patch).
199
+ /// Examples:
200
+ /// - 1.4.5 -> 1.4.6: false (patch change)
201
+ /// - 1.4.5 -> 1.5.0: true (minor change)
202
+ /// - 1.4.5 -> 2.0.0: true (major change)
203
+ /// - Empty -> 1.0.0: true (first install)
204
+ /// </summary>
205
+ private static bool HasMajorOrMinorVersionChanged(string previousVersion, string currentVersion)
206
+ {
207
+ // First install or version is empty
208
+ if (string.IsNullOrEmpty(previousVersion))
209
+ {
210
+ return true;
211
+ }
212
+
213
+ var (prevMajor, prevMinor, _) = ParseVersion(previousVersion);
214
+ var (currMajor, currMinor, _) = ParseVersion(currentVersion);
215
+
216
+ // Major version changed
217
+ if (currMajor != prevMajor)
218
+ {
219
+ return true;
220
+ }
221
+
222
+ // Minor version changed
223
+ if (currMinor != prevMinor)
224
+ {
225
+ return true;
226
+ }
227
+
228
+ // Only patch version changed (or no change)
229
+ return false;
230
+ }
231
+
232
+ private static bool HasMajorVersionChanged(string previousVersion, string currentVersion)
233
+ {
234
+ if(string.IsNullOrEmpty(previousVersion))
235
+ {
236
+ return true;
237
+ }
238
+
239
+ var (prevMajor, _, _) = ParseVersion(previousVersion);
240
+ var (currMajor, _, _) = ParseVersion(currentVersion);
241
+
242
+ // Only major version
243
+ return currMajor != prevMajor;
244
+ }
146
245
  }
147
246
  }
148
247
 
@@ -255,7 +255,7 @@ namespace Hyper.Editor
255
255
  {
256
256
  EditorGUILayout.BeginHorizontal();
257
257
  {
258
- if (GUILayout.Toggle(currentTab == TabType.WebGLSettings, "WebGL Settings", tallButtonStyleLeft))
258
+ if (GUILayout.Toggle(currentTab == TabType.WebGLSettings, "Configuration", tallButtonStyleLeft))
259
259
  {
260
260
  currentTab = TabType.WebGLSettings;
261
261
  }
@@ -289,7 +289,7 @@ namespace Hyper.Editor
289
289
 
290
290
  #endregion
291
291
 
292
- #region WebGL Settings Tab
292
+ #region Configuration Tab
293
293
 
294
294
  private static void DrawWebGLSettingsTab()
295
295
  {
@@ -563,7 +563,7 @@ namespace Hyper.Editor
563
563
  isOptimal = status.hyperLoaderAtIndex0,
564
564
  current = $"• Current: {(status.hyperLoaderAtIndex0 ? "HyperLoader at index 0" : "HyperLoader not at index 0")}",
565
565
  recommended = "• Recommended: HyperLoader at build index 0",
566
- description = "HyperLoader scene must be at build index 0 in Build Settings. This ensures proper SDK initialization before your game starts.",
566
+ description = "HyperLoader scene must be at build index 0 in Build Settings (from Assets/HyperSDK/HyperLoader.unity). This ensures proper SDK initialization before your game starts.",
567
567
  priority = SettingPriority.Critical,
568
568
  type = SettingType.HyperLoaderSceneIndex
569
569
  };
@@ -593,6 +593,18 @@ namespace Hyper.Editor
593
593
  };
594
594
  CategorizeSettings(buildTargetSetting, optimalSettings, recommendedSettings, outstandingSettings);
595
595
 
596
+ var hyperRandomSetting = new SettingInfo
597
+ {
598
+ name = "HyperRandom Usage",
599
+ isOptimal = status.hyperRandomUsed,
600
+ current = $"• Current: {(status.hyperRandomUsed ? "HyperRandom detected in your code" : "HyperRandom not found")}",
601
+ recommended = "• Recommended: Use HyperRandom for deterministic gameplay",
602
+ description = "HyperRandom ensures deterministic gameplay across devices. Use the RNG Migrator tool (Hyper > RNG Migrator) to migrate UnityEngine.Random and System.Random to HyperRandom.",
603
+ priority = SettingPriority.Critical,
604
+ type = SettingType.HyperRandomUsage
605
+ };
606
+ CategorizeSettings(hyperRandomSetting, optimalSettings, recommendedSettings, outstandingSettings);
607
+
596
608
  // Note: Texture compression is platform-specific (Android/iOS) and not applicable to WebGL builds
597
609
  // WebGL handles texture compression at runtime via browser support
598
610
  // This setting is kept for reference but won't affect WebGL builds
@@ -746,6 +758,15 @@ namespace Hyper.Editor
746
758
  };
747
759
  CategorizeSettings(buildTargetSetting, optimal, recommended, outstanding);
748
760
 
761
+ var hyperRandomSetting = new SettingInfo
762
+ {
763
+ name = "HyperRandom Usage",
764
+ isOptimal = status.hyperRandomUsed,
765
+ priority = SettingPriority.Critical,
766
+ type = SettingType.HyperRandomUsage
767
+ };
768
+ CategorizeSettings(hyperRandomSetting, optimal, recommended, outstanding);
769
+
749
770
  // Note: Texture compression is platform-specific and not applicable to WebGL builds
750
771
  }
751
772
 
@@ -1085,6 +1106,12 @@ namespace Hyper.Editor
1085
1106
  // WebGL handles texture compression at runtime via browser support
1086
1107
  HyperDebug.LogWarning("Texture compression settings are not applicable to WebGL builds. WebGL handles texture compression automatically at runtime based on browser support.");
1087
1108
  break;
1109
+
1110
+ case SettingType.HyperRandomUsage:
1111
+ // Open the RNG Migrator tool to help developers migrate their Random usage
1112
+ HyperRandomMigrationTool.ShowMigrationTool();
1113
+ if (IsSDKDeveloper()) HyperDebug.Log("Opened RNG Migrator tool");
1114
+ break;
1088
1115
  }
1089
1116
 
1090
1117
  RepaintWindow();
@@ -2545,7 +2572,8 @@ namespace Hyper.Editor
2545
2572
  ShowSplashScreen,
2546
2573
  ColorSpace,
2547
2574
  TextureCompression,
2548
- BuildTargetPlatform
2575
+ BuildTargetPlatform,
2576
+ HyperRandomUsage
2549
2577
  }
2550
2578
 
2551
2579
  private class SettingInfo
@@ -2581,8 +2609,9 @@ namespace Hyper.Editor
2581
2609
  public TextureImporterFormat textureCompression;
2582
2610
  public bool showSplashScreen;
2583
2611
  public BuildTarget buildTarget;
2612
+ public bool hyperRandomUsed;
2584
2613
 
2585
- public int GetTotalSettings() => 17;
2614
+ public int GetTotalSettings() => 18;
2586
2615
 
2587
2616
  public int GetConfiguredSettings()
2588
2617
  {
@@ -2606,6 +2635,7 @@ namespace Hyper.Editor
2606
2635
  if (hyperLoaderAtIndex0) count++;
2607
2636
  if (colorSpace == ColorSpace.Gamma) count++;
2608
2637
  if (buildTarget == BuildTarget.WebGL) count++;
2638
+ if (hyperRandomUsed) count++;
2609
2639
 
2610
2640
  return count;
2611
2641
  }
@@ -2713,7 +2743,7 @@ namespace Hyper.Editor
2713
2743
  // Property may not exist in this Unity version
2714
2744
  }
2715
2745
 
2716
- // Check if HyperLoader is at build index 0
2746
+ // Check if HyperLoader is at build index 0 (must be from Assets/HyperSDK/, not Packages/)
2717
2747
  bool hyperLoaderAt0 = false;
2718
2748
  try
2719
2749
  {
@@ -2721,8 +2751,8 @@ namespace Hyper.Editor
2721
2751
  if (scenes != null && scenes.Length > 0 && scenes[0].enabled)
2722
2752
  {
2723
2753
  string firstScenePath = scenes[0].path;
2724
- hyperLoaderAt0 = firstScenePath.Contains("HyperLoader") ||
2725
- firstScenePath.EndsWith("HyperLoader.unity", System.StringComparison.OrdinalIgnoreCase);
2754
+ // Only accept the HyperLoader scene from Assets/HyperSDK/, not from Packages/
2755
+ hyperLoaderAt0 = string.Equals(firstScenePath, HyperConstants.HYPER_LOADER_SCENE_PATH, StringComparison.OrdinalIgnoreCase);
2726
2756
  }
2727
2757
  }
2728
2758
  catch (System.Exception)
@@ -2766,6 +2796,9 @@ namespace Hyper.Editor
2766
2796
  // Get active build target
2767
2797
  BuildTarget activeBuildTarget = EditorUserBuildSettings.activeBuildTarget;
2768
2798
 
2799
+ // Scan for HyperRandom usage in Assets folder (excluding HyperSDK)
2800
+ bool hyperRandomUsed = ScanForHyperRandomUsage();
2801
+
2769
2802
  return new WebGLSettingsStatus
2770
2803
  {
2771
2804
  compressionFormat = PlayerSettings.WebGL.compressionFormat,
@@ -2787,10 +2820,55 @@ namespace Hyper.Editor
2787
2820
  showSplashScreen = PlayerSettings.SplashScreen.show,
2788
2821
  colorSpace = currentColorSpace,
2789
2822
  textureCompression = defaultTexFormat,
2790
- buildTarget = activeBuildTarget
2823
+ buildTarget = activeBuildTarget,
2824
+ hyperRandomUsed = hyperRandomUsed
2791
2825
  };
2792
2826
  }
2793
2827
 
2828
+ /// <summary>
2829
+ /// Scans Assets folder for HyperRandom usage, excluding HyperSDK folder.
2830
+ /// Returns true if HyperRandom is used at least once in developer's code.
2831
+ /// </summary>
2832
+ private static bool ScanForHyperRandomUsage()
2833
+ {
2834
+ try
2835
+ {
2836
+ string assetsPath = Application.dataPath;
2837
+ if (!System.IO.Directory.Exists(assetsPath))
2838
+ return false;
2839
+
2840
+ string[] csFiles = System.IO.Directory.GetFiles(assetsPath, "*.cs", System.IO.SearchOption.AllDirectories);
2841
+
2842
+ foreach (string filePath in csFiles)
2843
+ {
2844
+ // Exclude HyperSDK folder
2845
+ string normalizedPath = filePath.Replace("\\", "/");
2846
+ if (normalizedPath.Contains("/HyperSDK/") || normalizedPath.Contains("Assets/HyperSDK"))
2847
+ continue;
2848
+
2849
+ // Exclude TextMesh Pro
2850
+ if (normalizedPath.Contains("/TextMesh Pro/") || normalizedPath.Contains("Assets/TextMesh Pro"))
2851
+ continue;
2852
+
2853
+ // Quick read to check for HyperRandom usage
2854
+ string content = System.IO.File.ReadAllText(filePath);
2855
+
2856
+ // Check for HyperRandom usage patterns
2857
+ if (System.Text.RegularExpressions.Regex.IsMatch(content, @"\bHyperRandom\b", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
2858
+ {
2859
+ return true;
2860
+ }
2861
+ }
2862
+ }
2863
+ catch (System.Exception ex)
2864
+ {
2865
+ // If scan fails, default to false (will show as needing attention)
2866
+ if (IsSDKDeveloper()) HyperDebug.LogWarning($"HyperRandom scan failed: {ex.Message}");
2867
+ }
2868
+
2869
+ return false;
2870
+ }
2871
+
2794
2872
  #endregion
2795
2873
 
2796
2874
  #region Build Asset Analysis
@@ -0,0 +1,44 @@
1
+ #if UNITY_EDITOR
2
+ using UnityEditor;
3
+ using UnityEditor.SceneManagement;
4
+ using UnityEngine;
5
+
6
+ namespace Hyper.Editor
7
+ {
8
+ /// <summary>
9
+ /// Menu items for opening HyperSDK scenes.
10
+ /// </summary>
11
+ static class HyperSceneMenu
12
+ {
13
+ private const string HYPERLOADER_SCENE_PATH = "Assets/HyperSDK/HyperLoader.unity";
14
+ private const string MENU_PATH = "Hyper/Open HyperLoader Scene";
15
+
16
+ [MenuItem(MENU_PATH, priority = 200)]
17
+ private static void OpenHyperLoaderScene()
18
+ {
19
+ var sceneAsset = AssetDatabase.LoadAssetAtPath<SceneAsset>(HYPERLOADER_SCENE_PATH);
20
+ if (sceneAsset == null)
21
+ {
22
+ EditorUtility.DisplayDialog(
23
+ "Scene Not Found",
24
+ $"HyperLoader scene not found at:\n{HYPERLOADER_SCENE_PATH}\n\nPlease ensure the scene exists in the project.",
25
+ "OK"
26
+ );
27
+ return;
28
+ }
29
+
30
+ if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
31
+ {
32
+ EditorSceneManager.OpenScene(HYPERLOADER_SCENE_PATH);
33
+ }
34
+ }
35
+
36
+ [MenuItem(MENU_PATH, validate = true)]
37
+ private static bool ValidateOpenHyperLoaderScene()
38
+ {
39
+ return !EditorApplication.isPlaying;
40
+ }
41
+ }
42
+ }
43
+ #endif
44
+
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 781094a40eb9a2d439ddee78020e5d9f
package/HyperLoader.unity CHANGED
@@ -304,7 +304,7 @@ RectTransform:
304
304
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
305
305
  m_AnchorMin: {x: 0, y: 1}
306
306
  m_AnchorMax: {x: 0, y: 1}
307
- m_AnchoredPosition: {x: 489.112, y: -280.1698}
307
+ m_AnchoredPosition: {x: 489.20746, y: -280.1698}
308
308
  m_SizeDelta: {x: 1044.9, y: 239.347}
309
309
  m_Pivot: {x: 0.5, y: 0.5}
310
310
  --- !u!114 &751153944
@@ -840,7 +840,7 @@ GameObject:
840
840
  m_Component:
841
841
  - component: {fileID: 1064166296}
842
842
  m_Layer: 0
843
- m_Name: __HyperSDK_BuildMarker_639020542296075009
843
+ m_Name: __HyperSDK_BuildMarker_639030030877789930
844
844
  m_TagString: Untagged
845
845
  m_Icon: {fileID: 0}
846
846
  m_NavMeshLayer: 0
@@ -1092,7 +1092,7 @@ RectTransform:
1092
1092
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
1093
1093
  m_AnchorMin: {x: 0, y: 1}
1094
1094
  m_AnchorMax: {x: 0, y: 1}
1095
- m_AnchoredPosition: {x: 489.112, y: -133.2274}
1095
+ m_AnchoredPosition: {x: 489.20746, y: -133.2274}
1096
1096
  m_SizeDelta: {x: 875, y: 54.5378}
1097
1097
  m_Pivot: {x: 0.5, y: 0.5}
1098
1098
  --- !u!1 &2874543288936963705