Jump to content

Determine if running Don't Starve Together or Don't Starve.


Recommended Posts

After a lot of hard work I've finally found a sure fire way to determine if you have Don't Starve or Don't Starve Together open. Why does this particularly matter? In Don't Starve Together "GLOBAL.GetWorld()" is depreciated and therefore forces use to use "GLOBAL.TheWorld" which does not exist in Don't Starve. Instead of recreating my mod and have to update two versions, I found a way to determine which of the game versions we are running. It will work until Klei fixes this small hackery, which if they do fix it I hope they at least add an option or variable that allows us to know which client is running.

 

CODE:

--  Get the current running game engine. (e.g. Don't Starve (true) or Don't Starve Together (false))DS = (string.match(debug.getinfo(1).source, "dont_starve") == "dont_starve")

Just add that to your modmain.lua file as a global variable and anytime you need to do a check for the version, true is Don't Starve and false is Don't Starve Together.

 

I hope this helps people who are like me and only want to have to update a single mod for both games.

 

~Kzisor/Ysovuka

Link to comment
Share on other sites

 

@Kzisor, You should have asked sooner =\

 

 

/le sigh.

 

Oh well so much for my Tuesday afternoon being productive....thank you much for the code, now I can properly update my new mod.

 

P.S. I searched for 3 hours trying to find that information, where exactly whatwas that located?

 

This seems to be throwing an error on my end.

 

Error:

lua:22: attempt to call method 'GetSteamAppID' (a nil value)

 

Note: I imported TheSim via GLOBAL.

Edited by Kzisor
Link to comment
Share on other sites

@Kzisor, You can click the little arrow at the top-right of the quote to jump to the post.

 

Hmm... Well, I'm guessing the DONT_STARVE_APPID and such should be global too, but that's not the error you're getting. I haven't used the method myself, maybe Mark killed it since Seth wrote it. 

Link to comment
Share on other sites

@Kzisor, You can click the little arrow at the top-right of the quote to jump to the post.

 

Hmm... Well, I'm guessing the DONT_STARVE_APPID and such should be global too, but that's not the error you're getting. I haven't used the method myself, maybe Mark killed it since Seth wrote it.

He's probably running it on standalone (humble store/GOG), where TheSim:GetSteamAppID() doesn't exist, and so Seth's suggestion fails. That why I use

local is_dstfunction IsDST()    if is_dst == nil then        is_dst = kleifileexists("scripts/networking.lua") and true or false    end    return is_dstend
instead, which works everywhere (I cache the result in a variable because a filesystem access is relatively slow).

And Kzisor, I wouldn't quite recommend your original method because it might fail if the user installs the game on a non-standard installation path. This is especially troublesome for the Linux standalone version, which is portable (the game folder may be moved anywhere and renamed to anything), and released as just an archive which you decompress wherever.

Edited by simplex
Link to comment
Share on other sites

@Kzisor, You can click the little arrow at the top-right of the quote to jump to the post.

 

Hmm... Well, I'm guessing the DONT_STARVE_APPID and such should be global too, but that's not the error you're getting. I haven't used the method myself, maybe Mark killed it since Seth wrote it. 

 

I jumped to that but, didn't find anything of usefulness.

 

He's probably running it on standalone (humble store/GOG), where TheSim:GetSteamAppID() doesn't exist, and so Seth's suggestion fails. That why I use

local is_dstfunction IsDST()    if is_dst == nil then        is_dst = kleifileexists("scripts/networking.lua") and true or false    end    return is_dstend
instead, which works everywhere (I cache the result in a variable because a filesystem access is relatively slow).

And Kzisor, I wouldn't quite recommend your original method because it might fail if the user installs the game on a non-standard installation path. This is especially troublesome for the Linux standalone version, which is portable (the game folder may be moved anywhere and renamed to anything), and released as just an archive which you decompress wherever.

 

 

Very interesting simplex. However, no I actually was using Steam when using that particular code. Does your particular function work across all medians of operating systems?

Link to comment
Share on other sites

Very interesting simplex. However, no I actually was using Steam when using that particular code. Does your particular function work across all medians of operating systems?

Wow, I just checked and you're right, TheSim:GetSteamAppID() doesn't even exist in Steam's release of singleplayer. I don't see how it could be useful at all then, to be honest.

But anyway, yes, my method works in all platforms. It also works at worldgen.

Link to comment
Share on other sites

Wow, I just checked and you're right, TheSim:GetSteamAppID() doesn't even exist in Steam's release of singleplayer. I don't see how it could be useful at all then, to be honest.

But anyway, yes, my method works in all platforms. It also works at worldgen.

 

Wonderful, excellent find simplex!

 

I'm documenting my code for future and others references.

 

Note my code:

--  Get the current running game engine.DST = nilfunction IsDST()	return (DST == nil) and kleifileexists("scripts/networking.lua") and true or falseendDST = IsDST()-- Gets the Worldworld = (not DST and _G.GetWorld) or (DST and _G.TheWorld) or nilfunction PostInit(inst)local function Blah(inst)if inst:HasTag("DS") then-- Code for DS.else-- Code for DSTendif not DST theninst:AddTag("DS")endreturn instend
Edited by Kzisor
Link to comment
Share on other sites

 

I think this needs to be:

world = (not DST and _G.GetWorld()) or (DST and _G.TheWorld) or nil

(GetWorld() is a function, but TheWorld is a constant)

 

 

Actually it doesn't. It works perfectly fine in Don't Starve standalone however, it doesn't work in DST because TheWorld is a constant. Still trying to figure out how to properly execute that.

Edited by Kzisor
Link to comment
Share on other sites

@Kzisor, Yes, so either you need to change the places later on in the code where you use "world()" to "(type(world) == 'table' and world or world())" or you need to change the places later on in the code to "world" instead, and use the changed line I provided above.

Edited by rezecib
Link to comment
Share on other sites

@rezecib, the problem is that in DST world was always nil with my line of code, I had to change it.

 

For completeness here is the error you should receive with the previous code:

lua"]:96: attempt to call global 'world' (a nil value)

 

The solution is easy though, simply change:

world = (not DST and _G.GetWorld) or (DST and _G.TheWorld) or nil

to

world = function() if not DST then return _G.GetWorld() else return _G.TheWorld endend

Now it works in both Don't Starve and Don't Starve together and yes, you must use world as a function 'world()' in place of 'GLOBAL.TheWorld'.

Edited by Kzisor
Link to comment
Share on other sites

Actually it doesn't. It works perfectly fine in Don't Starve standalone however, it doesn't work in DST because TheWorld is a constant. Still trying to figure out how to properly execute that.

rezecib is correct. You're having issues because when mods are loaded the world entity hasn't been spawned yet. Mods are loaded at the end of main.lua, on line 289. After main.lua finishes, gamelogic.lua runs, and it is only there (on lines 467 or 470, within the function PopulateWorld) that the world entity is spawned. The line numbers I gave apply for DST, but the same argument (with different line numbers) apply for singleplayer.

You should only try to fetch the world entity in a sim postinit or later (such as in prefab constructors or prefab postinits; the world entity is the first entity to be spawned).

I also would suggest being mindful of how you use tags, since in DST they are transmitted to all clients, and thus you may end up wasting bandwidth, where a simple "inst.DS = true" would suffice. However, in this particular case this isn't an issue, since you're only adding a tag precisely in the singleplayer case.

Link to comment
Share on other sites

rezecib is correct. You're having issues because when mods are loaded the world entity hasn't been spawned yet. Mods are loaded at the end of main.lua, on line 289. After main.lua finishes, gamelogic.lua runs, and it is only there (on lines 467 or 470, within the function PopulateWorld) that the world entity is spawned. The line numbers I gave apply for DST, but the same argument (with different line numbers) apply for singleplayer.

You should only try to fetch the world entity in a sim postinit or later (such as in prefab constructors or prefab postinits; the world entity is the first entity to be spawned).

I also would suggest being mindful of how you use tags, since in DST they are transmitted to all clients, and thus you may end up wasting bandwidth, where a simple "inst.DS = true" would suffice. However, in this particular case this isn't an issue, since you're only adding a tag precisely in the singleplayer case.

 

simplex while populating world in a SimPostInit would resolve the issue, casting it as a function does the same thing.

Link to comment
Share on other sites

simplex while populating world in a SimPostInit would resolve the issue, casting it as a function does the same thing.

It does, but you would have to do the same in DST, by wrapping the fetch of _G.TheWorld in a function. TheWorld is nil when mods are loaded.

Link to comment
Share on other sites

It does, but you would have to do the same in DST, by wrapping the fetch of _G.TheWorld in a function. TheWorld is nil when mods are loaded.

 

I have already accounted for that.

 

Full Code:

--  Get the current running game engine.DST = nilfunction IsDST()	return (DST == nil) and kleifileexists("scripts/networking.lua") and true or falseendDST = IsDST()-- Gets the Worldworld = function()if not DST then return _G.GetWorld()else return _G.TheWorld endend-- Where you would use GLOBAL.GetWorld() or GLOBAL.TheWorld instead use:world()

Simple sweet and you use the exact same code for both versions because world() is already being used for GetWorld.

Edited by Kzisor
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...