Play the game at www.RainingChain.com.
Check the source code on Github.

Wednesday, 25 February 2015

Getting Rid of Global Variables

When I started this project about 2 years, I had little programming knowledge. Every function I coded was in the global scope and it didn't really cause problems. Eventually, the project became bigger and it started to be hard to remember the function names, let alone in what file they were.

I eventually decided to group functions into global modules:
moveActor became Actor.move
teleportActor became Actor.teleport

The Actor object was still a global object but it was a lot better than before. At this point, maintenance is quite easy. There's one thing however that cause problems: dependencies.
When the variable is global, any module can access it. This means the module for a quest made by a contributor can access the Database module, which is a security issue. It also has the problem that we can't directly know what are the dependencies of a certain module. So making a change in a module can result in unexpected consequences in other modules.

Adding dependencies on the server side is easy using require('moduleId'). NodeJS was meant for that. Declaring a variable with keyword var will create a variable only reachable within the scope of the page.

The problem comes with the client. By default, the scope is global. So creating a variable with the keyword var will result in a global variable.

To fix this, anonymous functions are needed:
//Old:
var myPrivateVar = 1;
var myPrivateFunction(){

}

//New:
(function(){
 var myPrivateVar = 1;
 var myPrivateFunction = function(){
 
 }
})();

It is quite annoying to do but it works...
Another way to insure that no global variables is to use "use strict" at the top of the page.
If global variables are needed, then first declare them at the top with no value.
In order to load dependencies on the client, I created a exports and require system similar to NodeJS.

var myGlobalVar = 10;
"use strict";
(function(){
 var myDependency = require("myDependency");
 
 var Actor = exports.Actor = {};
 Actor.publicVar = 100;
 var myPrivateVar = 1;
 var myPrivateFunction = function(){
 
 }
})();

//in the main file
require = function(id){
 return exports[id];
}

No comments:

Post a Comment