Copy and Paste Assets between Projects

PlayCanvas has a pretty cool (but not widely known about) feature that allows you to copy and paste entities and entity hierarchy between two instances of the Editor. This can save a lot of time, particularly when setting up new projects.

Many of you have requested the ability to do the same with assets. Well, we listened – and now you can! πŸš€

So if you need to grab some assets from another project, no more need to download from Project A and then upload to Project B. Just copy and paste in seconds, directly from project to project.

This makes it super easy to share reusable code and assets with your team and the rest of the PlayCanvas community, especially in combination with the recent launch of Templates to setup preconfigured Entities.

Use the context menu or the Ctrl/Cmd + C and Ctrl/Cmd + V hotkeys to copy assets across to your projects. πŸ’ͺ

Check out the documentation for more details.

Faster Load Times with glTF’s GLB Format!

The PlayCanvas team is super excited to announce the Editor support of glTF GLB conversion with model and animation imports.

This gives developers an order of magnitude reduction in load times compared to the JSON format while keeping similar gzipped download size.

Using the Stanford Dragon model (2,613,679 vertices, 871,414 triangles), we can compare GLB and JSON parse times on a Macbook Pro 16 inch.

The JSON format took over 3 secs just to parse the data, a peak memory usage of ~498 MB and a gzipped package size of 28.1MB.

JSON

GLB speeds ahead taking only 0.193 secs which is 17x faster, uses a peak of ~25.2 MB of memory and a gzipped package size of 25.7MB πŸš€!

GLB

That’s a huge saving in time and means applications will become snappier and more responsive to users, especially for content heavy games and product showcases.

We will be deprecating the use of JSON and the default format that model and animations files. Newly created projects will default to converting to GLB and in existing projects, this can be enabled in the projects settings:

If you would like to replace your current JSON assets with GLB, the User Manual has more information about the process to migrate over.

The conversion to GLB supports the importing of multiple animations in a single FBX which will help improve content workflows.

Remember our awesome glTF 2.0 Viewer? That is now integrated into the Editor to inspect any GLB asset from the project. Just right and select β€˜Open In Viewer’!

Also, we have exposed Animation Import Settings under Asset Tasks in project settings. These will allow developers to adjust a balance between animation quality and fidelity against file size.

Animation Import Settings

Our next steps are to add support for viewing and editing a model hierarchy in the Editor which will lead onto support for the importing of GLB files.

The team is hard at work designing and implementing these features so watch this space!

Introducing PCUI – An Open Source UI Framework for the Web πŸš€

Today, PlayCanvas is launching PCUI: a new, open source front-end framework for the web.

PCUI is designed with tools developers in mind. It is particularly well suited to building viewer and editor applications, providing a rich set of beautiful and consistent controls. It already powers the PlayCanvas Editor – the world’s most powerful WebGL production tool.

Here you can see tree controls, panels, buttons, checkboxes, toolbars, menus and more. The Editor also relies on PCUI’s observer system, that makes it easy to synchronize the state of your application’s UI with that of the underlying data. Plus, it has a built-in support for history to make implementing redo/undo a breeze.

Also built on PCUI is the PlayCanvas glTF Viewer, a tool for inspecting glTF 2.0 scenes.

Check out the viewer’s GitHub repo to see how a Typescript-based web application leverages PCUI.

If these applications inspire you to build your own browser-based tools, why not get started with PCUI today? Here are some useful links:

PCUI works great with vanilla JS projects, Typescript projects and React-based projects. It’s open source so we encourage you to get involved and help us advance PCUI.

If you’re building any kind of browser-based tool application – definitely check it out today and share your thoughts on the forum!

Supercharge your workflow with Template Assets!

It’s finally here! The PlayCanvas team is very excited to announce the public release of our new Templates feature! πŸŽ‰

Templates allow you to create preconfigured entities with all the values and child hierarchy as an asset reference.

This is a huge workflow boost as managing and changing objects in a scene is now easier and faster to do. New instances of the Template can be placed in the scene with the Editor. These instances have a link to the Template asset, so any changes to the asset will change the instances in the scene too.

Now we are able to change and update many scene entities via a single asset which is a welcome change from the tedious manual updating of multiple entities across multiple scenes.

Change all instances of Templates in one click! πŸš€

Other features of the Template system also include:

  • Adding instances in the Scene editor (including drag and drop support of template assets to the Hierarchy panel)
  • Overriding properties on a per instance basis
  • Nested Templates which allows referencing a Template in another Template
  • Creating a new instances via code from an asset reference

In terms of how they can be used, we have been beta-testing the feature since early 2020 (big thanks to all those that have given us feedback and bug reports πŸ™) and some of the use cases we’ve seen so far include:

  • Designing and creating sections of an infinite runner game
  • Managing UI screens and instantiating them at runtime
  • Different enemy types that a script can reference to randomly generate a level

As you can see, Templates give you a wide range of flexibility of workflow options to manage and modify content in your projects.

Find out more about Templates in the User Manual and give them a try yourself!

PlayCanvas launches glTF 2.0 Viewer Tool

Today, the PlayCanvas team is excited to announce the release of a brand new browser-based glTF viewer application.

Try it now: https://playcanvas.com/viewer

Or click these links to preload some classic glTF models: Boom Box, Damaged Helmet and Fox.

The viewer is open sourced under an MIT license and the code can be found on GitHub.

Fork it now: https://github.com/playcanvas/playcanvas-viewer

The viewer allows you to drag-and-drop any glTF 2.0 file and inspect it in detail. We challenge you to find one that doesn’t work! The viewer has the following features:

  • Visualize wireframe, skeleton, bounds and normals
  • Adjust scene lighting and skybox
  • Drag and drop equirectagular images (including HDR files) or six cubemap face images.
  • See how a model performs on both the CPU and GPU via the viewer’s real-time metrics panel
  • Play animations (including skinned and morphed meshes) – unlimited morph targets are supported
  • Visualize animation curves in real-time as graphs in the 3D view
  • Load models via drag-and-drop or by passing a URL query parameter
  • Support for Draco mesh compression

The release of the PlayCanvas Viewer coincides with the engine reaching 100% glTF 2.0 spec compliance! PlayCanvas passes every single core test in cx20’s glTF Test suite. We are now turning our attention to supporting the full range of glTF 2.0 extensions. The engine already supports:

  • KHR_materials_pbrSpecularGlossiness
  • KHR_materials_unlit

The engine itself can parse and render glTF 2.0 files incredibly quickly. You can expect glTF parse time to be approximately one tenth of that loading the equivalent JSON model.

Give it a try today – you’ll be impressed!

Plan Updates: More Storage, More Features, Same Price

Creativity makes our world a better place. PlayCanvas unlocks creativity through collaborative, frictionless tools that enable everybody to build, share and play together.

With PlayCanvas, getting started with game development is as simple as clicking on a hyperlink. No installation, available wherever you have access to a browser and easily shareable for a real-time collaborative workspace.

Super Snappy Bowling from NOWWA

Until today, some aspects of the platform have been limited or restricted. This just holds back the creativity of our community. So today, we have some incredibly exciting news. We have updated our plans to make our tools even more accessible for everyone at all levels!

We are now giving everyone:

Best of all, this comes at no extra cost! πŸŽ‰πŸŽ‰πŸŽ‰

If you’re new to PlayCanvas, now is the perfect time to get started! We hope you enjoy these new features and updates.

One last thing! We are super-excited to spread the word – can you help us with a retweet?
https://twitter.com/playcanvas/status/1285598408787582977

Porting a Large ES5 JavaScript Library to ES6 Modules and Rollup

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.

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!

TANX lives! Popular WebGL online game returns

In the early days of PlayCanvas, we published a game called TANX, an online multiplayer tank battle game.

To us, it was the perfect illustration of why the web makes such a great platform for gaming.

  • Bite-sized fun with drop-in/drop-out gameplay.
  • Nothing to download – just follow a hyperlink to stream the game in a couple of seconds.
  • True device independence – play on your phone, tablet or desktop.
  • Easy social sharing – get your friends into matches by posting your personal game URL to Twitter in real-time!

So we decided to keep developing the game. The first iteration above just had primitive tanks driving around an empty environment. v2.0 brought upgraded tank models, a new UI and a proper level:

And the game’s popularity continued to grow. It even hit #1 on Hacker News one lazy Friday afternoon!

By now, the PlayCanvas engine was rapidly evolving and had recently gained support for physically based rendering (PBR). We were desperate to upgrade the game to show off these new capabilities. So not long afterwards, we developed v3.0:

The game also leveraged PlayCanvas’ run-time lightmapper to generate the level’s shadows.

Not long after the upgrade, we decided to focus all of our resources on developing the core PlayCanvas engine. In the end, we didn’t have enough time to maintain the game and so, with heavy hearts, we took it offline.

Until today.

We’re really excited to announce that TANX is back! You can play it at:

https://tanx.io

Or alternatively, you can find the game hosted on Miniclip and Itch.io.

Keep your eyes peeled for a follow up article outlining how we rebuilt and deployed the game’s back-end!

Implementing Cloth Simulation in WebGL

The PlayCanvas WebGL game engine integrates with ammo.js – a JavaScript/WebAssembly port of the powerful Bullet physics engine – to enable rigid body physics simulation. We have recently been working out how to extend PlayCanvas’ capabilities by using soft body simulation. The aim is to allow developers to easily set up characters to use soft body dynamics.

Here is an example of a character with and without soft body cloth simulation running in PlayCanvas:

CLICK TO PLAY DEMO

Want to know how it was done? Read on!

Step 1: Create a soft body dynamics world

By default, PlayCanvas’ rigid body component system creates an ammo.js dynamics world that only supports generic rigid bodies. Cloth simulation requires a soft body dynamics world (btSoftRigidDynamicsWorld). Currently, there’s no easy way to override this, so for the purpose of these experiments, a new, parallel soft body dynamics world is created and managed by the application itself. Eventually, we may make the type of the internal dynamics world selectable, or maybe even allow multiple worlds to be created, but for now, this is how the demo was structured.

Step 2: Implement CPU skinning

PlayCanvas performs all skinning on the GPU. However we need skinned positions on CPU to update the soft body anchors (btSoftBody::Anchor) to match the character’s animation. CPU skinning may be supported in future PlayCanvas releases.

Step 3: Patch shaders to support composite simulated and non-simulated mesh rendering

Soft body meshes will generate vertex positions and normal data in world space, so in order to render the dynamically simulated (cloth) parts of character meshes correctly, we have to patch in support by overriding the current PlayCanvas vertex transform shader chunk. In a final implementation, no patching should be necessary, as we would probably add in-built support for composite simulated and non-simulated mesh rendering.

Step 4: Implement render meshes to soft body meshes conversion

PlayCanvas character meshes cannot be used directly by the soft body mesh creation functions (btSoftBodyHelpers::CreateFromTriMesh) and so require some conversion, so the PlayCanvas vertex iterator was used to access and convert the mesh data. Eventually this conversion could be done on asset import into the PlayCanvas editor.

Step 5: Implement per-bone attachments

PlayCanvas currently doesn’t have a way to attach objects to specific character bones via the Editor (it’s on our roadmap for the coming months!). Therefore, per-bone attachments was implemented in order to attach simplified rigid body colliders to different parts of the character to prevent the cloth from intersecting the character mesh. We are using simplified colliders instead of trying to use the full skinned character mesh because it runs much faster.

If you are feeling adventurous, you can find the prototype source code for the example above in this PlayCanvas project:

https://playcanvas.com/project/691109/overview/cloth-simulation-demo

It is a prototype implementation and so expect many changes (some of which are mentioned above) in a final implementation.

Want to try soft body dynamics on your own character? Here’s how:

Step 1: Fork the PlayCanvas prototype project.

Step 2: Mark out what parts of the character you want simulated:

This is done by painting colors into the character mesh vertices – the example character was downloaded from Mixamo, and imported into Blender:

Black = fully simulated, White = not simulated

Step 3: Import the character into the PlayCanvas editor and set up collision: 

On this character, only colliders for the legs and body are needed.

What’s Next

We are really excited about developing this technology in the coming months. We will focus on these areas:

  • Take learnings from the prototype and add good support for soft body dynamics in PlayCanvas
  • Create easy to use tools for PlayCanvas developers to import and setup characters with soft body dynamics
  • Further optimize and improve quality

We would love to get your thoughts and feedback so come join the conversation on the PlayCanvas forum!

A New UI for the PlayCanvas Editor

The PlayCanvas Editor has been around since 2011. Way back then, it was called the PlayCanvas Designer. It was built on Sencha’s ExtJS front end framework and looked like this:

As you can see, it sort of looks like a Windows XP application. If you think it looks retro now, it actually looked retro then! But you can more or less recognize it as PlayCanvas. The Pack Explorer is now the Hierarchy panel on the left. The Attribute Editor is now the Inspector. You can even see the ‘Who’s Online’ bar to the bottom right, which is still around today. We decided quite quickly to drop the WinXP aesthetic by adopting a darker theme in September 2013:

This refresh was definitely an improvement and it was the start of the Designer finding a personality of its own. But after this, the team was struggling to iterate quickly. We took the very difficult decision to throw away the entire ExtJS-based Designer application and rewrite it from scratch using the incredible Vanilla JS framework. And thus, by early 2015, the PlayCanvas Editor was born:

This initial version of the Editor should be much more recognizable. The toolbar and panels are all still in the same location. But today, the Editor packs in far more functionality and is much more powerful.

It was originally written in ES5 and a subset of CSS that would enable the Editor to work in browsers all the way back to IE11. Late last year, we embarked on the next major overhaul for the Editor, with the following goals:

  • Create a clean, structured underlying Editor API (more on this later)
  • Adopt ES6 (let’s get with the times!)
  • Adopt CSS grid to make managing the Editor’s layout easier
  • Refresh and refine the front-end design

We’ve slowly been phasing in the new front-end over the last several months, first deploying an updated Hierarchy Panel and then a new Inspector Panel. Today, we’re proud to announce the final step in the rollout – the new Asset Panel:

To the end user, the most obvious change is the addition of the Asset Panel’s Details View. As an alternative to thumbnails, you can now see a linear list of assets and even sort them on size and type.

We expect that this will rapidly become the default view for most PlayCanvas developers. No more mouse hovering to read long filenames!

So what’s next? Earlier, I mentioned that this completely rebuilt Editor front-end is built on a new, clean, object-oriented API. It is our plan to release this API publicly, once it is ready. This will enable you to write extensions and customizations to the Editor that will culminate in a full plugin system. Stay tuned for further details of that. But in the meantime, let us know what you think by joining the conversation on the forum!