WIP: Remove hardcoded Unvanquished references#16
WIP: Remove hardcoded Unvanquished references#16DefaultUser wants to merge 6 commits intoDaemonEngine:masterfrom
Conversation
|
Going to link this here since this seems related: Unvanquished/Unvanquished#817 |
src/common/Defs.h
Outdated
| #undef game | ||
| #define game(x) { PRODUCT_NAME_##x, PRODUCT_NAME_LOWER_##x, PRODUCT_VERSION_##x, DEFAULT_BASE_PAK_##x, GAMENAME_STRING_##x, GAMENAME_FOR_MASTER_##x, MASTER_SERVER_NAME_##x, IRC_SERVER_##x, IRC_CHANNEL_##x, WWW_BASEURL_##x, UNNAMED_SERVER_##x } | ||
|
|
||
| const gameinfo_t gamesinfo [ ] = { GAMES }; |
There was a problem hiding this comment.
I really don't like the macro-based approach and the overall C-ness of gameinfo_t, I think it could lead to nasty issues and make it harder to extend in the future
src/common/System.h
Outdated
| #ifndef COMMON_SYSTEM_H_ | ||
| #define COMMON_SYSTEM_H_ | ||
|
|
||
| extern const gameinfo_t* current_game; |
There was a problem hiding this comment.
Why do you use current_game directly if you have a getter? I think this should be an implementation detal.
src/common/Defs.h
Outdated
|
|
||
| #define IRC_SERVER "irc.freenode.org" | ||
| #define IRC_CHANNEL "unv-lobby" | ||
| #define WWW_BASEURL_UNV "dl.unvanquished.net/pkg" |
There was a problem hiding this comment.
Some of these could even become cvars.
There was a problem hiding this comment.
cvars for this kind of stuff sounds good
There was a problem hiding this comment.
I feel an UNV-suffixed definition or Cvar is still a branding that shouldn't be present in a game-agnostic engine.
There was a problem hiding this comment.
The cvar doesn't need the unv suffix
src/engine/qcommon/files.cpp
Outdated
|
|
||
| // Cvars to select the base and extra packages to use | ||
| static Cvar::Cvar<std::string> fs_basepak("fs_basepak", "base pak to load", 0, DEFAULT_BASE_PAK); | ||
| static Cvar::Cvar<std::string>* fs_basepak; |
There was a problem hiding this comment.
Why does this need to be a pointer? Can't you just change its value instead of allocating a new one?
There was a problem hiding this comment.
Looks like this is also what breaks the build.
src/engine/server/sv_main.cpp
Outdated
| #define HEARTBEAT_GAME PRODUCT_NAME | ||
| #define HEARTBEAT_DEAD PRODUCT_NAME "-dead" | ||
| #define HEARTBEAT_GAME getGameinfo()->name | ||
| #define HEARTBEAT_DEAD va("%s-dead", HEARTBEAT_GAME) |
There was a problem hiding this comment.
I think we can do without macro declarations for these.
|
I don't think we need to have this be a runtime thing. I don't think using the same game engine binary for different games should really be a goal. Each game should set overriding defines and have these compiled into their binary. I think Unvanquished made a mistake when we released our game with a "daemon" binary instead of an "unvanquished" binary. That said, I do agree we need to un-hardcode Unv references everywhere. |
|
I think we should ensure the client engine is able to work regardless of the game it came from. |
|
That's not a problem to just rename |
|
It is a worthy goal to have a single Daemon binary be able to run all games seamlessly and not have any hardcoded references to Unv. In most cases replacing "Unvanquished" with "Daemon" should be enough. However I don't think having a single "daemon.exe" for all games will be convenient in the short-term. On example is that all of Unv's packages are versioned and that we'll want to force the usage of .dpk over .pk3 (see #14). On the contrary Xonotic will want support for legacy packages to stay compatible with their maps and mods. I don't think it makes sense to be able to switch between the two modes at runtime as it would lower security if somehow servers can expose game mods that dynamically switch on support for legacy packages. |
|
That can be enforced by cvars on the client side. |
|
not related to that current topic but:
All the work done in #14 is thought to make Xonotic being able to use dpk for official assets one day (with version, deps, checksum and all awesome features), loading legacy contrib map as compat ones. I don't think it makes sense for a game using Dæmon engine to rely on broken pk3 vfs for their own official assets they can repackage, insted of getting the best from the engine. To give another example with a slightly different use case when games with open source engine and legacy official closed source assets from company don't allowing modifictions, like wolf:et. These games can't repackage the |
|
I removed the "-game" switch again, instead the gameinfo will be read from a file called "gameinfo.cfg" located in the libpath at runtime. This does break compiling the unvanquished game logic since the new "Gameinfo" class depends on file access for "libpath". This can be fixed by redefining "Q3_VERSION" in the game logic. |
|
Sorry if I'm being a pain, but I'm not sure this is any better than having the information compiled into the binary. The libpath dependency makes it so that you cannot use the same binary with different games without changing gameino.cfg. It doesn't seem there is a way to change this dynamically, and even if there were, i'm not sure there is a strong benefit to this. Still strongly in favor of simply compiling all of this information into the binary to decrease complexity. |
|
Actually you can use the same binary for different games as "libpath" can be set in the commandline arguments. |
|
I'm still not happy with the design of this and agree with @DolceTriade. There are also a whole lot of coding style / nits I want to make but will wait for the final design before doing so to avoid churn. Please refrain from merging before that "style" review. |
|
I don't see the point of having a named engine or having the engine knowing how to launch the game. Isn't it the launcher's job? The Quake Live engine is named quakezero internally, the Natural Selection 2 engine is named spark, no one cares. The engine is just another component of the game. Having the engine named like the game and having the engine embedding hardcoded game reference is only needed when then engine is also the launcher. We already have a launcher. If one day Unvanquished is distributed by some game directory like Steam, users will not care about the engine name and people will not need things to be hardcoded. To host a GoldenEye:Source server I just do: |
| #define PROTOCOL_VERSION 86 | ||
|
|
||
| #define URI_SCHEME GAMENAME_STRING "://" | ||
| #define URI_SCHEME "dgp://" |
There was a problem hiding this comment.
Looking at this I am no longer sure that the URI_SCHEME can be engine specific. How should the OS know what game to start when you click a link with an engine specific URI_SCHEME?
There was a problem hiding this comment.
External tools would only need to call the engine, the game for the server should be part of the out of band protocol, I think getstatus shows it.
There was a problem hiding this comment.
@mbasaglia with current file layout it works only if you mix assets from different games within same directories, which is ok for small mods but not for complete different games (I don't want to share the same pkg/ dir for both xonotic and unvanquished games for example) so the engine must known the game before joining the server 😕 or the file layout must be completely redesigned.
There was a problem hiding this comment.
By the way, it's not engine's task to redirect url calls to engine, not a problem to have both unvanquished and xonotic reads the url scheme if the desktop knows how to redirect these url to xonotic or unvanquished (I don't have magical solution, though). The problem of this kind of url stuff is it's more the job for a launcher (like the unvanquished updater), or a job for a game library manager like Steam or Lutris. If we want a common url for multiple games, it's something to design outside of Unvanquished : it's designing a standard with protocols, formats and common tools others can reuse, praising for adoption. 😐
There was a problem hiding this comment.
We can keep unv:// for the moment with a glorious FIXME: comment, the protocol is by definition something about others, so we have to take time to think properly about it, and it must not be a blocker for other things.
There was a problem hiding this comment.
@DefaultUser as it seems too early to think about protocol uri scheme and I don't want this to block the PR, can you revert this line to unv:// and add a FIXME: comment?
There was a problem hiding this comment.
After deep thoughts (I'm not sure) and long time passed (for sure), it now feels stupid to me to have the URI_SCHEME to be engine specific. What we need in engine is a way to grok the URI_SCHEME the game developer wants it to grok. It's up to the game developer to properly configure player system to redirect given URI_SCHEME to the engine with proper options (libpath containing the config file telling the URI_SCHEME proto).
So it now looks very OK to me to set that value in the config file.
Maybe name that constant URI_PROTO to be more explicit than GAMENAME_STRING.
Years later I completely forgotten what GAMENAME_STRING meant and I had to read the code to understand it was the URI proto string.
I guess there must be two versions: the engine version (hardcoded), and the game version (defined by game code). |
|
If we were going to insist on daemon somehow being able to figure out what game you meant, we could combine it with the idea of naming the binary after the game - if e.g. an |
|
wat? |
|
Any news on this @illwieckz @Kangz? |
|
Come over to #108 for more in-depth discussion of these issues. |
|
To me having a simple config files with that:
can be done the proposed way and I don't see any reason to not do it or to wait for something else. URI scheme can be discussed later, and well, it has to be discussed later. That problem is more complex because it's not how the engine initialize itself but how third-party tools talk to the engine a game specific way. It's not a big problem to fix other issues and we keep IRC channel and server thing can be discussed later, and I'm sorry but it is now made entirely obsolete with the need to mute unregistered clients due to increasing IRC spam, and it's obviously not possible to store an irc nick password in a config file distributed to anyone. The problem and its solution is out of topic.
The purpose of gameinfo.cfg is to be stored in libpath and distributed with vm. It's like loading a shared lib or a nexe except it's not compiled but interpreted since it's a config file. If the current code is not able to read the This also means we can go the “very small config file” for this now and talk later for other issues. Unlike the file-system initialisation, there is no security issue in having the game code tweaking the surfaceflags in runtime, for example. |
|
@DefaultUser, can you rebase this on master? I would like to experiment with it. :-) |
4dd5ada to
bdb3c5b
Compare
|
I cherry-picked the relevant commits and force-pushed the result |
In scope of this engine .cfg files are filled with commands. The Gameinfo file does not contain commands
| @@ -0,0 +1,7 @@ | |||
| NAME GameName | |||
| VERSION 0.0 | |||
| DEFAULT_BASEPAK mybasepak | |||
There was a problem hiding this comment.
why not just BASEPAK? We already know this is the default since it's stored in that file.
There was a problem hiding this comment.
After deep thoughts, this may be called BASENAME, there may be more than one usage for a basename.
We can also use it to compute ~/.local/share/${BASENAME} while other OS may do something with NAME instead if it's more common on such OS to do that (My Games/${GAME}).
I don't think it's a bad idea to enforce the basename is also the basepak name.
It may also make easier to reimplement per-directory full-conversion downloadable mod like quake3 did, by using this BASENAME (unvanquished or quake6) string instead of a shortcut (unv or baseq6).
| MASTERSERVER1 master.example.net | ||
| MASTERSERVER2 master.template.net | ||
| WWW_BASEURL dl.example.net/pkg | ||
| GAMENAME_STRING abc |
There was a problem hiding this comment.
URI_PROTO seems to be better or something like that.
| @@ -0,0 +1,7 @@ | |||
| NAME GameName | |||
| VERSION 0.0 | |||
| DEFAULT_BASEPAK mybasepak | |||
There was a problem hiding this comment.
After deep thoughts, this may be called BASENAME, there may be more than one usage for a basename.
We can also use it to compute ~/.local/share/${BASENAME} while other OS may do something with NAME instead if it's more common on such OS to do that (My Games/${GAME}).
I don't think it's a bad idea to enforce the basename is also the basepak name.
It may also make easier to reimplement per-directory full-conversion downloadable mod like quake3 did, by using this BASENAME (unvanquished or quake6) string instead of a shortcut (unv or baseq6).
| @@ -0,0 +1,7 @@ | |||
| NAME GameName | |||
There was a problem hiding this comment.
I don't think anything prevents to use a real-life example like Unvanquished default strings in the template.
There was a problem hiding this comment.
Same for the default values in the code if undefined.
Note that in the future we would be able to make the engine being able to load some built-in asset and display an error (like Darkplaces does) so the template and the hardcoded version would reference that dummy game that does nothing at all instead.
|
This is an idea I just got, let's imagine those two builtin in_name "Unvanquished"
builtin in_baseName "unvanquished"
builtin in_basePak "unvanquished"
builtin in_version "0.51.2"
builtin in_master1 "master.unvanquished.net"
builtin in_master2 "master2.unvanquished.net"
builtin in_wwwBaseURL "dl.unvanquished.net/pkg"
builtin in_protoUrl "unv"builtin in_name "Xonotuc"
builtin in_baseName "xonotic"
builtin in_basePak "xonotic"
builtin in_version "0.9.0"
builtin in_master1 "master.xonotic.org"
builtin in_master2 "master2.xonotic.org"
builtin in_wwwBaseURL "dl.xonotic.org/pkg"
builtin in_protoUrl "xon"
set fs_legacyPaks on
set fs_maxSymlinkDepth 1
set r_dpMaterial on
set r_dpBlend onYour non-cfg parser would read all lines starting with Then, we would hack the command line parser to read every line that does not start with a Note that some of these builtins may use normal cvars, like the I imagined that because Xonotic would win a lot from being able to set compatibility cvars in that file, about those, an user may choose to disable them without breaking the game itself, but they must be set by default. |
|
Also, I don't think it's a good idea to set the version in that file. Either the engine has a version, whatever the game, and it's better to hardcode it, either the game has a version, end the game can set it without recompiling the engine. So, basically, I think that is good: builtin in_name "Unvanquished"
builtin in_baseName "unvanquished"
builtin in_master1 "master.unvanquished.net"
builtin in_master2 "master2.unvanquished.net"
builtin in_wwwBaseURL "dl.unvanquished.net/pkg"
builtin in_protoUrl "unv"builtin in_name "Xonotuc"
builtin in_baseName "xonotic"
builtin in_master1 "master.xonotic.org"
builtin in_master2 "master2.xonotic.org"
builtin in_wwwBaseURL "dl.xonotic.org/pkg"
builtin in_protoUrl "xon"
set fs_legacyPaks on
set fs_maxSymlinkDepth 1
set r_dpMaterial on
set r_dpBlend on |
|
Superseded by #588. |
This adds support for other games by unhardcoding several references to
Unvanquished.
This switch automatically changes:
In my opinion,
PRODUCT_VERSION/getGameinfo()->versionshould be defined by the game's Menu code, but for now I will leave it in.