Global scope is considered evil. It especially resonates in the JavaScript world with a notorious window object. The most common advice out there is to avoid globals as much as possible.

However, a game state is essentially a one big global scope.

It defines where the enemies are, how many hit points they have, and how much health and ammo you’ve got. And each part of that system potentially can affect any other.

In reality, the global scope is not that bad if you know how to deal with it.

Collider.JAM offers its own approach of global scope organization and handling.

The Mix

The global scope in Collider.JAM represents the scene and all associated resources. It is called the mix since it mixes all mods and fixes into a single tree hierarchy. At the top of the mix, there is the root mod. All other mods are mounted inside at /mod by default.

Everything in your game is placed somewhere in the mix. You can think of it as a virtual filesystem that joins together all the *.mod and *.fix folders you have plus all the system *mod and *.fix folders shipped with Collider.JAM.

The mixing process is pretty straightforward - you start with a bunch of mod & fix folders and load them into a single tree at particular mount points.

$ Global Accessor

By default, the whole mix hierarchy is exported as a $ object.

It is done primarily for the convenience of debugging. You can always open the browser developer console and type $ to dump the whole mix, or maybe $.lab.hero to dump the hero object.

Since Collider.JAM DR9, the $ object is defined both as a global variable and as a variable within Collider.JAM scope.

The reason is that the global $ can be disabled to restrict the access to mix from the outside:

delete window.$

or

window.$ = null

Also, it can be reused for other purposes.

But within Collider.JAM scope, the $ will still be pointing at the mix.

Almost everything in your game can be accessed through $.* since everything is placed as a node on the mix tree. It is truly the global context of the game. The rare exception would be the data and functions hidden inside closures.

Local Mod

In most cases, you don’t need to access the root mod.

Usually, you work with the current mod and there are a bunch of links in scope to access it. We call it a local mod context, but it is not truly local. Better think of it as a global context of the current mod.

There is the _ accessor that points to the current mod.

There are also fast node accessors like res, env, dna, lab and trap. You can use them for quick access to particular components of the current mod.

Let’s assume you need to run the show() function on hud object in console.mod.

You can access it from anywhere by using the mix $ accessor:

$.mod.console.lab.hud.show()

But within console.mod you can say:

_.lab.hud.show()

Or even better, use the lab shortcut:

lab.hud.show()

By using the local path instead of global, you make code shorter and more portable. You can rename the mod or mount it at another node of the tree and all the local links will continue to work without any changes.

_ and $

Accessors _ and $ are the main things you need to know about the global scope in Collider.JAM.

Use _ to access current mod.

Use $ when you need to access things globally in other mods.

Also, use $ in the browser dev console. The _ accessor is defined only within each mod’s scope and makes no sense in the browser dev console context.

Collider.JAM Global Context

It would be unfair if I’ll not mention other objects in Collider.JAM global context.

Besides the _ and $, there are many more things defined in the mod scope.

There are drawing functions like line(), rect(), and circle().

There are math functions like sin(), cos(), and sqrt().

There are utility functions like defer() and kill().

But these would require more than a single post to cover them properly, so see you the next time.