Skip to content

Comments

Upgrade FreeSO to .NET 9.0#283

Merged
riperiperi merged 79 commits intoriperiperi:archivefrom
SegerEnd:dotnet9
Sep 28, 2025
Merged

Upgrade FreeSO to .NET 9.0#283
riperiperi merged 79 commits intoriperiperi:archivefrom
SegerEnd:dotnet9

Conversation

@SegerEnd
Copy link
Contributor

@SegerEnd SegerEnd commented Sep 20, 2025

Hi! I’m upgrading FreeSO to .NET 9.0, It is currently working and playable! There are still some areas for improvement. I wanted it to place it here already so it can be used, and maybe collaborate together.

  • Graphics: Now using the latest MonoGame version.
  • Dependencies: All major dependencies are now managed via NuGet. I updated them to the latest versions where possible, though some are still tied to .NET Framework 4.5.
  • Build process: Protobuild is no longer required you can clone, build, and run directly. (hope it works on other machines as well haha )
  • Performance & optimization: .NET 9.0 may provide runtime performance improvements, and the code can be further optimized to fully leverage the new framework.

  • I wanted the project to have AOT Compilation, that currently fails because Ninject and some other are still .NET 4.5 packages and some rely on reflection.
    • Should we replace Ninject with Microsoft.Extensions.DependencyInjection and consider modern alternatives for most older libraries?
    • Could the project structure also be improved while updating these libraries?

  • Makes it easier for new contributors to build and run the project.
  • Removes the need for Protobuild, simplifying the setup.
  • Updates the codebase to current .NET and MonoGame standards.
  • Opens opportunities for better performance and further optimization.

build as Class Libary succeeds in VS2022, I have not tried building game, need to migrate all other first
build as Class Libary succeeds in VS2022, I have not tried building game, need to migrate all other first
Need to look at packages later, it somehow compiles
@riperiperi
Copy link
Owner

riperiperi commented Sep 21, 2025

I'm getting some odd behaviour in Volcanic where a bunch of things seem to be the wrong size:
image
Here's what it looked like before:
image

I guess they've changed how a lot of these components render, and maybe they're also trying to adjust the sizing to better match modern Windows standards. When I open things in the designer and change them, it seems to update button sizes and positions:

image

The BHAV editor seems broken normally:
image

But after I resave the form from the designer, it fares a little better (still a lot bigger than it used to be):
image

I guess the runtime tries to resize things itself but ends up doing it worse than the designer. Not sure if they've documented this anywhere, or a way to work around it. It could just mean I need to go back and manually clean up all of the components to look the way they used to.

@riperiperi
Copy link
Owner

I figured it out, it attempts to rescale based on the default font.
image

Adding this line to Program.cs fixes it at runtime:
image
Application.SetDefaultFont(new Font(new FontFamily("Microsoft Sans Serif"), 8.25f));

The designer still tries to change the size. I think adding an ApplicationDefaultFont in the csproj should influence the designer, though it still seemed broken when I tried:

<ApplicationDefaultFont>Microsoft Sans Serif, 8.25pt, style=regular</ApplicationDefaultFont>

The FSO.Server project needs to exclude the Admin folder, as node_modules can contain cs files for build scripts
@SegerEnd
Copy link
Contributor Author

SegerEnd commented Sep 23, 2025

Hi! Thank you for the review and for taking the time to test it. The performance improvements are awesome to see, it really shows what improvements the newer version can do already ☺️.

I’m working through your notes and making improvements. A few updates from my side:

  • Archive server - I currently have not a way to test in “archive mode” myself yet. If there’s a downloadable version, so I can help with the archive changes and make sure I’m getting the same behavior. As it currently it tries to download from localhost server archive.ini / archive_test_2.zip :)

  • WindowsDX - I’ve made it the default again. It works the old way again using the MonogameLinker class, resolving the assembly from the platform dll, The monogame.framework.dll is also retrieved via NuGet and placed in the correct platform folder in FSO.Windows.csproj via a Target:

<Target Name="CopyMonoGameDLLs" AfterTargets="Build">
  • Format-on-save - My Visual Studio was happily reformatting everything I saved. I’ve turned it off for now so future diffs won’t be noisy.

  • The VMRouteFinder change: - I updated the using statement from using TSO.Files.formats.iff.chunks; to using FSO.Files.Formats.IFF.Chunks; so it would compile again. Bit hard to spot yes, with all the formatting happing.

  • Sandbox XMLs - I’ve set DtdProcessing to Parse. The job lots now load again, so that one bug is fixed.

  • FSO.Server Admin folder - I’ll excluded the Admin folder from the project to avoid pulling in the node_modules with the cs files.

  • Files removed - Deleted all the old/unused files and directories you mentioned, so the project is cleaner now. I could maybe also further remove the libraries in Other/ that we don’t use anymore (e.g., NuGet replacements).

  • MP3 playback - I replaced the path with the FileStream, and I am going to try and look into that startup stutter.

  • Volcanic IDE - I added the <ApplicationDefaultFont>, I thought about maybe migrating to something like Eto.Forms for cross-platform support, but that would require a full rewrite since it doesn’t support the designer. That would be a lot of work, just updating the IDE sizes seems like a good way.

next..

  • Simitone - Probably Simitone also needs to be migrated to .NET 9.0 since it uses FSO as a submodule. It shouldn’t be too hard to migrate i think, so that’s likely my next step when this is merged into Archive.

@riperiperi
Copy link
Owner

For Volcanic, I don't think ApplicationDefaultFont is enough, it still tries to resize the forms at runtime unless Application.SetDefaultFont(new Font(new FontFamily("Microsoft Sans Serif"), 8.25f)); is in the FSO.IDE main function. ApplicationDefaultFont does change the font selected by the designer in Visual Studio, but the component placements still end up wrong.

I can't release the archive data right now as it hasn't been fully stripped of sensitive data (and it would mean essentially publishing a release with a lot unfinished). I guess it's possible to make an "empty" archive template, but that might take a while to do. I'll try and look at the NLog and lot server connection handshake issues myself, since I know the most about the process anyways it should be less trouble for me.

Refactors MP3Player to replace old thread-based decoding and buffer
management with a .NET 9.0 async/Task-based implementation using
ConcurrentQueue and SemaphoreSlim. Improves performance, reduces
GC pressure with ArrayPool<byte>, and makes resource management
and cancellation more reliable. Simplifies buffer submission logic
and adds preload/buffer tuning options.
Added .idea/ directory to .gitignore to prevent JetBrains Rider IDE files from being tracked in the repository.
and made the application work again, because .NET 9 no longer supports AppDomain.CreateDomain. and AppDomainSetup.ConfigurationFile is also removed in .NET Core/.NET 5+
Copy link
Owner

@riperiperi riperiperi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured out the issue I was having, it's an SQLite problem where it puts an int32 into the database instead of a uint32, then errors trying to cast it on retrieval. I've pushed a workaround on the archive branch, since it might actually happen there, too.

I don't think this should be enabled on any of our projects:
<Nullable>enable</Nullable>
It'll just cause warnings everywhere right now, and would need the whole project to be reworked to properly annotate everything.

About the AppDomain use in the server updater, I can't really remember why I added it in the first place. The solution I settled on later on was just alternating running the patcher and the game using a watchdog script, so it's probably fine.

For the ApiClient methods that you've made async, you should use _ = ... to discard the explicitly discard the tasks so that the warnings don't appear. Awaiting them doesn't do anything useful since the data comes back on the callback.

I haven't been able to test the normal server or update process, but it's likely those are broken on the archive branch anyways so it's better to fix them when I come back around to cleaning everything up.

Things are looking pretty good now. Whenever you want a final review set the PR as non-draft and I'll give it another look.

<ItemGroup>
<None Include="NLog.config">
<None Update="config.json">
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this file exist? config.sample.json does, but it doesn't seem to be copied to the output directory now...

@riperiperi
Copy link
Owner

Did some profiling and looks like MonoGame still has the O(n) dispose time that gets worse the more resources you have loaded (so if you dispose them all, it's O(n^2). Joining the town hall and scrolling rapidly across the map gets me big stutters.
image

The game tends to dispose assets in big chunks in both the city and lot views, but it being magnitudes slower isn't great even if I do distribute it over a few frames. I'll see if I can update FSOMonogame to the latest version, repatch the issue and set up nuget packages.

Refactor FSOFacadeWorker login logic and update project files

- Removed config.json from FSO.Server output
- Added discord-rpc.dll to FSO.UI
- Refactored login logic in FSOFacadeWorker to remove async/await
- Updated method calls to use discard (_) for tasks
During migration, this method was made async to get the project to build properly. But now it builds succesfuly without async, so restoring the original archive branch implementation.
@francot514
Copy link
Contributor

Which Monogame is used, it allows the custom modifications?

@SegerEnd
Copy link
Contributor Author

SegerEnd commented Sep 25, 2025

Which Monogame is used, it allows the custom modifications?

Currently, its using the official latest 3.8.4 MonoGame NuGet packages, I saw that @riperiperi upgraded the modifed FSOMonoGame to the latest MonoGame version so we can switch to that soon I think.

@francot514
Copy link
Contributor

Still youre using the Monogame linker classes or just package dependency

@riperiperi
Copy link
Owner

It's using the Monogame linker so arguments can be passed to launch the game with a different backend.

Fixes that sometimes after closing the game, it not fully closes, it was still running in the background.
- It works but is it good to call Environment.Exit(0); ? or are there maybe background processes running that are not finshed yet, and i just kill now?
Fixes some/most of the scaling issues in Volcanic for dotnet9, and updates default font to modern Segoe UI.
@riperiperi
Copy link
Owner

I think I've solved the issue with the game not closing as well as properly waiting for the archive server to shut down with this change:

d803ce7

Let me know if it fixes it for you. You can cherry-pick it into this branch if it works.

Should prevent the game from accidentally staying open and fix the archive closing dialog
@SegerEnd
Copy link
Contributor Author

Yes, that change works for me, the game closes cleanly now on both IDE and Windows. I’ve cherry-picked it into this branch. Thanks!

Copy link
Owner

@riperiperi riperiperi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Things are looking good for now, apart from some small issues:

  • The Dispose performance issue. My fork has published development packages with the change, but GitHub's nuget store is pretty much useless for public projects since you need to login with a PAT token to read any public packages. On top of that being annoying to set up. Visual Studio asks me to re-enter the PAT token every time I start it. I've made a PR to upstream this over on the MonoGame repository, but I'm not sure when it'll be merged: MonoGame/MonoGame#9027
    • This isn't really blocking anything, it just makes the game a bit more stuttery.
  • FSOFacadeWorker appears to be trying to use DesktopGL monogame instead of WindowsDX. The custom graphics device code only works on the DX backend.
  • There are some visual issues in the IDE from changing the font (it's generally wider than the old one)
  • The HighDpi mode set in FSO.IDE doesn't work properly.

If you're good with everything so far, unmark it as draft and I'll merge.

@@ -68,6 +68,8 @@ public void InitVolcanic(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.SetDefaultFont(new Font(new FontFamily("Segoe UI"), 8.25f));
Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HighDpi modes don't seem to work properly when you have multiple monitors with mismatching DPI:

image

This happens after dragging from my 1x monitor to my 1.5x one, then back.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that’s not good! Guess the DPI setting should to be removed

@SegerEnd SegerEnd marked this pull request as ready for review September 28, 2025 18:43
@riperiperi riperiperi merged commit d5485b8 into riperiperi:archive Sep 28, 2025
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants