AGSteam question

Started by CaptainD, 06 Jul 2021, 17:16

« previous - next »

CaptainD

Sorry this is a stupid question, but...

If I wanted to have one version of a game that supported Steam achievements, but would also work fine on Itch or anywhere else without having to create two separate builds, would the following code enable this:

Code: ags
#ifdef AGS2Client_VERSION
//DO STEAM STUFF
#endif // AGS2Client


I'm not sure I've fully understood what this function is for - does it simply detect the presence of the plugin and ignore if not found, or does it check if the plugin is active at runtime / that the game is being run from the Steam client?
 

eri0o

#1
The macro uses the preprocessor

Code: ags
#define MYMACRO _
#ifdef MYMACRO
Display ("does this compile?");
#endif


Should show a display message. Remove the initial #define clause now and build and run again. It will not display the message.

You still need to build twice, but changing the macro definition - I guess that definition comes from the plugin, so just disable on the editor build, copy the results, enable the plugin, build again.

Now, there's one additional thing, the engine has stubs for some ags steam plugins. Depending on how you write your code you may just remove the plugin from the directory and run your game and check if it runs fine (without using macros at all). If there's a bug related to the plugin, then please report because if it's a missing stub it should be possible to add.

Crimson Wizard

"#ifdef" is a preprocessor command (preprocessor runs over the script before compiler does) that enables/disables certain pieces of code, depending on whether certain symbol is declared or not.

So, let's say a plugin declares its API (its script functions), and besides that also declares a symbol "AGS2Client_VERSION". If plugin is attached during compilation, then this symbol will be present, and so this part of code will be compiled into the game.

But if you compile without plugin, then there will be no such symbol, and such piece of code will be cut out from compilation.

Crimson Wizard

Quote from: eri0o on 06 Jul 2021, 17:45
Now, there's one additional thing, the engine has stubs for some ags steam plugins. Depending on how you write your code you may just remove the plugin from the directory and run your game and check if it runs fine (without using macros at all).

BTW, I think that if you go this route, - you may use Game.IsPluginLoaded function to test if plugin was loaded at runtime. That won't be useful if you provide stub plugin though, because it likely has same name.

Laura Hunt

Quote from: CaptainD on 06 Jul 2021, 17:16
Sorry this is a stupid question, but...

If I wanted to have one version of a game that supported Steam achievements, but would also work fine on Itch or anywhere else without having to create two separate builds, would the following code enable this:

Actually it's the opposite: if you want to have the same build for Steam and itch.io, you don't have to do anything. Just zip everything inside your Compiled windows folder, including the steam .dlls, and upload it to itch.io, and it should work without any issues (you can test this yourself by taking any AGS game you have on Steam, copying the files anywhere else in your hard drive, and running it without having the client running).

The only "problem" with this is that it looks kind of ugly/inelegant for people who downloaded it from itch.io to have a couple of Steam .dlls in the game folder, so if you want to have a "clean" build especifically for itch.io, then you would have to remove the .dlls from the folder, which means you would have to disable the plugin before compiling your game, which means you would have to do the whole #ifdef thing.

eri0o

@Laura Hunt, if you don't pack the steam/plugin for steam dlls, what happens?

Laura Hunt

#6
Quote from: eri0o on 06 Jul 2021, 20:14
@Laura Hunt, if you don't pack the steam/plugin for steam dlls, what happens?

If you compile the game with the plugin enabled but then remove the .dlls (AGSteam.dll and steam_api.dll) from the Compiled folder, the game will crash. I don't remember right now if it crashes right at the start, or whenever you call the plugin, for example when getting an achievement.

In short: if you compile the game with the plugin enabled, you need to have the .dlls there but it doesn't matter if you run the game from Steam or not. If you compile the game without the plugin enabled, then you can remove the .dlls from the compiled folder, but you need to do the #ifdef to ensure the plugin doesn't get called.

CaptainD

Thanks everyone for your answers!   :)
 

eri0o

#8
@CrimsonWizard, I may be confusing things. When I mentioned the stubs, I was thinking about the stubs in this file
https://github.com/adventuregamestudio/ags/blob/master/Engine/plugin/global_plugin.cpp

Does Game.IsPluginLoaded returns true when there's no plugin BUT there are stubs? (in engine, not external ones) I was thinking that for agsteam it would be safe to rely on this but I never tested - I have delayed building that plugin forever...

I have played one steam game on Linux that weren't Linux by using just the in-engine stubs - it was using an old agsteam plugin, this was the reason I recently add a missing stub there.

Crimson Wizard

Quote from: eri0o on 06 Jul 2021, 21:25
@CrimsonWizard, I may be confusing things. When I mentioned the stubs, I was thinking about the stubs in this file
https://github.com/adventuregamestudio/ags/blob/master/Engine/plugin/global_plugin.cpp

There are these stubs in the engine, but also "steam stub" plugin which is a real dll but without any real steam connection.

IIRC when the engine is using its own stubs the plugin is not considered active, because there's nothing to hook with or send events.

eri0o

Quote from: Crimson Wizard on 06 Jul 2021, 21:27
IIRC when the engine is using its own stubs the plugin is not considered active, because there's nothing to hook with or send events.

Ah, yes, I think you are right.

@LauraHunt, I think by using that mechanism it should be possible to detect the steam plugin at runtime. If it does crash at start, please send me the steam plugin used!

Detecting at runtime should be helpful to avoid building twice if desired.

Laura Hunt

Quote from: eri0o on 06 Jul 2021, 21:31
Quote from: Crimson Wizard on 06 Jul 2021, 21:27
IIRC when the engine is using its own stubs the plugin is not considered active, because there's nothing to hook with or send events.

Ah, yes, I think you are right.

@LauraHunt, I think by using that mechanism it should be possible to detect the steam plugin at runtime. If it does crash at start, please send me the steam plugin used!

Detecting at runtime should be helpful to avoid building twice if desired.

eri0o, not sure if there's been a confusion. I am not using the Game.IsPluginLoaded technique in my game. I am doing what monkey056 recommends at the very bottom of his plugin's README, which is to create an auxilary script: https://github.com/monkey0506/agsteam

(Also, I have no idea what a stub is :-D)

I guess doing Game.IsPluginLoaded would save you having to build twice, but on the other hand, you would have to wrap every single call to the plugin (for example, every time you trigger an achievement) in a condition such as if (Game.IsPluginLoaded("plugin_name")) // {do the stuff}. I personally prefer doing it with the #ifdef, even if it means I have to create two builds.

Crimson Wizard

#12
Quote from: Laura Hunt on 07 Jul 2021, 19:32
I guess doing Game.IsPluginLoaded would save you having to build twice, but on the other hand, you would have to wrap every single call to the plugin (for example, every time you trigger an achievement) in a condition such as if (Game.IsPluginLoaded("plugin_name")) // {do the stuff}.

No, it does not work like that, and if having plugin functions in script worked without plugin, then you would not have to wrap anything.

Laura Hunt

Quote from: Crimson Wizard on 07 Jul 2021, 20:01
Quote from: Laura Hunt on 07 Jul 2021, 19:32
I guess doing Game.IsPluginLoaded would save you having to build twice, but on the other hand, you would have to wrap every single call to the plugin (for example, every time you trigger an achievement) in a condition such as if (Game.IsPluginLoaded("plugin_name")) // {do the stuff}.

No, it does not work like that, and if having plugin functions in script worked without plugin, then you would not have to wrap anything.

Then I haven't understood how Game.IsPluginLoaded works. In order to, e.g., trigger an achievement, you need to do something like:

Code: ags
AGS2Client.SetAchievementAchieved(ACH_FINISH_ACT_1);


But if you compile the game with the plugin enabled and then remove the .dlls from the Compiled folder, then the game will crash when it gets to that line. So how would Game.IsPluginLoaded be used in this case in order to avoid that?


Crimson Wizard

#14
Quote from: Laura Hunt on 07 Jul 2021, 22:05
But if you compile the game with the plugin enabled and then remove the .dlls from the Compiled folder, then the game will crash when it gets to that line. So how would Game.IsPluginLoaded be used in this case in order to avoid that?

You can't use Game.IsPluginLoaded to avoid that, it was not meant for this.

In this particular situation it only makes any sense if these functions were provided by something else to prevent the linking errors. Another plugin, the script*, or the engine itself.

* that would be interesting to test if adding them in script works; script functions registration works somewhat differently, but I cannot tell by memory whether that will work or no.


NOTE: If the function implementation is missing the game won't crash when it gets to the particular line, it will error earlier, when loading the script.

SMF spam blocked by CleanTalk