diff --git a/.editorconfig b/.editorconfig
index 5c773a289e..93badf243a 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -63,7 +63,7 @@ dotnet_diagnostic.IDE0044.severity = warning
# IDE0062 Make local function static
#csharp_prefer_static_local_function = true
-dotnet_diagnostic.IDE0062.severity = silent # Requires C# 8
+dotnet_diagnostic.IDE0062.severity = silent # Requires C# 8 - TODO Consider enabling
# IDE0064 Make struct fields writable
# No options
@@ -137,15 +137,15 @@ dotnet_diagnostic.IDE0050.severity = silent
# IDE0054/IDE0074 Use compound assignment/Use coalesce compound assignment
#dotnet_style_prefer_compound_assignment = true
dotnet_diagnostic.IDE0054.severity = warning
-dotnet_diagnostic.IDE0074.severity = silent # Requires C# 8
+dotnet_diagnostic.IDE0074.severity = silent # Requires C# 8 - TODO Consider enabling
# IDE0056 Use index operator
#csharp_style_prefer_index_operator = true
-dotnet_diagnostic.IDE0056.severity = silent # Requires C# 8
+dotnet_diagnostic.IDE0056.severity = silent # Requires C# 8 - TODO Consider enabling
# IDE0057 Use range operator
#csharp_style_prefer_range_operator = true
-dotnet_diagnostic.IDE0057.severity = silent # Requires C# 8
+dotnet_diagnostic.IDE0057.severity = silent # Requires C# 8 - TODO Consider enabling
# IDE0070 Use 'System.HashCode.Combine'
# No options
@@ -169,7 +169,7 @@ dotnet_diagnostic.IDE0082.severity = warning
# IDE0090 Simplify 'new' expression
#csharp_style_implicit_object_creation_when_type_is_apparent = true
-dotnet_diagnostic.IDE0090.severity = silent # Requires C# 9
+dotnet_diagnostic.IDE0090.severity = silent # Requires C# 9 - TODO Consider enabling
# IDE0180 Use tuple to swap values
#csharp_style_prefer_tuple_swap = true
@@ -204,7 +204,7 @@ dotnet_diagnostic.IDE0041.severity = warning
# IDE0150 Prefer 'null' check over type check
#csharp_style_prefer_null_check_over_type_check = true
-dotnet_diagnostic.IDE0150.severity = silent # Requires C# 9
+dotnet_diagnostic.IDE0150.severity = silent # Requires C# 9 - TODO Consider enabling
# IDE1005 Use conditional delegate call
csharp_style_conditional_delegate_call = true # true is the default, but the rule is not triggered if this is not specified.
@@ -272,11 +272,11 @@ dotnet_diagnostic.IDE0066.severity = silent
# IDE0078 Use pattern matching
#csharp_style_prefer_pattern_matching = true
-dotnet_diagnostic.IDE0078.severity = silent # Requires C# 9
+dotnet_diagnostic.IDE0078.severity = silent # Requires C# 9 - TODO Consider enabling
# IDE0083 Use pattern matching ('not' operator)
#csharp_style_prefer_not_pattern = true
-dotnet_diagnostic.IDE0083.severity = silent # Requires C# 9
+dotnet_diagnostic.IDE0083.severity = silent # Requires C# 9 - TODO Consider enabling
# IDE0170 Simplify property pattern
#csharp_style_prefer_extended_property_pattern = true
@@ -291,7 +291,7 @@ dotnet_diagnostic.IDE0011.severity = none
# IDE0063 Use simple 'using' statement
#csharp_prefer_simple_using_statement = true
-dotnet_diagnostic.IDE0063.severity = silent # Requires C# 8
+dotnet_diagnostic.IDE0063.severity = silent # Requires C# 8 - TODO Consider enabling
## 'using' directive preferences
@@ -375,7 +375,7 @@ dotnet_diagnostic.IDE0100.severity = warning
# IDE0110 Remove unnecessary discard
# No options
-dotnet_diagnostic.IDE0110.severity = silent # Requires C# 9
+dotnet_diagnostic.IDE0110.severity = silent # Requires C# 9 - TODO Consider enabling
### Miscellaneous Rules
### https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/miscellaneous-rules
@@ -598,6 +598,11 @@ dotnet_diagnostic.SA1633.severity = none # FileMustHaveHeader
dotnet_diagnostic.SA1642.severity = none # ConstructorSummaryDocumentationShouldBeginWithStandardText
dotnet_diagnostic.SA1649.severity = none # FileNameMustMatchTypeName
+# Requires C# 8/9 - TODO Consider enabling
+dotnet_diagnostic.SA1141.severity = none # UseTupleSyntax
+dotnet_diagnostic.SA1316.severity = none # TupleElementNamesShouldUseCorrectCasing
+dotnet_diagnostic.SA1414.severity = none # TupleTypesInSignaturesShouldHaveElementNames
+
#### Code Quality Rules
#### https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/
@@ -615,8 +620,8 @@ dotnet_diagnostic.CA1827.severity = warning
# Use Length/Count property instead of Enumerable.Count method.
dotnet_diagnostic.CA1829.severity = warning
-# Use span-based 'string.Concat' (incompatible with mono builds).
-dotnet_diagnostic.CA1845.severity = none
+# Use span-based 'string.Concat'.
+dotnet_diagnostic.CA1845.severity = silent # TODO Consider enabling
# Use string.Contains(char) instead of string.Contains(string) with single characters.
dotnet_diagnostic.CA1847.severity = warning
diff --git a/Directory.Build.props b/Directory.Build.props
index a2a2f1960f..47a24e1897 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -5,7 +5,7 @@
true
true
true
- 7.3
+ 9
true
..
$(EngineRootPath)/bin
@@ -51,7 +51,6 @@
-
-
+
diff --git a/INSTALL.md b/INSTALL.md
index 722ddabe8a..3c2315e056 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -17,7 +17,7 @@ Run the game with `launch-game.cmd`. It can be handed arguments that specify the
Linux
=====
-.NET 6 or Mono (version 6.4 or later) is required to compile OpenRA. We recommend using .NET 6 when possible, as Mono is poorly packaged by most Linux distributions (e.g. missing the required `msbuild` toolchain), and has been deprecated as a standalone project.
+.NET 6 or Mono (version 6.12 or later) is required to compile OpenRA. We recommend using .NET 6 when possible, as Mono is poorly packaged by most Linux distributions (e.g. missing the required `msbuild` toolchain), and has been deprecated as a standalone project.
The [.NET 6 download page](https://dotnet.microsoft.com/download/dotnet/6.0) provides repositories for various package managers and binary releases for several architectures. If you prefer to use Mono, we suggest adding the [upstream repository](https://www.mono-project.com/download/stable/#download-lin) for your distro to obtain the latest version and the `msbuild` toolchain.
@@ -78,6 +78,6 @@ Type `sudo make install` for system-wide installation. Run `sudo make install-li
macOS
=====
-[.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0) or [Mono](https://www.mono-project.com/download/stable/#download-mac) (version 6.4 or later) is required to compile OpenRA. We recommend using .NET 6 unless you are running a very old version of macOS (10.9 through 10.14).
+[.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0) or [Mono](https://www.mono-project.com/download/stable/#download-mac) (version 6.12 or later) is required to compile OpenRA. We recommend using .NET 6 unless you are running a very old version of macOS (10.9 through 10.14).
To compile OpenRA, run `make` from the command line (or `make RUNTIME=mono` if using Mono). Run with `./launch-game.sh`.
diff --git a/Makefile b/Makefile
index 8c31c209c1..7e8ceea556 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
# to compile, run:
# make
#
-# to compile using Mono (version 6.4 or greater) instead of .NET 6, run:
+# to compile using Mono (version 6.12 or greater) instead of .NET 6, run:
# make RUNTIME=mono
#
# to compile using system libraries for native dependencies, run:
@@ -92,7 +92,7 @@ endif
all:
@echo "Compiling in ${CONFIGURATION} mode..."
ifeq ($(RUNTIME), mono)
- @command -v $(firstword $(MSBUILD)) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 6.4."; exit 1)
+ @command -v $(firstword $(MSBUILD)) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 6.12."; exit 1)
@$(MSBUILD) -t:Build -restore -p:Configuration=${CONFIGURATION} -p:TargetPlatform=$(TARGETPLATFORM)
else
@$(DOTNET) build -c ${CONFIGURATION} -nologo -p:TargetPlatform=$(TARGETPLATFORM)
@@ -173,7 +173,7 @@ help:
@echo 'to compile, run:'
@echo ' make'
@echo
- @echo 'to compile using Mono (version 6.4 or greater) instead of .NET 6, run:'
+ @echo 'to compile using Mono (version 6.12 or greater) instead of .NET 6, run:'
@echo ' make RUNTIME=mono'
@echo
@echo 'to compile using system libraries for native dependencies, run:'
diff --git a/OpenRA.Game/Exts.cs b/OpenRA.Game/Exts.cs
index 3f97b5446b..57ced8a9c3 100644
--- a/OpenRA.Game/Exts.cs
+++ b/OpenRA.Game/Exts.cs
@@ -144,7 +144,7 @@ namespace OpenRA
static T Random(IEnumerable ts, MersenneTwister r, bool throws)
{
var xs = ts as ICollection;
- xs = xs ?? ts.ToList();
+ xs ??= ts.ToList();
if (xs.Count == 0)
{
if (throws)
@@ -391,8 +391,8 @@ namespace OpenRA
string debugName, Func logKey = null, Func logValue = null)
{
// Fall back on ToString() if null functions are provided:
- logKey = logKey ?? (s => s.ToString());
- logValue = logValue ?? (s => s.ToString());
+ logKey ??= s => s.ToString();
+ logValue ??= s => s.ToString();
// Try to build a dictionary and log all duplicates found (if any):
var dupKeys = new Dictionary>();
diff --git a/OpenRA.Mods.Common/Activities/Move/Move.cs b/OpenRA.Mods.Common/Activities/Move/Move.cs
index 44485868ab..9ea28eb6bd 100644
--- a/OpenRA.Mods.Common/Activities/Move/Move.cs
+++ b/OpenRA.Mods.Common/Activities/Move/Move.cs
@@ -117,7 +117,7 @@ namespace OpenRA.Mods.Common.Activities
if (evaluateNearestMovableCell && destination.HasValue)
{
var movableDestination = mobile.NearestMoveableCell(destination.Value);
- destination = mobile.CanEnterCell(movableDestination, check: BlockedByActor.Immovable) ? movableDestination : (CPos?)null;
+ destination = mobile.CanEnterCell(movableDestination, check: BlockedByActor.Immovable) ? movableDestination : null;
}
// TODO: Change this to BlockedByActor.Stationary after improving the local avoidance behaviour
diff --git a/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs b/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs
index 1ce1ccc65f..31fecb9d1e 100644
--- a/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs
+++ b/OpenRA.Mods.Common/Graphics/DefaultSpriteSequence.cs
@@ -492,7 +492,7 @@ namespace OpenRA.Mods.Common.Graphics
});
}).ToArray();
- length = length ?? allSprites.Length - start;
+ length ??= allSprites.Length - start;
if (alpha != null)
{
diff --git a/OpenRA.Mods.Common/Pathfinder/PathSearch.cs b/OpenRA.Mods.Common/Pathfinder/PathSearch.cs
index 6bd19dd724..3db8904ffe 100644
--- a/OpenRA.Mods.Common/Pathfinder/PathSearch.cs
+++ b/OpenRA.Mods.Common/Pathfinder/PathSearch.cs
@@ -68,7 +68,7 @@ namespace OpenRA.Mods.Common.Pathfinder
else
graph = new MapPathGraph(LayerPoolForWorld(world), locomotor, self, world, check, customCost, ignoreActor, laneBias, inReverse);
- heuristic = heuristic ?? DefaultCostEstimator(locomotor, target);
+ heuristic ??= DefaultCostEstimator(locomotor, target);
var search = new PathSearch(graph, heuristic, heuristicWeightPercentage, loc => loc == target, recorder);
AddInitialCells(world, locomotor, froms, customCost, search);
diff --git a/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs
index c5a4451128..7c396c18f7 100644
--- a/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs
+++ b/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs
@@ -79,7 +79,7 @@ namespace OpenRA.Mods.Common.Scripting
for (var i = 0; i < actorTypes.Length; i++)
{
var af = actionFunc != null ? (LuaFunction)actionFunc.CopyReference() : null;
- var actor = CreateActor(owner, actorTypes[i], false, entryPath[0], entryPath.Length > 1 ? entryPath[1] : (CPos?)null);
+ var actor = CreateActor(owner, actorTypes[i], false, entryPath[0], entryPath.Length > 1 ? entryPath[1] : null);
actors.Add(actor);
var actionDelay = i * interval;
@@ -118,7 +118,7 @@ namespace OpenRA.Mods.Common.Scripting
public LuaTable ReinforceWithTransport(Player owner, string actorType, string[] cargoTypes, CPos[] entryPath, CPos[] exitPath = null,
LuaFunction actionFunc = null, LuaFunction exitFunc = null, int dropRange = 3)
{
- var transport = CreateActor(owner, actorType, true, entryPath[0], entryPath.Length > 1 ? entryPath[1] : (CPos?)null);
+ var transport = CreateActor(owner, actorType, true, entryPath[0], entryPath.Length > 1 ? entryPath[1] : null);
var cargo = transport.TraitOrDefault();
var passengers = new List();
diff --git a/OpenRA.Mods.Common/Scripting/Properties/RepairableBuildingProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/RepairableBuildingProperties.cs
index f90f67ed83..d87e760a3d 100644
--- a/OpenRA.Mods.Common/Scripting/Properties/RepairableBuildingProperties.cs
+++ b/OpenRA.Mods.Common/Scripting/Properties/RepairableBuildingProperties.cs
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Scripting
[Desc("Start repairs on this building. `repairer` can be an allied player.")]
public void StartBuildingRepairs(Player repairer = null)
{
- repairer = repairer ?? Self.Owner;
+ repairer ??= Self.Owner;
if (!rb.Repairers.Contains(repairer))
rb.RepairBuilding(Self, repairer);
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Scripting
[Desc("Stop repairs on this building. `repairer` can be an allied player.")]
public void StopBuildingRepairs(Player repairer = null)
{
- repairer = repairer ?? Self.Owner;
+ repairer ??= Self.Owner;
if (rb.RepairActive && rb.Repairers.Contains(repairer))
rb.RepairBuilding(Self, repairer);
diff --git a/OpenRA.Mods.Common/Traits/Cargo.cs b/OpenRA.Mods.Common/Traits/Cargo.cs
index a165fef67f..10eeee6263 100644
--- a/OpenRA.Mods.Common/Traits/Cargo.cs
+++ b/OpenRA.Mods.Common/Traits/Cargo.cs
@@ -331,7 +331,7 @@ namespace OpenRA.Mods.Common.Traits
public Actor Unload(Actor self, Actor passenger = null)
{
- passenger = passenger ?? cargo.Last();
+ passenger ??= cargo.Last();
if (!cargo.Remove(passenger))
throw new ArgumentException("Attempted to unload an actor that is not a passenger.");
diff --git a/OpenRA.Mods.Common/Traits/Turreted.cs b/OpenRA.Mods.Common/Traits/Turreted.cs
index 9bba19fecd..1f84338f2f 100644
--- a/OpenRA.Mods.Common/Traits/Turreted.cs
+++ b/OpenRA.Mods.Common/Traits/Turreted.cs
@@ -71,7 +71,7 @@ namespace OpenRA.Mods.Common.Traits
if (turretFacingInit != null)
{
var facing = turretFacingInit.Value;
- return bodyFacing != null ? (Func)(() => bodyFacing() + facing) : () => facing;
+ return bodyFacing != null ? () => bodyFacing() + facing : () => facing;
}
var dynamicFacingInit = init.GetOrDefault(info);
diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/20221203/ExplicitSequenceFilenames.cs b/OpenRA.Mods.Common/UpdateRules/Rules/20221203/ExplicitSequenceFilenames.cs
index 4169b7d354..c07286d0e5 100644
--- a/OpenRA.Mods.Common/UpdateRules/Rules/20221203/ExplicitSequenceFilenames.cs
+++ b/OpenRA.Mods.Common/UpdateRules/Rules/20221203/ExplicitSequenceFilenames.cs
@@ -149,7 +149,7 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules
continue;
resolvedSequenceNode.Value.Nodes = MiniYaml.Merge(new[] { resolvedDefaultsNode.Value.Nodes, resolvedSequenceNode.Value.Nodes });
- resolvedSequenceNode.Value.Value = resolvedSequenceNode.Value.Value ?? resolvedDefaultsNode.Value.Value;
+ resolvedSequenceNode.Value.Value ??= resolvedDefaultsNode.Value.Value;
}
}
diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/MenuButtonsChromeLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/MenuButtonsChromeLogic.cs
index 68b060943e..e2875b533a 100644
--- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/MenuButtonsChromeLogic.cs
+++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/MenuButtonsChromeLogic.cs
@@ -101,7 +101,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (button.DisableWorldSounds)
Game.Sound.DisableWorldSounds = true;
- widgetArgs = widgetArgs ?? new WidgetArgs();
+ widgetArgs ??= new WidgetArgs();
widgetArgs.Add("onExit", () =>
{
if (button.HideIngameUI)
diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs
index c7b188aa2e..99fadb3718 100644
--- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs
+++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs
@@ -235,7 +235,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
{ "initialMap", modData.MapCache.PickLastModifiedMap(MapVisibility.Lobby) ?? map.Uid },
{ "initialTab", MapClassification.System },
- { "onExit", Game.IsHost ? (Action)UpdateSelectedMap : modData.MapCache.UpdateMaps },
+ { "onExit", Game.IsHost ? UpdateSelectedMap : modData.MapCache.UpdateMaps },
{ "onSelect", Game.IsHost ? onSelect : null },
{ "filter", MapVisibility.Lobby },
});
diff --git a/packaging/macos/checkmono.c b/packaging/macos/checkmono.c
index 154a6129a0..708927bb7c 100644
--- a/packaging/macos/checkmono.c
+++ b/packaging/macos/checkmono.c
@@ -18,7 +18,7 @@
#include
#define SYSTEM_MONO_PATH "/Library/Frameworks/Mono.framework/Versions/Current/"
-#define SYSTEM_MONO_MIN_VERSION "6.4"
+#define SYSTEM_MONO_MIN_VERSION "6.12"
typedef char *(* mono_get_runtime_build_info)(void);
diff --git a/packaging/macos/launcher.m b/packaging/macos/launcher.m
index 25f2b293e9..17d9a3633c 100644
--- a/packaging/macos/launcher.m
+++ b/packaging/macos/launcher.m
@@ -13,7 +13,7 @@
#include
#define SYSTEM_MONO_PATH @"/Library/Frameworks/Mono.framework/Versions/Current/"
-#define SYSTEM_MONO_MIN_VERSION @"6.4"
+#define SYSTEM_MONO_MIN_VERSION @"6.12"
#define DOTNET_MIN_MACOS_VERSION 10.15
@interface OpenRALauncher : NSObject
diff --git a/packaging/macos/utility.m b/packaging/macos/utility.m
index 35636ba6a4..45f1121ad5 100644
--- a/packaging/macos/utility.m
+++ b/packaging/macos/utility.m
@@ -16,7 +16,7 @@
#include
#define SYSTEM_MONO_PATH @"/Library/Frameworks/Mono.framework/Versions/Current/"
-#define SYSTEM_MONO_MIN_VERSION @"6.4"
+#define SYSTEM_MONO_MIN_VERSION @"6.12"
#define DOTNET_MIN_MACOS_VERSION 10.15
typedef void* hostfxr_handle;