I'm writing a Tetris clone in JavaScript. I have a fair amount of experience in programming in general, but am rather new to game development.

I want to separate the core game code from the code that would tie it to one environment, such as the browser.

My quick thoughts led me to having the rendering and input functions external to my main game object. I could pass the current game state to the rendering method, which could render using canvas, elements, text, etc. I could also map input to certain game input events, such as move piece left, rotate piece clockwise, etc.

I am having trouble designing how this should be implemented in my object.

Should I pass references to functions that the main object will use to render and process user input? For example...

var TetrisClone = function(renderer, inputUpdate) {
    this.renderer = renderer || function() {};
    this.inputUpdate = input || function() {};
    this.state = {};

TetrisClone.prototype = {
    update: function() {

       // Get user input via function passed to constructor.
       var inputEvents = this.inputUpdate();

       // Update game state.

       // Render the current game state via function passed to constructor.


var renderer = function(state) {
    // Render blocks to browser page.

var inputEvents = {};

var charCodesToEvents = {
    37: "move-piece-left"
    /* ... */

document.addEventListener("keypress", function(event) {
    inputEvents[event.which] = true;

var inputUpdate = function() {
   var translatedEvents = [],

   for (event in inputEvents) {
       if (inputEvents.hasOwnProperty(event)) {
           translatedEvent = charCodesToEvents[event];

   inputEvents = {};

   return translatedEvents;


var game = new TetrisClone(renderer, inputUpdate);

Is this a good game design? How would you modify this to suit best practice in regard to making a game as platform/input independent as possible?

  • 1
    \$\begingroup\$ Typical case of YAGNI, I believe. \$\endgroup\$
    – jcora
    Aug 7, 2012 at 22:51
  • 2
    \$\begingroup\$ @Blane I started to get the same feeling, so I abandoned this approach. Still, I'd be interested in the best way to implement it, if only for curiosity's sake. \$\endgroup\$
    – alex
    Aug 7, 2012 at 23:39

1 Answer 1


In my current engine, I have a few globals (all inside the main closure, of course):

// variables
var game;
var input;
var screen;
var sound;

Which are pointers to the main controller on independent subsystems, one of which is the game subsystem. They're all singletons, instantiated from their respective pseudoclasses:

function Game() {}
function Input() {}
function Screen() {}
function Sound() {}

They work independently, calling each other through their global pointers when necessary, through a high-level set of public methods, such as game.reset(), sound.play(), input.hasCandidate(), etc.

Let me know if you need more information about this design.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .