Skip to content

Reduce size of game binaries #249

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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