JumpStart Game System
for developing multiuser 3D games & apps that run in
Google Chrome and/or AltspaceVR using JavaScript.

Based on THREE.js, Firebase,
the AltspaceVR SDK, and WebGL.

JumpStart created by Elijah Newman-Gomez.



Go to Steam Discussions

View on GitHub

VERSION 0.2.3

VRoxel Fashion

PLAY NOW

Create voxel art in VR. Then wear your creation on your head, on your torso, or held in your hands.
http://www.jumpstartsdk.com/live/VRoxelFashion.html
Tutorial: Getting Started

READ NOW

Know HTML & some JavaScript? Learn about what it takes to turn your idea into an AltspaceVR app!
http://www.jumpstartsdk.com/tutorialGettingStarted.html
Nature Picnic Attack

PLAY NOW

Defend your picnic from a nature attack! Swat down crows & bees with your hands, or toss rocks & boulders at them! If any creature makes it to your picnic basket, you lose!
http://www.jumpstartsdk.com/live/AirRush.html
Light Baker

PLAY NOW

Demonstrates vertex lighting that gets calculated based on a light source.
http://www.jumpstartsdk.com/live/LightBaker.html
Development Visualizer

PLAY NOW

Visualize the local player's gamepad states & tracking skeleton.
http://www.jumpstartsdk.com/live/DevVis.html
RC Deathmatch

PLAY NOW DEV BLOG

Choose a vehicle & enjoy! Each vehicle has its own unique properties plus a nifty grappling hook.
http://www.jumpstartsdk.com/live/RCDM.html
Hover Blaster

PLAY NOW

Top-down space shooter with artificial horizon!
http://www.jumpstartsdk.com/live/HoverBlaster.html
Stuntman

PLAY NOW

Shoot the stuntman safely into the pool!
http://www.jumpstartsdk.com/live/Stuntman.html
Shooting Gallery

PLAY NOW

Shoot the plates as they fly past.
http://www.jumpstartsdk.com/live/ShootingGallery.html
Mole Whack

PLAY NOW

Whack the moles before they eat all of your garden!
http://www.jumpstartsdk.com/live/MoleWhack.html
Line Racers

PLAY NOW

A mix between the Snake & TRON Light Cycles. Try to stay alive the longest to win!
http://www.jumpstartsdk.com/live/LineRacers.html
Building Blocks

PLAY NOW

An explosive voxel-based building app with multiplayer.
http://www.jumpstartsdk.com/live/BuildingBlocks.html
Soundboard

PLAY NOW

Add to any convo with whacky sound effects at the push of a button!
http://www.jumpstartsdk.com/live/Soundboard.html
Example

TEST NOW

A simple example that's perfect for using as a starting point for your own apps!

CODE-EXAMPLE
http://www.jumpstartsdk.com/live/example.html

JumpStart Game System

It is an event-driven THREE.js game system that provides you, the JavaScript VR app developer, the tools needed to quickly & easily create multiuser apps that run in AltspaceVR as well as in a Chrome preview mode.

Standard events have been added for the game system itself as well as each object in the game world. There are also a set of cursor-related events that give you everything you need to create your app.

Chrome preview mode makes debugging your multiuser apps as simple as can be. JumpStart's AltspaceVR emulation allows you to preview your app inside of a virtual enclosure that you can walk around in, exactly as your app will behave inside of AltspaceVR.

Portable code means that singleuser and multiuser apps use identical code, whether in AltspaceVR or in Chrome preview mode. You write your app once, and it works in all scenarios.

Behaviors allow you to apply complex functionality to an object in the game world using a single line of code. For example, apply a physics behavior to your ball to send it flying across the room.

Syncing your multiuser apps is absolutely essential to provide any kind of worthwhile experience to the user. With JumpStart, it's as easy as calling .sync() on your object, but is also able to get as complex as you require for complete control over how / when the objects in your app are synced.

Plus these features:
  • Automatic Scene Setup
  • Enclosure Boundaries
  • Scrolling Enclosures
  • Invisible Cursor Planes
  • Mesh-Accurate Ray Casting
  • Text Planes
  • Object Events

    CURSOR ENTER
  • The local user's pointer begins to hover over the object.
  • CURSOR EXIT
  • The local user's pointer is no longer over the object.
  • CURSOR DOWN
  • The local user begins to click on the object.
  • CURSOR UP
  • The local user finishes clicking on the object.
  • OBJECT SPAWNED
  • The object is added to the scene on the local client for the first time.
  • This event may be triggered from over the network.
  • OBJECT REMOVED
  • The object is removed from the scene on the local client.
  • This event may be triggered from over the network.
  • OBJECT REMOVED BY NETWORK
  • The object is removed from the scene on a remote client.
  • Unless you return false from this event, the object will be removed on the local client as well.
  • RENDER TICK
  • The renderer advances a single frame.
  • The time since the last frame was processed is stored in jumpStart.deltaTime.
  • System Events

    PRECACHE
  • The app is about to be initialized. All required assets should be loaded in.
  • Return FALSE for asynchronous loading, which requres you call jumpStart.doneCaching() when you are finished precaching.
  • INITIALIZE
  • The app is being loaded for the very first time.
  • Especially useful in multiuser apps to prepare persistent objects before users join.
  • This event occurs every time that a singleuser app loads.
  • READY
  • The simulation is about to begin.
  • This is your last chance to spawn objects that you want to exist at the very start of the game.
  • RENDER TICK
  • The renderer advances a single frame.
  • The time since the last frame was processed is stored in jumpStart.deltaTime.
  • CURSOR DOWN
  • The local user begins to click on ANY game object.
  • CURSOR UP
  • The local user finishes clicking on ANY game object.
  • Getting Started

    1. Have Prepros installed & ready to use on your project folder.
    2. Download JumpStart from GitHub and extract it into your project folder.
    3. Create your app by making a COPY of the file example.html
    4. Develop your app in AltsapceVR and/or Google Chrome using Prepros's Live Preview.

    Specification

    Click on the name of any method to see a code example for it.
    • window
      • loadJumpStart ( Object options)

        // Specify the non-default options to use.
        var myOptions = {
        	"appID": "MyAppID",
        	"sceneScale": 2.0,
        	"multiuserOnly": true,
        	"enclosureOnly": true,
        	"scaleWithEnclosure": true,
        	"debug": {"showCursorPlanes": false}
        };
        
        // Load JumpStart.
        loadJumpStart(myOptions);
      • jumpStart
        • doneCaching ()

          jumpStart.addEventListener("precache", function()
          {
          	var myModels = ["models/car", "models/explosion"];
          	jumpStart.loadModels(myModels).then(function()
          	{
          		// Indicate that precaching is complete.
          		jumpStart.doneCaching();
          	});
          
          	return false;	// False indicates ASYNCHRONOUS precaching.
          });
        • run ()

          jumpStart.addEventListener("ready", function()
          {
          	// Load in some last minute stuff
          	var imageElem = new Image();
          	imageElem.addEventListener("load", function()
          	{
          		// Alright, NOW we are ready to start the game.
          		jumpStart.run();
          	});
          	imageElem.src = "http://www.mydomain.com/picture.jpg";
          
          	return false;	// False indicates we are not ready yet.
          });
        • loadModels ( Array modelFiles )

          jumpStart.addEventListener("precache", function()
          {
          	// Define all of the models we want to load.
          	var myModels = ["models/car", "models/explosion"];
          
          	// Load all of these models.
          	jumpStart.loadModels(myModels).then(function()
          	{
          		// All models are done loading.
          		jumpStart.doneCaching();
          	});
          
          	return false;
          });
        • isWorldPosInsideOfEnclosure ( THREE.Vector3 worldPos )

          jumpStart.addEventListener("ready", function()
          {
          	// Have a world-space position to test.
          	var pos = new THREE.Vector3(123.4, 567.9, 910.11);
          
          	// Test it.
          	if( jumpStart.isWorldPosInsideOfEnclosure(pos) )
          		console.log("Yes.");
          	else
          		console.log("No.");
          
          	return;
          });
        • world READONLY THREE.Group
        • worldOffset READONLY THREE.Vector3
        • scene READONLY THREE.Scene
        • deltaTime READONLY Number
        • elapsedTime READONLY Number
        • clickedObject READONLY THREE.Object3D
        • hoveredObject READONLY THREE.Object3D
        • behaviors READONLY Object
        • clock READONLY THREE.Clock
        • camera READONLY (THREE.Camera || null)
        • gamepads READONLY Array
        • activeGamepadIndex READONLY Number
        • rayCaster READONLY THREE.Raycaster
        • audioContext READONLY webkitAudioContext
        • enclosure READONLY Object
          • innerDepth READONLY Number
          • innerHeight READONLY Number
          • innerWidth READONLY Number
          • adjustedDepth READONLY Number
          • adjustedHeight READONLY Number
          • adjustedWidth READONLY Number
          • scaledDepth READONLY Number
          • scaledHeight READONLY Number
          • scaledWidth READONLY Number
        • localUser READONLY Object
          • displayName READONLY String
          • userID READONLY String
          • lookHit READONLY THREE.Vector3
            • object READONLY THREE.Object3D
            • point READONLY THREE.Vector3
            • scaledPoint READONLY THREE.Vector3
        • options READONLY Object
          • appID READONLY String
          • multiuserOnly READONLY Bool
          • enclosureOnly READONLY Bool
          • sceneScale READONLY Number
          • scaleWithEnclosure READONLY Bool
          • webControls READONLY Bool
          • camera READONLY Object
            • position READONLY THREE.Vector3
          • debug READONLY Object
            • showCursorPlanes READONLY Bool
        • spawnTextPlane ( Object options )

          jumpStart.addEventListener("ready", function()
          {
          	// Configure non-default options.
          	var myOptions = 
          	{
          		"width": "auto",
          		"height": 12,
          		"text": "Hello World",
          		"fontSize": 12,
          		"color": "rgba(255,255,255,1.0)",
          		"background": "rgba(0,0,0,1.0)",
          		"backgroundImageElem": null
          	};
          
          	// Spawn the text plane
          	var myObject = jumpStart.spawnTextPlane(options);
          
          	return true;
          });
        • updateTextPlane ( THREE.Object3D textPlane , Object options )

          jumpStart.addEventListener("ready", function()
          {
          	// Configure non-default options.
          	var myOptions = 
          	{
          		"width": "auto",
          		"height": 12,
          		"text": "Hello World",
          		"fontSize": 12,
          		"color": "rgba(255,255,255,1.0)",
          		"background": "rgba(0,0,0,1.0)",
          		"backgroundImageElem": null
          	};
          
          	// Spawn the text plane
          	var myObject = jumpStart.spawnTextPlane(options);
          
          	// Wait for an event to happen.
          	myObject.addEventListener("cursorenter", function()
          	{
          		// Use the same options as before, but new text.
          		myOptions.text = "How are you?";
          
          		// Update the text plane.
          		jumpStart.updateText(this, myOptions);
          	});
          
          	return true;
          });
        • spawnCursorPlane ( Object options )

          jumpStart.addEventListener("ready", function()
          {
          	// Configure non-default options.
          	var myOptions = 
          	{
          		"width": jumpStart.enclosure.scaledWidth,
          		"height": jumpStart.enclosure.scaledHeight,
          		"parent": jumpStart.world
          	};
          
          	// Spawn the text plane.
          	var myObject = jumpStart.spawnCursorPlane(options);
          
          	// Make it solid.
          	myObject.blocksLOS = true;
          
          	// Wait for an event to happen.
          	myObject.addEventListener("tick", function()
          	{
          		// Make sure we are being hovered.
          		if( jumpStart.localUser.cursorHit && jumpStart.localUser.cursorHit.object === this )
          		{
          			// Output the cursor position.
          			console.log(jumpStart.localUser.cursorHit.scaledPoint);
          		}
          	});
          
          	return true;
          });
        • enclosureBoundary ( String boundaryID )

          jumpStart.addEventListener("ready", function()
          {
          	// BoundaryIDs: floor, ceiling, north, east, south, west
          
          	// Get (or create) a cursor plane for the floor of the enclosure.
          	var boundary = jumpStart.enclosureBoundary("floor");
          
          	// Add an event when somebody clicks on the floor.
          	boundary.addEventListener("cursordown", function()
          	{
          		console.log("You clicked the floor!");
          	});
          
          	return true;
          });
        • precacheSound ( String soundFile )

          jumpStart.addEventListener("precache", function()
          {
          	// Start loading the sound.
          	// NOTE: The sound will not be ready to play right away.
          	jumpStart.precacheSound("sounds/explosion");
          
          	return true;
          });
          
          jumpStart.addEventListener("ready", function()
          {
          	// Spawn a cursor plane to interact with.
          	var myObject = jumpStart.spawnCursorPlane();
          
          	// Make it solid.
          	myObject.blocksLOS = true;
          
          	// Wait for an event to happen.
          	myObject.addEventListener("cursordown", function()
          	{
          		// Either resume the loop, or start it up for the first time.
          		if( !!this.userData.mySound )
          			this.userData.sound.source.start(0);
          		else
          			this.userData.mySound = jumpStart.playSound("sounds/explosion", 1.0, true);
          	});
          
          	// Wait for a different event to happen.
          	myObject.addEventListener("cursorup", function()
          	{
          		// Stop the sound.
          		this.userData.mySound.source.stop(0);
          	});
          
          	return true;
          });
        • playSound ( String soundFile , Number volume , Bool loop )

          jumpStart.addEventListener("precache", function()
          {
          	// Start loading the sound.
          	// NOTE: The sound will not be ready to play right away.
          	jumpStart.precacheSound("sounds/explosion");
          
          	return true;
          });
          
          jumpStart.addEventListener("ready", function()
          {
          	// Spawn a cursor plane to interact with.
          	var myObject = jumpStart.spawnCursorPlane();
          
          	// Make it solid.
          	myObject.blocksLOS = true;
          
          	// Wait for an event to happen.
          	myObject.addEventListener("cursordown", function()
          	{
          		// Either resume the loop, or start it up for the first time.
          		if( !!this.userData.mySound )
          			this.userData.sound.source.start(0);
          		else
          			this.userData.mySound = jumpStart.playSound("sounds/explosion", 1.0, true);
          	});
          
          	// Wait for a different event to happen.
          	myObject.addEventListener("cursorup", function()
          	{
          		// Stop the sound.
          		this.userData.mySound.source.stop(0);
          	});
          
          	return true;
          });
        • spawnInstance ( String modelFile , Object options )

          jumpStart.addEventListener("ready", function()
          {
          	// Load a model to use.
          	jumpStart.loadModels(["models/car"]).then(function()
          	{
          		// Configure non-default options.
          		var myOptions = {
          			"parent": jumpStart.world
          		};
          
          		// Spawn a car.
          		var myObject = jumpStart.spawnInstance("models/car", myOptions);
          
          		// We are ready now.
          		jumpStart.run();
          	});
          	
          	return false;
          });
        • removeInstance ( String modelFile )

          jumpStart.addEventListener("ready", function()
          {
          	// Load a model to use.
          	jumpStart.loadModels(["models/car"]).then(function()
          	{
          		// Configure non-default options.
          		var myOptions = {
          			"parent": jumpStart.world
          		};
          
          		// Spawn a car.
          		var myObject = jumpStart.spawnInstance("models/car", myOptions);
          
          		// Make it solid.
          		myObject.blocksLOS = true;
          
          		// Wait for an event to happen.
          		myObject.addEventListener("cursorup", function()
          		{
          			// Remove us.
          			jumpStart.removeInstance(this);
          		});
          
          		// We are ready now.
          		jumpStart.run();
          	});
          	
          	return false;
          });
        • addEventListener ( String eventType , Function eventHandler )

          // Game System Events: precache, initialize, ready, tick, cursordown, cursorup
          
          // Wait for an event to happen.
          jumpStart.addEventListener("cursordown", function()
          {
          	console.log("Local user clicked on something!");
          });
        • removeEventListener ( String eventType , Function eventHandler )

          // Game System Events: precache, initialize, ready, tick, cursordown, cursorup
          
          // Wait for an event to happen.
          jumpStart.addEventListener("cursordown", function()
          {
          	console.log("Local user clicked on something!");
          
          	// arguments.callee gives us the current function.
          	var selfFunc = arguments.callee;
          
          	// Stop listening for this event.
          	jumpStart.removeEventListener("cursordown", selfFunc);
          });
    • THREE.Object3D (only if created using jumpStart.spawnInstance)
      • ownerID String
      • blocksLOS Bool
      • modelFile READYONLY String
      • boundingSphere THREE.Sphere
      • behaviors Object
      • userData Object
      • syncData Object
      • ignoreSync Object
        • transform Object
          • position Bool
          • quaternion Bool
          • scale Bool
      • setColor ( THREE.Color color )

        jumpStart.addEventListener("ready", function()
        {
        	// Load a model to use.
        	jumpStart.loadModels(["models/car"]).then(function()
        	{
        		// Spawn a car.
        		var myObject = jumpStart.spawnInstance("models/car");
        
        		// Change the color of the car.
        		var myColor = new THREE.Color("#00ff00");
        		myObject.setColor(myColor);
        
        		// We are ready now.
        		jumpStart.run();
        	});
        
        	return false;
        });
      • applyBehavior ( String behaviorID , Object options )

        jumpStart.addEventListener("ready", function()
        {
        	// Load a model to use.
        	jumpStart.loadModels(["models/car"]).then(function()
        	{
        		// Spawn a car.
        		var myObject = jumpStart.spawnInstance("models/car");
        
        		// Each behavior has its own unique options.
        		var myOptions = {"force": new THREE.Vector(0, 7.5, 0)};
        
        		// Toss the car straight up into the air.
        		myObject.applyBehavior("physics", myOptions);
        
        		// We are ready now.
        		jumpStart.run();
        	});
        
        	return false;
        });
      • unapplyBehavior ( String behaviorID )

        jumpStart.addEventListener("ready", function()
        {
        	// Load a model to use.
        	jumpStart.loadModels(["models/ball"]).then(function()
        	{
        		// Spawn a ball.
        		var myObject = jumpStart.spawnInstance("models/ball");
        
        		// Make the ball physics-controlled.
        		myObject.applyBehavior("physics");
        
        		// Wait for an event to happen.
        		myObject.addEventListener("cursordown", function()
        		{
        			// Stop the ball & remove the physics behavior.
        			this.unapplyBehavior("physics");
        		});
        
        		// We are ready now.
        		jumpStart.run();
        	});
        
        	return false;
        });
      • sync ( Object options )

        jumpStart.addEventListener("ready", function()
        {
        	// Load a model to use.
        	jumpStart.loadModels(["models/ball"]).then(function()
        	{
        		// Spawn a ball for this client.
        		var myObject = jumpStart.spawnInstance("models/ball");
        
        		// Attach some synced data.
        		myObject.syncData.team = 0;
        
        		// Sync it to the multiuser session so it exists on all clients.
        		myObject.sync();
        
        		// We are ready now.
        		jumpStart.run();
        	});
        
        	return false;
        });
      • addEventListener ( String eventType , Function eventHandler )

        // Object Events: cursorenter, cursorexit, cursordown, cursorup, spawn, remove, networkRemove, tick
        
        jumpStart.addEventListener("ready", function()
        {
        	// Load a model to use.
        	jumpStart.loadModels(["models/car"]).then(function()
        	{
        		// Spawn a car.
        		var myObject = jumpStart.spawnInstance("models/car");
        
        		// Wait for an event to happen.
        		myObject.addEventListener("tick", function()
        		{
        			// Spin this car.
        			var amount = 5.0 * jumpStart.deltaTime;
        			this.rotateY(amount);
        		});
        
        		// We are ready now.
        		jumpStart.run();
        	});
        
        	return false;
        });
      • removeEventListener ( String eventType , Function eventHandler )

        // Object Events: cursorenter, cursorexit, cursordown, cursorup, spawn, remove, networkRemove, tick
        
        jumpStart.addEventListener("ready", function()
        {
        	// Load a model to use.
        	jumpStart.loadModels(["models/car"]).then(function()
        	{
        		// Spawn a car.
        		var myObject = jumpStart.spawnInstance("models/car");
        
        		// Wait for an event to happen.
        		myObject.addEventListener("cursordown", function()
        		{
        			// Make this car twice as big.
        			this.scale.multiplyScalar(2.0);
        
        			// arguments.callee gives us the current function.
        			var selfFunc = arguments.callee;
        
        			// Stop listening fot his event.
        			this.removeEventListener("cursordown", selfFunc);
        		});
        
        		// We are ready now.
        		jumpStart.run();
        	});
        
        	return false;
        });



    Astro Catastrophe

    PLAY NOW

    Cooperatively build a base and gun towers to defend yourselves from the impending asteroid bombardment!

    This app was built on an outdated version of JumpStart.

    http://www.jumpstartsdk.com/live/AstroCatastrophe.html
    Space Pilot

    PLAY NOW

    Destroy the enemy ships in the galaxy before they destroy you!

    This app was built on an outdated version of JumpStart.

    http://www.jumpstartsdk.com/live/SpacePilot.html
    Gator Smasher

    PLAY NOW

    Smash the gators as they come out of the swamp.

    This app was built on an outdated version of JumpStart.

    http://www.jumpstartsdk.com/live/GatorSmasher.html
    Air Hockey

    PLAY NOW

    Play air hockey with a friend, or practice your bank-shot by yourself.

    This app was built on an outdated version of JumpStart.

    http://www.jumpstartsdk.com/live/AirHockey.html
    Vrisbee

    PLAY NOW

    Play VR frisbee with a friend, or smash targets with your flying disc. It's up to you!

    This app was built on an outdated version of JumpStart.

    http://www.jumpstartsdk.com/live/Vrisbee.html
    Sammy

    PLAY NOW

    A digital bug buddy that wonders around with smooth 3D animiation.

    This app was built on an outdated version of JumpStart.

    http://www.jumpstartsdk.com/live/Sammy.html
    Tiki Drum

    PLAY NOW

    Bounce the magical Tiki ball around with your friends.

    This app was built on an outdated version of JumpStart.

    http://www.jumpstartsdk.com/live/TikiDrum.html
    Spooky Memory

    PLAY NOW

    Match the cult Halloween icons without drawing the "DEATH" card!

    This app was built on an outdated version of JumpStart.

    http://www.jumpstartsdk.com/live/SpookyMemory.html
    Combo Breaker

    PLAY NOW

    A mix between Connect Four & Tetris. Work together with your friends to try and get the biggest combos!

    This app was built on an outdated version of JumpStart.

    http://www.jumpstartsdk.com/live/ComboBreaker.html



    Interstellar Defense


    An arcade-style top-down shooting game.

    This app was NOT built on JumpStart.

    http://www.smsithlord.com/SLURMVR/?play=1