stride3d / stride

Stride (formerly Xenko), a free and open-source cross-platform C# game engine.
https://stride3d.net
MIT License
6.53k stars 945 forks source link

Bring back UWP support #1517

Open yoshiask opened 2 years ago

yoshiask commented 2 years ago

Is your feature request related to a problem? Please describe. Stride 4.1 updated to .NET 6, and in the process dropped UWP support because it doesn't officially support .NET 5+. Without UWP support, there is no easy way to publish natively to Xbox or Hololens (or Team, perhaps for technical visualizations?).

Describe the solution you'd like Although UWP does not officially support .NET 6, it's possible and actually quite easy to make a .NET 6 UWP app. It can even be published to the Microsoft Store without issues, though of course you don't have to. Gustave Monce put together a proof-of-concept for a UWP XAML app targeting .NET 6 here: gus33000/CsUWP. Note that Gus used a modified version of C#/WinRT to generate a projection for Windows.UI.Xaml, but since Stride 4.0 supported CoreApplication directly, we don't need to worry about that or anything else involving XAML.

As is, Stride.Core can be referenced from .NET 6 UWP, but because the STRIDE_PLATFORM_UWP directive isn't defined for the standard net6.0 target in Stride 4.1, it incorrectly attempts to use the System.IO APIs to access the current working directory. This can be solved in a few ways:

  1. Check for UWP at compile time by explicitly adding net6.0-windows10.22000 as a target framework. Games built with this target will run only on Windows 10 and up, and as such can be UWP apps without conflicts. The net6.0 target will cover any Windows 7+ system. The benefit of this is that the 4.1 codebase would require minimal changes, as the STRIDE_PLATFORM_UWP can be set whenever the target framework OS is windows10. The downside is that the UWP version would erroneously be referenced if someone wanted to embed a Stride game in a WPF/WinForms/etc. project that also targets net6.0-windows10.
  2. Check for UWP at run time by calling the GetTokenInformation Win32 API with the TokenIsAppContainer class. This method can determine if the current process is running in an app container, which strictly speaking isn't limited to UWP apps, but should be effective and is officially supported. This has the benefit of not fudging the target frameworks, but since it's a run time check, the WinRT libraries have to be referenced even if the target OS won't use it. This shouldn't cause issues with the game itself, but it does mean adding a library that might never be used on certain OSes.

Describe alternatives you've considered As far as I know, without Stride multitargeting both net6.0 and uap10, there are no other options.

Additional context I'll be working on a proof-of-concept at yoshiask/Stride41Uwp, that runs the "Space Escape" sample game in a UWP app targeting .NET 6. (It's private at the moment because I haven't made many changes to Gus's CsUWP repo.)

ericwj commented 2 years ago

the STRIDE_PLATFORM_UWP can be set whenever the target framework OS is windows10

The goal is to eventually build stride with a near standard build and doing this hack is going to cause headaches later and probably today for people who want to reference these packages. windows10.0.22000 actually means Windows 11. Using this TFM prevents people from referencing the package from a project targetting a lower Windows version.

I propose to do a little bit more work in the build system and connect with what .NET already does.

Not the target framework moniker, but the presence of UseWinUI, UseWPF, UseMAUI, UseWindowsForms decides the inclusing of a certain UI platform. Just defining UseUWP should be made to work for targeting Universal Windows. If that requires to make changes to the build system, then bite the bullet. It's hard I know but it is needed.

yoshiask commented 2 years ago

The goal is to eventually build stride with a near standard build and doing this hack is going to cause headaches later and probably today for people who want to reference these packages. windows10.0.22000 actually means Windows 11. Using this TFM prevents people from referencing the package from a project targetting a lower Windows version.

My bad, I should have put net6.0-windows10.0.16299 like I did in my experiments.

I'm not very familiar with Stride's build system (I still can't get VS to show targets other than net6.0 in the code editor). Is this something the Stride team or someone else in the community can take up?

ericwj commented 2 years ago

You're probably best off making a build customization package which does what it needs to make UWP work, entirely separate from the proof of concept game, such that other projects can simply reference the package. If you know what to search for, there's quite a bit of information on how to do something like that.

You can do almost all that MSBuild can do from such a package, including adding references to the original project while it is being built.

Once you have such a package that works, you still have to use it appropriately from the Stride build system, so there's no way around figuring out a fair bit about that.

yoshiask/Stride41Uwp

That link is broken btw.

yoshiask commented 2 years ago

How can an external package change Stride.Core's code?

ericwj commented 2 years ago

How do you mean? Change C# source code? That isn't possible and shouldn't be necessary.

You change the build using .props and .targets files so the project obtains the right references and the output runs on UWP.

yoshiask commented 2 years ago

The current Stride.Core code doesn't work on .NET 6 UWP. Since the Windows and UWP target frameworks are identical now, there needs to be a check somewhere to determine when to use sandbox-safe APIs as opposed to the older Win32 ones.

ericwj commented 2 years ago

Yes, obviously. But think modular mate. The whole idea is to put that poc you referred to in a box and ship it all by itself.

  1. First create a proof of concept which runs on UWP (I think you've done that, or you're close). Clean it up as far as possible.
  2. Create a package Yoshiask.Uwp.Build that contains build customizations just using what your poc does to build that, but generalized.
  3. Create an empty project Yoshiak.Uwp.App referencing this Yoshiask.Uwp.Build which succeeds in creating a CoreWindow and showing a button Click me with a pretty much empty project file and no references besides Yoshiask.Uwp.Build.
  4. Create an empty project Yoshiak.Uwp.Dll referencing this Yoshiask.Uwp.Build which offers a custom control to Yoshiak.Uwp.App.

Basically you copy step 1 to step 3 and start moving stuff out of the latter project file to step 2. And then you really make it work like what you would normally do to make stuff awesome. Steal the whole idea from a new MAUI app e.g. the Platforms folder. Steal it mate, from blogs, from docs, from File New Project.

Then it is up to you and/or others to continue for Stride:

  1. Reference the Yoshiask.Uwp.Build package in the appropriate Stride projects and make sure all existing targets still build correctly.
  2. Add UseUWP to the project
  3. Integrate IDXGIFactory2::CreateSwapChainForCoreWindow in appropriate #if UWP from a <DefineConstant>$(DefineConstant);UWP</DefineConstant> in .\src\Yoshiak.Uwp.App\build\
  4. ...
Perksey commented 2 years ago

I feel like this is a step backwards though, Microsoft is actively pushing the .NET ecosystem to centralise fully on .NET 6. Microsoft has also made a conscious decision to not bring UWP to .NET 6. By supporting UWP you’d be going against the current flow of the ecosystem for little gain.

My opinion is if you want modern .NET tools to support UWP you need to take that up with Microsoft.

sidenote: .NET 7 NativeAOT has been made to work on UWP - in theory all that’s needed to support UWP is to build a MSBuild SDK that adds a UWP TFM and invokes NativeAOT in such a way that it links against OneCoreUAP. (As well as handle all the packaging stuff)

ericwj commented 2 years ago

The goal would be to enable deployment to Xbox. Any other use would be backwards indeed.

If ilc is realy 100% suitable for deployment to Xbox One, Series X/S, testing that with Stride would probably require SharpDX bindings for DX11 and any other platform specific stuff to use the right imports. Could just see if it works with just reverse forwarding if you don't have a means to generate those packages easily.

In writing that SDK yes that is a NuGet with props and targets, so lets start there and put it in a box before touching Stride's props and targets. Especially wrt integrating with Stride, making it an actual SDK only complicates things imho.

Fydar commented 4 months ago

According to this comment: https://github.com/stride3d/stride/issues/2157#issuecomment-1947616130

Microsoft killed UWP for Xbox without a replacement, so the motivation for this feature request might have to be re-evaluated.

yoshiask commented 3 months ago

According to this comment: https://github.com/stride3d/stride/issues/2157#issuecomment-1947616130

Microsoft killed UWP for Xbox without a replacement, so the motivation for this feature request might have to be re-evaluated.

What reference do we have for it being killed? UWP itself is still officially supported, even though it's not getting active updates now. It's also still one of the only ways for small devs to build apps and games for Xbox.

IXLLEGACYIXL commented 3 months ago

According to this comment: #2157 (comment) Microsoft killed UWP for Xbox without a replacement, so the motivation for this feature request might have to be re-evaluated.

What reference do we have for it being killed? UWP itself is still officially supported, even though it's not getting active updates now. It's also still one of the only ways for small devs to build apps and games for Xbox.

https://www.thurrott.com/dev/258377/microsoft-officially-deprecates-uwp dropped support 2021

yoshiask commented 3 months ago

Thurrott is infamous for spreading misleading or inaccurate information. UWP has not been killed, in fact it can still access new WinRT APIs introduced in Windows 11. Again, it remains as the only way to get apps and games on Xbox and Hololens.

Doprez commented 3 months ago

This has been discussed in forums due to the lack of support for the recent .NET versions https://developercommunity.visualstudio.com/t/Add-NET-678-support-to-UWP/1596483#TPIN-N10082751

https://github.com/microsoft/WindowsAppSDK/discussions/1615 It looks like the path forward for something like this would be WinUI3. Although I have no clue what the Xbox support for that would be like but there are a few different examples of concern for UWP and the version of .NET that Stride uses.

Im not sure what alternatives exist otherwise but is there any chance something like Avalonia would be a better option for this? Since there is already a goal for porting many of the editor components to Avalonia it may be a better solution if possible. Although this may not be useful since they dont explicitly say they support any consoles (They just say "And more")

MeharDT commented 3 months ago

Publicly, the path forward for Xbox One and Series support is Win32, GDK, and an ID@Xbox membership.

For developers building Xbox One games today, Win32 + GDK is a direct replacement for the WinRT-based Exclusive Resource Application (ERA) app model using the XDK, introduced on Xbox One; Xbox 360 developers similarly migrated to ERA in 2013.

https://github.com/microsoft/GDK?tab=readme-ov-file#q--how-do-i-run-a-gdk-game-built-for-the-xbox-app-on-windows-10-or-xbox-game-pass-for-pc-on-xbox-consoles

If you still need UWP support, there's honestly nothing wrong with continuing to use Stride 4.0. PR's are still accepted and updates can be published, it would be less work to back-port any 4.1+ changes you like to 4.0 than to try and work UWP into a newer release IMO.

@FLY1NGSQU1RR3L Hi, I hope it's not inappropriate for me to tag you here, just in case we're overlooking something in this discussion. :)

Perksey commented 3 months ago

As I understand it, public GDK can’t target Xbox consoles as UWP can. GDKX is required for that for which ID@Xbox or some other partner program is needed.

I’ve long been tempted to use NativeAOT with OneCoreUAP to see if we can get Silk.NET working on UWP, as I still love the UWP platform and think that people did dismiss it too quickly.

UWP is still supported, it’s a Windows component and will be supported forever as it currently stands (short of a massive Windows shiproom policy change) on desktop at least, and I see no reason why UWP wouldn’t continue working on Xbox so long as Windows is maintaining the tools.

However, it is publicly documented that, for Xbox, UWP is community-supported only; GDKX is the official way to target Xbox herein. Moreover, the Windows team has said that WPF or WinUI 3 is the recommended toolset for Windows development (with a clear undertone that you should not be using UWP, but again they don’t have the ability deprecate it officially as it currently stands)

It is a shame that GDK isn’t a subset of GDKX that contains common Xbox target support the same way that UWP is a workable subset for Xbox when used without the NDA Xbox extensions. That is to say you can’t develop within the Xbox Creator Program without UWP or without NDA program membership (which is the audience Stride’s UWP support would ultimately be targeting). I don’t think there’s been any change there, but hopefully Flying Squirrel can chime in there if they see their ping on this thread.