Have you done something like `#include <gog.h>´ (or whatever the filename is?)

1 Like

I did, but had it in quotations instead of < >. I think that was wrong because when I changed it, I was getting messages about other files that needed to be included. Worked through including all of those now. Thanks for the suggestion.

The error message is expanded a bit now:

	Line 7: In file included from upload/myextension/src/myextension.cpp:7:
In file included from /var/extender/sdk/4ebe7a1d548eae2398717ed46f9d7d1b103d5503/defoldsdk//include/dmsdk/sdk.h:23:
In file included from /var/extender/sdk/4ebe7a1d548eae2398717ed46f9d7d1b103d5503/defoldsdk//include/dmsdk/vectormath/cpp/vectormath_aos.h:40:
private field 'd' is not used [-Wunused-private-field]
    float d;

	Line 7: private field 'd' is not used [-Wunused-private-field]
    float d;

	Line 59: use of undeclared identifier 'SignInGalaxy'
    {"signInGalaxy", SignInGalaxy},

I imagine something in the GOG sdk is clashing with the Defold sdk, because line 7 in the myextension.cpp file is:

include <dmsdk/sdk.h>

The method I am trying to get a hold of looks like this:

virtual void SignInGalaxy(bool requireOnline = false, IAuthListener* const listener = NULL) = 0;

For each API function you wish to call in an SDK there needs to be a “glue” function in the extension.cpp file. The “glue” function read any arguments coming from the Lua script, calls the API function with the arguments, reads any return values and passes those back to the Lua script.

In the case of the SignInGalaxy function it seems to take two arguments: 1) requireOnline and 2) listener. This means that your “glue” function must read one boolean and one function. Something like this:

// store extension state in a struct
struct GOG
	// constructor
		memset(this, 0, sizeof(*this));

	dmScript::LuaCallbackInfo*  m_SignInListener;
} g_GOG;

static int GOG_SignInGalaxy(lua_State* L) {
	int top = lua_gettop(L);

	// read first argument, the requireOnline boolean
	const bool requireOnline = (bool)luaL_checknumber(L, 1);

	// read the second argument, the Lua listener function to call when logged in
	// destroy any existing listener first
	if (g_GOG.m_SignInListener) {
	g_GOG.m_SignInListener = dmScript::CreateCallback(L, 2);

You also need an instance of the IAuthListener and pass that to the SignInGalaxy() API function. The IAuthListener interface probably defines one or more callbacks with sign in result. In the implementation of these callbacks you read any result data and then call the m_SignInListener.

Also the virtual void SignInGalaxy() is a member function of a class. You need an instance of that class to call it:

gog = // some global function to create a gog context
gog->SignInGalaxy(requireOnline, my_iauth_listerner);

I noticed that Interrogation is on GoG as well: https://twitter.com/InterrogationG/status/1265959675767541762?s=19

@dapetcu21 did you have to implement the GoG Galaxy SDK?

1 Like

Yup. We implemented it for achievements. We should probably open source the native extension. I’ll see if I have some time this weekend to clean it up and put it in a separate project.


That would save my life. :sweat_smile:

1 Like

Nice! That would be very appreciated by @Alex_8BitSkull and others.


Here you go: https://github.com/dapetcu21/defold-gog-galaxy
Some assembly required


Massive thank you! :pray:

1 Like

You’re welcome. Would have posted it sooner, but this thread completely escaped my radar. Thanks to Bjorn for the tag.


I’ve only implemented it in your example project, not my actual game, but I did use my own client id/secret and this is the result:


Once again, thank you very much! This has saved me a ton of grief. I’d put you in the credits, but well, thanks to your work on DefOS you’re already there.

Also thank you to @britzl and @Mathias_Westerdahl for your guidance, thankfully I didn’t have to bombard you with a thousand follow up questions in the end.


Is it ok if I create an Asset Portal entry for this?

And I must say I not not like this line of code:

Usually, we recommend code like this for checking the existance of a native extension module:

if gog then

Yeah, sure. Go for it!

Those pharanteses creeped in because the original Interrogation code was something like local available = not not (env.build_with_gog_achievements and gog_galaxy). I should remove them. The not not is there to convert to a bool.

I had multiple achievement implementations (Steam, GoG and a debug logger) and they all followed the same API, so that’s why I needed that M.available there.

UPDATE: I removed it now. There’s really no need for it outside of that context.

Yeah, I understand why it’s there, but in a conditional check it doesn’t really matter if it’s a table or a boolean, as long as it evaluates to true. Also this as an alternative:

local available = (gog_galaxy ~= nil)

Yes, this notation is more explicit. :+1: I think I carried over this double negation idiosyncrasy from JS, where you otherwise have to check against both null and undefined.


I suspect @dapetcu21 and I are the only ones using this for now. However I figure it’s worth mentioning anyway in case someone else is having issues.

Mac builds recently started failing for me. It seems it’s because GOG’s SDK has been updated. I grabbed the ‘Mac OS X 10.10+ (64 bit)’ download from here (login required) and replaced the old libGalaxy.dylib with libGalaxy64.dylib in lib/osx and res/osx. Seems to be building fine now!