Louis Stowasser

Month

March 2012

11 posts

Recent Posts widget in Tumblr

Pure JavaScript and less than 600 bytes. This will create an unordered list of recent posts from the blog of your choosing in a div that will replace the script tag.

Unminified (864 bytes):
<script type="text/javascript">
(function(blog, limit) {
limit = +limit || 10;

var scriptTags = document.getElementsByTagName('script');
var scriptNode = scriptTags[scriptTags.length - 1];
var recent = document.createElement("div");
scriptNode.parentNode.appendChild(recent);
recent.setAttribute("class", "widget");
recent.setAttribute("id", "TumblrRecentPosts");

var script = document.createElement("script");
script.src = "http://" + blog + "/api/read/json";
script.onload = function(data) {
    if(!tumblr_api_read) return;

    var response = tumblr_api_read.posts;
    var post;
    var len = Math.min(response.length, limit);
    var html = "<ul>";

    for(var i = 0; i < len; ++i) {
        post = response[i];
        html += "<li><a href='" + (post['url-with-slug'] || post.url) + "'>" + 
            post['regular-title'] + "</a></li>";
    }

    recent.innerHTML = html;
};

document.body.appendChild(script);

})("louisstow.tumblr.com", 30); //enter your settings here
</script>
Minified (573 bytes):
<script type="text/javascript">
(function(d,e){var  e=+e||10,
a=document.getElementsByTagName("script"),
a=a[a.length-1],b=document.createElement("div");
a.parentNode.appendChild(b);b.setAttribute("class","widget");
b.setAttribute("id","TumblrRecentPosts");a=document.createElement("script");
a.src="http://"+d+"/api/read/json";a.onload=function(){if(tumblr_api_read){
for(var a=tumblr_api_read.posts,c,d=Math.min(a.length,e),f="<ul>",g=0;
g<d;++g)c=a[g],f+="<li><a href='"+(c["url-with-slug"]||c.url)+"'>"+
c["regular-title"]+"</a></li>";b.innerHTML= f}};
document.body.appendChild(a)})
("louisstow.tumblr.com",30); //enter your settings here
</script>
Usage:

Place the script tag where you want the unordered list to be in your HTML document. Enter the blog URL in the arguments and specify a limit to the number of posts to list (default being 10). My blog is louisstow.tumblr.com or louisstowasser.com and I specified a limit of 30 posts.

How it works:

It uses the old Tumblr API (accessed via http://{Tumblr URL}/api/read/json) and runs it as a script. The script sets a global variable called tumblr_api_read. This is a large object which includes public blog information and posts.

Replacing the script tag is done by grabbing all script tags through document.getElementsByTagName("script") where the last script will be the one currently executing (the one we want to replace). We can then append our created div to the parent of the script tag.

Mar 31, 201214 notes
#recent posts #widget #tumblr
Self promotion should be encouraged

The web seems to favour curation over creation. Self promotion is generally frowned upon and most will tell you sharing a mix of other’s links and your own is more acceptable; but why? This only encourages curation and stunts creation.

Content is king

Once upon a time this was the mantra of the web. Content above all else is most important. By this logic it doesn’t matter where the content came from, as long as it is good quality content.

Self promotion is not always spam

Some regard self promotion as a form of spam. Spam implies the content is unwanted which to me depends on the quality and frequency as opposed to whether the owner submited it for self gain.

Curation promotes reposts and stale content

We should be actively seeking new and quality content rather than sharing an already popular link otherwise known as reposts.

Good content goes to waste

It is very hard for content creators to get noticed. Think of how many blogs, tech articles, tutorials, videos, stories, games, music, tools, software, services or webcomics exist on the web. Some of them might be good, some might be great and not all of them will be discovered by curators.

Mar 30, 2012
Different monetization methods for HTML5 games and apps

Monetization is one of many challenges when creating a game or app in HTML5. After all the effort it would only be fair to recieve minor compensation to keep development alive. The problem is deciding how to earn money from your creation while not affecting it’s growth.

A standard method is to offer a freemium model (free with ads, pay for more content). Another is in-game purchases. I was thinking about various other ways it could be done where the player has more incentive to pay.

Raffle

Players would have to buy the game to enter (say for $1). The prize could be 10% of the proceeds or any other reward. Players can win by beating a level first or holding the highest score by a certain date.

It would encourage players to buy the game, play it and most of all share it with friends as it would increase the winnings.

In-game product placement

This is just another form of advertising but more subtle than an attention grabbing advertisment blocking half the screen. In-game items that advertise a brand name would be less obtrusive and most likely more effective. Finding sponsors wouldn’t be easy but there are other sources such as affiliate marketing (see Amazon Affiliate Program).

Sell unobfuscated and commented source code

With HTML5 games and apps the source code will always be there for all to see even if obfuscated. One may as well either publicly release it or offer the full commented and styled source code for a fee, should developers want to learn or expand on it.

Merchandise

Companies like CafePress offer the ability to customise T shirts, stickers, posters and various types of merchandise to sell to loyal fans or even as a prize for the aforementioned raffle.

There is definitely room for some creative forms of monetization that benefit the developer as well as the player. I would be interested in hearing other ideas.

Mar 29, 2012
#html5 #javascript #gamedev #monetization #apps #games
Simulating a player

Automated tests are a great way to do a sanity check against any changes you feel might affect other areas. You can quickly run some tests and ensure components do as they’re expected. This doesn’t cross over well into game development because other factors come into play such as input, randomization, networking and other variables that affect the program.

What’s really needed is to be able to simulate a player and observing the outcome exactly as it was when it was logged. To do this, every single variable that affects the game state has to be logged with a timestamp so it can be played back at the exact same interval. This includes randomly generated numbers, click or keyboard events, network data, time etc etc.

Benchmarking

There are more use cases than just automated tests. You can use it for benchmarking so that every platform you test will involve the same gameplay and actions. Domsz has done this for his game engine, ImpactJS.

Validate High Scores

Blindly accepting any high score as valid can and probably will lead to people sending requests with an obviously fake score. Sending the data to the server and replaying it to see what the end result is can be used to determine whether they cheated or not.

Multiplayer

Simulating the input on the server can be used for multiplayer games to keep two or more players in sync and prevent players from cheating. There’s obviously more to it than that but it’s an idea.

Gameplay

It’s now a common gameplay component to allow players to replay part of the game or for a stylised effect such as killcam.

For games that are heavily randomly generated (which a lot are), there is the option to save the seed used so all that is needed is to use the same seed when replaying to generate the same random numbers. Not all random functions provide this feature (JavaScript doesn’t). Another way around this is to log the generated value so when you replay it, use the same number that was generated last time.

There is a great post about implementing such as thing known as Deterministic Games. Unfortunately it is mainly relevant to the LWJGL framework.

Mar 21, 2012
#deterministic games #simulation #gamedev
Performance framework proof-of-concept

Performance is a very important factor for JavaScript games. It becomes a crucial factor when you bring mobile devices into the mix.

Luckily we have some great tools for testing different methods of coding such as JSPerf. This lets developers test code snippets across multiple browsers to compare.

On the same vein, JSGameBench stress tests rendering methods including WebGL, Canvas and DOM.

At Game Closure we want to look deeper and more thorough so I’ve been thinking about different ways to design a framework that will allow us to run tests with an assortment of different methods and combinations. With JSPerf one has to write individual test cases for every combination. Here is my proposal:

Templates

Code to test should have some templates that form the basis of what we’re testing. It is similar to startup and teardown methods but finer grained. You may want to move some startup code outside of the template to avoid it being benchmarked unnecessarily.

Placeholders

This is the key component to the power of this testing framework. Add placeholders in the template code that will be replaced based on the combinations being tested. The placeholders are denoted by a comment followed by a colon and the name of the placeholder.

function renderDOM() {
    dom.style.left = /*:x*/;
    dom.style.top = /*:y*/;
}

function renderCanvas() {
    ctx.drawImage(
        /*:type*/,
        /*:x*/,
        /*:y*/
    );
}

This looks like gibberish now but starts to make sense when you create a list of different values for these placeholders in the form of an object where the key is the name of the placeholder and the value is an array of possible combinations to test:

{
    x: [
        "~~x", 
        "x", 
        "Math.floor(x)"
    ],

    y: [
        "~~y", 
        "y", 
        "Math.floor(y)"
    ], 

    type: [
        "cnv", 
        "img"
    ]
}

The test framework will use all the possible combinations of these values testing to see which performs the best. You can also specify which functions to test against. In our case the two functions are “renderDOM” and “renderCanvas”. This means it will generate 36 combinations of the placeholders and functions.

Test it!

Running a test requires the startup code, a template defined with relevant placeholders and then an object with the combinations of values. You can optionally specify an amount of iterations to run (it defaults to 1000).

The above test gives us this:

~~x, ~~y, cnv, renderDOM | 28ms
~~x, ~~y, cnv, renderCanvas | 1222ms
~~x, ~~y, img, renderDOM | 18ms
~~x, ~~y, img, renderCanvas | 8ms
~~x, y, cnv, renderDOM | 33ms
~~x, y, cnv, renderCanvas | 1234ms
~~x, y, img, renderDOM | 33ms
~~x, y, img, renderCanvas | 8ms
~~x, Math.floor(y), cnv, renderDOM | 18ms
~~x, Math.floor(y), cnv, renderCanvas | 1237ms
~~x, Math.floor(y), img, renderDOM | 18ms
~~x, Math.floor(y), img, renderCanvas | 8ms
x, ~~y, cnv, renderDOM | 25ms
x, ~~y, cnv, renderCanvas | 1305ms
x, ~~y, img, renderDOM | 24ms
x, ~~y, img, renderCanvas | 7ms
x, y, cnv, renderDOM | 54ms
x, y, cnv, renderCanvas | 1322ms
x, y, img, renderDOM | 55ms
x, y, img, renderCanvas | 7ms
x, Math.floor(y), cnv, renderDOM | 25ms
x, Math.floor(y), cnv, renderCanvas | 1301ms
x, Math.floor(y), img, renderDOM | 26ms
x, Math.floor(y), img, renderCanvas | 8ms
Math.floor(x), ~~y, cnv, renderDOM | 18ms
Math.floor(x), ~~y, cnv, renderCanvas | 1238ms
Math.floor(x), ~~y, img, renderDOM | 18ms
Math.floor(x), ~~y, img, renderCanvas | 8ms
Math.floor(x), y, cnv, renderDOM | 36ms
Math.floor(x), y, cnv, renderCanvas | 1235ms
Math.floor(x), y, img, renderDOM | 34ms
Math.floor(x), y, img, renderCanvas | 7ms
Math.floor(x), Math.floor(y), cnv, renderDOM | 18ms
Math.floor(x), Math.floor(y), cnv, renderCanvas | 1235ms
Math.floor(x), Math.floor(y), img, renderDOM | 18ms
Math.floor(x), Math.floor(y), img, renderCanvas | 7ms

A few things to note is my method of benchmarking is currently very naive as this is a proof-of-concept. I will be looking into more solid forms detailed in this great post. The other thing to note is some of these tests are essentially duplicates. The renderDOM method doesn’t use the type placeholder so it generates combinations that have already been run. This isn’t really a problem and is more to do with how you define your templates and placeholders.

Analysing the data

Once we have this data we need a way to understand it and derive facts. I imagine a big table with the placeholders, functions and result as the columns and the combinations as the rows. You will be able to filter by placeholder values and sort ascending or descending on the result column.

Browsers

Running these tests against different browsers can be useful to determine cross-browser optimization or things to avoid. It is therefore important to be able to view and compare all the results and how they performed on which browsers. To display this in a table, the execution time column would have to include the result from different browsers. This could be done by adding a column for each browser result and keeping the main result as an average.

These ideas are still very early stage and I have only recently managed to get code executing from placeholders and generating combinations. I will do more research to determine how it can be more useful for existing projects and how to best display the data. Maybe even a GUI along the lines of JSPerf could make it more helpful.

Mar 18, 2012
Entity Component Systems: Inheritance vs Composition

My methodology of choice for game development is something known as an Entity Component System. Entities are game objects, they have no functionality until you apply components. This avoids long chains of inheritance so is easier to maintain and reuse.

There are two ways to implement Entity Component Systems, through composition or inheritance.

Crafty uses an entity component system through inheritance. An entity starts its life as a simple object, when you add a component the entity inherits all the functionality. It is similar to one layer of multiple inheritance (without the diamond problem) or mixins.

This makes abstraction easier where components can reference any other components without needing to know which component it is so long as they both implement the same interface. Crafty does this for the DOM and Canvas components.

There is an obvious problem with the lack of namespacing: naming collisions. I personally haven’t come across this yet (probably because I know the names of the internals) but it seems others have. It’s also not very elegant as your entities end up as big blob objects.

Composition seems to be the preferred way of doing things. Through composition you would create an instance of the component and give the entity a reference to it. This may seem elegant but how do components talk to each other? The only way to go about component communication is by giving the component a reference back to the entity.

CompA = Class(Component, function() {
    this.method = function() {
        this.owner.getComponent("CompB").method();
    }
});

We can get a direct reference to another component through the entity (this.owner) and we have component communication. But there are a few problems with this solution. First of all it’s hideously verbose but worst of all it creates a tight coupling between CompA and CompB. What if we change the name or can’t be sure what the component will be (say if there were two components that implement the same interface)?

The solution to this is messages or events. Tell the entity the component wants to send a message to all other components that want to listen. Other components can register a callback to those messages and decide what to do.

CompA = Class(Component, function() {
    this.method = function() {
        this.owner.sendMessage("doSomething");
    }
});

CompB = Class(Component, function() {
    this.method = function() {
        this.owner.recieveMessage("doSomething", this.doSomethingHandler);
    }

    this.doSomethingHandler = function() {
        //no coupling! :)
    }
});

Now the components are completely seperate from each other and can be individually replaced without worrying about dependencies. I mentioned my distaste for verbose solutions but luckily in the land of JavaScript we can make nice short cuts.

CompB = Class(Component, function() {
    this.onDoSomething = function() {
        //no coupling! :)
    }
});

The message dispatcher will just see if any components have a function called “on” + the message name and execute it.

While this approach is very elegant and decoupled it’s not a perfect solution. What about a component that changes the position of the entity. Sending a message each time gets tedious especially if that component is never going to change or be replaced (such as a Position component). In these situations keeping a reference isn’t so bad:

CompB = Class(Component, function() {
    this.init = function() {
        this.Position = this.owner.getComponent("Position");
    }

    this.onDoSomething = function() {
        this.Position.x += 10;
    }
});

My personal preference is through composition and message passing. It seems to be more flexible and has no real drawbacks.

Mar 14, 20123 notes
#entity component #gamedev #javascript #inheritance #composition
Pointer Lock for building an FPS

Now that Pointer Lock (formerly known as Mouse Lock) is semi-available in Chrome I decided to have a play with it.

My friend Andrew Baker has a very easy to use 2.5D renderer and a first person demo to go with it. I went about adding mouse support for the demo.

Firstly you need to enable Pointer Lock in about:flags. Put that in the address bar then scroll down to “Enable Pointer Lock” and relaunch Chrome.

While reading the Pointer Lock API on MDN I noticed that Chrome requires the page to be in the fullscreen state. This is simple enough (note that element is a DOMElement such as a canvas node):

element.webkitRequestFullScreen()

This revealed a problem. None of the keyboard events worked and the docs never mentioned this. After searching for a while I came across Brandon’s blog post on the subject. To allow the keyboard events to work in fullscreen mode, you have to pass in the ALLOW_KEYBOARD_INPUT constant:

element.webkitRequestFullScreen(element.ALLOW_KEYBOARD_INPUT)

To request a pointer lock on an element, you must use navigator.pointer.lock. In Chrome this is under the namespace navigator.webkitPointer. To normalise this you will want to add the following:

navigator.pointer = navigator.pointer || navigator.webkitPointer;

So after the request for fullscreen mode has been called we can request the pointer lock.

navigator.pointer.lock(element, 
    function() { 
        console.log("Request Succeeded") 
    }, 
    function() { 
        console.log("Request Failed") 
    }
);

In my version of Chrome (17.0.963.79 on Windows 7) I noticed that neither of these callbacks were called. The second thing I noticed was a. the cursor wasn’t hidden and b. the cursor wasn’t actually locked and it could move out of the bounds of the element. The only feature that actually worked were the mouse events (movementX/Y). To make use of this, just bind the element to the mousemove event and the movementX/Y values will be in the event object:

var sensitivity = 0.4; //the lower the less sensitive
element.addEventListener("mousemove", function(e) {
    var pos = {
        movementX: e.movementX || e.webkitMovementX,
        movementY: e.movementY || e.webkitMovementY,
    };

    if(pos.movementX < 0) {
        Mars.turnLeft((-pos.movementX) * sensitivity);
    } else {
        Mars.turnRight(pos.movementX * sensitivity);
    }
}, false);

If the movementX value was negative then the mouse was moved to the left. The values are actually the change in position since it was moved or the delta. By adding a sensitivity multiplier you can manipulate how much of an effect the movement values have on the view.

These new event values are great but isn’t useful if the mouse isn’t actually locked. I will have a play with non-stable versions of Chrome to see if it has been implemented but for now it’s not very helpful.

Checkout the latest demo from this article and tell me if it works on your browser or not.

Edit: I installed Chrome Beta (18.0.1025.56) and I can confirm it works perfectly :) The cursor is hidden and locked. Should be in the next release very soon! I look forward to the opportunities this creates for HTML5 games.

Mar 13, 2012
#pointer lock #html5 #javascript #fps #gamedev
Fixing CSS through a UI library

I believe CSS is one of the best methods of building interfaces. If you’ve used Swing, Tkinter or the like you will probably agree with me. The ability to style rectangles through selectors really segregates the data from the view.

That being said there are many things I would change and have been doing so through a User Interface library (to be implemented in the Game Closure SDK).

1. Positions and Dimensions

With CSS you can set the position and dimensions in a few different units, the most useful being pixels (px) and percentages (%). There have been many occasions where I needed to use both in a calculation. For instance having a box with a height of 100% minus a few pixels. To do this in CSS you would need to either use JavaScript or change the structure of the HTML.

My UI lib will take a basic expression such as: 100% - 30px. I was even toying with the idea of allowing developers to pass a callback for even more control over how it is calculated.

CSS manages flow and automatically positions elements based on it’s surrounding elements. This is very helpful when building a website. But building a user interface… not so much. My UI lib treats every element as if it had position: absolute applied. This may sound painful but it is made easier by the fact you can position elements using percentages and calculations. For instance imagine a UI with two columns:

column1 = new Panel({
    left: 0,
    top: 0,
    width: "50%",
    height: "100%"
});

column2 = new Panel({
    left: "50%",
    top: 0,
    width: "50%",
    height: "100%"
});

Easy!

2. The Box Model

This has recently become more of a known issue. The W3C box model is plain silly and believe it or not IE got it right (in my opinion). The W3C box model states that the width of an element is the inner most content. The IE box model states the width includes it’s border, padding and inner content. Confusing? See the diagram below:

My UI lib takes the IE approach. This means you can set the width to a logical unit and change the border and padding to your hearts content without worrying about changing the width to match. You can actually use the IE box model in your CSS today by using box-sizing: border-box.

You can see a not so recent live demo here. The currently supported properties are: borderColor, borderSize, borderRadius, backgroundColor, headerColor, padding, margin, fontSize, fontFamily, fontColor, textBaseline, lineHeight, opacity, width, height, left and top with more to come!

Mar 11, 2012
#css #ui lib #box model #canvas #html5
Unobtrusive Game Engines

We’ve suddenly seen an uprising up HTML5 game engines over the last year. To me not many of them stand out and that’s a personal opinion. Maybe because the things I look for in an engine is not actually an engine but a library. The best engine is the one I can replace.

I don’t like the idea of being tightly coupled to a game engine. Too much of the code base becomes unknown and at risk of deprecation or API changes. I also don’t want to be forced to use a methodology (MVC, entity component). This is probably why we have so many engines. Every developer has their own style and if they can’t reflect that in an engine they get frustrated and make one that can.

Take the UNIX philosphy: Rule of Separation: Separate policy from mechanism; separate interfaces from engines. http://www.faqs.org/docs/artu/ch01s06.html ‘Basics of the Unix Philosophy’

Here’s my wishlist of the perfect game engine which from now on I shall call library.

1. Hook for tick and render

This is the most basic requirement for creating a game. An unobtrusive API might be:

Game.tick(function(dt, frameNumber) {
    //register a callback on tick
});

The render hook would be similar:

Game.render(function(ctx) {

});

The important thing here is that I still have control and I can easily replace the library with something else that implements the same basic API. Heck, I could write a basic wrapper should another engine not implement it.

2. Input

An abstract layer for inputs that can generalise touch and mouse events and even keyboard events.

Game.input(function(type, e) {
    //type = Click, Down, Up, Key
    //e = Event object includes position in form of Point
    //    or key code for keyboard events
});

Generally you want to know if an entity lies within the position from the event. Which leads us to our next feature.

3. Maths

Some basic algorithms commonly used in 2D games such as SAT collision, polygons, points, rects, spatial data structures but again no dependence on how the entities are stored.

//Point = {x: Number, y: Number}
Game.math.pointInRect(Point, Rect);

//Rect = {x: Number, y: Number, w: Number, h: Number}
Game.math.collision(Rect, Rect[]);

However you organise game objects it should be simple enough to export it to the Rect interface if it isn’t stored like that already.

For determining if the user clicked/touched our entity:

Game.input(function(type, e) {
    if(Game.math.pointInRect(e.point, entity.rect)) {
        //clicked/touched
    }
});

Even if this is too verbose it is simple enough for the developer to write another abstraction that suits them.

4. Mobile Support

Most mobile browsers are capable of rendering the Canvas element. The issues arrive with resolution, aspect ratio and sizing the stage.

We don’t want an implementation that will be obtrusive so this can’t be an automatic fix.

if(Game.isMobile) {
    Game.maintainRatio(DOMElement);
}

This would detect if the user is on a mobile device, make the specified element “fullscreen” by scaling it as big as possible while maintaining the aspect ratio and using a black background for a letterbox effect.

Again, the problem here is this doesn’t match all solutions and is the reason this can’t happen automatically. What if the game was meant to stretch?

Game.stretch(DOMElement);

This will make the specified element as big as the window (so it doesn’t matter if it’s on mobile or not).

To find out the size of the stage:

Game.width; //Number
Game.height; //Number
5. Modular

I see mobile support as more of a module or extension than part of the core. Therefore the game library should allow extensions.

Game.extend({
    maintainRation: function(el) {},
    stretch: function(el) {}
});

I haven’t actually written this library, it’s just my ideas for a game library that would be flexible enough so developers can add their own touch to it without being forced into a style or methodology they dislike. Would love to hear feedback about this concept.

Some initial code for proof of concept is up here: https://github.com/louisstow/Game

Mar 11, 20122 notes
#html5 #javascript #game engine #game lib
The Return of Adventure Games

Growing up I never really took a shine to adventure games. I was very impatient and didn’t like to be mentally bested by a game. Only recently am I starting to see the appeal. My girlfriend is creating an HTML5 adventure game for her thesis (using Crafty) so I was introduced to the greats such as Day of the Tentacle.

It would be a sin to not mention the massive success of Double Fine’s new adventure game project. This alone shows how nostalgic this genre is to many many gamers.

This led me to think about implementing the genre for mobile devices and browsers. The genre is almost perfect for casual gaming. You can solve small puzzles in pockets of spare time and none of the immersion is lost.

This then led me to think about a framework for building adventure games where various callbacks would help construct the puzzles and gameplay. Typically adventure games are built up of:

  • Scenes
  • Actors
  • Items
  • Dialogue
  • Actions

Scenes being small rooms or areas the player can explore to find items and solve puzzles. Callbacks for scenes would include entering a scene, exiting a scene.

var Intro = Class(Scene, function(supr) {
    this.init = function(opts) {};

    this.onEnter = function(previousScene) {};
    this.onExit = function(nextScene) {};
});

Actors would be NPCs that can initiate dialogue and potentially reveal information or a piece of the puzzle if the player says the correct things. Actors could also be part of the scene that isn’t an item but reacts when used with an item.

var NPC = Class(Actor, function(supr) {
    this.init = function(opts) {}

    this.onPush = function() {};
    this.onPull = function() {};
    this.onOpen = function() {};
    this.onClose = function() {};
});

Items are things inside scenes that progress the plot and can be used to solve smaller puzzles. These usually have the biggest impact on gameplay and contribution towards a resolution. Some callbacks for items would be using an item, combining an item with another item or combining an item with an actor.

var MyItem = Class(Item, function(supr) {
    this.init = function(opts) {};

    this.onUse = function() {};
    this.onCombineItem = function(otherItem) {};
    this.onCombineActor = function(otherActor) {};
});

Dialogue usually has a few options about what you want to say to an actor which will either trigger another line from an actor, conclude the conversation or progress the plot. You could make some lines of dialogue have the same effect or a line of dialogue could be key to solving a puzzle. Callbacks would be when the player selects a line of dialogue.

var TalkingDude = Class(Actor, function() {
    this.onDialogue = function(lineSpoken) {};
});

Actions are how the player interacts with items, scenes and actors. Callbacks would be placed on Actors and Items for various actions such as open, close, push, pull, use, etc etc.

var MyItem = Class(Item, function(supr) {
    this.init = function(opts) {};

    this.onPush = function() {};
    this.onPull = function() {};
    this.onOpen = function() {};
    this.onClose = function() {};
});

I know this isn’t anything concrete but it is my interpretation of building an adventure game with the intention of modular and ultimate reuse. I intend to do more tinkering to come up with some working demos and maybe even design a JSON format to build scenes and lines of dialogue.

Mar 10, 2012
Welcome!

Hello all. I’ve decided to beef up my personal brand recognition, rather than networking under the guise of “that Crafty dude”.

It also allows me to post interesting things about the web but not necessarily related to Crafty.

Still trying to figure out how this will all be formatted (such as code snippets) so bare with me while I learn how to blog.

Bye!

Mar 10, 2012
Next page →
2012 2013
  • January
  • February 2
  • March
  • April
  • May
  • June
  • July
  • August
  • September
  • October
  • November
  • December
2012 2013
  • January
  • February
  • March 11
  • April 4
  • May
  • June
  • July
  • August
  • September
  • October
  • November
  • December