Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial saving fix for Godot 4 and swapped randoms to xoshiro #4959

Merged
merged 12 commits into from Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions LICENSE.txt
Expand Up @@ -44,6 +44,8 @@ System.Numerics.Vectors: MIT License Copyright (c) .NET Foundation and Contribut

SharpZipLib: MIT License Copyright © 2000-2018 SharpZipLib Contributors

XoshiroPRNG.Net: Released into the public domain by Pandu POLUAN

Nito.Collections.Deque: MIT License Copyright (c) 2015 Stephen Cleary

FastNoiseLite: MIT License Copyright(c) 2020 Jordan Peck (jordan.me2@gmail.com),
Expand Down
1 change: 1 addition & 0 deletions Thrive.csproj
Expand Up @@ -40,6 +40,7 @@
<PackageReference Include="SharpZipLib" Version="1.3.3" />
<PackageReference Include="Nito.Collections.Deque" Version="1.2.1" />
<PackageReference Include="Lib.Harmony" Version="2.3.1.1" />
<PackageReference Include="XoshiroPRNG.Net" Version="1.6.0" />
<PackageReference Include="YamlDotNet" Version="15.1.2" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0" PrivateAssets="all" />
Expand Down
3 changes: 2 additions & 1 deletion Thrive.sln.DotSettings
Expand Up @@ -807,4 +807,5 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=vseparation/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Weblate/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Wigglyness/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=writability/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/UserDictionary/Words/=writability/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=xoshiro/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
7 changes: 7 additions & 0 deletions doc/style_guide.md
Expand Up @@ -261,6 +261,13 @@ Code style rules

- `uint` type should not be used without a very good reason.

- `System.Random` should be avoided as its state cannot be
saved. Instead use the random number types in the `Xoshiro`
namespace (check the documentation on the types for which generators
are suitable for what kinds of numeric types). General advice is to
use 128-bit generators for 32-bit types (`int`, `float`) and 256-bit
generators for 64-bit types (`long`, `double`).

- Unrelated uses should not share the same variable. Instead they
should locally define their own variable instance.

Expand Down
4 changes: 3 additions & 1 deletion src/auto-evo/AutoEvoRun.cs
Expand Up @@ -6,6 +6,7 @@
using System.Threading.Tasks;
using AutoEvo;
using Godot;
using Xoshiro.PRNG64;
using Thread = System.Threading.Thread;

/// <summary>
Expand Down Expand Up @@ -369,7 +370,8 @@ public LocalizedStringBuilder MakeSummaryOfExternalEffects()
/// </summary>
protected virtual void GatherInfo(Queue<IRunStep> steps)
{
var random = new Random();
// TODO: allow passing in a seed
var random = new XoShiRo256starstar();

var alreadyHandledSpecies = new HashSet<Species>();

Expand Down
3 changes: 2 additions & 1 deletion src/auto-evo/simulation/PopulationSimulation.cs
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using Godot;
using Xoshiro.PRNG64;

/// <summary>
/// Main class for the population simulation part.
Expand All @@ -27,7 +28,7 @@ public static class PopulationSimulation
// to IRunStep.RunStep might not be worth the effort at all
var cache = existingCache ?? new SimulationCache(parameters.WorldSettings);

var random = new Random(randomSource.Next());
var random = new XoShiRo256starstar(randomSource.NextInt64());

var speciesToSimulate = CopyInitialPopulationsToResults(parameters);

Expand Down
6 changes: 4 additions & 2 deletions src/auto-evo/steps/CalculatePopulation.cs
@@ -1,7 +1,7 @@
namespace AutoEvo;

using System;
using System.Collections.Generic;
using Xoshiro.PRNG64;

/// <summary>
/// Step that calculate the populations for all species
Expand Down Expand Up @@ -50,7 +50,9 @@ public bool RunStep(RunResults results)

// Directly feed the population results to the main results object

PopulationSimulation.Simulate(config, null, new Random());
// TODO: allow passing in a random seed

PopulationSimulation.Simulate(config, null, new XoShiRo256starstar());

return true;
}
Expand Down
3 changes: 2 additions & 1 deletion src/auto-evo/steps/FindBestMigration.cs
Expand Up @@ -2,6 +2,7 @@

using System;
using System.Linq;
using Xoshiro.PRNG64;

/// <summary>
/// Step that finds the best migration for a single species
Expand All @@ -23,7 +24,7 @@ public class FindBestMigration : VariantTryingStep
this.worldSettings = worldSettings;
this.map = map;
this.species = species;
this.random = new Random(random.Next());
this.random = new XoShiRo256starstar(random.NextInt64());
cache = new SimulationCache(worldSettings);
}

Expand Down
3 changes: 2 additions & 1 deletion src/auto-evo/steps/FindBestMutation.cs
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Xoshiro.PRNG64;

/// <summary>
/// Step that finds the best mutation for a single species
Expand Down Expand Up @@ -32,7 +33,7 @@ public class FindBestMutation : VariantTryingStep
this.worldSettings = worldSettings;
this.map = map;
this.species = species;
this.random = new Random(random.Next());
this.random = new XoShiRo256starstar(random.NextInt64());
this.splitThresholdFraction = splitThresholdFraction;
this.splitThresholdAmount = splitThresholdAmount;
cache = new SimulationCache(worldSettings);
Expand Down
3 changes: 2 additions & 1 deletion src/auto-evo/steps/IncreaseBiodiversity.cs
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Xoshiro.PRNG64;

/// <summary>
/// Attempts to increase the biodiversity of a patch by force-splitting an existing species there or creating a
Expand Down Expand Up @@ -32,7 +33,7 @@ public class IncreaseBiodiversity : IRunStep
this.map = map;
this.patch = patch;
this.configuration = configuration;
this.random = new Random(random.Next());
this.random = new XoShiRo256starstar(random.NextInt64());
cache = new SimulationCache(worldSettings);
}

Expand Down
5 changes: 3 additions & 2 deletions src/benchmark/microbe/MicrobeBenchmark.cs
Expand Up @@ -6,6 +6,7 @@
using Components;
using DefaultEcs;
using Godot;
using Xoshiro.PRNG64;

/// <summary>
/// Benchmarking tool for the microbe stage. Used for checking performance impact of changes or for players to see
Expand Down Expand Up @@ -125,7 +126,7 @@ public partial class MicrobeBenchmark : Node

private EntitySet? microbeEntities;

private Random random = new(RANDOM_SEED);
private XoShiRo256starstar random = new(RANDOM_SEED);

private int aiGroup1Seed;
private int aiGroup2Seed;
Expand Down Expand Up @@ -439,7 +440,7 @@ protected override void Dispose(bool disposing)
private void StartBenchmark()
{
internalPhaseCounter = 0;
random = new Random(RANDOM_SEED);
random = new XoShiRo256starstar(RANDOM_SEED);

microbeStationaryResult = 0;
microbeAIResult = 0;
Expand Down
7 changes: 0 additions & 7 deletions src/engine/DebugOverlays.PerformanceMetrics.cs
Expand Up @@ -114,13 +114,6 @@ private void UpdateMetrics(double delta)
Constants.MEBIBYTE, 1);
var mibFormat = Localization.Translate("MIB_VALUE");

// These don't seem to work:
// Performance.GetMonitor(Performance.Monitor.Physics3dActiveObjects),
// Performance.GetMonitor(Performance.Monitor.Physics3dCollisionPairs),
// Performance.GetMonitor(Performance.Monitor.Physics3dIslandCount),

// TODO: check if memory use can finally be gotten on Windows

metricsText.Text =
new LocalizedString("METRICS_CONTENT", Performance.GetMonitor(Performance.Monitor.TimeProcess),
Performance.GetMonitor(Performance.Monitor.TimePhysicsProcess),
Expand Down
39 changes: 26 additions & 13 deletions src/engine/FeatureInformation.cs
Expand Up @@ -7,27 +7,45 @@
/// </summary>
public static class FeatureInformation
{
public const string PlatformWindows = "Windows";
public const string PlatformLinux = "Linux";
public const string PlatformMac = "OSX";
private const string PlatformWindows = "windows";
private const string PlatformLinux = "linux";

// TODO: check that this is correct for Godot 4
private const string PlatformMac = "osx";

private static readonly Lazy<OS.RenderingDriver> CachedDriver = new(DetectRenderer);

private static readonly Lazy<string> ResolvedOS = new(GetOSHelper);

private static readonly string[] SimpleFeaturePlatforms =
{
"Android",
"HTML5",
PlatformLinux,
PlatformWindows,
PlatformMac,

// TODO: check that these are correct for Godot 4
"android",
"html5",
"iOS",
};

public static string GetOS()
{
// TODO: fix this for Godot 4
if (OS.HasFeature("X11"))
return PlatformLinux;
return ResolvedOS.Value;
}

public static OS.RenderingDriver GetVideoDriver()
{
return CachedDriver.Value;
}

public static bool IsLinux()
{
return GetOS() == PlatformLinux;
}

private static string GetOSHelper()
{
foreach (var feature in SimpleFeaturePlatforms)
{
if (OS.HasFeature(feature))
Expand All @@ -38,11 +56,6 @@ public static string GetOS()
return "unknown";
}

public static OS.RenderingDriver GetVideoDriver()
{
return CachedDriver.Value;
}

private static OS.RenderingDriver DetectRenderer()
{
// TODO: switch to a proper approach when Godot adds support for reading this
Expand Down
6 changes: 5 additions & 1 deletion src/engine/LocalizedStringBuilder.cs
Expand Up @@ -19,8 +19,12 @@
[JSONDynamicTypeAllowed]
public class LocalizedStringBuilder : IFormattable
{
/// <summary>
/// Things to format into this builder. This is no longer <see cref="IFormattable"/> as string would throw an
/// error on JSON load.
/// </summary>
[JsonProperty]
private readonly List<IFormattable> items = new();
private readonly List<object> items = new();

private readonly StringBuilder stringBuilder;
private string formatString = string.Empty;
Expand Down
2 changes: 1 addition & 1 deletion src/engine/StartupActions.cs
Expand Up @@ -128,7 +128,7 @@ private StartupActions()
GD.PrintErr("Please do not report to us the next unhandled exception error about this, unless " +
"this is an official Thrive release that has this issue");

if (FeatureInformation.GetOS() == FeatureInformation.PlatformLinux)
if (FeatureInformation.IsLinux())
{
GD.PrintErr("On Linux please verify you have new enough GLIBC version as otherwise the library " +
"is unloadable. Updating your distro to the latest version should resolve the issue as long " +
Expand Down
14 changes: 12 additions & 2 deletions src/general/GameWorld.cs
Expand Up @@ -4,6 +4,7 @@
using AutoEvo;
using Godot;
using Newtonsoft.Json;
using Xoshiro.PRNG64;

/// <summary>
/// All data regarding the game world of a thrive playthrough
Expand Down Expand Up @@ -252,9 +253,18 @@ public MicrobeSpecies CreatePlayerSpecies()
/// <summary>
/// Generates a few random species in all patches
/// </summary>
public void GenerateRandomSpeciesForFreeBuild()
public void GenerateRandomSpeciesForFreeBuild(long seed = 0)
{
var random = new Random();
Random random;

if (seed == 0)
{
random = new XoShiRo256starstar();
}
else
{
random = new XoShiRo256starstar(seed);
}

var workMemory1 = new List<Hex>();
var workMemory2 = new List<Hex>();
Expand Down
7 changes: 3 additions & 4 deletions src/general/HelpScreen.cs
@@ -1,5 +1,6 @@
using System;
using Godot;
using Xoshiro.PRNG32;

/// <summary>
/// Manages the help screen GUI
Expand Down Expand Up @@ -29,14 +30,14 @@ public partial class HelpScreen : Control
[Export]
public PackedScene HelpBoxScene = null!;

private readonly Random random = new XoShiRo128starstar();

private VBoxContainer leftColumn = null!;
private VBoxContainer rightColumn = null!;
private Label tipMessageLabel = null!;
private Timer timer = null!;
#pragma warning restore CA2213

private Random random = null!;

[Signal]
public delegate void HelpScreenClosedEventHandler();

Expand All @@ -47,8 +48,6 @@ public override void _Ready()
tipMessageLabel = GetNode<Label>(TipMessageLabelPath);
timer = GetNode<Timer>(TimerPath);

random = new Random();

if (!string.IsNullOrEmpty(Category))
{
BuildHelpTexts(Category);
Expand Down
3 changes: 2 additions & 1 deletion src/general/Jukebox.cs
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using Godot;
using Xoshiro.PRNG32;

/// <summary>
/// Manages playing music. Autoload singleton
Expand Down Expand Up @@ -563,7 +564,7 @@ private void PlayNextTrackFromList(TrackList list, Func<int, AudioPlayer> getPla
}
else
{
var random = new Random();
var random = new XoShiRo128starstar();
int nextIndex;

if (mode == TrackList.Order.Random)
Expand Down
3 changes: 2 additions & 1 deletion src/general/MainMenu.cs
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using Godot;
using Godot.Collections;
using Xoshiro.PRNG32;

/// <summary>
/// Class managing the main menu and everything in it
Expand Down Expand Up @@ -535,7 +536,7 @@ private void RunMenuSetup()
/// </summary>
private void RandomizeBackground()
{
var random = new Random();
var random = new XoShiRo128starstar();

// Some of the 3D backgrounds render very incorrectly in GLES2 so they are disabled
// TODO: check if the 3D backgrounds look now fine in opengl mode
Expand Down