Open kyubuns opened 2 years ago
Hmm, I understand what you mean and that does seem undesirable. I'll look making this smoother in the next few weeks. The reason for the STEAMWORKS_NET define is outlined here: https://github.com/rlabrecque/Steamworks.NET/pull/484 and https://github.com/rlabrecque/Steamworks.NET/pull/465
But, Is it necessary to automatically add the "STEAMWORKS_NET" define? I am not in favor of this behavior.
Ne neither… I really dislike when plugins spam the global script defines. At least don't add it for platforms where it can't be used anyway.
I see no reason why STEAMWORKS_NET
shouldn't be added any time Steamworks.NET is present
The define its self should simply mean that Steamworks.NET is present nothing more. This isn't any different than Unity's own INPUT_SYSTEM and similar defines that indicate what modules are or are not present.
Worth noting that Unity its self isn't exactly consistent with this :) Input system old and new ... do use global defines Cinamachine, TMPro and various other modules do not
This is real fun with things like Mathmatics, various XR plugins, etc.
In the case of installers and all you can use the Package Manager API to check what is present ... assuming it was installed by Package Manager but that doesn't help for conditional compilation which really needs a script define somewhere.
Yes using the assembly's script define feature works but only if you know to use it and only if your assembly can reference the assembly your checking for ... so this breaks down for well most community contributions to Unity which is a lot of Steam related tools and for any asset that handles 3rd party add-ons like Mirror, FishNetworking and Net Code for GameObjects.
The reasons are talked about a bit in the links above e.g. the last post in #465 I think would answer most cases for you
In short the use of a global script define to indicate when a module or similar is present is the standard approach Unity has used, and that the wider community expects. Unity its self does this with its own modules and has others do this in Unity's community contributions such as Net Code for GameObjects.
I do agree there are mechanically better methods, a couple ... however none of those are widely used even by Unity ... at least not yet. The alternatives do put the responsibility on the consumer to manage that dependency and this caused issues in the past. If the script define is not present we see people deep copy Steamworks.NET into their source which creates a hell scape ... yes even Unity did this.
I do get it, I don't like having a ton of script defines to manage either. In our own asset we use a different approach and are not dependent on the script define being present or not. I do know Mirror, Net Code for GameObjects and I think FishNetworking all conditionally compile there steam networking transports based on this define so out right removing will break those. Making it optional will break those for new users.
I see. That was not what I initially thought define meant, but I can understand if that is what it is for.
However, we do not see that as a reason for defines to go into platforms (other than Windows, macOS, Linux) where Steamworks.net does not work. RedistInstall.AddDefineSymbols will work on all platforms, but could it be limited to Windows, macOS, and Linux? Also, it is not uncommon these days to have a multi-platform deployment, such as a steam version and a Microsoft Store version. At that time, you may want to manually remove the code because you don't want the code to be enabled by "STEAMWORKS_NET" to assume that Steamworks exists, right? I think the default behavior is "STEAMWORKS_NET will be added" which is fine, but an option to set it manually would be helpful.
The problem is in the way Unity compiles
Yes we could wrap the editor script in question with platform check such that it doesn't write this unless its a valid platform.
However it would still be present on other platforms if at anytime you switched platform. That is the script defines are per-project as I recall not per-platform.
I suppose the editor script could be set up to add the script define if missing on platforms that support Steam and remove the script define if present on platforms that do not.
However again this script define being present shouldn't be an issue and should be able to exist on builds that are not for Steam ... for example if you wanted to for PC but non-Steam ... you would define #DISABLESTEAMWORKS and make sure you code was wrapped accordingly. This would prevent the Steam API bits from compiling however #STEAMWORKS_NET would still be present
Which this is true ... in project which is the only place these defines exist,,, Steamworks is present. The fact that it is also excluded from compilation is defined by the presence of DISABLESTEAMWORKS. Any code you have that depends on Steamworks should be checking
#if !DISABLESTEMWORKS
// Steam only code
#else
// Non-steam only code
#endif
// Everywhere code
Now if your an asset developer that has created some add-on or componenet that is dependent on Steam you would have a different structure something like this
#if STEAMWORKS_NET && !DISABLESTEAMWORKS
using Steamworks;
namespace MySteamAssetAddon
{
public class DoingSomeCoolStuff
{
}
}
#endif
So why does an asset developer do this?
Well 1 if the asset doesn't depend on Steam and simply has parts that may be enabled if Steam is present that is the most common use case ... think of all the various HLAPIs out there that have lobby managers, transports, etc.
What this says is
if Steamworks.NET is present ... and ... The developer didn't disable or its not on a non-Steam platform then and only then compile this object
So this lets an asset developer or add-on developer creating a module for some other assets create code that will only compile when Steamworks.NET is present. They can then respect the disable as well.
Some interesting cases here. You can create an asset with editor scripts that help the developer update steam, manage the disable steamworks define, etc.
Such an editor script needs to know if Steamworks.NET is present. It shouldn't' simply non-compile if DISABLESTEAMWORKS is true
So for example we could add a button in our editor extensions that let you disable steamworks with a click ... this would simply add DISABLESTEAMWORKS to the script defines or remove it depending if toggle on or off. We used to do similar when we used global script defines but don't current use script defines at all in our tools.
In short STEAMWORKS_NET Indicates that Steamworks.NET is installed in the Unity project. It is used by editor tools, asset developers and others creating extensions that would need to know if Steamworks.NET is installed in the project. It DOES NOT indicate that Steamworks.net is being used in the project ... only that it is installed in the project
DISABLESTEAMWORKS This indicates that Steamworks is not being used in the project. This is what you would use to conditionally compile your code to respect rather or not Steam API is in use... when coupled with STEAMWORKS_NET it allows complex situations such as code that should compile if Steamworks.NET is present but not compile if the developer disable Steamworks.NET.
Little hypothetical tool for you Psedo code of course
public class SteamworksNetEditorTools
{
public static void ToggleSteamworks()
{
#if STEAMWORKS_NET
#if DISABLESTEAMWORKS
// Show a button to remove enable Steamworks in the build
#else
// Show a button to disable Steamworks in the build
#endif
#else
// Show a button to install Steamworks.NET form Package Manager for the user
#endif
}
}
I am developing a multi-platform game. In other words, it is for Steam and also for iOS. And other platforms.
After updating steamworks.NET to 20.1.0, the auto-build has slowed down and I have investigated why. My Unity Editor targets Standalone. The first time I put in 20.1.0, the "STEAMWORKS_NET" define was added for Standalone. However, when I run the Editor with iOS Target on the machine that does the automatic build, the "STEAMWORKS_NET" definition is added for iOS. The change in the "STEAMWORKS_NET" define means that all scripts need to be recompiled. And since the code in the repository does not have the "STEAMWORKS_NET" define for iOS, it will be removed and added again in the next build.
"Why not just define "STEAMWORKS_NET" for iOS as well?" That's all there is to it. But, Is it necessary to automatically add the "STEAMWORKS_NET" define? I am not in favor of this behavior.