Jump to content

[INFO] New "version_compatible" feature


Recommended Posts

Ignore this feature if it isn't necessary to you.

 

How it works

It is useful only for "all_clients_require_mod". And it's useless for "client only" and "server only" mods.

version = "1.7"version_compatible = "1.6"
What does it mean? For example, author of the mod pushes new version to Steam Workshop. As you know, you have to restart your server if you want new players to be able to join your server. Right? Let's say, there is the mod with version 1.6 on your server and the mod with version 1.7 on Steam. This feature tells to the game that 1.6 and 1.7 are compatible and clients with new 1.7 version (without 1.6 cached version) can join on the server with old 1.6 version of the mod.

 

So author of the mod now can safely push new updates of the mod.

 

But be careful. Use it only if you are sure that old and new versions are really compatible. Otherwise this feature can become a source of errors.

 

Tips & Tricks:

 

Let's say that there are two parts in the mod: client side part and server side part. You should know lua well to be sure where is server part and where is client part.

  • ​​Only server part is changed. This means that server uses old server part. It does not affect clients. So versions are compatible.
  • ​​Only client part is changed, e.g. art. This means that new players will see new art, and old players will continue see old art. It does not affect the server mechanics. So versions are compatible.
  • ​​You changed both parts and how they affect each other. For example, you added new net_var. This means that versions are not compatible. In some cases they may be compatible. But I recommend to set version_copatible = "1.7" in such cases to be sure that there won't be errors.
  • ​​You changed recipe - not compatible.
  • ​​You changed few strings, e.g. names or phrases. Compatible.
  • ​​Added missing names. Compatible.
  • ​​Added phrases. Means minor only server side fix. Compatible.
  • ​​Added new AddPrefabPostInit to server side section. Compatible.
  • ​​Changed prefab only after "ismastersim" (e.g. only server side section). Compatible.
  • ​​Changed prefab only before "ismastersim" (e.g. both server and client side). Probably not compatible.
  • etc
How strings are compared

print("2.0" > "1.0") --trueprint("2.0" > "1.") --trueprint("2.0" > "1.9") --trueprint("2.0" > "1.999") --trueprint("2.0" > "1.0000001") --trueprint("2.0a" > "2.0") --trueprint("2.0b" > "2.0a") --trueprint("2.1a" > "2.0b") --trueprint("DST 2.1" > "DST 2.0") --trueprint("2.1 DST" > "2.0 DST") --trueprint("aa" > "a") --trueprint("b" > "a") --trueprint("B" > "A") --trueprint("b" > "aa") --true--etc
You can continue experiments in console. :-)

​But:

print("02.1" > "2.0") --FALSE!!!print("2.0B" > "2.0a") --FALSE!!!print("2.1" > "DST 2.0") --FALSE!!!
Edited by Maris
Link to comment
Share on other sites

  • Developer

Hey @Maris, thanks for posting this! Unfortunately the change I implemented was actually supporting the opposite scenario where the server version is ahead of the client version. I must have misunderstood the original request, but now that I think about it again, I agree with you that it would be more useful to have the the version compatibility work when the Steam Workshop is ahead of the server version.

I'll take a look at this again later today and hopefully we'll be able to it support compatibility for either the server or the client being ahead.

If you're curious to take a look at the existing version check, it's in modindex.lua in ModIndex:DoesModExist.

Link to comment
Share on other sites

At first, let's think about meaning of these two variables.

version - is current version. This is main meaning. So if I'm updating the mod, I have to increase this variable. Obviously.

version_compatible. What about this variable? If this must be equal or above the version, it doesn't make sense. Because in this case I should update all old modinfo.lua. Why update only version_compatible varibale if I could update whole mod?

So, version_compatible variable must be equal or lower than version. Meaning is obvious: "The mod with version [version] is compatible with all versions above or equal [version_compatible]".

Second, I thought about compatibility in both directions. Client must be compatible with server. And server must be compatible with client. On next pictures it does not matter is the client on the right or on the left.

Compatibility:

7444217.png

Incompatibility:

7422712.png

it's in modindex.lua in ModIndex:DoesModExist.

I saw the code. Here it is:

function ModIndex:DoesModExist( modname, desired_version, version_compatible )	local result = false	local modinfo = self:GetModInfo(modname)	if modinfo ~= nil then		if desired_version >= modinfo.version and modinfo.version >= version_compatible then			result = true		else			result = false		end	end	print("Does "..modname.." vc:"..version_compatible.. " exist? " .. tostring(result) )	return resultend

​And I'd like to change the code as following:

function ModIndex:DoesModExist( modname, current_server_version, server_version_compatible )	local result = false	local modinfo = self:GetModInfo(modname)	if modinfo ~= nil then		if current_server_version == modinfo.version then			--Versions are equal. 100% compatibility.			result = true		elseif			--server must be compatible with client			tostring(current_server_version) >= tostring(modinfo.version_compatible or modinfo.version) 			--client must be compatible with server			and tostring(modinfo.version) >= tostring(server_version_compatible)		then			result = true		else			result = false		end	end	--print("Does "..modname.." vc:"..server_version_compatible.. " exist? " .. tostring(result) )	print("Server: "..tostring(current_server_version).."/"..tostring(server_version_compatible)		.."; Client: "..tostring(modinfo.version).."/"..tostring(modinfo.version_compatible)		.."; - "..(result and "Compatible" or "Incompatible")	)	return resultend
 

I already tested my code. And it works perfect:

7417592.png

 

P.S.

However I noticed that subscribed mods won't update until user goes to Mods menu and click "Update" button. So user is able to subscribe to the mod and play with old version forever if it's compatible. I think it's not right. The game should check new versions of "all_clients_require_mod" and cache them on every join the new server with these mods.

 

Better behaviour is to automatically select nearest version from all known (existing and cached) mods. But it requires more deep thinking and coding.......

Edited by Maris
Link to comment
Share on other sites

P.S.

However I noticed that subscribed mods won't update until user goes to Mods menu and click "Update" button. So user is able to subscribe to the mod and play with old version forever if it's compatible.

 

This is not accurate.

 

When client's join servers with a mod that is a higher version than their own they will download the newest version from the workshop. If the server has a version that is not the same that is on the workshop then the client will be disconnected due to missing mods or incompatibility with versions of a mod.

 

I know this as a fact because my wife does not download, install or update her mods and yet she has always been able to join the server when I update the mods on my computer. When/if she joins after a mod is updated on the workshop and it was updated after I launched the server then she can not join because she has the newest update.

 

Over the last year both scenario's have become a constant with some mods and it's tiring to have to shut down the dedicated server just to download mods.

 

Link to comment
Share on other sites

  • Developer

Yeah, @Maris, I've put in logic similar to what you have. One slight differences is that I structured/worded it differently that's a bit easier for me to read, but I believe it's logically equivalent. (I haven't tested it yet so feel free to point out my logic errors ;) )
 

if server_version >= modinfo.version then	--server is ahead or equal version, check if client is compatible with server	return modinfo.version >= server_version_compatibleelse	--client is ahead, check if server is compatible with client	return server_version >= modinfo.version_compatibleend

The question I'm pondering now is what do we want to do in the case where the client is behind the server, but still is compatible. Should the client download the latest from the Workshop and try to use that? If the latest ends up not being compatible with the server, then it should fallback to using a cached version probably, but which one? My concern here is that the logic for which mod version gets used will start to be convoluted, and hard for people to tell why the system functioned the way it did.
 

I believe the strong use for this is as @Kzisor mentioned, not requiring the server to always restart when a mod update is published, by allowing for some clients to be ahead of the server.

 

Here's what I'm planning to implement;

 

If you have the exact server version or it's in the cache then use that, otherwise download the latest from the Workshop (grab if it from the cache if it's available). If the Workshop downloaded file is compatible with the server then use it, otherwise search the cache for a compatible version.

 

 

Ideally we'd always be able to download the exact version of the mod that we want from the Workshop, but Steam doesn't currently support versioning of Workshop data. It's something I'm investigating though, as it'd make everyone's lives simpler.

Link to comment
Share on other sites

If you have the exact server version or it's in the cache then use that, otherwise download the latest from the Workshop (grab if it from the cache if it's available). If the Workshop downloaded file is compatible with the server then use it, otherwise search the cache for a compatible version.

I like this plan. :-)

What about part where the client is searching the cache for a compatible version? I think client should use the nearest version to server version. Actually it doesn't really matter which compatible version to pick from all known compatible versions. But I belive that there is a chance of wrong compatibility. And nearest version has maximum compatibility.

We can't count distances between versions but we know the order of versions and that's enough.

V1 < V2 < V3 < SERVER_VERSION < V4 < V5

(Should pick V4)

Also I'd like to mark all versions with different priority as "low compatibility" (but still compatible). Better to pick version with the same priority as on server. Because order of active mods (on client and on server) is important for compatibility too.

 

my wife does not download, install or update her mods

Let your wife install the mod. Then she will need to update the mod manually every time. Edited by Maris
Link to comment
Share on other sites

  • Developer

@Maris, unfortunately my initial plans ended up becoming rather convoluted in the code and the main use for this system is when the client is ahead of the server, so I changed the way it works slightly. Here's how it works now.

When you connect, the client tries to find the exact version that the server uses installed or in the cache, if it can't then it, then it downloads the latest from the Workshop and if it's ahead of the server then it uses the compatibility version value to see if it works with the server's version.

 

It's not ideal because there's a few edge cases that aren't supported, but I believe those will be rare. I'm going to leave the system as is while I investigate a more general solution that will work for all mods, without having to manually specify the version_compatible.

 

 

Thanks for all the thoughts on this topic! It's much appreciated.

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...