<~
\^/

How to Create Games using TypeScript, Vite, and BabylonJS Part One: A Basic Scene with Objects, a Light, and a Camera

TypeScript, Vite, and BabylonJS

If you need a fast, reliable, and lightweight way to create 3D browser games you've landed on the right post. With BabylonJS, a powerful 3D engine; Vite, one of the latest fast and lightweight build tools; and TypeScript, arguably a better version of JavaScript, we can create decent-sized WebGL games with realistic graphics, physics, skeletal animation, and post-processing effects just to name a few of the features.

Let's get right into it!

Creating a Vite Project

They've made it nice and simple to install Vite with a helpful CLI:

When running these commands, replace devlon with the name of your game and pick the options Vanilla then TypeScript on the CLI menus that appear.

1npm create vite@latest devlon 2&& cd devlon 3&& npm install 4

Your generated project folder should look like this:

1tree 2your-awesome-game-name/ 3├── index.html 4├── node_modules 5├── package-lock.json 6├── package.json 7├── public 8│   └── vite.svg 9├── src 10│   ├── counter.ts 11│   ├── main.ts 12│   ├── style.css 13│   ├── typescript.svg 14│   └── vite-env.d.ts 15└── tsconfig.json 16

You can test it out right now by running:

1npm run dev 2

Did you get any errors? Make sure you have the latest version of npm installed and before trying again.

Next we can install BabylonJS and configure everything to work together.

Installing BabylonJS

Run the following command to install babylonjs-core

1npm install --save babylon 2

We only need BabyonJS core for now, but we install the loaders and GUI package in another tutorial in this series.

Configure Vite and TypeScript

We need to configure Vite to use BabylonJS's max script so that it's easier to code and debug.

Create a file called vite.config.js in your project root and add the following:

This simply tells vite to use the babylon.max. This is the human-readable readable script version. babylonjs is the optimized-for-speed version for when we launch to production.

1import { defineConfig } from 'vite'; 2 3export default defineConfig(({ command, mode }) => { 4 return { 5 resolve: { 6 alias: { 7 'babylonjs': mode === 'development' ? 8 'babylonjs/babylon.max' : 'babylonjs' 9 } 10 } 11 }; 12}); 13

TS Config

Lastly, update tsconfig.json in root to include the vite config file.

1{ 2 ... 3 "include": [ 4 "src", 5 "vite.config.js" 6 ] 7} 8

Package Config

In package.json change the value of scripts: dev to vite --open to automatically open the page when we run the game:

1{ 2 ... 3 "scripts": { 4 "dev": "vite --open", 5 ... 6 } 7} 8

Awesome! We have our project set up with Vite, BabylonJS, and TypeScript. We can create decent games with only these three libraries. We'll get to that later. For now, let's create a basic scene.

Creating the Scene

In BabyonJS every game object lives in the Scene. Think of it like the "game world". We'll start by updating the index.html to make it ready for rendering.

index.html

The main and potentially only HTML file you'll need. It'll start off pretty basic. Most of our code will be in modular TypeScript files in the src/ folder. We add a canvas element that Babylon uses to render the scene, change the title of our page, and add a style element that makes the canvas fill the screen.

1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="UTF-8" /> 5 <link rel="icon" type="image/svg+xml" href="/vite.svg" /> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 <title>Devlon!</title> 8 <style> 9 html, 10 body { 11 overflow: hidden; 12 width: 100%; 13 height: 100%; 14 margin: 0; 15 padding: 0; 16 text-align: center; 17 } 18 19 #game { 20 width: 100%; 21 height: 100%; 22 } 23 </style> 24 </head> 25 26 <body> 27 <canvas id="game"></canvas> 28 <script type="module" src="/src/main.ts"></script> 29 </body> 30 31</html> 32

So far so good.

Scripts

The following additions and changes will happen in the src/ folder.

src/main.ts

This is the first script that is run as we saw in index.html. Change it to look like this:

We will create the Game.ts file next, so don't worry about any import errors.

1import { Game } from './Game'; 2 3window.addEventListener('DOMContentLoaded', () => { 4 let canvas: any = document.getElementById('game') as HTMLCanvasElement; 5 let game: Game = new Game(canvas); 6 game.run(); 7}); 8

src/game.ts

Create src/game.ts. Replace the file src/AppOne.js if the vite-cli created it in the first step.

Finally, some BabylonJS!

Import the modules using ES6 modules.

1// Imports es6 style 2import { 3 Engine, 4 Scene, 5 Vector3, 6 MeshBuilder, 7 FreeCamera, 8 HemisphericLight, 9} from "babylonjs"; 10

Create the Game class.

1// The game class used in `main.ts` 2export default class Game { 3 engine: Engine; 4 scene: Scene; 5 6 constructor(readonly canvas: HTMLCanvasElement) { 7 this.engine = new Engine(canvas); 8 // allows the engine to resize the scene when the browser window changes. 9 window.addEventListener("resize", () => { 10 this.engine.resize(); 11 }); 12 this.scene = createScene(this.engine, this.canvas); 13 } 14} 15

Add the follow methods to the bottom of class Game.

1// Turns on the Game Engine "level editor" toolbars. Awesome feature! Now you have a Game Engine on par with the likes of Unity, Godot, and Unreal! 2 debug(debugOn: boolean = true) { 3 if (debugOn) { 4 this.scene.debugLayer.show({ overlay: true }); 5 } else { 6 this.scene.debugLayer.hide(); 7 } 8 } 9 10 run() { 11 this.debug(true); 12 this.engine.runRenderLoop(() => { 13 this.scene.render(); 14 }); 15 } 16} 17

Add the createScene function to the bottom of the file

1es6 imports <------| collapsed for clarity, don't change 2class Game{...} <--| anything from prev code. 3 4var createScene = function (engine: Engine, canvas: HTMLCanvasElement) { 5 // The scene that holds our objects and camrea. 6 var scene = new Scene(engine); 7 8 // The camera we will control to look around. 9 var camera = new FreeCamera("camera1", new Vector3(0, 5, -10), scene); 10 11 // Point the camera to origin of the scene. 12 camera.setTarget(Vector3.Zero()); 13 14 // Attach that camera to the canvas. 15 camera.attachControl(canvas, true); 16 ... 17

Create the light, sphere, and ground plane.

1 ... 2 // A light that poitns towards 0,1,0 - straight up. 3 var light = new HemisphericLight("light", new Vector3(0, 1, 0), scene); 4 5 // Default intensity is 1. This is dimmer. 6 light.intensity = 0.7; 7 8 // A sphere! 9 var sphere = MeshBuilder.CreateSphere( 10 "sphere", 11 { diameter: 2, segments: 32 }, 12 scene 13 ); 14 // Move the sphere upward 1. 15 sphere.position.y = 1; 16 17 // A ground! 18 var ground = MeshBuilder.CreateGround( 19 "ground", 20 { width: 6, height: 6 }, 21 scene 22 ); 23 ground.position.y = -1; 24 25 return scene; 26}; 27 28/// End of main.ts 29 30

Your project should now like this:

1index.html 2├── node_modules 3├── package-lock.json 4├── package.json <--- changed 5├── public 6│   └── vite.svg 7├── src 8│   ├── game.ts <--- new 9│   ├── main.ts <--- changed 10│   ├── style.css 11│   ├── typescript.svg 12│   └── vite-env.d.ts 13└── tsconfig.json <--- changed 14|__ vite.config.json <--- new 15

Run the Game

Let's see what we've got.

1npm run dev 2

This should open your browser to https://localhost:5173. You can open it manually if it did not.

Done!

You should see this:

basicscene.png: A picture of a ball and a sphere

A ball and a plane -.- ....

But a great start! You'll have to go to the next chapter for the flashy game features :D

V

More Posts

Cover Image for How to Create Games using TypeScript, Vite, and BabylonJS Part One: A Basic Scene with Objects, a Light, and a Camera

How to Create Games using TypeScript, Vite, and BabylonJS Part One: A Basic Scene with Objects, a Light, and a Camera

TypeScript, Vite, and BabylonJS

If you need a fast, reliable, and lightweight way to create 3D browser games you've landed on the right post. With BabylonJS, a powerful 3D engine; Vite, one of the latest fast and lightweight build tools; and TypeScript, arguably a better version of JavaScript, we can creat...

Cover Image for If You Had to Choose One Thing to Rely on When Things Get Tough, What Would it Be?

If You Had to Choose One Thing to Rely on When Things Get Tough, What Would it Be?

If You Had to Rely on One Thing

Life has a way of throwing unexpected curveballs and presenting us with unexpected challenges and opportunities. It teaches us how to live through the many tasks and obstacles we each need to deal with to progress. If you had to rely on one thing in life what would it be? Life, Yourself, God, Goals, Philosophy, or something else? Luckily we can choose more than ...