Software development philosophy
Landmarks is primarily maintained and developed by psychologists and cognitive neuroscientists from a range of backgrounds with varying levels of experience in programming and software development. Landmarks can be described as loosely conforming to specific, formalized software design principles. After identifying a question, or problem, experimental design often involves creating a paradigm to test hypotheses regarding that problem, piloting these paradigms, and repeating this process until the paradigm is optimized to address the question/hypothesis. Unsurprisingly, this iterative and incremental process is paralleled in the development of Landmarks.
With respect to software development, Landmarks is most consistent with an adaptive software development philosophy (Highsmith, 2013). Adaptive software development is characterized by high speed (i.e., frequent updates or releases) and high change (i.e., modifications driven largely by uncertain needs). For example, over the past year (at the time of writing) there have been over 200 (approximately four contributions per week) individual contributions to the code base on GitHub, which can be defined as any addition, deletion, or modification of code that is then uploaded to the public GitHub repository—indicative of high speed. While many of these contributions were small, many involved widespread changes including the addition of a completely new data logging system, new player controllers, and integration with third-party hardware and software—indicative of high change. This high-change and high-speed model of software development allows Landmarks to adapt to the demands of users, including staying up to date with the rapidly evolving landscape of VR hardware.
Framework
To implement the features in Landmarks while allowing for high-change development and design, we have broken the experimental design process into four main components: Characters (cameras and player controllers; e.g., the avatar), Timeline (state machines; i.e., the sequence and structure of tasks in the experiment), Environment (3D models; e.g., streets, props, buildings), and Data (output files; e.g., text files or tab-delimited files). The first three are visually present in the implementation of Landmarks (see Hierarchy window in Fig. 1), _Landmarks_.prefab (Landmarks Prefab) Unity asset with the Experiment.cs script (Experiment) attached, and the fourth, data, is handled in the background and automatically generated for all experiments. We discuss each of these components in turn.
Characters
One of the most powerful features in Landmarks is that it is one of the only 3D experimental design solutions to offer compatibility with VR hardware and is, to our knowledge, the only solution that allows seamless switching between a variety of desktop and VR interface configurations. To support this functionality, a core piece of the Landmarks framework involves managing and handling various player controllers and cameras. When new player controllers are created and added to Landmarks and configured with the LM_PlayerController.cs script (LM_PlayerController), they are automatically detected and managed by Experiment.
Timeline
As we have mentioned, one of the greatest challenges of 3D experimental design involves incorporating the intrinsic framework of experimental design into a game engine such as Unity. Empirical research often visualizes this intrinsic framework in methods sections with figures that generally comprise a “timeline” of the experimental tasks—either pictures or descriptions of each component of the experiment ordered from left to right or top to bottom. Similarly, Landmarks implements this framework in the form of Unity GameObjects and child GameObjects, specifically the “Tasks” GameObject in the Landmarks Prefab (see Fig. 1, Hierarchy window). Just as experiments are hierarchically organized in sessions, blocks, and trials, these tasks that make up the greater experiment timeline can be set to repeat a specified number of trials and can be organized into experimental blocks and phases depending on the visual organization tasks in the form of child GameObjects of the “Tasks” GameObject. Next we will describe how these timelines and tasks function internally as finite state machines following a general structural framework.
The “Tasks” GameObject contains all of the experimental tasks that will take place in the experiment. When it comes to video game design, many of the tools rely on finite state machines to manage the flow of events (in our case, experimental tasks). In their simplest forms, finite state machines can control simple behaviors such as what happens when a light switch is flipped on or off. In this simple example, one could imagine certain aspects that could be programmed into each state (e.g., ON: any light bulb models associated with the switch begin emitting light and heat, their temperature rises, and their remaining lifespan is shortened as time passes in the on state; OFF: any light bulb models associated with the switch stop emitting light and heat, their temperature cools until it reaches baseline, and the lifespan ceases to shorten). This is only a subset of the behaviors that could be associated with these two states, and many state machines comprise a greater number of possible states.
When Landmarks is run in a functioning experiment, the Experiment finds and identifies an “LM_Timeline.” This timeline is a list of tasks defined by the associated TaskList.cs script (any object with TaskList.cs attached can be referred to as a TaskList). TaskList inherits from the base-level class defined in “ExperimentTask.cs” (any object with an associated script inherited from ExperimentTask.cs, which can be referred to as an ExperimentTask—all TaskLists are ExperimentTasks). This outlines basic experimental task states (e.g., start [what do we need to do to get ready for this task], update [what happens during this task], end [what do we need to do to close down or “clean up” after this task]), and affects operations common to all tasks that inherit from it. TaskList will hierarchically carry out any child ExperimentTask, including any other TaskLists. In summary, Landmarks implements experimental timelines via a hierarchy (i.e., GameObjects and their child GameObjects) of ExperimentTasks, with any given ExperimentTask having essentially three finite states (start, update, end). The “Tasks” GameObject is one of the child GameObjects of LM_Timeline (both are TaskLists) and represents the organization of various experimental operations that would be included in a methods figure depicting the experiment timeline in an empirical report. For example, LM_Timeline runs various ExperimentTasks such as showing a general welcome message for participants and locating and inventorying task-relevant target objects in the environment before executing “Tasks” and any child ExperimentTasks nested within “Tasks” and then closing down the experiment when there are no more ExperimentTasks to execute.
Environment
The third component in the implementation of Landmarks is the 3D environment. Indeed, the need for 3D environments that comprise a collection of 3D models is one of the primary reasons for utilizing the Unity game engine software in experimental design. This is largely handled through simple organization of GameObjects within the Landmarks prefab, because most of the 3D models serve only as “filler” props (i.e., task-irrelevant features of the environment), with a select few serving as experimentally crucial target objects and task-relevant locations (for either player controllers or target objects, with the latter being optional). For Landmarks to run, all users must do is provide one or more task-relevant GameObjects, with the tag “target” and the layer “targets” selected (see Box 1; for context, see Fig. 1).
Data
In designing Landmarks, we understand that 3D experiments are a means to an end, with that end being empirically valid data for subsequent analysis and publication. Data for any and all existing tasks are automatically handled by Landmarks via several logging scripts (dbLog.cs, LM_TrialLog.cs) that use the StreamReader and StreamWriter class of assets. Any experimentally relevant variables and values are written line-by-line to a central log file (.log extension; e.g., player position, player rotation, task state, etc., on a moment-by-moment basis) using the dblog class. Variables and values that we anticipate being immediately relevant for processing and analyzing behavioral data are added to a current trial dictionary and formatted as a row of header labels and a corresponding row of data variables; these are then logged into the central log file at the end of each trial in a task.
In addition to a central log file, which already contains all recorded data in a line-by-line temporal order, Landmarks automatically detects unique experimental tasks (logged using the LM_TrialLog class) included in an experiment, extracts this data, and formats it as a tab-delimited file (.csv extension) with a single header row, compatible with most data analysis software. Table 1 shows actual data, as organized and preprocessed, from the navigation task of the demo experiment included with Landmarks. Thus, each experiment run in Landmarks will generate a single raw data file (.log) as well as a formatted file (.csv) for each unique task included in the experiment timeline.
Table 1 Example data file outputted from Landmarks for a navigation task. The outputted file was opened in Microsoft Excel, pasted into Microsoft Word, and formatted based on American Psychological Association (APA) guidelines User interaction
Every aspect of Landmarks has been designed and updated with the goal of serving the widest range of users, with an emphasis on users who have little to no programming experience. While it is virtually impossible to automate all aspects of a software package that caters to a high-change application, such as experimental design with VR integration, we wanted to provide users with a comprehensive basis of experimental design that can be used via a graphical user interface without the need for any programming—the Unity Editor. Working with Landmarks at this level involves simple drag-and-drop mechanics (place an ExperimentTask prefab in the appropriate place as a child of the experimental timeline) combined with changing values and properties of the task that are visually displayed in the Unity editor. We believe that many users will find this to be a sufficient starting point for building 3D environments and using common, simple experimental tasks from the field of navigation and spatial cognition. That said, Landmarks users are by no means restricted to the preconfigured prefab tasks that come bundled with Landmarks.
An appealing aspect of Landmarks is that users are free to “challenge by choice” (see Fig. 2). That is to say that users whose experimental designs or tasks require varying levels of complex additions or modifications to Landmarks are not necessarily “doomed” to acquire a comprehensive understanding of the C# programming language to implement such changes. Rather, Landmarks offers incremental levels of abstract use cases which require only commensurate, incrementally greater understanding of Unity and C#. Figure 2 shows four example tiers of software and programming abilities, sample descriptions for what users could accomplish at each skill level, and an example implementation in the context of a spatial cognition experiment built in Landmarks.
The Landmarks Unity project
Landmarks is a custom asset package designed for use in the Unity game engine. Normally, adding a custom asset package to Unity would involve users obtaining a compressed file of the asset package, importing the package into the current Unity project as a custom package, and ensuring that any other asset packages required for it to work are also imported into the project. To streamline this process, Landmarks is bundled as an entire Unity project folder. This allows users to simply download the Landmarks project folder (or clone it into a local Git repository) and open it in Unity. All necessary asset packages and additional assets are already included using versions that have been tested for compatibility with Landmarks.
The primary purpose of Landmarks is to provide easy-to-use, high-quality experimental tasks and the mechanics to implement those tasks in a linear fashion consistent with experimental design and procedures. It is important to note that Landmarks alone is not sufficient to create 3D, virtual reality experiments. While Landmarks provides a user-friendly framework for implementing experimental design in Unity, many of the features and functionality built into Landmarks are only possible through the use of other open-source asset packages for Unity. These include SteamVR (Valve Corporation, Bellevue, WA), VRTK (Extend Reality Ltd, https://github.com/ExtendRealityLtd), Oculus Integration (Oculus VR, Menlo Park, CA), and other assets available in the Unity Asset Store (Unity Standard Assets, VR Samples, TextMesh Pro). The complete Unity project folder can be downloaded or cloned from GitHub (https://github.com/mjstarrett/Landmarks).
The Landmarks Unity package
While Landmarks is made available in the form of a complete Unity project, for compatibility reasons, the Landmarks package is a custom asset package that appears as a folder in the Project View window of the Unity Editor (see Fig. 1), just as any other imported asset package would appear. Indeed, the Landmarks package folder appears with the other imported assets that come bundled with the Landmarks Unity project. Moreover, when developing Landmarks, we followed a structure of organization similar to many other Unity asset packages (subdirectories in the package folder that organize assets by their function in the Unity game engine, e.g., materials, prefabs, scenes, scripts). Several major categories used to organize the Landmarks package will be covered briefly.
Materials
The Unity engine uses materials to define the visual appearance of GameObjects in a scene. Materials reference assets called shaders and textures that provide information on how to wrap images around a GameObject’s geometry and subsequently render that image in the scene and game. A detailed description of Unity’s materials, shaders, and textures system is beyond the scope of this paper. This folder of the Landmarks package contains any materials, shaders, and textures that were created specifically for Landmarks. Contributors are encouraged to add any additional materials they create and configure to this folder. A set of basic color shaders (e.g., Red.mat) are included with Landmarks in a sub-directory named “base_shaders.”
Text files
Text files are the source for any written information that will be presented during an experiment. Out of the box, this folder will contain several text files, which are used by some of the prebuilt tasks included with Landmarks. These files use the “.txt” extension and are used to supply prewritten text to any object that supports text assets. For example, “Break_VR.txt” contains the unformatted text, “Please remove the VR headset and take a short break.” If this file is dragged onto the “message” property of the “BeginExperiment”—an InstructionsTask ExperimentTask—GameObject (see Fig. 1, Hierarchy window), the next time the experiment is run, participants will be greeted with a display that reads, “Please remove the VR headset and take a short break,” instead of the default welcome message preconfigured in the Landmarks Prefab. Thus, users can easily change the task instructions that are presented to participants by creating new text files.
Scripts
The functionality of Landmarks is powered by custom scripts we have written to implement the framework outlined above. Landmarks scripts are written in C#. Novice users may choose not to interact with these scripts at all or they may choose to only interact with them through the inspector window of the Unity Editor (see Fig. 1). Clicking on a GameObject reveals any scripts attached as components of that GameObject, so that basic properties (e.g., the number of times to run a navigation task) can be edited in the Unity Editor’s Inspector window (see Fig. 1). For those interested in programming or seeing the code for a component, the associated script can be opened directly from the Unity Editor (using Visual Studio or some other IDE).
In principle, configuring all of these scripts properly would require extensive documentation and troubleshooting. Fortunately, because these configurations are largely shared across experiments, Landmarks comes packaged with preconfigured GameObjects that already have all the necessary scripts attached and configured. In Unity, such GameObjects are called “prefabs,” which contain the necessary configurations of properties (i.e., variables that can be accessed within the Unity Editor) in common Landmarks scripts. Users without programming knowledge can easily modify these prefabs in the Unity Editor by selecting them in the Hierarchy window and changing their properties in the Inspector window (see Fig. 1). Users with C# programming experience can further customize and modify these prefabs and their scripted components to create new tasks (i.e., for other tests of spatial memory that are not currently implemented within Landmarks). For more information on components and requisite programming required, see Box 1 and Fig. 2. The LM_Dummy.cs (LM_Dummy) script is an example template for an ExperimentTask (see section on Framework). LM_Dummy includes comments in the code that serve to aid users to change and add public variables, or properties, as well as code for the three states of an ExperimentTask (start, update, end). LM_Dummy is an ideal candidate to examine for users looking to get started with programming their own new tasks and scripts in Landmarks.
Prefabs
The Unity game engine provides a convenient system for creating preconfigured GameObjects, called prefabs. These prefabs may already have scripted components attached to them as well as other GameObjects nested within them as “children” (children are objects that inherit the properties of their “parents,” objects that are higher up in the programming hierarchy; see Box 1 for more details). In addition to being prebuilt (i.e., already containing any necessary GameObjects), Unity prefabs are also preconfigured (i.e., those GameObjects have any necessary scripts already attached with all parameters and properties already defined). Unity’s prefab system also provides flexibility by allowing users to replace the preconfigured parameters and properties with their own custom values; users can even save their custom settings as their own prefab. In Landmarks, prefabs are at the core of the user-friendly framework and facilitate the drag-and-drop creation of experiments.
The only prefab required for design is the Landmarks Prefab, which contains child GameObjects that correspond to core components of the experimental design: Characters, Timeline, Environment, and Data (see section on Framework and Fig. 1). Characters are handled by selecting the desired user interface on the “LM_Experiment” userInterface property (e.g., ViveRoomspace for HTC Vive in an open room), Timeline is handled by adding any prefabs with the “TASK_” prefix or any GameObject that has an associated ExperimentTask component (see section on Framework), Environment is handled by organizing 3D models that make up the environment (e.g., a cube or a building prefab) in the “LM_Environment” child of the Landmarks Prefab, and Data is handled in the background by automated scripts that output data files (.log and .csv extensions).
Scenes
In Unity, a scene is often synonymous with a level in a video game (see Box 1). Scenes are saved individually in a Unity project using the “.unity” extension and can be opened in the Editor or loaded at runtime in a game. In Landmarks, a scene is the environment used for an experimental session, e.g., a 50 × 50 meter arena with colored walls or a 10 × 10 meter room with fluorescent lighting and wood flooring. The GameObjects that make up these environments are integrated into Landmarks prefabs, such that they can automatically interface with a variety of task prefabs (e.g., Landmarks-specific prefabs that facilitate specific experimental tasks, such as a navigation task or a map learning task) that users can drag and drop into the scene. This structure makes it easy to change the environment used for an experiment developed with Landmarks (e.g., replace a museum environment containing target exhibits to visit with an outdoor space containing sports equipment to collect). More scenes will be added in the future, and users are encouraged to contribute their scenes with their own customized environments. Landmarks comes with an example scene (demo_SimpleSample_50x50.unity) that demonstrates a working experiment in Landmarks. The scene comprises a Landmarks Prefab, a 50 × 50 meter environment with geometric target objects (sphere, cube, capsule, cylinder), and two experimental prefab tasks (TASK_LearnTargets.prefab and TASK_NavigationTask) configured. Users need only open the scene and click “play” in the Unity Editor to test the experiment.
Proprietary
Some resources that have been used with or created for Landmarks rely on proprietary software or packages that the authors cannot freely distribute. For example, an omnidirectional treadmill may require a Unity script or asset package that is only made available by the manufacturer to those who have purchased one of their treadmills. It may be the case that Landmarks has been made compatible with this treadmill, but such scripts are not useful unless a user has access to the proprietary assets. In this case, users can contact us to be given the Landmarks assets that will work with the proprietary hardware. This is because including these Landmarks assets (which we can distribute freely) in the Landmarks Unity project download without the proprietary software, code, or package they depend on (which we cannot distribute freely) would cause bugs and errors. At the time of writing, Landmarks provides support for proprietary assets and code for Cyberith’s Virtualizer line of omnidirectional treadmills, KatVR’s Katwalk omnidirectional treadmill (KatVR, Los Angeles, CA), and Tobii Pro’s VR integration for eye tracking with HTC Vive (Tobii Pro, Washington, D.C.). A complete, up-to-date list of all proprietary products and assets that are supported by or have confirmed compatibility with Landmarks is available on the Landmarks Wiki “About Landmarks” page, https://github.com/mjstarrett/Landmarks/wiki/About-Landmarks.
Resources for using Landmarks
The Landmarks Wiki
Landmarks cannot, yet, completely eliminate the need for some additional learning and familiarization with designing 3D navigation experiments in Unity, but we intend to support Landmarks users through freely available resources by maintaining a public wiki. The Landmarks Wiki covers a range of topics, including setting up Landmarks with GitHub, using existing scenes to create your own experiment in minutes, using a new scene to create your own environments and experiments from scratch, citing Landmarks in manuscripts and presentations, and contributing to Landmarks using Git. This wiki serves as living documentation and reference material for Landmarks. It will be revised and updated to keep up with the development of Landmarks. The Landmarks Wiki can be found within the Landmarks repository on GitHub (https://github.com/mjstarrett/Landmarks/wiki).
Video tutorials
At the time of writing, an initial series of six videos have been produced and uploaded to the YouTube (YouTube LLC, San Bruno, CA) platform. The series, entitled “Getting Started with Landmarks,” serves as the most comprehensive user manual currently available and covers accessing the GitHub page to download Landmarks, building 3D environments with free 3D assets in Unity, creating drag-and-drop experiments in minutes, and more. Additional videos on more advanced use cases, discussed here, and specialized situations will be added over time. These videos are intended to allow users to follow along in order to learn general principles for using Landmarks, while encouraging users to attempt variations of what is shown. The videos are publicly available on YouTube, and the corresponding author can provide direct links upon request.