This guide walks you through setting up your development environment and building the VR-Engage examples.
Prerequisites
Development Environment Requirements
Visual Studio Requirements:
- Visual Studio 2022 (version 17.0)
- MSVC v143 toolset
- C++17 language support
- CMake Tools for Visual Studio (recommended)
CMake Requirements:
- CMake 3.16 or later (3.20+ recommended)
- Available in system PATH
- Visual Studio generator support
Required MAK Toolkits:
- VR-Engage toolkit installation
- VR-Forces toolkit installation compatible with VR-Engage version
- VR-Link toolkit installation compatible with VR-Engage version
Optional Toolkits:
- CIGI toolkit installation (required for CIGI integration examples)
Required Environment Variables
The examples build system requires environment variables to locate dependencies. These are configured using the setupEnv.bat script in the examples directory (see step 1 below):
MAK_VRFDIR - VR-Forces installation path
MAK_VRLDIR - VR-Link installation path
MAK_RTIDIR - MAK RTI installation path
QTDIR - Qt installation path
MAK_CIGIDIR - CIGI installation path (only required if building CIGI example)
Understanding Plugin Types and Installation
VR-Engage uses three distinct types of DLLs, each with specific installation locations:
Plugin Types
Frontend Plugins (plugins64/vrEngage/release/):
- Player station components and UI extensions
- Input handling and control logic
- Role-specific frontend behavior
- Examples:
debugMenuAddition.dll, vehicleBlinkerFrontend.dll, commentFrontend.dll
- Created by: VR-Engage component projects
Simulation (Backend) Plugins (plugins64/vrForces/release/):
- Entity actuators and simulation behavior
- Backend physics and state management
- VR-Forces extensions
- Examples:
vehicleBlinkerSim.dll, customProjectile.dll
- Created by: VR-Forces extension projects
Shared Libraries (bin64/):
- Message definitions shared between frontend and backend
- Utility libraries used by multiple plugins
- Protocol-independent code
- Examples:
commentMessage.dll
- Created by: Shared library projects
Installation Directory Structure
<VR-Engage-Installation>
├── bin64/ # Shared libraries and message definitions
│ └── commentMessage.dll
├── plugins64/ # Plugin directories
│ ├── vrEngage/ # Frontend plugins
│ │ ├── debugMenuAddition.dll
│ │ ├── vehicleBlinkerFrontend.dll
│ │ └── commentFrontend.dll
│ ├── vrForces/ # Simulation (backend) plugins
│ │ ├── vehicleBlinkerSim.dll
│ │ └── customProjectile.dll
│ └── vrVantage/ # VR-Vantage plugins
└── ...
Building the Examples
1. Environment Configuration
Navigate to the examples directory and configure your environment:
cd <VR-Engage-Installation>\examples
setupEnv.bat
Edit setupEnv.bat to match your installation paths:
REM Required environment variables
set MAK_VRFDIR=C:\MAK\vrforces5.2
set MAK_VRLDIR=C:\MAK\vrlink5.10
set MAK_RTIDIR=C:\MAK\makRti5.0
set QTDIR=C:\qt\5.15.2
REM Optional environment variables
set MAK_CIGIDIR=C:\Cigi\4.0.3.2
2. Build the Example Projects and Solution
Generate the Visual Studio solution and project files:
This script:
- Automatically calls
setupEnv.bat to configure environment variables
- Runs CMake to generate Visual Studio project files for all examples
- Creates a unified solution file:
build/VR-Engage-Examples.sln
3. Build in Visual Studio
Open the generated solution and build the examples:
- Open
build\VR-Engage-Examples.sln in Visual Studio 2022
- Select RelWithDebInfo configuration from the toolbar (this is the only configuration available)
- Build → Build Solution (or press F7)
The examples CMake configuration sets CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD, which includes the INSTALL target in the default build. This means Build Solution automatically compiles all plugins and copies them to the appropriate VR-Engage installation directories based on plugin type.
Alternatively, build and install from the command line:
cd build
cmake --build . --config RelWithDebInfo
cmake --install . --config RelWithDebInfo
4. Verify Installation
Check plugin installation:
REM VR-Engage frontend plugins
dir "%VRENGAGE_INSTALL_ROOT%\plugins64\vrEngage\release\*.dll"
REM VR-Engage simulation (backend) plugins
dir "%VRENGAGE_INSTALL_ROOT%\plugins64\vrForces\release\*.dll"
REM Shared libraries
dir "%VRENGAGE_INSTALL_ROOT%\bin64\commentMessage.dll"
Test Your Plugin:
- Launch VR-Engage
- Load a scenario and select a role
- Verify your plugin's functionality (the specific test depends on what your plugin does) For example:
- For components: Check that the component initializes (look for log messages)
- For UI extensions: Press SHIFT-F4 to open the debug menu and look for custom entries
- For input handlers: Test the configured input bindings
- Check the log files to confirm your plugin loaded successfully (logs are in the MAK log directory, typically
C:/MAK/logs or as configured via MAK_LOG_DIR):
- Frontend plugins: Check
vrEngage.log for plugin loading messages
- Simulation plugins: Check
vrfSim.log for plugin loading messages (includes plugin metadata from DtPluginInformation)
- Look for any errors or warnings related to your plugin
Debugging Shortcuts
The examples solution includes pre-configured debugging shortcuts for common testing scenarios:
VREngageDebug - Launches VR-Engage alone:
- Right-click
VREngageDebug project → Debug → Start New Instance
- Launches:
vrEngage.exe from the VR-Engage installation
- Use for: Quick testing with a single ownship entity or loading pre-existing scenarios; supports both frontend and simulation plugin testing
VRForcesVREngageDISLocalhost - Launches VR-Forces + VR-Engage (DIS):
- Right-click
VRForcesVREngageDISLocalhost project → Debug → Start New Instance
- Launches VR-Forces with "DIS (7) localhost" exercise connection
- Then launches VR-Engage with matching DIS connection
- Use for: Testing integrated frontend/backend examples with DIS protocol
VRForcesVREngageHLA - Launches VR-Forces + VR-Engage (HLA):
- Right-click
VRForcesVREngageHLA project → Debug → Start New Instance
- Launches VR-Forces with "HLA 1516 Evolved" exercise connection
- Then launches VR-Engage with matching HLA connection
- Use for: Testing integrated frontend/backend examples with HLA protocol
Location in Solution Explorer: All shortcuts are organized under the "Shortcuts" folder
How They Work:
- These are custom targets created by the CMake build system
- They use
VS_DEBUGGER_COMMAND to execute batch files or executables
- Batch files are generated in
examples/batchFiles/ during CMake configuration
- Generated batch files handle proper working directory and command-line arguments
Iterative Development Workflow
After the initial full build, you can work on individual examples more efficiently.
Initial Setup (One-Time Requirement)
The CMake install configuration requires all example targets to be built at least once:
cd build
cmake --build . --config RelWithDebInfo
cmake --install . --config RelWithDebInfo
Why this is required: The INSTALL project depends on all example targets. CMake generates installation rules that reference all built DLLs, so each target must be built successfully before the install step can complete.
Working on Individual Examples
Once you've completed the initial full build, you can iterate on specific examples:
Option 1: Visual Studio
- Open
build\VR-Engage-Examples.sln
- Right-click the specific example project (e.g.,
notification) → Build
- Right-click INSTALL project → Build
- The INSTALL project will copy only the rebuilt DLLs to the VR-Engage installation
Option 2: Command Line (Single Example)
cd build
cmake --build . --config RelWithDebInfo --target notification
cmake --install . --config RelWithDebInfo
Option 3: Command Line (Multiple Specific Examples)
cd build
cmake --build . --config RelWithDebInfo --target notification --target inputDevice
cmake --install . --config RelWithDebInfo
When to Rebuild All Examples
You need to rebuild all examples if:
- You modify
CMakeLists.txt files or the build configuration
- You update environment variables in
setupEnv.bat
- You re-run
buildExampleSolution.bat to regenerate project files
- A new example is added to the solution
Development Best Practices
- Initial Setup: Always do a full build first (
cmake --build . --config RelWithDebInfo)
- Iterative Changes: Build only the examples you're modifying
- Install Often: Run the INSTALL project after each build to deploy your changes
- Verify Deployment: Check that your DLL timestamp updated in
plugins64/ directories
- Clean Builds: If you encounter issues, try Clean Solution and rebuild
Understanding the Build System
CMake Structure
The VR-Engage examples use CMake to generate Visual Studio project files. Understanding this structure helps you create your own plugins.
examples/
├── CMakeLists.txt # Root configuration - configures all examples
├── utilities.cmake # Shared helper functions for plugin builds
├── setupEnv.bat # Environment variable configuration
├── buildExampleSolution.bat # Solution generation script
├── batchFiles/ # Generated batch files for debugging shortcuts
│ ├── vrfVreDISLocalhost.bat
│ └── vrfVreHLA.bat
├── debugMenuAddition/ # Example: VR-Engage frontend plugin
│ └── CMakeLists.txt
├── notification/ # Example: Component lifecycle conventions
│ └── CMakeLists.txt
└── ...
Debugging Shortcuts Implementation
The CMake build system automatically generates debugging shortcuts for testing examples:
Generated Batch Files (examples/batchFiles/):
vrfVreDISLocalhost.bat - Launches VR-Forces and VR-Engage with DIS protocol
vrfVreHLA.bat - Launches VR-Forces and VR-Engage with HLA protocol
CMake Configuration (in examples/CMakeLists.txt):
# Create custom target for VR-Engage only
add_custom_target(VREngageDebug DEPENDS ALL_BUILD)
set_target_properties(VREngageDebug PROPERTIES
VS_DEBUGGER_COMMAND ${MAK_VREDIR}/bin64/vrEngage.exe
VS_DEBUGGER_WORKING_DIRECTORY ${MAK_VREDIR}/bin64
FOLDER "Shortcuts"
)
# Generate batch file and create target for VR-Forces + VR-Engage (DIS)
GenerateBatchFile(vrfVreDISLocalhost.bat ${BATCH_FILES_DIR} "${disArguments}")
add_custom_target(VRForcesVREngageDISLocalhost DEPENDS ALL_BUILD)
set_target_properties(VRForcesVREngageDISLocalhost PROPERTIES
VS_DEBUGGER_COMMAND ${BATCH_FILES_DIR}/vrfVreDISLocalhost.bat
VS_DEBUGGER_WORKING_DIRECTORY ${MAK_VREDIR}/bin64
FOLDER "Shortcuts"
)
Benefits:
- No need to manually launch VR-Forces and VR-Engage separately
- Consistent connection settings between applications
- Quick access from Visual Studio's Debug menu
- Batch files can be customized for specific testing scenarios
Per-Example Debugging Configuration
Individual examples can configure their own debugging parameters to launch VR-Engage with example-specific scenarios and settings.
Example-Specific Launch Arguments:
Many examples include VS_DEBUGGER_COMMAND_ARGUMENTS in their CMakeLists.txt to automatically load their associated simulation model set:
# From examples/playerStateAttribute/CMakeLists.txt
set_target_properties(playerStateAttribute PROPERTIES
OUTPUT_NAME "examplePlayerStateAttribute"
FOLDER "Examples"
VS_DEBUGGER_COMMAND ${MAK_VREDIR}/bin64/vrEngage.exe
VS_DEBUGGER_WORKING_DIRECTORY ${MAK_VREDIR}/bin64
VS_DEBUGGER_COMMAND_ARGUMENTS "-c -n 3 --setting \"playerStationApp.defaultSimulationModelSets = {'${MAK_VREDIR}/data/simulationModelSets/examples/playerStateAttribute.sms'};\""
)
What This Enables:
- Right-click the example project (e.g.,
playerStateAttribute) → Debug → Start New Instance
- VR-Engage launches with the example's specific simulation model set pre-loaded
- No manual scenario loading or configuration needed
- Each example can have its own tailored test environment
Command-Line Arguments Breakdown:
-c (or --showConsole) - Displays a console window for viewing runtime output and log messages
-n 3 - Sets the logging verbosity to level 3 (verbose), providing detailed diagnostic output
- ‘--setting "playerStationApp.defaultSimulationModelSets = {'path/to/example.sms’};"` - Specifies the simulation model set to load at startup
When to Use This Approach:
Add VS_DEBUGGER_COMMAND_ARGUMENTS to your example's CMakeLists.txt when:
- Your example requires specific scenario data or role configurations
- You have a dedicated
.sms (simulation model set) file in data/simulationModelSets/examples/
- You want one-click testing directly from Visual Studio
- Your example needs specific VR-Engage startup settings
Example Template for Your Plugin:
set_target_properties(myExamplePlugin PROPERTIES
OUTPUT_NAME "exampleMyPlugin"
FOLDER "Examples"
VS_DEBUGGER_COMMAND ${MAK_VREDIR}/bin64/vrEngage.exe
VS_DEBUGGER_WORKING_DIRECTORY ${MAK_VREDIR}/bin64
VS_DEBUGGER_COMMAND_ARGUMENTS "-c -n 3 --setting \"playerStationApp.defaultSimulationModelSets = {'${MAK_VREDIR}/data/simulationModelSets/examples/myExample.sms'};\""
)
Note: If your example doesn't have an associated simulation model set, you can omit VS_DEBUGGER_COMMAND_ARGUMENTS or use the global shortcuts (VREngageDebug, VRForcesVREngageDISLocalhost, etc.) instead.
Creating Your Own Plugin
Each example subdirectory contains a CMakeLists.txt that demonstrates how to build a specific plugin type. Use these as templates:
VR-Engage Frontend Plugins (UI, player station components):
- Reference:
playerStateAttribute/CMakeLists.txt
- Install location:
plugins64/vrEngage/
- Links against: VR-Engage framework libraries, Qt (if UI needed)
VR-Engage Simulation Plugins (backend entity behavior, sensors):
- Reference: Look for VR-Forces extension examples
- Install location:
plugins64/vrForces/
- Links against: VR-Forces libraries, simulation framework
VR-Vantage Plugins (graphics, rendering extensions):
- Reference: Look for VR-Vantage-specific examples
- Install location:
plugins64/vrVantage/
- Links against: VR-Vantage graphics libraries
Key CMake Conventions
When creating your plugin's CMakeLists.txt, follow these conventions from the examples:
- Use utility functions from
utilities.cmake: include(${CMAKE_SOURCE_DIR}/utilities.cmake)
- Set plugin properties:
add_library(MyPlugin SHARED myPlugin.cxx)
set_target_properties(MyPlugin PROPERTIES FOLDER "MyCategory")
- Link required libraries:
target_link_libraries(MyPlugin PRIVATE vrEngageFramework utilities)
- Configure installation to correct plugin directory:
install(TARGETS MyPlugin DESTINATION plugins64/vrEngage)
Adding Your Plugin to the Build
To include your plugin in the examples solution:
- Create a subdirectory under
examples/ for your plugin
- Create a
CMakeLists.txt following an appropriate example template
- Add your subdirectory to
examples/CMakeLists.txt: add_subdirectory(myPlugin)
- Re-run
buildExampleSolution.bat to regenerate the solution
Message Code Generation
VR-Engage provides a code generator that creates C++ message classes from Lua schema definitions. The generateMessages() CMake function in utilities.cmake processes .lua files and produces header and source files with type-safe accessors, serialization, and factory registration.
Function Signature:
generateMessages(target path namespace exportMacro exportInclude headerIncPath [headerPath] [sourcePath])
Required Parameters:
| Parameter | Description |
target | CMake target name for the message library |
path | Directory containing .lua message definition files |
namespace | C++ namespace for generated classes (typically makVre) |
exportMacro | DLL export macro name (e.g., MYMESSAGES_DLL) |
exportInclude | Path to export header file |
headerIncPath | Include path prefix for generated headers |
Optional Parameters:
| Parameter | Description |
headerPath | Output directory for generated headers (defaults to path) |
sourcePath | Output directory for generated source files (defaults to path) |
Complete Example:
This example is based on the commentMessage library from the Custom PDU example:
# filepath: examples/myPlugin/myMessages/CMakeLists.txt
# Create the shared library
add_library(myMessages SHARED)
set(TARGET myMessages)
set_target_properties(myMessages PROPERTIES
OUTPUT_NAME "exampleMyMessages"
FOLDER "Examples/MyPlugin"
)
# Add include directories for VR-Engage, VR-Forces, and VR-Link headers
AddIncludeDirectories(${TARGET}
${CMAKE_CURRENT_SOURCE_DIR}
${MAK_VRFDIR}/include
${MAK_VRLDIR}/include
${MAK_VREDIR}/include
${MAK_VREDIR}/include/framework
${MAK_VREDIR}/include/utilities
)
AddLinkDirectories(${TARGET}
${MAK_VRLDIR}/lib64
${MAK_VREDIR}/lib64
${MAK_VRFDIR}/lib64
)
# Generate message code from .lua files in this directory
generateMessages(${TARGET} ${CMAKE_CURRENT_SOURCE_DIR} makVre MYMESSAGES_DLL "${CMAKE_CURRENT_SOURCE_DIR}/export.h" ${CMAKE_CURRENT_SOURCE_DIR})
# Add all source files (including generated .cpp files)
file(GLOB SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/*.cxx
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/*.h
${CMAKE_CURRENT_SOURCE_DIR}/*.hpp
)
# Add .lua files for IDE visibility (not compiled)
file(GLOB LUA_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.lua)
set_source_files_properties(${LUA_SOURCES} PROPERTIES HEADER_FILE_ONLY TRUE)
if(SOURCES)
target_sources(${TARGET} PRIVATE ${SOURCES})
endif()
if(LUA_SOURCES)
target_sources(${TARGET} PRIVATE ${LUA_SOURCES})
source_group("LUA Files" FILES ${LUA_SOURCES})
endif()
# Link required libraries
AddLibrariesToLinkWith(${TARGET}
vl
readerWriter
matrix
vlutil
mtl
vrvCore
vrvUtil
vreUtil
vreMessageManager
)
# Define export macro and platform definitions
AddCompilerDefinitions(${TARGET}
-DWIN32 -D_WINDOWS -D_WIN32_WINNT=0x0601
-DNOMINMAX -DDT_DLL_BUILD -DDT_USE_DLL
-DMYMESSAGES_EXPORTS
)
# Install to bin64 (shared libraries used by both frontend and backend)
install(TARGETS myMessages
RUNTIME DESTINATION ${MAK_VREDIR}/bin64
LIBRARY DESTINATION ${MAK_VREDIR}/lib64
)
Export Header:
Create an export.h file in your message directory. The export macro name must match the exportMacro parameter passed to generateMessages():
#pragma once
#ifdef _WIN32
#ifdef MYMESSAGES_EXPORTS
#define MYMESSAGES_DLL __declspec(dllexport)
#else
#define MYMESSAGES_DLL __declspec(dllimport)
#endif
#else
#define MYMESSAGES_DLL
#endif
Generated Output:
For each MESSAGE{} block in a .lua file, the generator produces:
<fileName>.h - Header with class declaration, accessors, and type constant
<fileName>.cpp - Implementation with serialization and factory registration
The generated classes inherit from DtVreMessage and include:
- Static
create() and createFromData() factory methods
- Static
theType() returning const std::string& with the message type
- Static
theId() returning the DtVreMessageId for routing
- Type-safe
get and set methods for each attribute
serialize() and deserialize() methods for network transport
getData() accessor returning a struct with all fields
- Automatic factory registration on library load
Example Projects:
See these examples for complete message generation implementations:
- Custom PDU - Basic message definition with frontend/backend communication
- Entity Detection - Structured messages with nested data types
For message schema syntax and attribute types, see Inter-Process Communication.
Environment Variables Used by CMake
The build system uses environment variables set in setupEnv.bat:
MAK_VRFDIR - Locates VR-Forces headers and libraries
MAK_VRLDIR - Locates VR-Link headers and libraries
MAK_RTIDIR - Locates MAK RTI headers and libraries
QTDIR - Locates Qt framework (for UI plugins)
CMAKE_BUILD_TYPE - Set to RelWithDebInfo (only available configuration)
Troubleshooting Common Issues
Environment Variable Problems
Symptom: CMake can't find required dependencies
CMake Error: Could not find required MAK product installation
Solution: Verify environment variables are set correctly in setupEnv.bat:
echo %MAK_VRFDIR%
echo %MAK_VRLDIR%
echo %QTDIR%
Compiler Toolset Issues
Symptom: Wrong Visual Studio version selected
CMake Error: Could not find MSVC toolset v143
Solution: Install Visual Studio 2022 with C++ workload. The build system will automatically detect the correct toolset.
Library Linking Problems
Symptom: Unresolved external symbols during linking
error LNK2001: unresolved external symbol
Common Causes and Solutions:
- Missing VR-Engage libraries: Check
lib64/ directory exists
- Architecture mismatch: Ensure building for x64 architecture
- Configuration mismatch: Use RelWithDebInfo configuration
Plugin Loading Issues
Symptom: Plugin DLL builds but doesn't load in VR-Engage
Diagnostic Steps:
- Check plugin is in correct directory under
plugins64/:
- VR-Engage plugins:
plugins64/vrEngage/
- VR-Forces plugins:
plugins64/vrForces/
- VR-Vantage plugins:
plugins64/vrVantage/
- Verify DLL dependencies using Dependency Walker
- Check VR-Engage log files for loading errors
- Ensure plugin exports required symbols