app.hypergames.hypersdk 1.11.0-beta.23 → 1.11.0-beta.25

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,17 @@
1
+ # [1.11.0-beta.25](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.24...v1.11.0-beta.25) (2026-09-04)
2
+
3
+
4
+ ### Features
5
+
6
+ * **replay:** include final score metadata ([463dcad](https://github.com/mvmhyper/hyper-sdk/commit/463dcadd4df5e5684f3be328b0ec361f25f26f2a))
7
+
8
+ # [1.11.0-beta.24](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.23...v1.11.0-beta.24) (2026-09-04)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **replay:** add 1.5x playback speed ([3f7875f](https://github.com/mvmhyper/hyper-sdk/commit/3f7875fcc4934ed01aaa521dce45327a177f67a6))
14
+
1
15
  # [1.11.0-beta.23](https://github.com/mvmhyper/hyper-sdk/compare/v1.11.0-beta.22...v1.11.0-beta.23) (2026-09-03)
2
16
 
3
17
 
@@ -448,7 +448,11 @@ namespace Hyper.Internal
448
448
  return false;
449
449
  }
450
450
 
451
- ReplaySessionState.SetMetadata(replay.PlayerName, replay.AvatarUrl, replay.Seed);
451
+ ReplaySessionState.SetMetadata(
452
+ replay.PlayerName,
453
+ replay.AvatarUrl,
454
+ replay.Seed,
455
+ replay.FinalScore);
452
456
  ReplaySessionState.SetReplayData(replay.ActivityNdjson);
453
457
  HyperDebug.Log($"Replay loaded from {path}");
454
458
  return true;
@@ -179,7 +179,8 @@ namespace Hyper.Internal.Managers
179
179
  ReplaySessionState.SetMetadata(
180
180
  replay.PlayerName,
181
181
  replay.AvatarUrl,
182
- replay.Seed);
182
+ replay.Seed,
183
+ replay.FinalScore);
183
184
  ReplaySessionState.SetReplayData(replay.ActivityNdjson);
184
185
  HyperDebug.Log($"Replay downloaded for entry {entryId}.");
185
186
  onSuccess?.Invoke();
@@ -289,9 +290,10 @@ namespace Hyper.Internal.Managers
289
290
  string seedLine = reader.ReadLine();
290
291
  string nameLine = reader.ReadLine();
291
292
  string avatarLine = reader.ReadLine();
293
+ string scoreLine = reader.ReadLine();
292
294
  string activities = reader.ReadToEnd();
293
295
 
294
- if (seedLine == null || nameLine == null || avatarLine == null)
296
+ if (seedLine == null || nameLine == null || avatarLine == null || scoreLine == null)
295
297
  {
296
298
  error = "The replay response is missing required metadata.";
297
299
  return false;
@@ -302,6 +304,7 @@ namespace Hyper.Internal.Managers
302
304
  JArray seedData = JArray.Parse(seedLine);
303
305
  JArray nameData = JArray.Parse(nameLine);
304
306
  JArray avatarData = JArray.Parse(avatarLine);
307
+ JArray scoreData = JArray.Parse(scoreLine);
305
308
 
306
309
  if (seedData.Count != 1 ||
307
310
  seedData[0].Type != JTokenType.Integer ||
@@ -327,6 +330,18 @@ namespace Hyper.Internal.Managers
327
330
  return false;
328
331
  }
329
332
 
333
+ if (scoreData.Count != 1 ||
334
+ scoreData[0].Type != JTokenType.Integer ||
335
+ !int.TryParse(
336
+ scoreData[0].ToString(),
337
+ NumberStyles.Integer,
338
+ CultureInfo.InvariantCulture,
339
+ out int finalScore))
340
+ {
341
+ error = "Replay metadata contains an invalid final score.";
342
+ return false;
343
+ }
344
+
330
345
  if (string.IsNullOrWhiteSpace(activities))
331
346
  {
332
347
  error = "The replay response contains no gameplay activities.";
@@ -337,6 +352,7 @@ namespace Hyper.Internal.Managers
337
352
  seed,
338
353
  nameData[0].Value<string>() ?? string.Empty,
339
354
  avatarData[0].Value<string>() ?? string.Empty,
355
+ finalScore,
340
356
  activities);
341
357
 
342
358
  return true;
@@ -354,13 +370,20 @@ namespace Hyper.Internal.Managers
354
370
  internal long Seed { get; }
355
371
  internal string PlayerName { get; }
356
372
  internal string AvatarUrl { get; }
373
+ internal int FinalScore { get; }
357
374
  internal string ActivityNdjson { get; }
358
375
 
359
- internal ReplayResponse(long seed, string playerName, string avatarUrl, string activityNdjson)
376
+ internal ReplayResponse(
377
+ long seed,
378
+ string playerName,
379
+ string avatarUrl,
380
+ int finalScore,
381
+ string activityNdjson)
360
382
  {
361
383
  Seed = seed;
362
384
  PlayerName = playerName;
363
385
  AvatarUrl = avatarUrl;
386
+ FinalScore = finalScore;
364
387
  ActivityNdjson = activityNdjson;
365
388
  }
366
389
  }
@@ -375,6 +375,7 @@ namespace Hyper.Internal.Managers
375
375
  new object[] { HyperRandom.CurrentSeed }));
376
376
  _editorReplay.AppendLine(JsonConvert.SerializeObject(new object[] { "hypergamer" }));
377
377
  _editorReplay.AppendLine(JsonConvert.SerializeObject(new object[] { string.Empty }));
378
+ _editorReplayMetadataLength = _editorReplay.Length;
378
379
  #endif
379
380
  _replayRecorder?.StartSession();
380
381
  }
@@ -426,6 +427,7 @@ namespace Hyper.Internal.Managers
426
427
 
427
428
  #if UNITY_EDITOR
428
429
  private readonly StringBuilder _editorReplay = new StringBuilder(4096);
430
+ private int _editorReplayMetadataLength;
429
431
 
430
432
  private void CaptureEditorReplayActivity(object[] activity)
431
433
  {
@@ -434,6 +436,8 @@ namespace Hyper.Internal.Managers
434
436
 
435
437
  private void SaveEditorReplay()
436
438
  {
439
+ string finalScoreLine = JsonConvert.SerializeObject(new object[] { CurrentScore }) + Environment.NewLine;
440
+ _editorReplay.Insert(_editorReplayMetadataLength, finalScoreLine);
437
441
  try
438
442
  {
439
443
  File.WriteAllText(ReplaySessionState.EditorReplayFilePath, _editorReplay.ToString());
@@ -443,6 +447,10 @@ namespace Hyper.Internal.Managers
443
447
  {
444
448
  HyperDebug.LogWarning($"Unable to save Editor replay: {exception.Message}");
445
449
  }
450
+ finally
451
+ {
452
+ _editorReplay.Remove(_editorReplayMetadataLength, finalScoreLine.Length);
453
+ }
446
454
  }
447
455
  #endif
448
456
 
@@ -14,6 +14,7 @@ namespace Hyper.Internal
14
14
  public static string AvatarUrl { get; private set; }
15
15
  public static string EntryId { get; private set; }
16
16
  public static string ReplayNdjson { get; private set; }
17
+ public static int? FinalScore { get; private set; }
17
18
  public static Texture2D AvatarTexture { get; private set; }
18
19
  public static bool HasReplayData => !string.IsNullOrWhiteSpace(ReplayNdjson);
19
20
  public static long OriginalRandomSeed { get; private set; }
@@ -48,6 +49,7 @@ namespace Hyper.Internal
48
49
  AvatarUrl = avatarUrl ?? string.Empty;
49
50
  EntryId = entryId ?? string.Empty;
50
51
  ReplayNdjson = string.Empty;
52
+ FinalScore = null;
51
53
  ReleaseAvatarTexture();
52
54
  OriginalRandomSeed = originalRandomSeed;
53
55
  Progress01 = 0f;
@@ -61,13 +63,18 @@ namespace Hyper.Internal
61
63
  GameplayStartProgress01 = 0f;
62
64
  }
63
65
 
64
- public static void SetMetadata(string playerName, string avatarUrl, long originalRandomSeed)
66
+ public static void SetMetadata(
67
+ string playerName,
68
+ string avatarUrl,
69
+ long originalRandomSeed,
70
+ int finalScore)
65
71
  {
66
72
  if (!IsActive) return;
67
73
 
68
74
  PlayerName = playerName ?? string.Empty;
69
75
  AvatarUrl = avatarUrl ?? string.Empty;
70
76
  OriginalRandomSeed = originalRandomSeed;
77
+ FinalScore = finalScore;
71
78
  }
72
79
 
73
80
  public static void SetReplayData(string ndjson)
@@ -193,6 +200,7 @@ namespace Hyper.Internal
193
200
  AvatarUrl = string.Empty;
194
201
  EntryId = string.Empty;
195
202
  ReplayNdjson = string.Empty;
203
+ FinalScore = null;
196
204
  ReleaseAvatarTexture();
197
205
  OriginalRandomSeed = 0;
198
206
  Progress01 = 0f;
@@ -19,7 +19,7 @@ namespace Hyper.Internal
19
19
  [SerializeField] private Button pauseButton;
20
20
  [SerializeField] private Button playbackSpeedButton;
21
21
  [SerializeField] private TextMeshProUGUI playbackSpeedLabel;
22
- [SerializeField] private float[] playbackSpeeds = { 1f, 1.25f, 1.75f, 2f, 0.5f };
22
+ [SerializeField] private float[] playbackSpeeds = { 1f, 1.25f, 1.5f, 1.75f, 2f, 0.5f };
23
23
  [SerializeField, Min(1f)] private float seekPlaybackSpeed = 10f;
24
24
  [SerializeField, Min(0f)] private float readOnlyProgressSmoothTime = 0.08f;
25
25
  [SerializeField, Range(0.25f, 1f)] private float seekSnapshotScale = 0.55f;
@@ -1,3 +1,4 @@
1
+ using System.Globalization;
1
2
  using TMPro;
2
3
  using UnityEngine;
3
4
  using UnityEngine.UI;
@@ -38,7 +39,7 @@ namespace Hyper.Internal
38
39
 
39
40
  if (scoreValue != null)
40
41
  {
41
- scoreValue.text = (HyperRuntime.DataManager?.CurrentScore ?? 0).ToString("N0");
42
+ scoreValue.text = FormatFinalScore(ReplaySessionState.FinalScore);
42
43
  }
43
44
 
44
45
  if (scoreOwnerName != null)
@@ -99,6 +100,13 @@ namespace Hyper.Internal
99
100
  : $"@{normalizedName.ToUpperInvariant()}'S SCORE";
100
101
  }
101
102
 
103
+ internal static string FormatFinalScore(int? finalScore)
104
+ {
105
+ return finalScore.HasValue
106
+ ? finalScore.Value.ToString("N0", CultureInfo.InvariantCulture)
107
+ : "--";
108
+ }
109
+
102
110
  private void UpdateSoundPresentation()
103
111
  {
104
112
  bool isSoundOn = HyperRuntime.DataManager == null || HyperRuntime.DataManager.GetSound() == 1;
@@ -351,6 +351,7 @@ MonoBehaviour:
351
351
  playbackSpeeds:
352
352
  - 1
353
353
  - 1.25
354
+ - 1.5
354
355
  - 1.75
355
356
  - 2
356
357
  - 0.5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "app.hypergames.hypersdk",
3
- "version": "1.11.0-beta.23",
3
+ "version": "1.11.0-beta.25",
4
4
  "displayName": "HyperSDK",
5
5
  "description": "Official Unity SDK for Hyper: multiplayer battles, leaderboards, deterministic RNG, session management, tutorials, and WebGL optimizations for production-ready games.",
6
6
  "unity": "6000.0",