# Overal & Processes
:::info
From Jason's document
:::
## Viewer
The UniVirtual viewer is in some ways the heart of the UniVirtual development ecosystem. Ultimately all content created under the UniVirtual brand is interacted with via the UniVirtual Viewer; all the visual and programmatic components for a course are loaded into the viewer on demand as a user accesses their course. The viewer itself aims to be as light as possible for easy distribution, and content agnostic so that courses can be updated independently of the viewer itself.
The viewer is composed of two main Unity projects:
* The "Viewer" project, which houses the code and visual assets that make up the UI and any third-party systems that the content needs to utilize (such as the Avatar system or the Voice Chat Framework)
* The "Framework" project, which contains our custom framework for UniVirtual specific logic (such as our course running logic, and communications with the back end)
### Viewer Project
The Viewer is built from a Unity project hosted on GitHub at https://github.com/cndgdev/dev-univirtual_viewer. This project does most of the heavy lifting of handling the UniVirtual Viewer's UI and interacting with the third-party systems we rely on. There is more detail on the Third-Party assets further on within this document, but a basic outline is:
* Photon - the networking stack we use to create a multi-user environment
* Vivox - provides voice chat services
* Backtrace - Handles bug aggregation so we can more effectively diagnose and correct application issues
* UMA & o3n - provides an avatar customization system
* ZFBrowser - provides an integrated browser for displaying text-based content
* NWH - a vehicle physics system
* Ink - a narrative scripting language, for our NPC dialogues
All developed content can be tested within the viewer Unity project to allow easier debugging. The viewer itself is built and distributed via our CI (Continuous Integration) system, detailed further in the document. Changes to the viewer's code (new features) take place via git "branches" off the "develop" branch, which are then merged back once the feature is complete.
Both the Windows and MacOS environment are supported and builds for both environments are created from the same shared codebase. There are currently only very minor differences between the environments that must be handled, mostly related to where user settings and course assets are stored.
The UI of the viewer is explored more in depth on the Wireframes Miro board, located at https://miro.com/app/board/o9J_kyviUmg=/. The UniVirtual UI handles all user interactions when outside of a course, such as logging in and course selection, as well as avatar customization, and user settings. There are also course-specific elements, such as NPC dialogues and Quiz taking, along with avatar and object labels, interaction prompts, etc.
## Framework Project
The Framework Unity contains code used by the viewer and by content projects (details further in) to run our custom developed components and systems. This project is hosted on GitHub at https://github.com/cndgdev/dev-module_flow/. The main goal of the Framework is to allow our custom work to be project agnostic, ultimately assisting in the creation of an SDK.
The Framework handles many important systems:
* All custom content features, such as:
* our animation timeline customization
* NPC dialogue system
* pathfinding system
* content notifications
* compass system
* All communications with the back-end API (detailed further in)
* Quiz system
* Avatar interaction (interacting with objects, using tools)
* Task state machines
* Custom network components on top of Photon
* Content API (exposes our custom systems to content creators)
* Module flow, for progressing through a course module
* Avatar Attachments
Most of these features are given further explanation within the Content section of this document.
## Backend
The UniVirtual backend is a collection of services, duplicated across multiple environments (Development, Staging, Production), that house and provide course/content data and record user data, all through a custom API.
As the Viewer itself is content agnostic, all the information that defines a course is configured and stored externally to the viewer and loaded in at runtime. A high-level overview of the structure of a course, from a backend perspective, is:
* The course itself, comprised of
* One or more modules, comprised of
* A module flow, outlining the activities and locations of the module
* A state machine, which controls the module's flow and notifications, etc
* One or more content packs, containing HTML content for information displaying
* One or more "scenes", locations where user activity occurs, comprised of
* One or more assemblies, DLLs containing module content code
* One or more asset bundles, containing 3D models and textures
* A room specification, defining load balancing parameters
* One or more Quiz slots, allowing a quiz to be associated with the module
User accounts and course enrollment are controlled through the backend, as well as the creation of courses and all course related objects (modules, scenes, content packs, etc.). All course assets (DLLs, Unity asset bundles) are automatically created via our CI system and pushed to AWS. It may be necessary to create dummy versions of the definitions for these in the Development environment, as the rapid nature of the content development cycle often involves local building of assets on the developer's machine.
Data about the user's progress within a module, as well as specific module completion data, is stored in the backend, along with the user's quiz results. This data is aggregated and exposed to whoever is running a course through a separate backend system.
### Configuring a Course
To create a course on the backend, the path you take slightly varies depending on what environment you are interacting with. On staging, your assets (Asset Bundles, Assemblies, Content Packs, etc.) should be populated automatically by the CI process; on test, there is no such process, and this must be done manually. With that in mind, when creating a course on test, it is best to do it “from the ground up” and define your assets first.
A simple one module, one scene course could be created in the following manner:
* Create a State Machine, where the label is the name of your module core scene in Unity
* Create an Asset Bundle, where the label is the name of your main scene in Unity
* Create a Content Pack, where the label is the name of your content pack in Unity
* Create an Assembly, if needed; most content code should end up in the shared assembly which may already be defined
* Create a Scene, where the Token is your scene name in Unity
* Set the Room Spec to {"loadBalanced":true,"maxUsers":15}
* Associate the Assembly and Asset Bundle with the Scene
* Create a Module, and set the image fields to none
* Paste the Default Flow from the content
* Associate the State Machine with the Module
* Associate the Content Pack with the Module
* Associate the Scene with the Module
* Create a Course
* Associate the Module with the Course
* Toggle the course Accessibility to Open
* Enroll your user into the course
On Staging, all steps before “Create a Scene” should be able to be skipped. For now, moving a Course from Staging to Production requires manually copying over all information.
### API
The API provides two-way communications between the backend and the viewer. All communication with the backend happens via HTTP requests, no connections are maintained.
Specific endpoints are outlined in the document "UniVirtual API Usage & Endpoints". At a high level, the API is split into two parts, one which handles communications up to and including logging in and one which handles everything once a user is authenticated. The flow of communication between the viewer and the backend is outlined on the Design Miro board (https://miro.com/app/board/o9J_kzfKxG8=/?moveToWidget=3074457353056390670&cot=14).
### Quiz System
The quiz system is outlined on Miro here: https://miro.com/app/board/o9J_lUlkIiw=/. The current implementation of the quiz system allows a course instructor to present multiple-choice questions before, during, or after a module (or any combination), and records the results.
### Future Expansion
Currently, there is support for associating scene names with modules in the backend, which would enable content to use a separate name for the scene file than the name the backend uses for the scene; this may help speed up testing, however, it is not hooked up within the Framework yet.
The quiz system currently does not support advanced question or answer types as outlined on the Miro board.
It may be prudent to implement API call batching, allowing multiple API queries in a single HTTP request. For now, there is no real-world data on the load generated through API requests, and so this has not been a high priority.
## Launcher/Patcher
The UniVirtual Launcher/Patcher is a program that the user runs before starting the Viewer application, which verifies the integrity of their installation, downloads any new or missing files, and updates any outdated files. The design goal is to handle updates seamlessly to the user and enable a very slim initial download from a website for the user.
The base code comes from the PATCH Updating System Unity asset (https://assetstore.unity.com/packages/tools/utilities/patch-updating-system-pro-46639), with modifications added to support UniVirtual specific assets.
Once installed, on first run, the latest version of the viewer will be downloaded and installed, followed by any currently published asset files (DLLs, asset bundles). On subsequent launches, only changed files will be downloaded, streamlining the update process.
The Launcher/Patcher can also self-update, as new features are added.
### Current State
Due to differences between the Windows and MacOS platforms, there are currently two versions of the Launcher/Patcher, maintained concurrently. The Windows version codebase (a Windows only executable) is available at https://github.com/cndgdev/dev-univirtual_launcher/, and the MacOS version codebase (a Unity project) is available at https://github.com/cndgdev/dev-univirtual_launcher/.
Both Launcher/Patcher versions read the same data format from the backend, but at current only the Windows version can use command line shortcuts to change the production environment.
### Build Process
`needs more in-depth information`
### Future Expansion
The most immediate future goal is to merge the Windows and MacOS Launcher/Patchers under the same codebase, specifically the one currently used for MacOS. Maintaining two separate codebases introduces needless complexity.
Further down the line, users will login through the Launcher/Patcher, allowing it to download only assets relevant to their enrolled courses.
## Continuous Integration
Continuous integration is handled through Jenkins, located at https://ci.univirtual.com/. All assets for the BSC2010 project are built and uploaded to AWS, for both Windows and MacOS; asset information is also automatically updated on the Staging environment. The Windows build of the Viewer is also built and uploaded to AWS. Additionally, the Windows viewer build can be versioned and added to the patching system automatically.
### Viewer Build Walkthrough
#### Windows
* Create a new feature branch off develop on the viewer project git repository
* Once your feature is complete, merge back to develop
* In Jenkins, run the Univirtual_Viewer_(Win)_-_develop project
* Once the build is complete, run the Publish Windows Viewer project
* After that completes, open the univirtual AWS bucket
* Navigate to the patch/Builds/ folder and note the most recent build_X.Y.Z.json file
* Edit the builds_index.json file to set “AvailableBuilds” to the X.Y.Z value
* The viewer build is now live through the patcher
#### MacOS
* needs more in-depth information
#### Future Expansion
Apple support for the CI pipeline is high on the list of desired additions. Additionally, automatic building and distribution of the Launcher/Patcher would be very useful, once the Launcher/Patcher codebases are integrated.
## Third Party
The UniVirtual Viewer relies on a handful of third-party libraries to provide functionality that benefits us or our users while reducing the development load required to support these functions.
### Photon
The Photon library (https://www.photonengine.com/) provides a networking stack to the Viewer, allowing us to have multiple users within a virtual space, sharing their experience. At a basic level, any module "scene" can exist as a separate virtual location; this location can be further divided through a "phasing" system, still in development.
Some of our custom networking functionality is built on top of Photon, outlined on GitHub here https://github.com/cndgdev/dev-univirtual_viewer/wiki/Photon-CNDG-Implementation and on Miro here https://miro.com/app/board/o9J_kj-hcjE=/.
### Vivox
The Vivox library (https://unity.com/products/vivox) provides multi-user voice and text communication.
### Backtrace
Backtrace (https://backtrace.io/) provides error and crash reporting, and allows easy aggregation of errors users may experience, along with automatically opening tickets and alerts.
## Content
Course content is loaded on demand into the viewer and is built from separate Unity projects utilizing the Framework and Viewer Simulator. A course can be configured in the CI pipeline to have all of its assets automatically built and uploaded to AWS.
### Simulator
The Viewer Simulator is an attempt to provide the Viewer experience within a content project. Although not currently at exact parity with the viewer itself, many functions can be coded and tested completely within the Unity content project, sparing the need to build out the assets and test them within the viewer itself. For basic content, it’s possible to rapidly iterate on the design this way.
There are some gaps within the simulator at current; most notably, the simulator cannot provide a flying experience. Additionally, the camera physics are not completely shared between the viewer and simulator. While it is possible to do some networked testing with the simulator, there is no actual networking code, and no connection to the multiplayer environment is possible.
### Manual Build
Manually building assets for a Module should only need to be done for testing purposes. A simple one scene module could be set up and built as follows:
* Create 3 new CNDG / Autobuild / AssetBundle asset in the Assets/_CNDG Assets/_AutoBuild/AssetBundles folder of the project
* Configure one for each of the Core Module, Scene, and Content Pack types
* Select all three of your new assets and click Build Windows AssetBundle in the inspector
* Once building is complete, copy the files from AutoBuild/WIN to your viewer project, under the folder localAssetBundles
* Additionally, copy the content DLL from Library/ScriptAssemblies to your viewer project, under the folder localAssemblies
* Your content should now load in the viewer for testing
### New Unity Project Creation
needs more in-depth information
### Future Expansion
Eventually the goal is to have as close to 1:1 parity between the simulator and the viewer, allowing rapid testing of all types of content. It may never be possible to provide a full networking stack, however, as this would require bloating all content projects with the full suite of the Photon framework.