Skip to main content

3 posts tagged with "javascript"

View All Tags

Using Visual Studio Code with PlayCanvas

· 2 min read

Visual Studio Code is massively popular. In the Stack Overflow 2023 Developer Survey, Visual Studio Code was ranked the most popular developer environment tool among 86,544 respondents, with 73.71% reporting that they use it.

Any PlayCanvas developer building directly on top of the Engine will very likely opt to use VS Code. But if you use the PlayCanvas Editor, you will normally rely on the built-in, browser-based Code Editor. Today, we're excited to give you another option by launching an open-source Visual Studio Code Extension for PlayCanvas.

VS Code Extension

Benefits

The PlayCanvas Code Editor is actually built on the Monaco Editor, the beating heart of VS Code. So why use VS Code instead of the PlayCanvas Code Editor?

  • GitHub Copilot - leverage AI to help you write PlayCanvas code faster.
  • Powerful IntelliSense tools (code completion, parameter info, quick info, and member lists).
  • Leverage a huge library of other extensions to accelerate your development.

We ❤️ Open Source

As you might expect, we have open sourced the VS Code extension under a liberal MIT license!

So if you find a bug or have a suggestion, please do log an issue. And for the more adventurous, consider making a code contribution!

We want you to feel empowered to make these tools your own. Let's make them awesome together! 🙌

Get Started Now

If this all sounds great to you, why not give it a try? Head over to the User Manual for instructions on how to get started:

READ THE DOCS

Porting a Large ES5 JavaScript Library to ES6 Modules and Rollup

· 5 min read

Since 2011, the PlayCanvas engine sourcebase has adhered strictly to the ES5 JavaScript specification. Since then, the JavaScript language and the surrounding tools ecosystem has moved on considerably. But PlayCanvas has steadfastly stuck to ES5. Why? Internet Explorer 11.

IE11 was released on October 17, 2013. But even today, StatCounter reports that IE11 has 2.43% of the global desktop browser market. Since PlayCanvas content is viewed by 100s of millions of end users, this is a pretty big deal.

Over time, the engine codebase has grown significantly. It's now nearly 100,000 lines long. Maintaining and building such a large codebase can be problematic. To help bring some level of consistency and structure, we imposed the following pattern:

Object.assign(pc, (function () {
var SomeClass = function () {
this.other = new pc.OtherClass();
};

Object.assign(SomeClass.prototype, {
someFunction: function () {}
});

return {
SomeClass: SomeClass
};
}()));

pc is the PlayCanvas library namespace. So a developer would create instances of this class as follows:

var thing = new pc.SomeClass();

To build the engine, we wrote a node.js script which would parse a list of dependencies (JavaScript filenames) and concatenate them. There were several problems:

  1. The pattern above is overly verbose making it harder to inspect the code.
  2. Object.assign needs to be called 250 times when the library is initially executed by the browser, once for each module. This increases app start-up times.
  3. In internal engine code, all class names and constants need to be accessed via the pc namespace. This is because the internals of the pattern above cannot see the internals of other modules and vice versa. This bloats the engine code and slows things down.
  4. The dependencies file had to be carefully manually ordered to ensure things were declared in the right order.
  5. The build script itself was about 1000 lines of JavaScript which carried its own maintenance overhead.
  6. Unused code was being included in the published engine.

We believed the solution to these problems was to migrate the engine codebase from vanilla ES5 to ES6 modules. This would transform the original module pattern to:

import { OtherClass } from './other-class.js';

var SomeClass = function () {
this.other = new OtherClass();
};

Object.assign(SomeClass.prototype, {
someFunction: function () {}
});

export { SomeClass };

Much better!

  • No more needless calls to Object.assign to the pc namespace.
  • No further need to use the pc namespace within modules.
  • Dependencies are explicitly described in each JS file.
  • Only what is necessary is exported from modules (and the overall engine).

But what about IE11? It doesn't understand ES6 module syntax! 😱 PlayCanvas still needs to ship as a strictly ES5 library. To transform the entire codebase from ES6 module format to ES5 UMD format (PlayCanvas is used in both the browser and Node), you simply need to leverage a JavaScript bundler.

There are many options for selecting a JS bundler. In the end, 3 options were tested: Rollup, Parcel and ESBuild. You can see the PRs for each here:

In the end, Rollup was selected over Parcel and ESBuild. In testing, Parcel needed up to 16s for an initial build, while Rollup only required 3s. And we were reticent to adopt ESBuild since it was far less established and battle tested compared to Rollup. But we may review this decision in the future. Now that the engine is ported to ES6 modules, switching bundler is fairly straightforward.

With Rollup, the build script reduced from ~1000 lines to ~100 lines. Quite a saving. Rollup's plugin system made it incredibly easy to write custom handling for GLSL files and also run a C-like preprocessor in order to build debug, release and profile versions of the engine.

What's Next?

Now that we have merged the ES6 Module port, where do we go from here?

First up, Rollup is kindly informing us that circular dependencies exist in the PlayCanvas codebase.

Rollup Circular Dependencies

We want to clean things up and eliminate them. What's the motivation for that? It makes it easier for the bundler to employ tree-shaking to remove unreferenced code from the engine. At the moment, the engine's Application class imports pretty much everything. And many classes import the Application. This makes it hard to build a version of the library which doesn't include the particle engine, say. Or maybe the physics engine.

Beyond that, we are keen to explore leaving ES5 behind and fully embracing 'modern' JavaScript, or maybe TypeScript. Rollup can trivially run Babel or the TypeScript compiler as plugins, thereby ensuring we can still ship an ES5 library. We're looking forward to making that decision based on your feedback. So feel free to let us know what you think on the forum!

Will HTML5 change the way games are made?

· 2 min read

Oops, we've been so busy that we forgot to mention this article that Will wrote for Game Developer. It was well received though not without a little controversy - turns out there are still a fair few Flash lovers out there, and a lot of people still aren't seeing the joy of JavaScript. 🙈

If you haven't read it, here are a few choice quotes to give you a feel.

The cloud brings a lot of benefits in the context of games. There is nothing to install since the web app is delivered to the browser from the server (or the browser's cache). The tools always stay seamlessly up to date, which ensures that users remain in sync with each other and are always using the latest and greatest release. User data is always safely backed up and trivially restorable.

And:

One of the key strengths of HTML5 as a technology for tools is that all content sits on a URL. Each of the resources that make up a game can be accessed at a specific web address: a script file, a texture, a sound, a level or even the game itself. If a new asset is added to a project, the developer can tweet, IM or mail the link immediately.

And:

Let's face it: making games is hard, and making a (good) game alone is not an option for most developers. The spectrum of skills required is often just too great. Developers need to be able to find each other and get involved in the game projects that excite them the most.

And finally one that's close to my heart:

It's likely that a lot of people who convert to JavaScript won't be going back.