Skip to content

Reduce size of game binaries #249

@ForNeVeR

Description

@ForNeVeR

Currently, the published game binaries are enormous, more than 100 MiB when unpacked (per platform).

For comparison, the original game was about 3 MiB unpacked.

We can significantly (in my experiments — up to 3× in size) reduce this size by using assembly trimming.

But after any trimming, the game stops working for me :(

So let's enable trimming and figure it out.

Here's a patch to enable trimming (and single-file deployment, while we are at it):

Index: O21.Game/O21.Game.fsproj
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/O21.Game/O21.Game.fsproj b/O21.Game/O21.Game.fsproj
--- a/O21.Game/O21.Game.fsproj	(revision Staged)
+++ b/O21.Game/O21.Game.fsproj	(date 1747580079091)
@@ -9,6 +9,8 @@
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net9.0</TargetFramework>
+        <PublishTrimmed>true</PublishTrimmed>
+        <PublishSingleFile>true</PublishSingleFile>
    </PropertyGroup>

    <ItemGroup>

And here's a command to publish the game to check it out in this mode:

$ dotnet publish O21.Game --self-contained --runtime win-x64 --configuration Release --output publish.win-x64

This results in an exception:

Unhandled exception. System.InvalidOperationException: Type O21.CommandLine.Arguments+StartGame appears to be immutable, but no constructor found to accept values.
   at CommandLine.Infrastructure.ReflectionHelper.CreateDefaultImmutableInstance(Type type, Type[] constructorTypes)
   at CommandLine.Core.ReflectionExtensions.AutoDefault(Type type)
   at CommandLine.Core.InstanceChooser.<>c__DisplayClass3_0.<MatchVerb>b__1()
   at CommandLine.Core.InstanceBuilder.<>c__1`1.<Build>b__1_0(Func`1 f)
   at CSharpx.MaybeExtensions.MapValueOrDefault[T1,T2](Maybe`1 maybe, Func`2 func, T2 noneValue)
   at CommandLine.Core.InstanceBuilder.Build[T](Maybe`1 factory, Func`3 tokenizer, IEnumerable`1 arguments, StringComparer nameComparer, Boolean ignoreValueCase, CultureInfo parsingCulture, Boolean autoHelp, Boolean autoVersion, Boolean allowMultiInstance, IEnumerable`1 nonFatalErrors)
   at CommandLine.Core.InstanceChooser.MatchVerb(Func`3 tokenizer, IEnumerable`1 verbs, Tuple`2 defaultVerb, IEnumerable`1 arguments, StringComparer nameComparer, Boolean ignoreValueCase, CultureInfo parsingCulture, Boolean autoHelp, Boolean autoVersion, Boolean allowMultiInstance, IEnumerable`1 nonFatalErrors)
   at CommandLine.Core.InstanceChooser.<Choose>g__choose|1_1(<>c__DisplayClass1_0&)
   at CommandLine.Core.InstanceChooser.Choose(Func`3 tokenizer, IEnumerable`1 types, IEnumerable`1 arguments, StringComparer nameComparer, Boolean ignoreValueCase, CultureInfo parsingCulture, Boolean autoHelp, Boolean autoVersion, Boolean allowMultiInstance, IEnumerable`1 nonFatalErrors)
   at CommandLine.Parser.ParseArguments(IEnumerable`1 args, Type[] types)
   at CommandLine.ParserExtensions.ParseArguments[T1,T2,T3](Parser parser, IEnumerable`1 args)
   at O21.CommandLine.CommandLineParser.parseArguments(String[] args, IConsole reporter, FSharpFunc`2 worker) in G:\Projects\O21\O21.CommandLine\CommandLineParser.fs:line 38
   at Program.main(String[] args) in G:\Projects\O21\O21.Game\Program.fs:line 112

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions