-
Notifications
You must be signed in to change notification settings - Fork 2
Getting Started
This guide will walk you through setting up your development environment and creating your first mod for Q2RTXPerimental.
Before you begin, ensure you have the following installed:
| Platform | Minimum Version |
|---|---|
| Windows | Windows 7 x64 (Windows 10 recommended) |
| Linux | Ubuntu 16.04 x86_64 or aarch64 (or binary compatible distributions) |
| Software | Minimum Version | Download Link |
|---|---|---|
| Git | 2.15 | https://git-scm.com/downloads |
| CMake | 3.8 | https://cmake.org/download/ |
| Vulkan SDK | 1.2.162 | https://www.lunarg.com/vulkan-sdk/ |
| GPU Driver (NVIDIA) | 460.82+ | https://www.geforce.com/drivers |
| GPU Driver (AMD) | 21.1.1+ | https://www.amd.com/en/support |
- Windows: Visual Studio 2019 or later (recommended) or Visual Studio Code with C++ extension
- Linux: GCC 7+ or Clang 6+ with standard build tools
- Open a terminal or command prompt
- Clone the repository with all submodules:
git clone --recursive https://github.com/PolyhedronStudio/Q2RTXPerimental.git
cd Q2RTXPerimentalIf you forgot the --recursive flag, initialize submodules manually:
git submodule update --init --recursiveThe engine requires game asset packages to run:
-
Create a
baseq2directory in the repository root if it doesn't exist:mkdir baseq2
-
Download or copy the following required files into
baseq2/:-
blue_noise.pkz- Blue noise textures for path tracing -
q2rtx_media.pkz- Q2RTX media assets -
pak0.pakandpak1.pak- Original Quake II game data files
-
-
For the Q2RTXPerimental-specific content, also include:
-
pak2.pak(if available) - Additional Q2RTXPerimental assets
-
Note: The .pkz files can be found in Q2RTX releases. The original pak files come from your Quake II installation or from GOG.
The build directory must be named build under the repository root (required for shader build rules):
mkdir build
cd buildcmake .. -G "Visual Studio 16 2019" -A x64Or for Visual Studio 2022:
cmake .. -G "Visual Studio 17 2022" -A x64cmake .. -DCMAKE_BUILD_TYPE=ReleaseImportant: Only 64-bit builds are supported.
cmake --build . --config Release- Open
Q2RTXPerimental.slnin Visual Studio - Select "Release" configuration
- Build → Build Solution (Ctrl+Shift+B)
make -j$(nproc)After building, the executable will be in:
-
Windows:
build/Release/q2rtxp.exe -
Linux:
build/q2rtxp
Run it from the repository root directory:
# Windows
.\build\Release\q2rtxp.exe
# Linux
./build/q2rtxpUnderstanding the repository layout:
Q2RTXPerimental/
├── baseq2rtxp/ # Game data directory for Q2RTXPerimental
├── src/
│ ├── baseq2rtxp/ # Game module source code
│ │ ├── clgame/ # Client game module
│ │ ├── svgame/ # Server game module
│ │ └── sharedgame/ # Shared code between client and server
│ ├── client/ # Engine client code
│ ├── server/ # Engine server code
│ ├── refresh/ # Rendering/graphics code
│ └── common/ # Common engine utilities
├── inc/ # Public header files
├── extern/ # External dependencies (submodules)
├── build/ # Build output directory (create this)
├── wiki/ # This documentation
└── CMakeLists.txt # Main CMake configuration
Now that you have the engine built, let's create a simple custom entity as your first mod.
Q2RTXPerimental uses a modular architecture:
- Server Game (svgame): Authoritative game logic, physics, AI
- Client Game (clgame): Client-side prediction, rendering, effects
- Shared Game (sharedgame): Code shared between client and server
For this tutorial, we'll create a simple custom entity on the server side.
Let's create a custom light entity that pulses in brightness:
Create src/baseq2rtxp/svgame/entities/misc/svg_misc_pulselight.h:
#pragma once
#include "svgame/entities/svg_base_edict.h"
/**
* @brief A simple pulsing light entity
*
* This entity demonstrates basic entity creation with a Think callback.
* The light will pulse in brightness over time.
*/
class svg_misc_pulselight_t : public svg_base_edict_t {
public:
// Constructor
svg_misc_pulselight_t() = default;
virtual ~svg_misc_pulselight_t() = default;
// Required: Spawn function
virtual void Spawn() override;
// Think callback for pulsing logic
void PulseThink();
private:
float baseLight = 200.0f; // Base light intensity
float pulseSpeed = 2.0f; // Pulse speed in cycles per second
float pulseAmount = 100.0f; // How much to vary the light
};
// Register the entity type with the spawn system
DECLARE_EDICT_SPAWN_INFO(misc_pulselight, svg_misc_pulselight_t);Create src/baseq2rtxp/svgame/entities/misc/svg_misc_pulselight.cpp:
#include "svg_misc_pulselight.h"
#include "svgame/svg_main.h"
// Register this entity with the spawn system
DEFINE_EDICT_SPAWN_INFO(misc_pulselight, svg_misc_pulselight_t);
/**
* @brief Spawn the pulse light entity
*/
void svg_misc_pulselight_t::Spawn() {
// Call base class spawn first
svg_base_edict_t::Spawn();
// Set entity properties
s.entityType = ET_GENERAL; // Generic entity type
solid = SOLID_NOT; // No collision
movetype = MOVETYPE_NONE; // Doesn't move
// Read spawn parameters from entity dictionary
if (entityDictionary.contains("light")) {
baseLight = std::stof(entityDictionary["light"]);
}
if (entityDictionary.contains("speed")) {
pulseSpeed = std::stof(entityDictionary["speed"]);
}
if (entityDictionary.contains("amount")) {
pulseAmount = std::stof(entityDictionary["amount"]);
}
// Set up model if specified
if (entityDictionary.contains("model")) {
gi.SetModel(edict, entityDictionary["model"].c_str());
}
// Link into world
gi.LinkEntity(edict);
// Set up Think callback
SetThinkCallback(&svg_misc_pulselight_t::PulseThink);
nextThinkTime = level.time + FRAMETIME;
}
/**
* @brief Update light intensity in a pulsing pattern
*/
void svg_misc_pulselight_t::PulseThink() {
// Calculate current light value using sine wave
float time = level.time.count() * pulseSpeed;
float pulse = std::sin(time * M_PI * 2.0f);
float currentLight = baseLight + (pulse * pulseAmount);
// Update light style (would require light system integration)
// For this example, we just demonstrate the pattern
s.renderEffects = (currentLight > baseLight) ? EF_HYPERBLASTER : 0;
// Schedule next think
nextThinkTime = level.time + FRAMETIME;
}Edit src/baseq2rtxp/svgame/CMakeLists.txt (or the appropriate build file) to include your new files:
# Add to the svgame source list
set(SVGAME_SOURCES
# ... existing files ...
entities/misc/svg_misc_pulselight.cpp
entities/misc/svg_misc_pulselight.h
# ... rest of files ...
)cd build
cmake --build . --config ReleaseIn your map editor (like TrenchBroom), you can now place an entity with:
-
classname:
misc_pulselight - light: 200 (base brightness)
- speed: 2.0 (pulses per second)
- amount: 100 (pulse intensity variation)
Now that you've created your first custom entity, explore more advanced topics:
- Entity System Overview - Learn about the entity architecture
- Creating Custom Entities - More advanced entity creation techniques
- Server Game Module - Understanding server-side game logic
- Client Game Module - Adding client-side effects
Q2RTXPerimental supports hot-reloading of game modules during development:
- Start the engine with the console enabled:
+set developer 1 - After rebuilding game DLLs, reload them with:
game_restart
This saves time by not requiring a full engine restart.
- Set
q2rtxpas the startup project - Set breakpoints in your entity code
- Press F5 to start debugging
gdb ./build/q2rtxp
(gdb) run
# Reproduce issue
(gdb) bt # Show backtrace when crash occursUseful console commands for development:
-
developer 1- Enable developer mode with extra logging -
map <mapname>- Load a specific map -
give all- Give all weapons and items (single player) -
god- Toggle god mode -
noclip- Toggle no-clip mode (fly through walls) -
spawn <classname>- Spawn an entity at your location -
sv_cheats 1- Enable cheats (required for some commands)
CMake can't find Vulkan SDK
- Ensure Vulkan SDK is installed and
VULKAN_SDKenvironment variable is set - Restart your terminal/IDE after installing Vulkan SDK
Submodule errors
git submodule update --init --recursive --forceShader compilation errors
- Ensure you created the
builddirectory at the repository root - Check that
glslangValidatoris available in your PATH
"Couldn't load pics/colormap.pcx"
- Ensure
pak0.pakandpak1.pakare in thebaseq2directory
Black screen or no rendering
- Verify GPU drivers are up to date
- Check Vulkan SDK is properly installed
- Ensure your GPU supports Vulkan 1.2+
Game crashes on startup
- Check console output for error messages
- Verify all required
.pkzfiles are present - Try running with
+set developer 1for more verbose logging
If you encounter issues:
- Check existing GitHub Issues
- Join the Discord server for real-time help
- Review the Q2RTX documentation for engine-level issues
Next: Architecture Overview - Learn about Q2RTXPerimental's architecture