diff --git a/Documentation/Main.md b/Documentation/Main.md index abd8ea81..822f4084 100644 --- a/Documentation/Main.md +++ b/Documentation/Main.md @@ -9,6 +9,8 @@ This is a software development kit (SDK) and development environment created by The Nuclide project produces a freely available game-logic component and development platform on top of [FTEQW](https://www.fteqw.org); which is the engine we happen to use. +**The general idea is that Nuclide takes care of ~90% of the code you shouldn't have to worry about.** + The goal is to create a modern research base for new advancements, as well as to have a stable base with a decent API for making games. @@ -16,13 +18,17 @@ It comes with a simple example game (simply referred to as 'Base') and some test General feature overview: -- SDK in the spirit of 'id Tech' development environments -- Client-side predicted movement, predicted weapons and vehicle systems -- Implementations of well known, established entity classes as seen in popular and critically acclaimed games -- Reference implementations for a lot of features exlusive to the FTEQW engine -- Designed to be familar to developers who are used to GoldSrc and Source engine - project workflows -- Everything written from scratch with the modern QuakeC language advancements in mind +- The 'missing' SDK for engines like FTEQW +- Support for client-side predicted movement, weaponry and vehicles +- Documented APIs for everything you need to interface with the engine +- APIs and Frameworks for managing updates, mods, servers, and platform specific features +- Complete re-implementations of hundreds of entities, from GoldSrc/Source engine games +- Entity communication via traditional one-way triggers, or our Source Engine I/O compatible system +- Includes BotLib, a framework for multiplayer-AI that can receive game-specific overrides +- Includes VGUILib, a re-imagining of Valve's GUI library, which can also be used for in-game surface based interfaces +- Designed to be familar to developers coming from GoldSrc/Source +- VR/XR aware codebase +- All permissively licensed ### 1. Why might I want to use it? {#why} @@ -67,9 +73,9 @@ If you do posess a basic knowledge of the following: Then you will have a good time. We strive to keep the codebase portable and conform to open standards wherever possible. -This means that if you develop on Windows, you probably want to install something like [Cygwin](https://www.cygwin.com/) to make this bearable. +This means that if you develop on Windows, you probably want to install something like WSL or even [Cygwin](https://www.cygwin.com/) to make this bearable. -Please don't ask us how to learn UNIX/Cygwin. +Please don't ask us how to use WSL or Cygwin. We do not provide support for either. We do not develop on Windows. **This is a development kit and a development environment. This is not a game.** diff --git a/README.md b/README.md index 966eaf0b..3c0e2edf 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,27 @@ # ![FTE Logo](Documentation/fte.svg) Nuclide - Software Development Kit -Software Development Kit, built around idTech with focus on advanced features and +Software Development Kit, built around id Technology with focus on advanced features and clean-room implementations of true-and-tested game-logic frameworks. -It's been used to ship a commercial product. So it's proven to some extent. + +*It's been used to ship a commercial product. So it's proven to some extent.* All of this is written in QuakeC, but there's also some GLSL and shell scripts in here. If you and your team are unfamilar with any of these, you may want something else. +## Features + +- The missing SDK for engines like FTEQW +- Support for client-side predicted movement, weaponry and vehicles +- Documented APIs for everything you need to interface with the engine +- APIs and Frameworks for managing updates, mods, servers, and platform specific features +- Complete re-implementations of hundreds of entities, from GoldSrc/Source engine games +- Entity communication via traditional one-way triggers, or our Source Engine I/O compatible system +- Includes BotLib, a framework for multiplayer-AI that can receive game-specific overrides +- Includes VGUILib, a re-imagining of Valve's GUI library, which can also be used for in-game surface based interfaces +- Designed to be familar to developers coming from GoldSrc/Source +- VR/XR aware codebase +- All permissively licensed + ## Documentation You can find up-to-date documentation over at https://developer.vera-visions.com/ @@ -14,10 +29,17 @@ You can find up-to-date documentation over at https://developer.vera-visions.com This documentation is built entirely from this repository using doxygen. You do not need to be on-line to view the documentation. +You can build the HTML documentation by running `doxygen` inside the root +of the repository. The output is located under `Documentation/html/index.html` + +## Support + +You can get personal support for Nuclide by negotiating a support contract with us. Reach out to marco@vera-visions.com if you want to know about our rates. + ## Special Thanks To id software and specifically John Carmack for having released the sources of -various pieces of id Technology under free licenses. +various works of id Technology under free licenses, without which a project like this would be unfeasible. David Walton for **FTEQW** and the **FTEQCC** compiler, which is the brain of this SDK. diff --git a/platform/cvars.cfg b/platform/cvars.cfg index 7307f54d..3e005249 100644 --- a/platform/cvars.cfg +++ b/platform/cvars.cfg @@ -64,6 +64,11 @@ seta mp_td_dmgToKick 300 // Specifies how much damage one player has to inflict seta mp_td_dmgToWarn 200 // Specifies how much damage one player has to inflict to others players before getting warned. alias mp_friendlyfire sv_friendlyFire +// xr related cvars +seta xr_roomScale 1.0 // Scales world<>game translation. +seta xr_viewHeight -48.0 // Specifies the head offset when in XR mode. +seta xr_testInputs 0 // Send faux XR input signals when enabled. + // aliases for the older commands (may be removed some day) alias cl_autojump pm_autoJump alias cl_showfps com_showFPS diff --git a/src/botlib/bot.h b/src/botlib/bot.h index 2381ed96..83a1113b 100644 --- a/src/botlib/bot.h +++ b/src/botlib/bot.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2023 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -15,25 +15,32 @@ */ #define COST_INFINITE 99999 + +/** The desired target destination has been reached. */ #define BOTROUTE_DESTINATION -1 +/** Unloading of the route in progress. */ #define BOTROUTE_END -2 +/** Bot Personality */ typedef enum { - BOT_PERSONALITY_NORMAL, /* this bot will be dynamic */ - BOT_PERSONALITY_AGRESSIVE, /* this bot will always prefer to be attacking */ - BOT_PERSONALITY_DEFENSIVE /* this bot will always prefer to stay behind */ + BOT_PERSONALITY_NORMAL, /**< this bot will be dynamic */ + BOT_PERSONALITY_AGRESSIVE, /**< this bot will always prefer to be attacking */ + BOT_PERSONALITY_DEFENSIVE /**< this bot will always prefer to stay behind */ } botpersonality_t; +/** Bot State */ typedef enum { - BOT_STATE_IDLE, /* this should rarely happen */ - BOT_STATE_PATROLLING, /* this is basically most deathmatch cases */ - BOT_STATE_DEFENDING, /* this is for when bots stay put and stay around spawn, or their teams goalitem */ - BOT_STATE_ATTACKING, /* this is for when bots go to the enemy spawn, or to the enemy team's goalitem */ - BOT_STATE_FLEEING /* this is for when the AI should just get as far away as possible */ + BOT_STATE_IDLE, /**< this should rarely happen */ + BOT_STATE_PATROLLING, /**< this is basically most deathmatch cases */ + BOT_STATE_DEFENDING, /**< this is for when bots stay put and stay around spawn, or their teams goalitem */ + BOT_STATE_ATTACKING, /**< this is for when bots go to the enemy spawn, or to the enemy team's goalitem */ + BOT_STATE_FLEEING /**< this is for when the AI should just get as far away as possible */ } botstate_t; +/** Base class for the Bot AI. +*/ class bot:player { /* routing */ @@ -95,8 +102,10 @@ class bot:player virtual void(string) SetName; }; +/** Adds a bot to the game with some basic info. Returns the resulting entity. __NULL__ if unavailable. */ entity Bot_AddQuick(void); +/** Applies random custom colors to the given bot entity. */ void Bot_RandomColormap(bot target) { diff --git a/src/platform/achievements.h b/src/platform/achievements.h index f30c8985..1bbad702 100644 --- a/src/platform/achievements.h +++ b/src/platform/achievements.h @@ -14,6 +14,15 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/*! @file achievements.h + @brief Achievement APIs + + The Achievements API manages the retrieval, storage and networking + of game achievements. + + This is a work in progress. +*/ + /** Data for an achievement definition. */ typedef struct { diff --git a/src/platform/defs.h b/src/platform/defs.h index 2eb6b13b..1f413e1a 100644 --- a/src/platform/defs.h +++ b/src/platform/defs.h @@ -20,7 +20,6 @@ #include "modserver.h" #include "music.h" #include "richpresence.h" -#include "servers.h" #include "tcp.h" #include "updates.h" #include "gamelibrary.h" diff --git a/src/platform/error.h b/src/platform/error.h index 4c1735f4..6de04c7a 100644 --- a/src/platform/error.h +++ b/src/platform/error.h @@ -1,5 +1,25 @@ +/* + * Copyright (c) 2023 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + var string g_lastDisconnectReason = ""; +/** Query if we've been disconnected from the server. +The function is designed to be run every frame. It will return `true` only once per server session, so check it in one place and cache the result if necessary. This is meant for menu developers. If you are adding onto an existing menu framework, calling it more than once and out of order may break core menu functionality in your module. + +@return Will return `true` if we've been disconnected and `false` any other time. */ bool Error_ServerDisconnected(void) { @@ -18,6 +38,9 @@ Error_ServerDisconnected(void) return true; } +/** Query the last reason for a server disconnect. Will stick and always return something valid when you've been disconnected at least once. + +@return The reason for the disconnect. */ string Error_GetDisconnectReason(void) { diff --git a/src/platform/includes.src b/src/platform/includes.src index e80ddc52..0a6c3da7 100644 --- a/src/platform/includes.src +++ b/src/platform/includes.src @@ -4,7 +4,6 @@ master.qc modserver.qc music.qc richpresence.qc -servers.qc tcp.qc util.qc updates.qc diff --git a/src/platform/modserver.h b/src/platform/modserver.h index b8ebdf22..db4a2f5f 100644 --- a/src/platform/modserver.h +++ b/src/platform/modserver.h @@ -14,6 +14,16 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/*! @file modserver.h + @brief Remote ModServer APIs + + The ModServer API manages the retrieval of custom game info + (usually modifications) into the ModLibrary. + + This is kept separate from ModLibrary, in case where + connections to remote sources is disallowed. +*/ + /* Emscripten builds and mods? Forgetaboutit! */ #ifndef WEBMENU diff --git a/src/platform/music.h b/src/platform/music.h index 26d1cfd6..746fc8b0 100644 --- a/src/platform/music.h +++ b/src/platform/music.h @@ -23,6 +23,8 @@ This is the code that handles how music track id's are translated into different path/naming conventions and file formats. + + Some tracks may only want to be played once (as opposed to looping). */ /* we're forced to support a few different paths */ diff --git a/src/platform/servers.h b/src/platform/servers.h deleted file mode 100644 index bf9acb3b..00000000 --- a/src/platform/servers.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2016-2022 Vera Visions LLC. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -/* returns if a given address is external */ -int Server_IsLan(string address); diff --git a/src/platform/servers.qc b/src/platform/servers.qc deleted file mode 100644 index c6e53cb3..00000000 --- a/src/platform/servers.qc +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2016-2022 Vera Visions LLC. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -int -Server_IsLan(string address) -{ -#if 0 - return (0); -#endif - tokenizebyseparator(address, "."); - - if (argv(0) == "192" && argv(1) == "168") { - return (1); - } else { - return (0); - } -} diff --git a/src/platform/tcp.h b/src/platform/tcp.h index 09c69849..af1d10b7 100644 --- a/src/platform/tcp.h +++ b/src/platform/tcp.h @@ -14,6 +14,21 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/*! @file tcp.h + @brief TCP/IP Networking API + + The TCP API manages the sending/receiving of data over TCP sockets. + + First, establish a connection with TCP_Connect(), which will return + a file descriptior. + If TCP_Connect returns a value below 0, no connection is possible. + You can send data through TCP_Send() once TCP_GetState returns + STATE_CONNECTED. + + You need to run TCP_Frame() on your tcpinfo_t struct every frame + in order to listen to network activity. +*/ + #define TCP_BUFFER_LENGTH 32 /** State of a TCP connection. */ diff --git a/src/shared/cloader.h b/src/shared/cloader.h index 5a1ece4f..ccd03633 100644 --- a/src/shared/cloader.h +++ b/src/shared/cloader.h @@ -14,7 +14,42 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/*! @file cloader.h + @brief Constants macro loader + +Scripters and level designers are able to define parameters through the use +of name-based lookups. + +In the game directory, they are defined within `scripts/constants.txt`. +An example file looks like this: + +``` +// weapon constants +WEAPON_NONE 0 +WEAPON_KNIFE 1 +WEAPON_POTATO 2 +``` + +Within [EntityDefs](Documentation/EntityDef.md) files, you will then be able to set a given key to the value +of one of the defined constants by prefixing the name with a `$` symbol. +That would look something like this: + +``` +"weapon" "$WEAPON_POTATO" +``` + +The same applies to data read within level files and most routines related to parsing key/value pairs, so it is not limited to usage within EntityDef. +*/ + +/** Called upon world init internally to populate our look-up table. +*/ void Constants_Init(void); -string Constants_LookUp(string, string); + +/** Look up a name and retrieve its value. + +@param constName Name of the constant to look up. +@param returnValue The value to return if constName is not defined. +@return The value of the named constant. Will return returnValue if it does not exist. */ +string Constants_LookUp(string constName, string returnValue); var hashtable g_hashConstants; \ No newline at end of file diff --git a/src/shared/colors.h b/src/shared/colors.h index aed6626e..d8298ff9 100644 --- a/src/shared/colors.h +++ b/src/shared/colors.h @@ -15,7 +15,10 @@ */ /** Takes a normalized color vector and returns the hexadecimal equivalent - for "funstrings". E.g. '1.0 0.0 0.0' becomes "^xF00". */ + for "funstrings". E.g. '1.0 0.0 0.0' becomes "^xF00". + +@param color Normalized color value to convert. +@return Returns the funstring equivalent.*/ string Colors_RGB8_to_HEX(vector color) { @@ -23,7 +26,10 @@ Colors_RGB8_to_HEX(vector color) } /** Takes a 0-255 based color vector and returns the hexadecimal equivalent - for "funstrings". E.g. '255 0 0' becomes "^xF00". */ + for "funstrings". E.g. '255 0 0' becomes "^xF00". + +@param color 0-255 based color value to convert. +@return Returns the funstring equivalent.*/ string Colors_RGB255_to_HEX(vector color) { diff --git a/src/shared/defs.h b/src/shared/defs.h index 1a47a975..f7e5bd4c 100644 --- a/src/shared/defs.h +++ b/src/shared/defs.h @@ -126,6 +126,7 @@ string __fullspawndata; #include "colors.h" #include "weapons.h" #include "motd.h" +#include "util.h" #define BSPVER_PREREL 28 #define BSPVER_Q1 29 diff --git a/src/shared/util.h b/src/shared/util.h new file mode 100644 index 00000000..50eddc06 --- /dev/null +++ b/src/shared/util.h @@ -0,0 +1 @@ +void Util_ChangeClass(entity, string); \ No newline at end of file diff --git a/src/shared/util.qc b/src/shared/util.qc index 7be75957..4c0b5710 100644 --- a/src/shared/util.qc +++ b/src/shared/util.qc @@ -60,4 +60,13 @@ Util_IsTeamplay(void) #else return (serverkeyfloat("teams") > 0) ? (true) : (false); #endif +} + +void +Util_ChangeClass(entity objectID, string className) +{ + entity oldSelf = self; + self = objectID; + callfunction(strcat("spawnfunc_", className)); + self = oldSelf; } \ No newline at end of file diff --git a/src/xr/NSXRInput.h b/src/xr/NSXRInput.h index 47c3f7c1..c79b9c4f 100644 --- a/src/xr/NSXRInput.h +++ b/src/xr/NSXRInput.h @@ -14,6 +14,12 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/*! @file NSXRInput.h + @brief Managing of Input sources. + + An NSXRInput contains the state of a potential input source. +*/ + /** Various input device types. Right now each client will have a single head, a 'left' and a 'right' NSXRInput. */ typedef enum diff --git a/src/xr/NSXRSpace.h b/src/xr/NSXRSpace.h index ba3bbab1..8a4b1281 100644 --- a/src/xr/NSXRSpace.h +++ b/src/xr/NSXRSpace.h @@ -14,9 +14,16 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/** This class represents a local client space in the world. +/*! @file NSXRSpace.h + @brief Managing of simulated Spaces. -It's used to handle room to world translation for VR, for example. + NSXRSpace manages the conversion between real-world + to game-world coordinates. + + It's used to handle room to world translation for VR, for example. +*/ + +/** This class represents a local client space in the world. */ class NSXRSpace { public: diff --git a/src/xr/xr.h b/src/xr/xr.h index d092a00c..b1ed9b25 100644 --- a/src/xr/xr.h +++ b/src/xr/xr.h @@ -14,15 +14,20 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/** Called internally by client/server modules for when a player joins. */ void XR_Init(entity); +/** Called internally by client/server modules for when a player leaves. */ void XR_Shutdown(entity); +/** Returns if XR features are available on the entity. */ bool XR_Available(entity); +/** Called on client/server modules after an input packet has been dispatched. */ void XR_InputFrame(entity); #ifdef CLIENT +/** Sets up view properties from a client entity before a rendering call. */ void XR_UpdateView(entity); #endif -var float autocvar_xr_roomscale = 1.0f; -var float autocvar_xr_viewheight = -48.0f; -var bool autocvar_xr_debug_fakeinputs = false; \ No newline at end of file +var float autocvar_xr_roomScale = 1.0f; +var float autocvar_xr_viewHeight = -48.0f; +var bool autocvar_xr_testInputs = false; \ No newline at end of file diff --git a/src/xr/xr.qc b/src/xr/xr.qc index 840c6f00..91a5ab76 100644 --- a/src/xr/xr.qc +++ b/src/xr/xr.qc @@ -73,7 +73,7 @@ XR_UpdateView(entity ePlayer) /* now we get the HMD's org/ang and send that off to the renderer */ setviewprop(VF_ANGLES, pl.m_xrInputHead.GetAngles()); - setviewprop(VF_ORIGIN, pl.m_xrInputHead.GetOrigin() + [0,0,autocvar_xr_viewheight]); + setviewprop(VF_ORIGIN, pl.m_xrInputHead.GetOrigin() + [0,0, autocvar_xr_viewHeight]); } else { pl.m_xrSpace.SetOrigin(g_view.GetCameraOrigin()); pl.m_xrSpace.SetAngles(input_angles); @@ -95,7 +95,7 @@ XR_InputFrame(entity ePlayer) if (!pl.m_xrSpace) return; - if (autocvar_xr_debug_fakeinputs) { + if (autocvar_xr_testInputs) { input_head_status = (XR_STATUS_ORG | XR_STATUS_ANG); input_left_status = (XR_STATUS_ORG | XR_STATUS_ANG); input_right_status = (XR_STATUS_ORG | XR_STATUS_ANG); @@ -113,7 +113,6 @@ XR_InputFrame(entity ePlayer) pl.m_xrInputHead.InputFrame(); pl.m_xrInputLeft.InputFrame(); pl.m_xrInputRight.InputFrame(); - } bool