diff --git a/.editorconfig b/.editorconfig index a87e5e0651..fa740a7511 100644 --- a/.editorconfig +++ b/.editorconfig @@ -351,7 +351,7 @@ resharper_csharp_qualified_using_at_nested_scope = false resharper_csharp_prefer_qualified_reference = false resharper_csharp_allow_alias = false -[*.{csproj,xml,yml,yaml,dll.config,msbuildproj,targets,props}] +[*.{csproj,xml,yml,yaml,dll.config,msbuildproj,targets,props,slnx}] indent_size = 2 [nuget.config] diff --git a/.github/workflows/build-docfx.yml b/.github/workflows/build-docfx.yml index 1f010b7291..dee31e9b31 100644 --- a/.github/workflows/build-docfx.yml +++ b/.github/workflows/build-docfx.yml @@ -21,7 +21,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v4.1.0 with: - dotnet-version: 9.0.x + dotnet-version: 10.0.x - name: Install dependencies run: dotnet restore diff --git a/.github/workflows/build-map-renderer.yml b/.github/workflows/build-map-renderer.yml index e3971024d6..04891d378f 100644 --- a/.github/workflows/build-map-renderer.yml +++ b/.github/workflows/build-map-renderer.yml @@ -36,7 +36,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v4.1.0 with: - dotnet-version: 9.0.x + dotnet-version: 10.0.x - name: Install dependencies run: dotnet restore diff --git a/.github/workflows/build-test-debug.yml b/.github/workflows/build-test-debug.yml index decc74d255..961145ecb8 100644 --- a/.github/workflows/build-test-debug.yml +++ b/.github/workflows/build-test-debug.yml @@ -36,7 +36,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v4.1.0 with: - dotnet-version: 9.0.x + dotnet-version: 10.0.x - name: Install dependencies run: dotnet restore diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5dfa0358f7..3418834a81 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -23,7 +23,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v4.1.0 with: - dotnet-version: 9.0.x + dotnet-version: 10.0.x - name: Get Engine Tag run: | diff --git a/.github/workflows/test-packaging.yml b/.github/workflows/test-packaging.yml index 38a6dcd6ed..490e31f735 100644 --- a/.github/workflows/test-packaging.yml +++ b/.github/workflows/test-packaging.yml @@ -51,7 +51,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v4.1.0 with: - dotnet-version: 9.0.x + dotnet-version: 10.0.x - name: Install dependencies run: dotnet restore diff --git a/.github/workflows/yaml-linter.yml b/.github/workflows/yaml-linter.yml index d7ad9b073d..ca925f4791 100644 --- a/.github/workflows/yaml-linter.yml +++ b/.github/workflows/yaml-linter.yml @@ -26,7 +26,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v4.1.0 with: - dotnet-version: 9.0.x + dotnet-version: 10.0.x - name: Install dependencies run: dotnet restore - name: Build diff --git a/.gitignore b/.gitignore index 0cd376f5dc..b033e538d0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# MSbuild binlog files +*.binlog + ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. diff --git a/BuildChecker/git_helper.py b/BuildChecker/git_helper.py index 53526ee442..733b8b1c21 100644 --- a/BuildChecker/git_helper.py +++ b/BuildChecker/git_helper.py @@ -11,7 +11,7 @@ import time from pathlib import Path from typing import List -SOLUTION_PATH = Path("..") / "SpaceStation14.sln" +SOLUTION_PATH = Path("..") / "SpaceStation14.slnx" # If this doesn't match the saved version we overwrite them all. CURRENT_HOOKS_VERSION = "4" QUIET = len(sys.argv) == 2 and sys.argv[1] == "--quiet" diff --git a/Content.Benchmarks/Content.Benchmarks.csproj b/Content.Benchmarks/Content.Benchmarks.csproj index c3b60a1c69..8d4dfa31bd 100644 --- a/Content.Benchmarks/Content.Benchmarks.csproj +++ b/Content.Benchmarks/Content.Benchmarks.csproj @@ -1,17 +1,20 @@  - - $(TargetFramework) ..\bin\Content.Benchmarks\ - false false Exe true - 12 + false + disable + + + + + @@ -19,10 +22,12 @@ - - - - - + + + + + + + diff --git a/Content.Benchmarks/DestructibleBenchmark.cs b/Content.Benchmarks/DestructibleBenchmark.cs index 1b54bacca0..aa759c35fc 100644 --- a/Content.Benchmarks/DestructibleBenchmark.cs +++ b/Content.Benchmarks/DestructibleBenchmark.cs @@ -51,6 +51,8 @@ public class DestructibleBenchmark private readonly List> _damageables = new(); private readonly List> _destructbiles = new(); + private TestMapData _currentMapData = default!; + private DamageSpecifier _damage; private TestPair _pair = default!; @@ -70,8 +72,6 @@ public class DestructibleBenchmark _pair = await PoolManager.GetServerClient(); var server = _pair.Server; - var mapdata = await _pair.CreateTestMap(); - _entMan = server.ResolveDependency(); _protoMan = server.ResolveDependency(); _random = server.ResolveDependency(); @@ -86,19 +86,25 @@ public class DestructibleBenchmark _damage = new DamageSpecifier(type, DamageAmount); _random.SetSeed(69420); // Randomness needs to be deterministic for benchmarking. + } + [IterationSetup] + public void IterationSetup() + { var plating = _tileDefMan[TileRef].TileId; + var server = _pair.Server; + _currentMapData = _pair.CreateTestMap().GetAwaiter().GetResult(); // We make a rectangular grid of destructible entities, and then damage them all simultaneously to stress test the system. // Needed for managing the performance of destructive effects and damage application. - await server.WaitPost(() => + server.WaitPost(() => { // Set up a thin line of tiles to place our objects on. They should be anchored for a "realistic" scenario... for (var x = 0; x < EntityCount; x++) { for (var y = 0; y < _prototypes.Length; y++) { - _map.SetTile(mapdata.Grid, mapdata.Grid, new Vector2i(x, y), new Tile(plating)); + _map.SetTile(_currentMapData.Grid, _currentMapData.Grid, new Vector2i(x, y), new Tile(plating)); } } @@ -107,7 +113,7 @@ public class DestructibleBenchmark var y = 0; foreach (var protoId in _prototypes) { - var coords = new EntityCoordinates(mapdata.Grid, x + 0.5f, y + 0.5f); + var coords = new EntityCoordinates(_currentMapData.Grid, x + 0.5f, y + 0.5f); _entMan.SpawnEntity(protoId, coords); y++; } @@ -115,12 +121,17 @@ public class DestructibleBenchmark var query = _entMan.EntityQueryEnumerator(); + _destructbiles.EnsureCapacity(EntityCount); + _damageables.EnsureCapacity(EntityCount); + while (query.MoveNext(out var uid, out var damageable, out var destructible)) { _damageables.Add((uid, damageable)); _destructbiles.Add((uid, damageable, destructible)); } - }); + }) + .GetAwaiter() + .GetResult(); } [Benchmark] @@ -150,6 +161,26 @@ public class DestructibleBenchmark }); } + [IterationCleanup] + public void IterationCleanupAsync() + { + // We need to nuke the entire map and respawn everything as some destructible effects + // spawn entities and whatnot. + _pair.Server.WaitPost(() => + { + _map.QueueDeleteMap(_currentMapData.MapId); + }) + .Wait(); + + // Deletion of entities is often queued (QueueDel) which must be processed by running ticks + // or else it will grow infinitely and leak memory. + _pair.Server.WaitRunTicks(2) + .GetAwaiter() + .GetResult(); + + _destructbiles.Clear(); + _damageables.Clear(); + } [GlobalCleanup] public async Task CleanupAsync() diff --git a/Content.Benchmarks/HeatCapacityBenchmark.cs b/Content.Benchmarks/HeatCapacityBenchmark.cs new file mode 100644 index 0000000000..cef5bc10c7 --- /dev/null +++ b/Content.Benchmarks/HeatCapacityBenchmark.cs @@ -0,0 +1,83 @@ +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using Content.IntegrationTests; +using Content.IntegrationTests.Pair; +using Content.Server.Atmos.EntitySystems; +using Content.Shared.Atmos; +using Robust.Shared; +using Robust.Shared.Analyzers; +using Robust.Shared.GameObjects; + +namespace Content.Benchmarks; + +[Virtual] +[GcServer(true)] +[MemoryDiagnoser] +public class HeatCapacityBenchmark +{ + private TestPair _pair = default!; + private IEntityManager _sEntMan = default!; + private IEntityManager _cEntMan = default!; + private Client.Atmos.EntitySystems.AtmosphereSystem _cAtmos = default!; + private AtmosphereSystem _sAtmos = default!; + private GasMixture _mix; + + [GlobalSetup] + public async Task SetupAsync() + { + ProgramShared.PathOffset = "../../../../"; + PoolManager.Startup(); + _pair = await PoolManager.GetServerClient(); + await _pair.Connect(); + _cEntMan = _pair.Client.ResolveDependency(); + _sEntMan = _pair.Server.ResolveDependency(); + _cAtmos = _cEntMan.System(); + _sAtmos = _sEntMan.System(); + + const float volume = 2500f; + const float temperature = 293.15f; + + const float o2 = 12.3f; + const float n2 = 45.6f; + const float co2 = 0.42f; + const float plasma = 0.05f; + + _mix = new GasMixture(volume) { Temperature = temperature }; + + _mix.AdjustMoles(Gas.Oxygen, o2); + _mix.AdjustMoles(Gas.Nitrogen, n2); + _mix.AdjustMoles(Gas.CarbonDioxide, co2); + _mix.AdjustMoles(Gas.Plasma, plasma); + } + + [Benchmark] + public async Task ClientHeatCapacityBenchmark() + { + await _pair.Client.WaitPost(delegate + { + for (var i = 0; i < 10000; i++) + { + _cAtmos.GetHeatCapacity(_mix, applyScaling: true); + } + }); + } + + [Benchmark] + public async Task ServerHeatCapacityBenchmark() + { + await _pair.Server.WaitPost(delegate + { + for (var i = 0; i < 10000; i++) + { + _sAtmos.GetHeatCapacity(_mix, applyScaling: true); + } + }); + } + + [GlobalCleanup] + public async Task CleanupAsync() + { + await _pair.DisposeAsync(); + PoolManager.Shutdown(); + } +} diff --git a/Content.Benchmarks/MapLoadBenchmark.cs b/Content.Benchmarks/MapLoadBenchmark.cs index 126ac99774..d43b7d7d19 100644 --- a/Content.Benchmarks/MapLoadBenchmark.cs +++ b/Content.Benchmarks/MapLoadBenchmark.cs @@ -5,7 +5,7 @@ using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using Content.IntegrationTests; using Content.IntegrationTests.Pair; -using Content.Server.Maps; +using Content.Shared.Maps; using Robust.Shared; using Robust.Shared.Analyzers; using Robust.Shared.EntitySerialization.Systems; diff --git a/Content.Client/Access/UI/AccessLevelControl.xaml b/Content.Client/Access/UI/AccessLevelControl.xaml index 56968d8983..6a3155effa 100644 --- a/Content.Client/Access/UI/AccessLevelControl.xaml +++ b/Content.Client/Access/UI/AccessLevelControl.xaml @@ -1,4 +1,4 @@ diff --git a/Content.Client/Access/UI/AccessOverriderWindow.xaml b/Content.Client/Access/UI/AccessOverriderWindow.xaml index ae482140bc..545ebec494 100644 --- a/Content.Client/Access/UI/AccessOverriderWindow.xaml +++ b/Content.Client/Access/UI/AccessOverriderWindow.xaml @@ -2,7 +2,7 @@ MinSize="650 290"> - +