<?xml version="1.0" encoding="UTF-8" standalone="no"?><?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" version="2.0">
<channel>
    
    <link>http://vasir.net/feed</link>
    <title>Erik Hazzard</title>
    <description>Experiments with data visualizaiton, story telling, and game design</description>


    <lastBuildDate>Thu, 26 Feb 2015 00:00:00 GMT</lastBuildDate>
    <sy:updatePeriod>monthly</sy:updatePeriod>
	<sy:updateFrequency>2</sy:updateFrequency>
	<language>en-US</language>

    
    <feedburner:info uri="erikhazzard"/><geo:lat>37.865026</geo:lat><geo:long>-122.285901</geo:long><image><link>http://vasir.net</link><url>http://vasir.net/static/branding/header.png</url><title>Erik Hazzard</title></image><feedburner:info uri="erikhazzard"/><geo:lat>37.865026</geo:lat><geo:long>-122.285901</geo:long><feedburner:info uri="erikhazzard"/><geo:lat>37.865026</geo:lat><geo:long>-122.285901</geo:long><feedburner:info uri="erikhazzard"/><geo:lat>37.865026</geo:lat><geo:long>-122.285901</geo:long><feedburner:info uri="erikhazzard"/><geo:lat>37.865026</geo:lat><geo:long>-122.285901</geo:long><feedburner:info uri="erikhazzard"/><geo:lat>37.865026</geo:lat><geo:long>-122.285901</geo:long><feedburner:info uri="erikhazzard"/><geo:lat>37.865026</geo:lat><geo:long>-122.285901</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" href="http://feeds.feedburner.com/ErikHazzard" rel="self" type="application/rss+xml"/><feedburner:info uri="erikhazzard"/><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" href="http://pubsubhubbub.appspot.com/" rel="hub"/><geo:lat>37.865026</geo:lat><geo:long>-122.285901</geo:long><item>

        <title>Crafting Experiences with Data Visualization</title>
        <pubDate>Thu, 26 Feb 2015 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/n9NfAJ2bV-8/crafting-experiences-with-data-visualization</link>
        <guid isPermaLink="false">http://vasir.net/blog/data-visualization/crafting-experiences-with-data-visualization</guid>
        <category>Data Visualization&gt;</category>


        <description>My presentation about design, data visualization, and user experience at a D3 meetup


Story-Telling, Design, and Data Visualization

I recently gave a presentation at the Oakland D3 meetup, organized by the amazing &lt;a href='http://www.seemantk.com/' target='_blank'&gt;@seemantk.

The presentation is about an hour long, so I wanted to summarize some of the topics I discussed. This post is an overview of the talk, along with some notes. You can &lt;a href='https://www.youtube.com/watch?v=jQTKnlVSnV8&amp;feature=youtu.be' target='_blank'&gt;watch the presentation here (or the video above).


User-Driven Experiences

This sounds so nebulous: 'User-Driven Experiences.'  It's as seemingly meaningless as 'synergy,' but in my mind it is a clear philosophy. I'm a developer, and I sometimes get so wrapped up in thinking about code that it's hard to step back and see the purpose that code serves. We write code to create a product, which is (at least in my line of work) consumed by people. 



Since people use our products, we can do well to place the person's experience at the forefront of our design and development processes. What do I mean? Every decision we make - color, font, data visualization type - should be carefully thought about in terms of how it will impact the user's experience. 


First, decide what kind of experience you want the user to have. Then, pick the visualization type that best will deliver that experience. If you're already set on using a cool force layout visualization, you may miss the larger picture if that visualization type isn't the most effective for the story you're trying to tell.


Analyzing Experiences with Interest Curves

Maybe a user-first approach still sounds abstract. So, in an attempt to make it more clear, let's analyze what an experience looks like. As with any kind of data, there are an infinite number of ways to visualize an experience. We could look at an experience in terms of &lt;a href='http://www.amazon.com/Flow-The-Psychology-Optimal-Experience/dp/0061339202' target='_blank'&gt;flow, which can be very helpful when designing games. We'll save flow for another talk, and focus instead on Interest Curves.


 
    &lt;img src='http://s3.amazonaws.com/vasir-assets/crafting-experiences/interest-curve.png' class='center' width='650' height='330' /&gt; 
     
        Interest Curve - Interest over Time
     



One way to visualize an experience is to think of it in terms of interest over time. This is just a tool - the above curve isn't some universally perfect example of a good experience - but it's pretty damn good. Most successful books, movies, and games follow this general shape. 


    A great experience often starts with a hook. Sometimes it's cheap, like an explosion or a character death. But whatever method is used, the goal of a hook is to pique your interest. Then, we need to let that interesting experience sink in, to allow the peaks of interest to be meaningful. It eventually culminates in a climax, which is ideally the peak of the entire experience. This can be applied to any kind of experience - not just a game or movie - but also physical experiences.


 
    &lt;img src='http://s3.amazonaws.com/vasir-assets/crafting-experiences/physical-interest.png' class='center' width='600' height='360' /&gt; 
     
        Interest Curve in Real Life
     



    This applies equally to data visualization. While a bar chart may not represent a temporal dimension, users experience your visualization over time. People must process what the data visualization is trying to tell them, and if you just throw all the data at them it's a bad experience. If you can instead craft the experience to have peaks and valley of interest, it could be more powerful. 


 Loading Bars 

We often overlook one of the strongest parts of the experience - the initial loading experience. This is our hook. If we can ease the user into an experience, or give them a taste of what it will be like, we can help craft these peaks and valley of interest. I talked a little bit about this a &lt;a href='http://vasir.net/blog/design/misleading-users-to-create-better-experiences' target='_blank'&gt;previous blog post on misleading users, and you can &lt;a href='https://www.youtube.com/watch?v=jQTKnlVSnV8&amp;feature=youtu.be&amp;t=9m37s' target='_blank'&gt;jump to the discussion on loading bars in my presentation


 SVG Filters 

We can't talk about chart junk without talking about filters. Tufte is right in saying that chart junk obscures the data:ink ratio; but how important is a high data:ink ratio is people have a bad experience? What's better: a forgettable visualization (i.e., story) with a perfect data:ink ratio; or a memorable story which creates interest and sparks discussion that uses decorations and chart junk? Depending on your audience, the answer is almost always the latter. 



If you're designing for scientists or white papers, decorations make the audience unhappy. But, if you're designing for the general public, sometimes decorations can create a more compelling experience. Maybe it's not a 'pure data viz,' but is that truly the end goal? SVG Filters are a tool that can be used to create 'chart junk,' or to also craft a more compelling experience.



You can check out some of my thoughts on filters: &lt;a href='/blog/data-visualization/enhancing-data-visualization-with-svg-filters' target='_blank'&gt;enhancing data visualization with SVG filters and &lt;a href='/blog/data-visualization/using-d3-and-svg-filters-to-create-fog-of-war' target='_blank'&gt;using SVG filters to create a fog of war effect, or &lt;a href='https://www.youtube.com/watch?v=jQTKnlVSnV8&amp;feature=youtu.be&amp;t=36m0s' target='_blank'&gt;jump to the discussion of the power of filters in my presentation.


 Games 

Game designers grapple with unique design problems. They have to somehow integrate audio design, animation, UI design, gameplay, art, storytelling, and numerous other disciplines together. Games have the highest ceiling of difficultly in terms of experience crafting. A successful game must be successful in creating experiences using numerous art forms, then bring all those individual experiences together to craft a larger, more coherent experience in a player's mind. If we view design as a search problem, then games can provide a wealth of inspiration.


 
I talk about &lt;a href='/blog/game-development/data-visualization-in-games' target='_blank'&gt;data visualization in games, and you can also &lt;a href='http://youtu.be/jQTKnlVSnV8?t=43m2s' target='_blank'&gt;jump to the discussion on games in the presentation.


 Data Visualization Driven Game Design 

I'm currently working on a game which focuses on data visualization help improve your gameplay experience. More information can be &lt;a href='/blog/game-development/designing-a-browser-based-game-with-d3js-part-1' target='_blank'&gt;found in a previous post, or you can &lt;a href='https://www.youtube.com/watch?v=jQTKnlVSnV8&amp;feature=youtu.be&amp;t=53m60s' target='_blank'&gt;watch a demo of it.



 End 
Feel free to check out &lt;a href='https://www.youtube.com/watch?v=jQTKnlVSnV8&amp;feature=youtu.be' target='_blank'&gt;the presentation, which goes into more depth for each of these concepts. Slides of the presentation can be &lt;a href='https://github.com/enoex/D3-Oakland-Experience-Jan-2015' target='_blank'&gt;found on github.&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/dJ1XoocKMec" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/Tqpq1bsQVjU" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/meiZdiqSEpE" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/n9NfAJ2bV-8" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/data-visualization/crafting-experiences-with-data-visualization</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/dJ1XoocKMec/crafting-experiences-with-data-visualization</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/Tqpq1bsQVjU/crafting-experiences-with-data-visualization</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/meiZdiqSEpE/crafting-experiences-with-data-visualization</feedburner:origLink></item>
    
    <item>

        <title>Data Visualization in Games: Leaderboards</title>
        <pubDate>Wed, 24 Sep 2014 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/_B7kiDMC6OY/data-visualization-in-games-leaderboards</link>
        <guid isPermaLink="false">http://vasir.net/blog/data-visualization/data-visualization-in-games-leaderboards</guid>
        <category>Data Visualization&gt;</category>


        <description>In one of my earlier gaming memories, I'm playing &lt;a href='http://en.wikipedia.org/wiki/Centipede_(video_game)' target='blank'&gt;Centipede on an old, busted arcade cabinet. Not at an arcade though, but at a doctor's office. I guess it's a bit strange now to think that a doctor's office had a small arcade in it, but at the time it made sense. I remember visiting that particular doctor's office a few times and caring only to play that game. The memory of actually playing the game is faded now. But even as I write this over two decades later, the anticipation I felt before playing it is just as palpable. Even today, few games can elicit such excitement as going to the doctor's office did. The game itself was irrelevant. In fact, the game probably wasn't Centipede. What stuck with me, what caused my Christmas-eve-night eagerness for the next opportunity to visit the Doctor's office, was a leaderboard.




    &lt;img
        src='https://s3.amazonaws.com/vasir-assets/leaderboards/leaderboard-1.jpg'
        class='center' 
        width=300
        height=351 /&gt;
    
    
 


Leaderboards can create powerful emotional responses. As for my six-ish year old self, they can create motivation to play a game - regardless of the game. I wanted so bad to play not because the game was fun (it probably was, but I can't even remember the game). I wanted so bad to play because I wanted to see my three initials in that high score screen. I was excited to return because I hoped my name would stay on that list, even they probably unplugged it often and the high scores likely got wiped (but I didn't understood that). Leaderboards provide far more than just motivation. Not all players care to see their name on a global leaderboard, but competition is only one facet. 


 Data Visualization with Leaderboards 

    Leaderboards are a visualization of achievement. Their goal is to make comparisons between some player (or item's) ranks. This is a broad statement because implementations of leaderboards can be found not just in arcades, not just in single or multiplayer games, but also in non-games. &lt;a href='http://reddit.com' target='blank'&gt;Reddit.com is a great example of a leaderboard in a non-game context (in other words, gamification). Each post is upvoted, or downvoted into oblivion, and each vote will cause its position on the 'leaderboad' (i.e,. the site) to change. Reddit is a social leaderboard for content.  Even if you never post something yourself, you can still affect a post's position. 




    &lt;img
        src='https://s3.amazonaws.com/vasir-assets/leaderboards/reddit.jpg'
        class='center' 
        width=580
        height=169 /&gt;
    
        Reddit is the social leaderboard for content on the internet
    
 


By visualizing data, you give data power. The method of visualizing it shapes how people interpret it and their emotional responses. I'll focus specifically on games, but all the same concepts apply in non-game (i.e., gamification) context. I want to discuss leaderboards from two perspectives: How leaderboards can be visualized and their effect on players.


Leaderboard Effects

    Leaderboards serve many purposes, but three powerful ones are:


&lt;ol&gt;
    &lt;li&gt;Measuring Progress / Achievement: Leaderboards provides a way to visualize your skill progression. As you become a better player, you get higher scores, and you're able to compare it with past performances.
    &lt;li&gt;Status: Many players are motivated to keep playing and improving because seeing your name on a leaderboard provides status. Most players feel pretty good when they see they're better than a bunch of other players.
    &lt;li&gt;Providing a sense of what's possible: In a global, absolute leaderboard, the highest score gives you a sense of what's possible. If you know the best player has 300,000 points and you're 'stuck' at 200,000, you will know it's at least possible to increase your skill to reach that higher score. The caveat here is that if the leaderboard displays cheaters (like pretty much every iOS game center leaderboard I've seen), you completely lose this benefit - and this goes from being a positive to a negative. If the highest score is outside of the realm of possibility, or *everyone* has it, then it's not a realistic measure of potential skill. 



How to Visualize Achievement

Leaderboards aren't the only way to visualize achievement of course (badges are another popular method), but they are one of the most effective for encouraging engagement. The obvious leaderboard visualization, and a fairly inefficient one in today's games, is the traditional arcade-style high score screen with ten to twenty names listed. For a local arcade cabinet, this can be effective. However, for a persistent, multiplayer game with social components, there are more effective visualizations. Few players will be the top twenty in the world, and not all players are motivated to appear on a global leaderboard.


Types of Leaderboards

    If many people play a game, then of course few people will be in the global top twenty. Many players will even be discouraged because they know they will not (and have no desire) to reach the top tier. For non-local multi-player games, relative leaderboards can be more effective. 


Relative

    With relative leaderboards, the leaderboard is centered on you. You can see people above and below you, but the goal isn't necessarily to reach the top. Progress is much easier to see, as you will be able to more easily rise above the people that were ranked higher than you. 


Geographical

    Another way to present leaderboard information is to group is by geography. This could be based on region (e.g., US or Europe), or at a smaller state, city, or even local level. Maybe it's not realistic to compete against the world, but you'll probably be able to achieve a higher ranking at a city level than you would at a national level (at least, initially).

Local Leaderboards

    Even if a game is multi-player, it does not necessitate a multi-player leaderboard. A local listing of your own high scores and progress is powerful. Not all players are motivated by the status a public leaderboard provides, but nearly all game players are interested in seeing progress to some degree.


Temporal

    By grouping by time, leaderboards can stay fresh. Maybe you couldn't get to the top twenty last week, but perhaps you can this week. If the rankings are changing by time, it can also make the game feel more active. Dedicated players that show up day after day (or week, or month - whatever the interval is) have high status. For instance, on Reddit users that constantly comment and receives a lot of upvotes will often have more of an impact on the conversations than an unknown user. The flip side - and another advantage - is that with a time based ranking system, more players have more chances to show up in the leaderboard.


Ladder Systems

    Games like Starcraft and League of Legends (and most other skill-based games) have a ladder system. In it, there are various 'tiers', or 'leagues'. Each tier may have numerous divisions (instances of the tier - for example, there may be 1,000 'Bronze League' divisions which each contain 100 players). The lower tiers usually have a ton, while the final tier may have only a single division. You advance to the next tier by ranking high in your current one. This is a sort of hybrid of a relative and absolute leaderboard. Absolute, in the sense that you may be number 99 out of 100 - but relative in the sense that you're in a 'group' and not compared absolutely to the top tier of players (unless, of course, you're in the top tier).


    Ladders systems provide a way for players to increase their position in a leaderboard, but do so at a rate that is neither too fast or slow. If you're good, then you'll quickly get to a point where you stop progressing quickly - and if you're bad, you'll drop down in ranks and get to a point where you can rise up by increasing your skill.


More Leaderboards

These aren't the only types of leaderboards. The type that produces perhaps the most motivation are leaderboards that pit groups against each other. For example, teams (or guilds, or clans, or groups in a real world company) that have a ranking. The members of each team want their team to be at the top, and often can be more motivated to be engaged vs. their non-teammed, solo counterparts.



Other types in your social graph, how you and your friends compare to each other. There is really a virtually limitless way to slice and categorize the data.  Each slicing, each way you present a leaderboard, will change not just how the player perceives their achievements and progress; but will also affect their motivation. By showing friend comparisons, for instance, there is social proof which can be stronger than competing against anonymous players. However, some players are more motivated to improve their own skill and may find local leaderboards that track their individual progress more effective. 



When you start combining different types of leaderboards, you can create powerful incentives for playing (e.g., grouping by time and location). Allowing sorting can provide another powerful way of exploring the data. Providing too many options, too many leaderboards, is probably a bad idea. However, being cognizant of your game's goals and understanding your game's audience and their goals, providing different types of leaderboards can create incredibly strong impulses to play. In the case of my younger self, the presentation of achivements through leaderboards can be even more powerful than the game itself.&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/yfhdeOzAlts" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/eQUKnjr2-qs" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/7XHKRdoHBKk" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/_B7kiDMC6OY" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/data-visualization/data-visualization-in-games-leaderboards</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/yfhdeOzAlts/data-visualization-in-games-leaderboards</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/eQUKnjr2-qs/data-visualization-in-games-leaderboards</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/7XHKRdoHBKk/data-visualization-in-games-leaderboards</feedburner:origLink></item>
    
    <item>

        <title>Designing a Browser Based Game with D3.js</title>
        <pubDate>Sun, 21 Sep 2014 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/DYi4k9qWRWM/designing-a-browser-based-game-with-d3js-part-1</link>
        <guid isPermaLink="false">http://vasir.net/blog/game-development/designing-a-browser-based-game-with-d3js-part-1</guid>
        <category>Game Development&gt;</category>


        <description>&lt;a href='http://scarsoftheuntrodden.com' target='blank'&gt;
        &lt;img
            src='https://s3.amazonaws.com/vasir-assets/scars-1/full.gif'
            class='center' 
            width=560
            height=356 /&gt;
        
            Scars of the Untrodden, an HTML5 game built using D3.js.  View the introduction
        
    
 


    First impressions are powerful. The initial exposure to a game, book, or even web application, affects your not only your interest in it, but your perception and expectations of it. That initial exposure is a promise to the player, reader, or user. It's a sort of taste of the full experience, a sort of summary. If you read a book that starts out like Harry Potter but halfway through turns into Game of Thrones, the author did a bad job at getting across the books' tone on the first page. 



&lt;a href='http://scarsoftheuntrodden.com' target='blank'&gt;Scars of the Untrodden is a browser based, fantasy, rouge-like map exploration game I've been working on which makes heavy use of data visualizations. I waited until I had completed most of the game to work on the introduction. I feel the initial experience is incredibly important - not just from an aesthetic perspective, but from a teaching one. 



Within the first moments of gameplay, I feel that a good game will communicate the tone of the game, teach the user what kind of experiences to expect, and convey a sort of summary of the full experience. One of my favorite examples of a game executing this beautifully is Megaman X (
&lt;a href='https://www.youtube.com/watch?v=8FpigqfcvlM' target='blank'&gt;watch Sequilitis's explanation of Megaman's level design - warning: explicit).



In this post, I'd like to share part of the initial experience of my browser based HTML5 rogue-like fantasy game. The core of it uses SVG (and &lt;a href='http://d3js.org/' target='blank'&gt;D3.js) for gameplay, but there is also a heavy emphasis of data visualization in the game. It's a work in progress, and I'm not a designer, so I welcome suggestions and criticisms. I'll describe the things I'm trying to accomplish from a design standpoint, as well as how I'm accomplishing them from a development standpoint. Feel free to &lt;a href='http://scarsoftheuntrodden.com' target='blank'&gt;take a look at the initial experience, which is what I'll be discussing in this article. NOTE: This is designed for modern browsers, and may not work in older browsers and some mobile devices


 Sources of Inspiration 


No idea is developed in a vacuum. Taking ideas from other disciplines can be powerful and create a richer, more unique game experience. Ideas from game design can be applied to other fields as well - for instance, I tried to incorporate some of the concepts from 
&lt;a href='https://www.youtube.com/watch?v=8FpigqfcvlM' target='blank'&gt;Sequelitis's Megaman Video into our &lt;a href='http://labs.five.com' target='blank'&gt;Five Labs experiment. These are the goals I'm trying to accomplish with the initial experience of my game:


&lt;ol&gt;
    &lt;li&gt;Use diegetic elements as much as possible, and establish a clear and consistent design language.
    &lt;li&gt;Create a promise (summary) of the full gameplay experience: convey the tone and communicate the large role data visualization will play. This is a broad goal, and also involves things such as immediately providing the player with meaningful choices




    There are countless sources of inspiration I've used, but I want to focus on just a few.


 Deadspace 

Deadspace not only has amazing diegetic design, but it also has a clear design language. Interactive elements have a consistent color, and your character is in a consistent position (your character's healthbar is on your character, so a consistent position is incredibly important). Deadspace's lead designer, Dino Ignacio, gave an &lt;a href='http://www.gdcvault.com/play/1017723/Crafting-Destruction-The-Evolution-of' target='blank'&gt;amazing talk of Deadspace's UI at GDC in 2013. This was a powerful presentation for me, and has heavily influenced the way I think about not just game design, but app design, and design in general.


 Shining Force 

One of my favorite games of all time is Shining Force. When I moved and started a new school in third grade, I asked every kid in class if they had ever heard of it, and some of my friends I met were because of it. Nostalgia aside, one of the things I loved about Shining Force was the introduction. When you start the game, a little bit of the story starts scrolling in. It stuck with me, and I love the way the text comes in word by word, scrolls down; the experience it creates. Every time I turned the game on, it just felt like I was starting a journey in a fantasy world.



    &lt;img
        src='https://s3.amazonaws.com/vasir-assets/scars-1/shiningforce1.gif'
        class='center' 
        width=560
        height=356 /&gt;
    
        Shining Force I introduction
    
 


 Understanding Comics 

&lt;a href='http://www.amazon.com/Understanding-Comics-The-Invisible-Art/dp/006097625X' target='blank'&gt;Understanding Comics is an amazing book that has a lot to do with comics, but not as much as the title implies. One of the many concepts it discusses is the concept of audience involvement. It's easier to relate to a stick figure than it is to a realistic drawing of a man. Your imagination sort of fills in the blank.



    &lt;a href='http://www.amazon.com/Understanding-Comics-The-Invisible-Art/dp/006097625X' target='blank'&gt;
        &lt;img
            src='https://s3.amazonaws.com/vasir-assets/scars-1/comics.jpg'
            class='center' 
            width=330
            height=256 /&gt;
        
            Understanding Comics
        
    
 


The more the concept of an object is emphasized, the less realistic it is drawn. Less emphasis is given to their physical appearance. To portray the beauty and complexity of the physical world, however, realism plays a larger part. It's fine for the background in comics to be more realistic, as brick walls and landscapes aren't things audiences identify themselves with. Likewise, in my game I've tried to give the backgrounds and map a little more high fidelity, while the foreground character sprites resemble characters from a SNES or SEGA role playing game.



 Technology Used 

Scars of the Untrodden makes heavy use of SVG filters and CSS filters (both built in, and using custom SVG filters). Browser based games have tremendous potential. One reason, I think, is the power of different HTML element types. The &amp;lt;canvas&amp;gt; element can be used to render things that change often. &amp;lt;Div&amp;gt; tags can be overlaid to display text (taking advantage of the browser's built-in text rendering engines, as opposed to writing your own), or to handle UI elements. SVG and D3 can be used to easily handle interactive elements or provide visualizations. The menagerie of different elements available can make the prototyping and development process extremely fast and less bug prone. 


In Scars of the Untrodden, SVG is the primary technology used to play the game, and D3.js is the primary library used to handle it. A canvas element is overlaid and used when necessary to render particle effects and other things that require frame-by-frame updates. Normal HTML elements are used to draw and handle UI elements. This approach won't work for all games of course, but by leveraging the built-in elements browsers provide, I'm able to quickly iterate and make little or no performance tradeoffs. For some games, like action games, canvas (or webgl) is an obvious choice... but for others, like tactics-based games (Shining Force), there can be benefits to using SVG. In my game, there are few graphic updates each game loop iteration, so for me SVG is a fine fit.



Initial Experience Breakdown

I'd like to share how I'm designing my game's initial experience. &lt;a href='http://scarsoftheuntrodden.com' target='blank'&gt;Feel free to check it out before reading about it.



 General Aestethics 


    &lt;a href='http://scarsoftheuntrodden.com' target='blank'&gt;
        &lt;img
            src='https://s3.amazonaws.com/vasir-assets/scars-1/title.jpg'
            class='center' 
            width=560
            height=356 /&gt;
        
            Scars of the Untrodden, an HTML5 game built using D3.js.  View the introduction
        
    
 


    This is a fantasy rogue-like game. I want to immediately convey that this takes place in a fantasy world and is centered around exploration. The book, typography, title, and blurred out map hopefully convey this. I like the idea of using a journal in the introduction, as I'm trying to imply that this is a story the player is creating by exploring the world. The journal is also, to some degree, a diegetic interface. The goal is to try to encourage a more immersive experience right from the start. 



 The First Page 

Let's take a look at the first page; what you immediately see when opening the game:



    &lt;a href='http://scarsoftheuntrodden.com' target='blank'&gt;
        &lt;img
            src='https://s3.amazonaws.com/vasir-assets/scars-1/scars-title.gif'
            class='center' 
            width=340
            height=456 /&gt;
        
            Initial loading / title sequence
        
    
 

    Like Shining Force, the body of the text fades in word by word. The actual meaning of the text is a bit nebulous, but it hints at the underlying story. It's also a type of visualization (although a bit subtle). As you progress, the text will change based on your progress. It will be a subtle cue, and something that isn't critical to playing the game (but could add a little flavor for those that enjoy it). If you don't want to wait for the text to fade in, you can click it or press escape. This is important as most players don't want to be forced to wait to play, and forcing it on them could be considered bad design.



    After the text fades in, the name input comes up. It's the only thing that has any behavior when interacting with, so hopefully it's clear enough without being too obvious. The background is white and the font is different. Like Deadspace, I'm trying to immediately establish a consistent design language for interactions. When you see something white with that different font, it means you should (or can) interact with it.


 Race Selection 
    
        &lt;a href='http://scarsoftheuntrodden.com' target='blank'&gt;
            &lt;img
                src='https://s3.amazonaws.com/vasir-assets/scars-1/race.gif'
                class='center' 
                width=320
                height=400 /&gt;
            
            Race selection
            
        
     

    
        After entering your name, you're presented with the option to select a race. Like the name input, the background is also white to imply that it is interactive. When you click the race, the font of the selected race changes as well.
    
    
        Many role playing games allow you to select a race. By providing race selection so soon, I'm trying to imply that this is some sort of fantasy role playing game. There are two races that can be selected, and two that cannot which have the name 'undiscovered'. This is a visualization as well, and it aims to do a couple things:
    
    &lt;ul&gt;
        &lt;li&gt;
        First, it implies that you have a choice. By providing two selections immediately, I'm trying to give you a hint that you will have to make choices in how you customize your character. 
        
        &lt;li&gt;
        Second, by showing other races that are 'undiscovered', it implies that you will be able to unlock them somehow. Hopefully, this also immediately sparks a bit of curiosity.
        
    
    
        One game that also does this well is &lt;a href='http://www.wizardslizard.com/' target='blank'&gt;A Wizard's Lizard:
    
    
        &lt;a href='http://scarsoftheuntrodden.com' target='blank'&gt;
            &lt;img
                src='https://s3.amazonaws.com/vasir-assets/scars-1/awl.png'
                class='center' 
                width=360
                height=200 /&gt;
            
                A Wizard's Lizard's character selection
            
        
     

     Race Description and Visualization 
    
        The bonuses for each race hopefully seem like they will have a heavy impact on gameplay, even if you know nothing about gameplay. I'm trying to immediately present the player with significant choices. Selecting human grants +20% exp, but but Elves have a chance to completely avoid all damage. Without knowing anything about the game mechanics, other than what has been implied so far (likely some sort of progression based fantasy game), hopefully the player will already have the sense that they are making significant descisions.
    
    
        &lt;a href='http://scarsoftheuntrodden.com' target='blank'&gt;
            &lt;img
                src='https://s3.amazonaws.com/vasir-assets/scars-1/race-ability.jpg'
                class='center' 
                width=400
                height=345 /&gt;
            
            More experience or chance to avoid damage?
            
        
     

    
        D3.js is used both for the main gameplay, and for drawing visualizations. The visualizations are intentionally nebulous in that no numbers are shown and there is no scale provided. The experience this kind of visualization creates is different than a straight, clean bar chart with numbers. There are a few things I'm trying to accomplish:
    
    
    &lt;ol&gt;
        &lt;li&gt;
            To convey that this game will involve a significant amount of visualizations.
        
        &lt;li&gt;
            Visualizations in this game are designed to help aide in your decision making process.
        
        &lt;li&gt;
            While data visualizations will play a key role, they are not the game. By including them as the last thing on the page, it emphasizes it's importance.
        
        &lt;li&gt;
            The visualization is to, some degree, diegetic. I'm trying to make it look like it's a bar chart that someone could have drawn in their diary. 
        
    
    

    
        &lt;a href='http://scarsoftheuntrodden.com' target='blank'&gt;
            &lt;img
                src='https://s3.amazonaws.com/vasir-assets/scars-1/race-viz.jpg'
                class='center' 
                width=400
                height=123 /&gt;
            
            Semi-abstract race visualization
            
        
    

     Data Visualization in Games - Abstractions 
    
        The visualization the games provide will provide a sense of what the data means, but they do not fully represent the data. By this, I mean that the goal of the visualizations is to not give you perfect information. The concepts that visualizations in games represent are abstractions. A character's health is an abstraction. In real life, humans don't have hit points. If I can jog a couple miles - does that mean I have 75 stamina? Quantifying these things are tough. How do I translate my programming ability into 'programming' skill points? 
    
    
    The point I'm trying to make is that hit points, ability and stats in video games are by nature abstractions of reality. By showing a health bar of exactly how many 'hit points' your character has, you expose the data behind the abstraction, you expose that abstraction for what it is. An abstraction.  So, by showing a bar without displaying the 'behind the curtain' value calculation, I think that the visualization can help aide in creating a more immersive experience. In Scars of the Untrodden, I'll rarely (if ever) show the actual number values, and instead will try to keep the visualizations a bit nebulous.
    


 Conclusion 

    This game is a work in progress and while a lot of it is coded, I have not yet planned a release date. You can &lt;a href='http://scarsoftheuntrodden.com' target='blank'&gt; check out the demo of the initial experience. I'm trying to improve my design skills, so I appreciate any suggestions or criticisms. 


After selecting your character's race, you will then select abilities. You'll explore a procedurally generated world by interacting with a map, hoping from place to place. Some locations may contain battles, or shops, or quests. The map exploration is inspired by &lt;a href='http://www.ftlgame.com/' target='blank'&gt;FTL, and is built using D3.js and SVG filters:

    
        &lt;a href='http://scarsoftheuntrodden.com' target='blank'&gt;
            &lt;img
                src='https://s3.amazonaws.com/vasir-assets/scars-1/in-game1.jpg'
                class='center' 
                width=500
                height=242 /&gt;
            
            Map Exploration with SVG and Filters
            
        
    

    
    My &lt;a href='http://localhost:8130/blog/data-visualization/using-d3-and-svg-filters-to-create-fog-of-war' target='blank'&gt;last post explained how to use D3.js to create a fog of war effect like the one I'm using in my game. The battle system is in real time, a sort of mixture between final fantasy and League of Legends.
    
    
    In future posts, I'll go more deeply into other areas of gameplay, design, and more how I use D3.js and a variety of HTML5 elements to create a browser based game which makes use of a variety of browser features. 
    
    
    In the meantime, feel free to take a look at the initial experience. Feedback is welcome!
    
    
        &lt;a href='http://scarsoftheuntrodden.com' target='blank'&gt;
            &lt;img
                src='https://s3.amazonaws.com/vasir-assets/scars-1/full.gif'
                class='center' 
                width=580
                height=402 /&gt;
            
            View the initial demo&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/RmmKqicklFg" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/RIO15ohT-qE" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/BnyjQeO8TYQ" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/DYi4k9qWRWM" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/game-development/designing-a-browser-based-game-with-d3js-part-1</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/RmmKqicklFg/designing-a-browser-based-game-with-d3js-part-1</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/RIO15ohT-qE/designing-a-browser-based-game-with-d3js-part-1</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/BnyjQeO8TYQ/designing-a-browser-based-game-with-d3js-part-1</feedburner:origLink></item>
    
    <item>

        <title>Using D3 and SVG Filters to Create a Fog of War Effect</title>
        <pubDate>Sun, 14 Sep 2014 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/S4F4kXXpi9E/using-d3-and-svg-filters-to-create-fog-of-war</link>
        <guid isPermaLink="false">http://vasir.net/blog/data-visualization/using-d3-and-svg-filters-to-create-fog-of-war</guid>
        <category>Data Visualization&gt;</category>


        <description>&lt;a href='http://bl.ocks.org/erikhazzard/3a6f39dadf4d9fec7ca4' target='blank'&gt;
        &lt;img
            src='https://s3.amazonaws.com/vasir-assets/fog-of-war/fog-final.jpg'
            class='center' 
            width=560
            height=356 /&gt;
        
            Simple Fog of War Example Using SVG Filters and Masks. Click to reveal fog
        
    
 


The Fog of War is a common type of game data visualization, frequently used in Real Time Strategy (RTS) games. At the core, the idea is simple: areas on the map where you control units (or have explored) are visible, and unexplored areas are dark. 




This post describes a simple way to achieve this effect for a browser based game using SVG filters and masks, along with a little bit of &lt;a href='http://d3js.org/' target='blank'&gt;D3.js. Filters can be not only a powerful prototyping tool, but also an easy way to achieve impressive visual effects for browser based games.




    Note: Filters are not supported in all browsers. If using filters in production, be sure to be aware of the performance tradeoffs and the browsers your audience uses.  &lt;a href='http://bl.ocks.org/erikhazzard/3a6f39dadf4d9fec7ca4' target='blank'&gt;View demo.



Masks


There are many ways to create a fog of war effect, but one potential simple way to think of it as a &lt;a href='http://www.w3.org/TR/SVG/masking.html#Masking' target='blank'&gt;mask effect. For example:




    &lt;svg id='mask-example' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
        width='200' height='200'&gt;
        
            
                
            
        

        
        
    
    
        setTimeout(function(){
            var svg = d3.select('mask-example');
            d3.select('#circle-mask').transition()
                .each('end', pulse);

            function pulse(){
                var circle = d3.select(this);
                (function repeat(){
                    circle = circle.transition().duration(1000).attr({ r: 50 })
                        .transition().duration(1000).attr({ r: 0 })
                        .each('end', repeat);
                })();
            }
        }, 2000);
    



Here, we have two rectangles which both have a width of 200 and a height of 175. One rectangle is black, the other is blue. However, the reason why a pulsating circle appears as opposed to a blue rectangle is because we have added a mask (and used D3 to change its radius). Let's look at the full source code quickly: 


    &amp;lt;svg id='mask-example' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'&amp;gt;
        &amp;lt;defs&amp;gt;
            &amp;lt;mask id='mask'&amp;gt;
                &amp;lt;circle id='circle-mask' cx='100' cy='75' r='25' fill='#ffffff'  /&amp;gt;
           &amp;lt;/mask&amp;gt;
        &amp;lt;/defs&amp;gt;

        &amp;lt;rect x='0' y='0' width='200' height='175' fill='#000000' /&amp;gt;
        &amp;lt;rect x='0' y='0' width='200' height='175' fill='#ffffff' mask='url(#mask)' /&amp;gt;
    &amp;lt;/svg&amp;gt;



To create a mask element, we just need a defs tag with a mask tag inside of it. The mask tag has an ID which allows other elements to reference it. Inside of the mask tag, elements can be placed inside which create the actual mask:

&amp;lt;circle id='circle-mask' cx='100' cy='75' r='25' fill='#ffffff'  /&amp;gt;


A fill of white ('#ffffff') will be masked completely, while black (#000000) will not appear.  To give an element a mask, the mask attribute is added to the element - for instance, we give the blue rectangle a 'mask' property attribute:


&amp;lt;rect x='0' y='0' width='200' height='175' fill='#ffffff' mask='url(#mask)' /&amp;gt;


Now, the blue rectangle will be masked by whatever elements are contained with the &amp;lt;mask id='mask'&amp;gt; tag. In this example, we have a single circle in the mask tag. The mask is a composition of whatever elements (rects, circles, paths, etc.) are placed in the mask tag. Multiple elements can be placed in the mask as well, and each element in the mask can have a different fill color:



    &lt;svg id='mask-example-2' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
        width='200' height='200'&gt;
        
            
                
                
                
                
                
                
            
        

        
        
    



    Because any SVG element can be placed in a mask, we can dynamically add and remove elements from a mask. We can transition property values, allowing the mask to fade in. We can also place elements with gradients or patterns in an element in the mask tag. And, if we want to make a fog of war effect, we can use filters.



Filters

A &lt;a href='http://localhost:8130/blog/data-visualization/enhancing-data-visualization-with-svg-filters' target='blank'&gt;previous post discussed filters, so we won't go too in depth here. There are an infinite amount of possible filter effects that can be created, but chances are you're familiar with the common primitives - such as blur, turbulence, lighting effects. Let's take a look at a rectangle and circle before a filter is applied to it:




 





    We can make this far more interesting by adding a filter effect.  One filter effect I've been playing around with is a combination of a blur, turbulence, and displacementMap (&lt;a href='http://www.w3.org/TR/SVG/filters.html#FilterPrimitivesOverview' target='blank'&gt;more information on these filter primitives). Here are the same elements with that filter applied to it:














 


&lt;a href='http://bl.ocks.org/erikhazzard/36c8144402b3d2b38545' target='blank'&gt;
View filter source code




To me, this filter reminds me of a torn map. Filters can be applied as properties to elements (like rect, circle, and path), which means we can apply filters to elements that are in a mask. 
























&lt;a href='http://bl.ocks.org/erikhazzard/8dc0183dfc8acfcb59b0' target='blank'&gt;
View filter source code









Conclusion

The fog of war is a common form of data visualization in games. Using d3.js and SVG filters to create a fog of war effect for browser based games is not only easy, it provides great flexibility and power. 



In the example below, a mask is created and circles are added to it for explored areas. When the circles are added, their fill color is transitioned from #000000 to #ffffff, causing a fade-in effect. Each circle added to the mask also has a filter effect, causing a sort of jagged visual effect. A dark, gray-scale image of the map is masked over the 'normal' map image, which allows us to provide a subtle hint of what's hidden behind darkness. To see the effect in action (a circle being added to the mask), click anywhere on the map:



    &lt;iframe 
        src='https://s3.amazonaws.com/vasir-assets/fog-of-war/fog.html'
        class='center'
        scrolling='no'
        style='background-color: #cdcdcd;' 
        seamless='seamless'
        frameborder=0 width=560 height=356&gt;
    
    
        Click the map to reveal fog. Using filters to create the fog of war data visualization effect used in games. 
        
        &lt;a href='http://bl.ocks.org/erikhazzard/3a6f39dadf4d9fec7ca4'
            target='blank'&gt;
            View Source
        
    



However, the tradeoff is often at the cost of performance. In the example, you likely noticed that performance hits are noticable even after a relatively small amount of elements to the mask. 
While this is just an unoptimized demo, using complex SVG filters can be a large bottleneck. One other area that could be optimized is the filter itself. A simplier filter is more efficient, as less processing has to be done to fewer pixels.



If you were developing an RTS game where the fog of war was constantly changing, this method is likely a bad fit. For games that need only a small number of elements masked, like a rogue-like map exploration HTML5 game I'm building, the tradeoff is acceptable. 



    With tradeoffs in mind, and depending on your application, using SVG filters in browser based games can be great. Even if the performance isn't acceptable for your use case though, filters can serve as a powerful prototyping tool.



Happy filtering, now go filter yourself!





&lt;link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/default.min.css"&gt;

.hljs{display:block;overflow-x:auto;padding:0.5em;background:#fdf6e3;color:#657b83}.hljs-comment,.hljs-quote{color:#93a1a1}.hljs-keyword,.hljs-selector-tag,.hljs-addition{color:#859900}.hljs-number,.hljs-string,.hljs-meta .hljs-meta-string,.hljs-literal,.hljs-doctag,.hljs-regexp{color:#2aa198}.hljs-title,.hljs-section,.hljs-name,.hljs-selector-id,.hljs-selector-class{color:#268bd2}.hljs-attribute,.hljs-attr,.hljs-variable,.hljs-template-variable,.hljs-class .hljs-title,.hljs-type{color:#b58900}.hljs-symbol,.hljs-bullet,.hljs-subst,.hljs-meta,.hljs-meta .hljs-keyword,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-link{color:#cb4b16}.hljs-built_in,.hljs-deletion{color:#dc322f}.hljs-formula{background:#eee8d5}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}


hljs.initHighlightingOnLoad();&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/Bbi8ACp1N7g" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/ZQ4E7Dzc8Ik" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/CTLvNggjqzg" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/S4F4kXXpi9E" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/data-visualization/using-d3-and-svg-filters-to-create-fog-of-war</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/Bbi8ACp1N7g/using-d3-and-svg-filters-to-create-fog-of-war</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/ZQ4E7Dzc8Ik/using-d3-and-svg-filters-to-create-fog-of-war</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/CTLvNggjqzg/using-d3-and-svg-filters-to-create-fog-of-war</feedburner:origLink></item>
    
    <item>

        <title>Data Visualization in Games</title>
        <pubDate>Sun, 31 Aug 2014 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/aedoFO3DPrc/data-visualization-in-games</link>
        <guid isPermaLink="false">http://vasir.net/blog/game-development/data-visualization-in-games</guid>
        <category>Game Development&gt;</category>


        <description>Data visualization augments cognition.  Data visualization provides new insights; data visualization teaches the reader. Games, at their core, are all about learning: spatial, temporal, motor, and sometimes even intellectual. You learn how to play within a game&amp;#39;s rule-set, and to improve you learn. Once you completely master a game to the core, it ceases to be fun. Once you stop learning, or if you&amp;#39;re unable to learn, you play games for reasons other than fun. Data visualization provides a way to aide in the learning process; to keep games fun. If the game is no longer fun, data visualization can also be used to provide other motivators to play.

Types of Data Visualizations in Games

The purpose of data visualizations in games can vary. Some visualizations, like a health bar, exist to show you a character&amp;#39;s status. Others, like a technology tree in Age of Empires, exist to show how a character can progress. Even more data visualizations exist not for players - but for observers, such as kill:death ratios and gold count per character in League of Legend game streams on twitch.tv. 

While there are many, I believe there are two primary types of data visualizations used in games:

1. Status Information

These are visualizations which provide status information about players or characters, such as: health, score, experience points.

The primary goal of status visualizations is enable players to make gameplay decisions (prospective choices) or to give players information on what has happened (retrospective decisions). Sometimes, they do both - as with progress indicators (such as how much experience is left to level up, or what kind of buildings can be built).

As in data visualizations outside of games, some choices are better than others. For instance, a bar chart can be &lt;a target='blank' href='https://www.csc2.ncsu.edu/faculty/healey/download/tochi.96.pdf'&gt;pre-attentively processed, meaning that it can understood subconsciously in under ~100 milliseconds. This is an especially important consideration for games. Text must be read before it can be processed, which means it cannot be preattentively processed - which also means it will distract a player, because they have to draw their attention away from the game.

Virtually every game has some sort of status visualizations, either explicit or implicit. Even the game Asteroids has a score counter. An example of status visualizations can be seen in the independent game &lt;a target='blank' href='http://www.wizardslizard.com/'&gt;A Wizard&amp;#39;s Lizard:

&lt;img alt='A Wizard&amp;#39;s Lizard' src='https://s3.amazonaws.com/vasir-assets/data-viz-games-part-1/wizardslizard.jpg'/&gt;

There are multiple status visualizations here: Health (a number and bar chart in the shape of a heart), resource count (money, displayed as a number), current weapon (a dagger in the square next to health), various other items and item counts (other boxes with icons and a number), position on a map (minimap in the top right), and enemy health (bar chart under each enemy).

Audience of Status Visualizations

Status visualizations can be targeted at the current person playing the game (e.g., in a single player game), hidden from other players (e.g., information asymmetry in games like Starcraft), or explicitly shown to other players (like in social games, such as in Massively Multi-player Online Role Playing Games - MMORPGs). The kinds of status visualizations and which players can see them (in online games) have massive impacts on the game&amp;#39;s design.

2. Training

These visualizations may use status visualizations, but the goal of these visualizations is to improve gameplay. They can be seen by other players, but usually are tailored for the individual player of the game. Charts that show status over time after the game session has ended are an example of training visualizations. However, only a subset of games incorporate these kinds of charts.

An example of this kind of visualization can be found in Starcraft 2 after a match has ended. After each game, various graphs are presented which show how the game progressed for each player over time for various dimensions, such as army size and economy.

&lt;img alt='Starcraft 2 Overview' src='https://s3.amazonaws.com/vasir-assets/data-viz-games-part-1/sc2-overview.jpg'/&gt;

Many skill-based games like Starcraft or League of Legends also capture all gameplay and allow you to watch it as a replay. By watching replays, like in sports, players can see where their gameplay broke down and make better decisions next time. More skilled players will often upload game replays to allow others to learn from them; &lt;a target='blank' href='blip.tv/day9tv/'&gt;some people, like Day9, even provide extensive replay analysis.

How games use data visualization

Different genres of games have different goals, which influence the kinds of visualizations they provide. While they may have different objectives, they use a combination of status and training visualization types to accomplish their aims.

1. Training Visualizations

First Person Shooters (FPS) and Real Time Strategy (RTS) games are largely skill based; inherently driven by improving one&amp;#39;s gameplay. If you play Starcraft (a RTS) and you constantly die, it&amp;#39;s not very fun. Likewise, if you never die, it&amp;#39;s not very fun. A delicate balance exists between skill and difficulty. 

In these kinds of games, an abundant amount of training visualizations exist to help you improve your gameplay. Like chess, progress is all internal to the player of the game. Like chess, these games are based solely on skill: the only advantage you have in the game is your ability to play it. Each game session is self contained, and pits your skill against another player&amp;#39;s skills. If your gameplay is not improving, you are not learning, your skill is not increasing, and you cease having fun and stop playing.

2. Status Visualizations

All games, including skill-based games, use some forms of status visualizations. The way they are used varies amongst genres.

Decision Making Power

Skill-based games use status visualizations to assist your gameplay decisions, but can only provide assistance. The &amp;quot;Fog of War&amp;quot; is a visualization in RTS and other similar games that allows you to only see what your units can see. You are prevented from seeing the enemy&amp;#39;s information, and this information asymmetry is a key part of a game&amp;#39;s design. The player must make the decision to scout or to attack blindly. And, even if you do have information of the enemy base, often times the enemy will have units hidden elsewhere; or, they might be baiting you in. Even if you had &amp;quot;perfect information&amp;quot;, there is the additional layer of the enemy&amp;#39;s skill in maneuvering their units, or in how well the enemy can micro-manage their army. With these games, visualizations alone play small roles in the in-game decision making process.

Other genres of games, such as social games like Massively Multi-Player Online Role Playing Games (MMORPGs), have different data visualization goals. In these games, your progress is largely in-game. As such, the need for traning visualizations is lessened. While these games certainly involving learning and difficultly, they are not inherently skill-based.  In social games, in-game visualizations provide more decision making power. For instance, in many MMORPGs a &amp;quot;consider&amp;quot; system exists which color codes enemies by difficultly:

&lt;img alt='EQ2 Con' src='https://s3.amazonaws.com/vasir-assets/data-viz-games-part-1/eq2-cons.jpg'/&gt;

In Everquest 2, enemies are colored by difficultly. Yellow means the fight will likely be tough. Just having a single piece of information about the strength of the enemy will inform your decision to attack them. If an enemy &amp;quot;cons&amp;quot; green, for instance, it means the fight will be trivial. In these games, the data visualization is the main driving force behind the decision making process. 

Depending on the genre, some kinds of data visualizations are more useful than others. As a very broad statement, skill-based games rely largely on training visualizations to improve a player&amp;#39;s skill to help the player make decisions for future games. Social oriented games rely more on status visualizations to aide more in decision making as it happens, and have fewer training visualization types.

3. Other

Many games use visualizations that are, in a sense, &amp;quot;outside&amp;quot; of the game itself. Their purpose is largely to motivate you to keep playing. 

Social Motivators

Nearly all online games use some sort of data visualization to provide social motivation, such as custom appearance options, which has little impact on gameplay.

One example of a social motivator that has little to do with actual game data is your equipment&amp;#39;s appearance in games like World of Warcraft or Everquest 2. In these games, the appearance of your equipment can be customized. This divorces the visual appearance to the actual equipment data, making the visualization nearly meaningless in the context of knowing what the &amp;quot;stats&amp;quot; of the equipment are. However, the visual appearance of your character is a social expression, and some players are often motivated to obtain visually distinguishable equipment as a way to communicate social status.

Other games, such as League of Legends, also makes use of social motivators. In League of Legends, you can purchase custom &amp;quot;skins&amp;quot; for your character which have no impact on gameplay. However, custom skins act as a social status symbol to other players. Your kill:death record is also public, and some players may be motivated to play to increase their total games won, or their rank in the ladder / tournament system.

Achievements

Most games these days include some sort of achievement system. Achievements act as visible indicators of progress. If these are public, they can also act as social motivators. If the game is fun and enjoyable, achievements can enhance gameplay. If the game has ceased to be fun, however, achievements can act as ways to keep otherwise unengaged players motivated to keep playing.

Immersion: Diegetic vs. Non-Diegetic

Most games largely use Non-Diegetic interfaces. A non-diegetic interface is one that exists outside of the game world; it exists only for the player of the game, not the characters inside the game. 

For many games, like League of Legends, data visualizations don&amp;#39;t distract much from the game. Seeing a player&amp;#39;s health bar, or the minimap, or the fog of war, does not ruin immersion. For some genres, like Multiplayer Online Battle Arena (MOBA) or Real Time Strategy games, this kind of information is critical. 

&lt;img alt='League of Legends' src='https://s3.amazonaws.com/vasir-assets/data-viz-games-part-1/leagueoflegends.jpg'/&gt;

This kind of interface is called a &amp;quot;non-diegetic&amp;quot; interface. This means the interface exists outside of the game world; the interface exists for the player of the game - not the characters inside the game world. With nice aesthetic design (like the organic insect-like user interface in Starcraft for the Zerg race), non-deigetic interfaces do not necessarily ruin immersion, or make the player feel like they are not in the game. 

Diegetic Interfaces

Designing visualizations for non-diegetic interfaces is a bit easier, as the visualizations need only to be interpreted by the player. Diegetic interfaces, on the other hand, are interfaces that exist inside the game world. These are interfaces that must make sense both for the characters in the world and the player of the game. 

Diegetic interfaces help make a game more immersive. If a health bar and ammunition count are displayed in a non-diegetic way, stuck at the top or bottom of the screen, it can be distracting. Anything distracts the player is usually a bad thing; especially when you&amp;#39;re exploring an abandoned spaceship and shooting space zombies. &lt;a target='blank' href='http://www.ea.com/dead-space-3'&gt;Deadspace is a game where nearly all interface components and visualizations are diegetic.

&lt;img alt='Deadspace' src='https://s3.amazonaws.com/vasir-assets/data-viz-games-part-1/deadspace-in-game.jpg'/&gt;

In this screenshot of Deadspace, there are at least three obvious pieces of data being visualized - and they all exist both in the game world and for the player. 

First, the health bar. In Deadspace, your character&amp;#39;s health is represented as cyan colored bars on the back of the in-game character (near the bottom left of the screen). Health is a status usually indicated by a bar chart; in Deadspace it&amp;#39;s still essentially a bar chart but it&amp;#39;s actually on the character in game. 

Second, your weapon&amp;#39;s ammunition count. Your gun has a sort of heads-up display with the amount of ammo left. It looks static in the screenshot, but that display actually exists in the game world, and moves around with the character. Both you and the character see the ammo displayed. 

Third, the targeting lines. In games like Counterstrike or Call of Duty, a crosshair is usually used to indicate where your bullet will go. A crosshair is a non-diegetic interface component - the player in the world cannot see the crosshair; only you can. In Deadspace, there is no crosshair. Instead, you see a laser indicating where your bullets will fly. Both you and the character see these laser lines.

Visualizations and Immersion

Visualizations in games need not feel &amp;quot;tacked on.&amp;quot; They can be subtle. When playing Deadspace, my &amp;quot;health bar&amp;quot; does not feel like an explicit data visualization. The diegetic visualization of a health bar makes me feel as if it&amp;#39;s giving me information without having to look at it. It creates more of an emotional reaction than an intellectual one. 

With traditional visualizations, you know you&amp;#39;re being given information. Bar charts and pie charts explicitly tell you a story about the data. There exists a great potential for games to contain data visualizations which inform the player in subtle ways. Visualizations which feel like they are part of the world - which may not even feel like visualizations at all - can be far more powerful for creating experiences.

How Data Visualization can Improve Games

Games have as much potential as any form of art, and possibly even more potential, to create powerful experiences. Writing, cinema, music, and painting all create experiences in the participant&amp;#39;s mind. Like movies, games can include all other art forms (including games inside of games - &amp;#39;minigames&amp;#39;), which can be used together to create novel experiences. Unlike other art forms, games are inherently interactive. With that interactivity comes a bigger potential for creating perhaps more powerful experiences, or having experiences emerge that the designers never intended.

Of course, video games are relatively young. While there is much talk about how games are evolving as an art form, there seems to be far fewer people talking about how data visualization fits into game design.  Not only am I excited about how games will progress as an art form; I am excited by how games can better incorporate (and even move forward) the field of data visualization. 

&lt;img alt='Playfair Chart' src='https://s3.amazonaws.com/vasir-assets/data-viz-games-part-1/playfair.jpg'/&gt;

&lt;a target='blank' href='http://en.wikipedia.org/wiki/William_Playfair'&gt;William Playfair was the founder of graphical methods of statistics - inventing the line and bar charts in 1786. Since then, we&amp;#39;ve seen a lot of novel data visualizations, such as &lt;a target='blank' href='http://en.wikipedia.org/wiki/Charles_Joseph_Minard'&gt;Charles Minard&amp;#39;s flow map of Napolean&amp;#39;s Russian Campaign.

&lt;img alt='Minard&amp;#39;s Chart' src='https://s3.amazonaws.com/vasir-assets/data-viz-games-part-1/minard.jpg'/&gt;

Computers increase the potential of what data visualizations can be, and tools like &lt;a target='blank' href='http://d3js.org/'&gt;D3 are increasing the number of people make data visualizations. I think games have the potential to allow for novel visualizations and novel ways of combining existing chart types (like how Minard&amp;#39;s flow map so eloquently used multiple visualization types). Not only can data visualization improve the player&amp;#39;s gameplay and aide in decision making, it can be used to more fully immerse the player in the game&amp;#39;s universe. Games, I believe, not only make possible new visualizations; but visualizations can make possible better games.&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/QzL36xGdh7Q" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/jmfEoNAH6Vo" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/raE1mVzsIj8" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/aedoFO3DPrc" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/game-development/data-visualization-in-games</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/QzL36xGdh7Q/data-visualization-in-games</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/jmfEoNAH6Vo/data-visualization-in-games</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/raE1mVzsIj8/data-visualization-in-games</feedburner:origLink></item>
    
    <item>

        <title>Better Group-based Javascript Logging for Browsers</title>
        <pubDate>Sun, 24 Aug 2014 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/eAf4wsOHh7c/bragi-javascript-logging-browser</link>
        <guid isPermaLink="false">http://vasir.net/blog/programming/bragi-javascript-logging-browser</guid>
        <category>Programming&gt;</category>


        <description>This is the last in a series of posts on logging. The 
&lt;a target='blank' href='http://vasir.net/blog/programming/how-logging-made-me-a-better-developer'&gt;first post describes how group based logging can be a powerful tool
, the 
&lt;a target='blank' href='http://vasir.net/blog/programming/bragi-a-javascript-logging-library'&gt;second post introduces Bragi, a NodeJS logging framework
, and this post discusses 
&lt;a target='blank' href='https://github.com/enoex/Bragi-Browser'&gt;Bragi for the Browser


 

&lt;a target='blank' href='https://github.com/enoex/Bragi-Browser'&gt;
&lt;img alt='Bragi for the Browser' src='https://s3.amazonaws.com/vasir-assets/bragi/bragi-log-browser.gif'/&gt;

 
Bragi, a Javascript Logger
 
Last week I introduced 
&lt;a target='blank' href='https://github.com/enoex/Bragi-Node'&gt;Bragi-Node
, a Javascript, NodeJS based logging library. This week I&amp;#39;d like to introduce the 
&lt;a target='blank' href='https://github.com/enoex/Bragi-Browser'&gt;browser version of Bragi
. My team and I have been using a version of this library for the past year. Next to unit tests (and in some ways even more benefical than them), group-based logging has been the most useful tool in our toolbox.
 
In my previous posts, I talked about some of the benefits of logging and why groups and colors are important, so I&amp;#39;ll just briefly mention them here:
 
Groups
 
By group based logging, I mean log messages that are categorized by groups. Not levels (info, warn, error), like most logging libraries I&amp;#39;ve encountered, but groups. Filtering certain types of messages (and sending them to the console or a remote host) is possible with groups. Bragi also allows namespacing, so you can have a group, like &amp;quot;error:customerController:fetchUsers&amp;quot; - this would be interpreted as an error 
and
 it is able to be filtered. 
 
We could log with the group &amp;quot;app1:component1:userId&amp;quot;, and filter out only log messages from the app1 namespace; or even more fine-grained to show only 
app1:component1
 messages. Or, by using regular expressions (which Bragi supports), we could show 
all
 messages that involve 
userId
 (which could be a dynamic string of the actual user&amp;#39;s ID or whatever you&amp;#39;d like), by specifying to show logs from &amp;quot;.*:userId&amp;quot;.
 
Colors
 
My philosophy lately has been to log everything. I liberally liter my code with log messages: every time a function is called or returned, anytime a significant bit of logic is run, etc. Of course, if there&amp;#39;s no way to filter the logs and all messages look the same, I&amp;#39;d have a huge problem. It&amp;#39;s really a data visualization problem (for me, log messages are data).
 
Color coding groups makes it possible to see any number of groups at once, while still gaining insight from the logs. If you enable all logs and see a color repeating over and over, it means some function or group is being called a lot. Being able to visualize that, especially when a system is running in production, is incredibly useful. Colors are a great visual cue. They can help you regain the context of how the code works by enabling all messages and tracing the flow of execution. It&amp;#39;s easier to maintain context when different groups are easily distinguishable.
 
Javascript Browser Logging
 
Bragi itself as a library is new, but the ideas behind it are old. Improvements, suggestions, and criticisms are all welcome. 
&lt;a target='blank' href='https://github.com/enoex/Bragi-Browser'&gt;Check out the browser version of Bragi on github
. Or, open your console to see an example. Happy logging.



    BRAGI.log('blog:bragi:browser', 'Hey there. You are reading a post about Bragi, the logger powering this log message');
    BRAGI.log('warn', 'And this one! Watch out, pay attention');
    BRAGI.log('user:about', 'Using different groups for different information is useful. Looks like you are using %s', window.navigator.userAgent);
    for(var i=0; i&lt;10; i++){
        (function loopClosure(i){
         BRAGI.log('group' + i, 'Each group gets a unique color', {curIndex: i});
        })(i)
    }
    BRAGI.log('blog', 'And here is a log from the base blog group, which is colored the same at the first blog message.');
    BRAGI.log('blog:bragi', 'Try it out yourself. Simply run `BRAGI.log(\"groupName\", \"Message\");`. And parameters afterwards are optional, and can be used to show information about objects');
    BRAGI.log('user:callToAction', 'Thanks for checking this out. Check it out on github, https://github.com/enoex/Bragi-Browser');&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/EIelplRmhOc" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/1_tFd4VTn24" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/rbFAJyz-phg" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/eAf4wsOHh7c" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/programming/bragi-javascript-logging-browser</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/EIelplRmhOc/bragi-javascript-logging-browser</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/1_tFd4VTn24/bragi-javascript-logging-browser</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/rbFAJyz-phg/bragi-javascript-logging-browser</feedburner:origLink></item>
    
    <item>

        <title>Bragi - A Javascript Logging Library for NodeJS</title>
        <pubDate>Sun, 17 Aug 2014 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/0VyYAokZkYQ/bragi-a-javascript-logging-library</link>
        <guid isPermaLink="false">http://vasir.net/blog/programming/bragi-a-javascript-logging-library</guid>
        <category>Programming&gt;</category>


        <description>My &lt;a target='blank' href='http://vasir.net/blog/development/how-logging-made-me-a-better-developer'&gt;first post talked about logging on an abstract level. In this post, I discuss a concrete implementation of those ideas.


&lt;a target='blank' href='https://github.com/enoex/Bragi-Node' title='Bragi javascript logging library in action'&gt;
    &lt;img alt='Bragi - Javascript Logging Library' src='https://s3.amazonaws.com/vasir-assets/bragi/bragi-log-still-small.png'/&gt;


I’d like to share with you &lt;a target='blank' href='https://github.com/enoex/Bragi-Node'&gt;Bragi, a Javascript logging library I wrote that has made my development workflow more efficient and enjoyable. In this first part, I’ll discuss the &lt;a target='blank' href='https://github.com/enoex/Bragi-Node'&gt;NodeJS version of Bragi. Next week, I’ll release and discuss the web browser version.


*tl;dr: Just want the library? Check out &lt;a target='blank' href='https://github.com/enoex/Bragi-Node'&gt;Bragi, a javascript logging library that allows expressive logging, uses colors and symbols, and allows piping logs to numerous outputs (console, file, remote hosts). Note that this is a public, early version which is subject to API changes.

Ideas behind Bragi

Some of the core concepts driving &lt;a target='blank' href='https://github.com/enoex/Bragi-Node'&gt;Bragi are:

&lt;ul&gt;&lt;li&gt;By design, there should be many calls to log() inside the application’s codebase and these calls should never need to be removed. &lt;li&gt;Log output should not be coupled to calls to log(). It should be easy to send the output of log() calls to the console, to a file, or to a remote host. It should even be simple to have the library send your phone a push notifications for certain types of logs.&lt;li&gt;Logs messages should be structured data - for Bragi, all calls to log() should produce a JSON object with the logged message and some meta info. This makes working with logs easier and allows better integration with third party services like Graylog or Kibana&lt;li&gt;The logging library itself should not care what you do with the logs, but instead enable you to effortlessly do whatever you wish with them.

Before I dive into examples of how to use &lt;a target='blank' href='https://github.com/enoex/Bragi-Node'&gt;Bragi, I want to discuss how it differs from many traditional logging approaches.

Traditional Logging Breakdown

&lt;ol&gt;&lt;li&gt;The call to log() itself&lt;li&gt;Outputting log messages (either to the console, to a file, a remote host, etc)

Normally, these two tasks are bundled together. For example, console.log() is a call to log which immediately prints something. When a log message directly prints something to your console, leaving log messages in a codebase pollutes the application’s output and can make it more difficult to develop or gain insights. 

The calls to log() and the output of those calls should be decoupled, and it should be possible for the output to be filtered. 

1. Calls to log()

The paradigm I’ve found most helpful is to leave log messages in code and have a way to filter what is output and how it is outputted (e.g., via console or written to a file). Most libraries I’ve used just have a linear log level setting - e.g., “debug”, “info”, “warn”, “error.” This is a step in the right direction, but it’s not expressive enough. With linear log levels alone, your ability to filter messages is greatly limitted and you have no fine grain control over what is shown.

Log Groups and Filtering

Bragi uses “log groups.” Instead of a linear log level, each log message belongs to some arbitrary group you create. This allows logging to be more expressive and tailored to your specific application. This allows the traditional “debug”, “info”, “error” log levels; but it also allows having log messages grouped by file name, method name, user id, etc. 

I’ve found it helpful to have group names separated by a colon (namespaces, in a way). For instance, this allows such fine grain groups such as: “userController:updateUser:name:userId123”. The group name is just a string, so it can be built dynamically - userId could be populated by whatever user is being updated. 

With groups, filtering becomes easy. We could show all messages from the userController namespace by enabling “userController” logs, or see only calls to updateUser by enabling “userController:updateUser”. If the logging library supports regular expressions (Bragi does), then we could also see all logs across the entire system for a specific user by adding /.*:userId123/ to the enabled groups. Expressive log groups can provide a complete and fully controllable view into exactly what your code is doing at any time by any metric or facet you desire.

2. Output of Logs: Transports

Bragi uses the notion of “transports” (inspired by [winston]), which determine what is done with a log message. By default, Bragi will print colored log messages to the console. Currently, it can also write to a file or output JSON.  

When log() is called, an object is created based on the group and passed in message. This object is augmented with some meta information, such as the time the message was logged and the calling function’s name (if it has one). Additionally, any extra arguments passed into log() are added onto a properties key. 

In &lt;a target='blank' href='https://github.com/enoex/Bragi-Node'&gt;Bragi, Console is the only transport enabled by default. To remove all transports, you can call transports.empty(), and to add a transport transports.add( new Tranport...() ) can be called.

Writing good log messages

Like naming variables, writing a good log message is not trivial. Some of the problems around writing good messages are tied to how code is structured. One thing I’ve found to be very helpful is to name all functions, so when looking at a stack trace I never see “anonymous function” and have to wonder where it is.

Another thing that has helped me is to use colors and symbols. Color is a powerful way to visualize information (e.g., all error messages have a red background with white text. Whenever you see it, you know immediately that it is an error). 

Bragi provides a function, logger.util.print(message, color), which takes in a message {String} and a color {String} (like ‘red’ or ‘green’), and returns the passed in message colored by the passed in color. This is useful for printing messages that contain color. For instance:

&lt;img alt='Colors example' src='http://s3.amazonaws.com/vasir-assets/bragi/bragi-colors-example.png'/&gt;

Symbols are also incredibly useful way to encode data in an easy to consume form.

Using Symbols In Logs

Symbols provide powerful visual cues. Looking at a sea of text is daunting, but if the text has various ✔︎ or ✗ or ☞, your eyes are drawn towards them. In fact, I can guess what happened when you saw this paragraph: the symbols initially jumped out at you and you directed your focus towards them, maybe even reading the word “various” before jumping back to the top of the paragraph to read it.

These cues allow you to quickly filter out certain messages. When you setup your logging, if you give all asynchronous calls an ✗ symbol, they will become much easier to spot.  Or maybe you give all warnings a ☞ symbol. Or maybe before an async request is made you print a ◯ symbol, then a ◉ symbol when the async process is finished. 

Bragi provides some UTF-8 symbols, accessible via 


var logger = require(‘brag’);
// symbols can be accessed via the `util` property. 
// It is a dictionary of symbols, such as logger.util.symbols.success 
console.log( logger.util.symbols );


How to use Bragi

The core of Bragi involves a call to log(). It takes in two required parameters and any number of additional objects. For instance:

var logger = require(‘bragi’);
logger.log(‘group1’, ‘Hello world’);
logger.log(‘group1:subgroup1’, ‘I can also log some objects’, { key: 42 });

Configuring Options

Filtering is a key feature of what makes this kind of logging powerful. With Bragi, you can specify what logs to show by providing a groupsEnabled array which can contain strings or regular expressions. If group1:subgroup1 is a value in the array, all messages that match group1:subgroup1, including nested subgroups, would get logged. If groupsEnabled is a boolean with a value of true, everything will be logged.

Similarly, you can specify log messages to ignore via the groupsDisabled key (also an array). It works the same as groupsEnabled, but in reverse. It will take priority over groups specified in groupsEnabled. This is useful, for instance, if you want to log everything except some certain messages. As with groupsEnabled, it is an array which can take in strings or regular expressions.

More configuration information can be found in &lt;a target='blank' href='https://github.com/enoex/Bragi-Node/blob/master/lib/bragi.js'&gt;Bragi&amp;#39;s source code.

Conclusion

Bragi is the result of me trying to formalize and publicly release a logging library I’ve been using for the past couple of years. It’s worked great for my team and me, so I thought others might find it useful. Bragi is in the incipient stage so the API will likely change. Criticisms and improvements are welcome, and I’ll be updating it and adding more transports throughout the next few weeks. Bragi is not just for NodeJS - next week, I’ll release and discuss the web browser version. 

 You can find &lt;a target='blank' href='https://github.com/enoex/Bragi-Node'&gt;Bragi, a Javascript logger on Github&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/eTgGrcEuuIU" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/hxCrzQB7Lsg" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/zdlRi--Ev-I" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/0VyYAokZkYQ" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/programming/bragi-a-javascript-logging-library</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/eTgGrcEuuIU/bragi-a-javascript-logging-library</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/hxCrzQB7Lsg/bragi-a-javascript-logging-library</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/zdlRi--Ev-I/bragi-a-javascript-logging-library</feedburner:origLink></item>
    
    <item>

        <title>How Logging Made me a Better Developer</title>
        <pubDate>Sun, 10 Aug 2014 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/FeMnnn4pUTc/how-logging-made-me-a-better-developer</link>
        <guid isPermaLink="false">http://vasir.net/blog/programming/how-logging-made-me-a-better-developer</guid>
        <category>Programming&gt;</category>


        <description>I think logging is one of the most powerful tools in a programmer&amp;#39;s toolbox. Unfortunately, it&amp;#39;s supremely underutilized. Logging gives you data about what your code is doing. Over the past couple years, I&amp;#39;ve found logging helps me to manage complexity, communicate my code to other developers (and vice versa), and allows me to rapidly develop and debug software. As simple and silly as it may seem; for me, logging is unequivocally the most beneficial tool in my toolbox.

This is the first part in a two part series on logging. This post describes why I think logging is important on an abstract level, and the second post will discuss a concrete implementation of a Javascript logging library that uses the concepts outlined here

When I first started learning to program, I remember using log statements a lot. Almost all introductory programming classes or tutorials demonstrate concepts by using logging, or print(), or some other function to print output to the console.  What quicker way exists to verify your code is doing what you expect it to (or doing anything at all)?  As I learned more about how to program, I stopped littering my code with log statements. I thought logging was a sort of novice thing to do.  Over the past couple years, however, I&amp;#39;ve gone back to my logging roots.

Many of my peers have little to no logging in their codebases, and many - if not most - popular third party libraries are devoid of any logging. Of course there are exceptions, but I&amp;#39;m confused why finding well logged code is not the norm. Why is this? I don&amp;#39;t know, and I&amp;#39;m not going to try to answer it. I can only share what has worked for me, and why I&amp;#39;ve found logging to be incredibly useful.

Why Log?

Liberal use of logging has a plethora of benefits. At the highest level, programs are hard to write and manage because they are complex. The complexity of the problem you&amp;#39;re solving, the building of abstractions, is the hard part. Logging, unit tests, agile programming, test driven development, scrum, continuous integration, third party framework X or Y; or any other tool really does not decreases complexity (the essence of programming). However, logging has helped both myself and my team to manage that complexity more efficiently.  Not only has it helped ease the communication of what we built, logging also provides numerous other beneficial side effects.

What I mean by logging

I&amp;#39;m going to describe a lot of the benefits logging has provided me. However, the positive effects are affected by what is being logged and how often it occurs. I lean towards logging nearly everything. When a function is called, I log that it has been called along with any passed in arguments, the time it was called, and in Javascript, the name of the function that called it. I also log before a function returns, along with the time and any relevant return data. I log when asynchronous calls return. I log when significant logic changes happen. I leave these log messages in the code; I don&amp;#39;t comment them out or remove them (of course, I don&amp;#39;t have the output of all log messages always enabled - I&amp;#39;ll cover how I filter the output of log messages later).

Benefits

This approach might sound ugly and make it seem like the code would be cluttered and unreadable. As crazy as it might sound though, this method allows me to develop code more quickly and effectively than unit tests, can communicate what the code is doing better than comments, and is easier and faster to implement than nearly any other tool or technique I&amp;#39;ve used.

Visibility into code helps manage complexity.

For me, the primary benefit of logging is visibility into what my code is doing. Breakpoints can do this to some extent - but they require manual setting and clearing. Unit tests provide significant advantages as well, but they don&amp;#39;t let you see what your code is doing (important when it&amp;#39;s running in production, but also even a consideration when you&amp;#39;re developing). Sufficient logging allows answering nearly any question about what a program is doing. 

There are two sides I see to increased visibility: the first is visibility into what your code is doing after it&amp;#39;s running and people are using the software you wrote. The second is visibility into your code during development.

Visibility after shipping

Seeing what your code is doing when it&amp;#39;s being used is extremely beneficial if you&amp;#39;re developing any kind of product that changes over time. With logging, if you have an API, you can see what endpoints are being hit and when. With minimal additional sophistication to a logging framework, you could even track the time for every request / response for free. If you write a game, you can track for every player how many units are killed or what the average score is at different points of time in the game. More data allows more questions to be asked and answered. The more you log, the more data you have.

Visibility while developing

Just as useful as visibility into shipped code is visibility into code during development. By logging when a function is called and returned, I get on demand stack traces for free. I don&amp;#39;t have to know a-priori that I want a stack track. If a related and unanticipated edge case bug occurs in some other area of my code when I&amp;#39;m developing, I wouldn&amp;#39;t know to set a breakpoint. With logging, it&amp;#39;s almost as if I set breakpoints everywhere, so I can trace the flow of execution (and a lot of state) for every call after they&amp;#39;ve happened. This, of course, isn&amp;#39;t convenient just for me.

Communication

Logging allows other develops to see exactly code is doing. Unit tests are wonderful for many reasons, but they aren&amp;#39;t great at communicating what code does - only that it does or doesn&amp;#39;t do something. They help to verify code works after changing something, but how effective are they in helping to understand how the code works? With good logging in place, it&amp;#39;s easier for other developers to see exactly what the code is doing. By enabling all logging messages, other developers can follow through the execution of any parts of the program they desire without needing to manually set break points.

Explicit comments.

To me, the ideal commenting system involves small functions with a sentence or two high level description at the top of the function describing its purpose. This, coupled  with well named variables, is expressive (e.g., &amp;quot;var x=4&amp;quot; doesn&amp;#39;t count - this is position, some random variable, what?). Code should describe itself, but those descriptions often aren&amp;#39;t enough to give a high level overview of what&amp;#39;s happening.  In reality, functions often times get to be larger than anticipated, and due to various non-programming constraints (e.g., time), we often don&amp;#39;t have the luxury (or are too lazy) to go back and write proper comments or cleaner code.

Logging helps solve this problem. By sprinkling a function with log messages, you&amp;#39;re implicitly providing a comment about what the should be doing at that point. When the program runs, it explicitly logs what it is doing.  Reading and understanding a function&amp;#39;s behavior is easier when there are comments, but if you can replace a lot of comments with log messages, you get both the benefits of documentation and explicit information when a program runs.

How I log

I&amp;#39;ve found the benefits of logging to be only as good as what and how I&amp;#39;m logging. In the past, I would write a log statement to validate some assumptions, but then remove the log statement afterwards. Nobody wants their code producing irrelevant output. If the log statements were once helpful, however, I think they can continue to be helpful. The trick is to leave the messages in, but have a method of filtering them.

The following spec has worked wonderfully for me. A sample log message might look like: logger.log(&amp;quot;filename:methodname&amp;quot;, &amp;quot;some message: %s&amp;quot;, &amp;quot;replaced string&amp;quot;);

First, we need a way to log messages. The logging library exposes a &amp;quot;log&amp;quot; function which takes in two (and possibly more) parameters:

&lt;ol&gt;&lt;li&gt;group: a {string} specifying the group the log message belongs to. Subgroups are delineated by colons (:)&lt;li&gt;message : a {string} specifying the message to log.  If it contains formatting parameters (e.g., http://nodejs.org/api/util.html#utilutilformat_format ), additional parameters can be passed in to be replaced.&lt;li&gt;n more arguments: objects that will be formatted by the message string

Next, we need a way to filter the messages. The idea is to have a bunch of log messages and leave them in without negatively impacting the application&amp;#39;s output. By specifying the group(s) a log message belongs to, we can filter by group and any level of subgroups. 

One possible implementation, the approach I took, is to provide a logLevel parameter which is takes in an array of strings specifying what to log (e.g., &amp;quot;filename&amp;quot; would log anything that matched &amp;quot;filename&amp;quot;, as well as any subgroups: filename:group1&amp;quot;, &amp;quot;filename:group1:subgroup1&amp;quot;, etc.). Each time log() is called, the passed in log group is checked against the valid log groups.

Conclusion

I believe logging is a terribly underutilized tool that can provide tremendous benefits. Logging provides data about code. This data allows you to gain insights into what your code is doing and how it&amp;#39;s doing it. Along with increased visibility into code, logging enhances communication about it. For my team and me, logging has been incredibly helpful. I think it&amp;#39;s a practice that should be more widely used. In my next post, I&amp;#39;ll discuss the concrete implementation of a logging library I developed based on these concepts that I&amp;#39;ve been using for the past couple years. &lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/foHufLgwwS0" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/1jF1jLmM5fA" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/6xLiMOJYRL8" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/FeMnnn4pUTc" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/programming/how-logging-made-me-a-better-developer</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/foHufLgwwS0/how-logging-made-me-a-better-developer</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/1jF1jLmM5fA/how-logging-made-me-a-better-developer</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/6xLiMOJYRL8/how-logging-made-me-a-better-developer</feedburner:origLink></item>
    
    <item>

        <title>How to Build an Entity Component System Game in Javascript</title>
        <pubDate>Sun, 03 Aug 2014 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/JM1sYZM6wTw/how-to-build-entity-component-system-in-javascript</link>
        <guid isPermaLink="false">http://vasir.net/blog/game-development/how-to-build-entity-component-system-in-javascript</guid>
        <category>Game Development&gt;</category>


        <description>&lt;a href='http://erikhazzard.github.io/RectangleEater/' target='blank'&gt;
    &lt;img style='display: table; margin: 0 auto; width: 440px; height: 400px;' alt='Rectangle Eater' 
        src='https://s3.amazonaws.com/vasir-assets/rectangle-eater/rectangleeater.gif'
    /&gt;

&lt;blockquote class='center font-sans-serif'&gt;
&lt;a href='https://github.com/erikhazzard/RectangleEater'&gt;View the source code or &lt;a href='http://erikhazzard.github.io/RectangleEater/'&gt;play Rectangle Eater


Creating and manipulating abstractions is the essence of programming. There is no &amp;quot;correct&amp;quot; abstraction to solve a problem, but some abstractions are better suited for certain problems than others. Class-based, Object Oriented Programming (OOP), is the most widely used paradigm for organizing programs. There are others. Prototypical based languages, like Javascript, provide a different way of thinking around how to solve problems. Functional programming provides yet another completely different way to think about and solve problems. Programming languages are just one area where a different mindset can help solve problems better.

Even within a class based or prototype based language, many methods exist for structuring code. One approach I&amp;#39;ve grown to love is a more data driven approach to code. One such technique is Entity-Component-System (ECS). While it is a general architecture pattern that could be applied to many domains, the predominant uses of it are in game development. In this post, I&amp;#39;ll cover the basic topics of ECS and we&amp;#39;ll build a basic HTML5 game about eating rectangles - oh-so creatively called &lt;a href='http://erikhazzard.github.io/RectangleEater/' target='blank'&gt;&amp;quot;Rectangle Eater&amp;quot;.



Entity-Component-System

Discovering Entity Component System (ECS) was an &amp;quot;ah-hah&amp;quot; moment for me. With ECS, entities are just collections of components; just a collection of data.

&lt;ul&gt;&lt;li&gt;Entity: An entity is just an ID&lt;li&gt;Component: Components are just data.&lt;li&gt;System: Logic that runs on every entity that has a component of the system. For example, a &amp;quot;Renderer&amp;quot; system would draw all entities that have a &amp;quot;appearance&amp;quot; component.

With this approach, you avoid having to create gnarly inheritance chains. With this approach, for example, a half-orc isn&amp;#39;t some amalgamation of a human class and an orc class (which might inherit from a Monster class). With this approach, a half-orc is just a grouping of data.

An entity is just a like a record in a database. The components are the actual data. Here&amp;#39;s a high level example of what the data might look like for entities, shown by ID and components. The beauty of this system is that you can dynamically build entities - an entity can have whatever components (data) you want.



|         | component-health  | component-position |  component-appearance |
|---------|-------------------|--------------------|-----------------------|
|entity1  | 100               | {x: 0, y: 0}       | {color: green}        |
|entity2  |                   | {x: 0, y: 0}       |                       |
|entity3  |                   |                    | {color: blue}         |



Dynamic Data Driven Design

Everything is tagged as an entity. A bullet, for instance, might just have a &amp;quot;physics&amp;quot; and &amp;quot;appearance&amp;quot; component.  Entity Component System is data driven. This approach allows greater flexibility and more expression. One benefit is the ability to dynamically add and remove components, even at run time. You could dynamically remove the appearance component to make invisible bullets, or add a &amp;quot;playerControllable&amp;quot; component to allow the bullet to be controlled by the player. No new classes required. 

This can potentially be a problem as systems have to iterate through all entities. Of course, it&amp;#39;s not terribly difficult to optimize and structure code so not all entities are hit each iteration if you have too many, but it&amp;#39;s helpful to keep this constraint in mind, especially for browser based games.

Assemblages

One benefit of a Class based approach is the ability to easily create multiple objects of the same type. If I want one hundred orcs, I can just create a hundred orc objects and know what properties they&amp;#39;ll all have. This can be accomplished with ECS through an abstraction called an assemblage, which is just a way to easily create entities that have some grouping of components.  For instance, a Human assemblage might contain &amp;quot;position&amp;quot;, &amp;quot;name&amp;quot;, &amp;quot;health&amp;quot;, and &amp;quot;appearance&amp;quot; components. A Sword assemblage might just have &amp;quot;appearance&amp;quot; and &amp;quot;name&amp;quot;.

One benefit this provides over normal Class inheritance is the ability to easily add on (or remove) components from assemblages. Since it&amp;#39;s data driven, you can manipulate and change them programmatically based on whatever parameters you desire. Maybe you want to create a ton of humans but have some of them be invisible - no need for a new class, just remove the &amp;quot;appearance&amp;quot; component from that entity.

Code

This is not an attempt to build out a robust ECS library. This is designed to be an overview of Entity Component System implemented in Javascript. It&amp;#39;s not the best or most optimized way to do it; but it can provide a foundation for a concrete understanding of how everything fits together. 

All code can be &lt;a href='https://github.com/erikhazzard/RectangleEater/blob/master/scripts/game.js'&gt;found on github.


Entity

The abstraction is that an entity is just an ID; a container of components. Let&amp;#39;s start by creating a function which we can create entities from. Each entity will have just an id and components property.  (Note: the follow expects a global ECS object to exist, which looks like var ECS = {};)

ECS.Entity = function Entity(){
    // Generate a pseudo random ID
    this.id = (+new Date()).toString(16) + 
        (Math.random() * 100000000 | 0).toString(16) +
        ECS.Entity.prototype._count;

    // increment counter
    ECS.Entity.prototype._count++;

    // The component data will live in this object
    this.components = {};

    return this;
};
// keep track of entities created
ECS.Entity.prototype._count = 0;

ECS.Entity.prototype.addComponent = function addComponent ( component ){
    // Add component data to the entity
    // NOTE: The component must have a name property (which is defined as 
    // a prototype protoype of a component function)
    this.components[component.name] = component;
    return this;
};
ECS.Entity.prototype.removeComponent = function removeComponent ( componentName ){
    // Remove component data by removing the reference to it.
    // Allows either a component function or a string of a component name to be
    // passed in
    var name = componentName; // assume a string was passed in

    if(typeof componentName === &amp;#39;function&amp;#39;){ 
        // get the name from the prototype of the passed component function
        name = componentName.prototype.name;
    }

    // Remove component data by removing the reference to it
    delete this.components[name];
    return this;
};

ECS.Entity.prototype.print = function print () {
    // Function to print / log information about the entity
    console.log(JSON.stringify(this, null, 4));
    return this;
};

&lt;a href='https://github.com/erikhazzard/RectangleEater/blob/master/scripts/Entity.js'&gt;View Source

To create a new entity, we&amp;#39;d simply call it like: var entity = new ECS.Entity();.

There&amp;#39;s not a lot going on in the code here. First, in the function itself, we generate an ID based on the current time, a call to Math.random(), and a counter based on the total number of created entities. This ensures we get a unique ID for each entity. We increment the counter (prototype properties are shared across all object instances; sort of similar to a class variable). Then, we create an empty object to stick components (the data) in. 

We expose an addComponent and removeComponent function on the prototype (again, single functions in memory shared across all object instances). Each take in a component object and add or remove the passed in component from the Entity. Lastly, the print method simply JSON-ifies the entity, providing all the data. We could use this to dump out and reload data later (e.g., saving).

So, at the core, an Entity is little more than an object with some data properties. We&amp;#39;ll cover how to create multiple Entities soon, and where assemblages fit in.

Component

Here&amp;#39;s where the data part of data driven programming kicks in. I&amp;#39;ve structured components similarly to entities; for example:

ECS.Components.Health = function ComponentHealth ( value ){
    value = value || 20;
    this.value = value;

    return this;
};
ECS.Components.Health.prototype.name = &amp;#39;health&amp;#39;;

To get a Health component, you&amp;#39;d simply create it with new ECS.Components.Health( VALUE ) where VALUE is an optional starting value (20 if nothing is passed in). Importantly, there is a name property on the prototype which tells the Entity what to call the component. For example, to create an entity then give it a health component:

var entity = new ECS.Entity();
entity.addComponent( new ECS.Components.Health() );

That&amp;#39;s all that is required to add a component to an entity. If we printed the entity out now (entity.print();), we&amp;#39;d see something like:

{
    &amp;quot;id&amp;quot;: &amp;quot;1479f3d15bd4bf98f938300430178&amp;quot;,
    &amp;quot;components&amp;quot;: {
        &amp;quot;health&amp;quot;: {
            &amp;quot;value&amp;quot;: 20
        }
    }
} 

That&amp;#39;s it - it&amp;#39;s just data! We could change the entity&amp;#39;s health by modifying it directly, e.g., entity.components.health.value = 40; We can have any kind of data nesting we want; for example, if we created a position component with x and y data values, we&amp;#39;d get as output:


{
    &amp;quot;id&amp;quot;: &amp;quot;1479f3d15bd4bf98f938300430178&amp;quot;,
    &amp;quot;components&amp;quot;: {
        &amp;quot;health&amp;quot;: {
            &amp;quot;value&amp;quot;: 20
        },
        &amp;quot;position&amp;quot;: {
            &amp;quot;x&amp;quot;: 426,
            &amp;quot;y&amp;quot;: 98
        }
    }
} 

To keep this post manageable, &lt;a href='https://github.com/erikhazzard/RectangleEater/blob/master/scripts/Components.js'&gt;here&amp;#39;s all the code for all these components used in the game

Since components are just data, that don&amp;#39;t have any logic. (Depending on what works for you, you could add some prototype functions to components that would aide in data calculations, but it&amp;#39;s helpful to view components just as data). So we have a bunch of data now, but to do anything interesting we need to run operations on it. That&amp;#39;s where Systems come in.

System

Systems run your game&amp;#39;s logic. They take in entities and run operations on entities that have specific components the system requires. This way of thinking is a bit inverted from typical Class based programming.

In Class based programming, to model a cat, a Cat Class would exist. You&amp;#39;d create cat objects and to get the cat to meow, you&amp;#39;d call the speak() method. The functionality lives inside of the object. The object is not just data, but also functionality.

With ECS, to model a Cat you&amp;#39;d first create an entity. Then, you&amp;#39;d add some components that cats have (size, name, etc.). If you wanted the entity to be able to meow, maybe you&amp;#39;d give it a speak component with a value of &amp;quot;meow&amp;quot;. The distinction here though is that this is just data - maybe it looks like:

{
    &amp;quot;id&amp;quot;: &amp;quot;f279f3d85bd4bf98f938300430178&amp;quot;,
    &amp;quot;components&amp;quot;: {
        &amp;quot;speak&amp;quot;: {
            &amp;quot;sound&amp;quot;: &amp;quot;meeeooowww&amp;quot;
        }
    }
}

The entity can do nothing by itself. So, to get a &amp;quot;cat&amp;quot; entity to speak, you&amp;#39;d use a speak System. (Note: the component name and system name do not have to be 1:1, this is just an example. Most systems use multiple different components). The system would look for all entities that have a speak component, then run some logic - plugging in the entity&amp;#39;s data.

The functionality happens in Systems, not on the objects themselves. You&amp;#39;ll have many different systems that are tailored for your game. Systems are where your main game logic lives. For our rectangle eating game, we only need a few systems: collision, decay, render, and userInput.

The way I&amp;#39;ve sturctured systems is to take in all entities (here, the entities are an object of key:value pairs of entityId: entityObject). Let&amp;#39;s take a look at a snippet of the render system. Note, the systems are just functions that take in entities.

ECS.systems.render = function systemRender ( entities ) {
    // Here, we&amp;#39;ve implemented systems as functions which take in an array of
    // entities. An optimization would be to have some layer which only 
    // feeds in relevant entities to the system, but for demo purposes we&amp;#39;ll
    // assume all entities are passed in and iterate over them.

    // This happens each tick, so we need to clear out the previous rendered
    // state
    clearCanvas();

    var curEntity, fillStyle; 

    // iterate over all entities
    for( var entityId in entities ){
        curEntity = entities[entityId];

        // Only run logic if entity has relevant components
        //
        // For rendering, we need appearance and position. Your own render 
        // system would use whatever other components specific for your game
        if( curEntity.components.appearance &amp;amp;&amp;amp; curEntity.components.position ){

            // Build up the fill style based on the entity&amp;#39;s color data
            fillStyle = &amp;#39;rgba(&amp;#39; + [
                curEntity.components.appearance.colors.r,
                curEntity.components.appearance.colors.g,
                curEntity.components.appearance.colors.b
            ];

            if(!curEntity.components.collision){
                // If the entity does not have a collision component, give it 
                // some transparency
                fillStyle += &amp;#39;,0.1)&amp;#39;;
            } else {
                // Has a collision component
                fillStyle += &amp;#39;,1)&amp;#39;;
            }

            ECS.context.fillStyle = fillStyle;

            // Color big squares differently
            if(!curEntity.components.playerControlled &amp;amp;&amp;amp;
            curEntity.components.appearance.size &amp;gt; 12){
                ECS.context.fillStyle = &amp;#39;rgba(0,0,0,0.8)&amp;#39;;
            }

            // draw a little black line around every rect
            ECS.context.strokeStyle = &amp;#39;rgba(0,0,0,1)&amp;#39;;

            // draw the rect
            ECS.context.fillRect( 
                curEntity.components.position.x - curEntity.components.appearance.size,
                curEntity.components.position.y - curEntity.components.appearance.size,
                curEntity.components.appearance.size * 2,
                curEntity.components.appearance.size * 2
            );
            // stroke it
            ECS.context.strokeRect(
                curEntity.components.position.x - curEntity.components.appearance.size,
                curEntity.components.position.y - curEntity.components.appearance.size,
                curEntity.components.appearance.size * 2,
                curEntity.components.appearance.size * 2
            );
        }
    }
};

The logic here is simple. First, we clear the canvas before doing anything. Then, we iterate over all entities. This system renders entities, but we only care about entities that have an appearance and position. In our game, all entities have these components - but if we wanted to create invisible rectangles that the player could interact with, all we&amp;#39;d have to do is remove the appearance component. So, after we&amp;#39;ve found the entities which contain the relevant data for the system, we can do operations on them.

In this system, we just render the entity based on the colors properties in the appearance component. One benefit too is that we don&amp;#39;t have to set all the appearance properties here - we might set some in the collision system, or in the health system, or in the decay system; we have complete flexibility over what roles we want to assign to each system. Because the systems are driven by data, we don&amp;#39;t have to limit our thinking to just &amp;quot;methods on classes and objects.&amp;quot; We can have as many systems as want, as complex or simple as we want that target whatever kinds of entities we want.

Overview of Rectangle Eater&amp;#39;s systems:

&lt;ul&gt;&lt;li&gt;collision: Handles collision, updating the data for health on collision, and removing / adding new entities (rectangles). Bulk of the game&amp;#39;s logic.&lt;li&gt;decay: Handles rectangles getting small and losing health. Any entity with a health component (e.g., most rectangles and the player controlled rectangle) will be affected. This is where a lot of the &amp;quot;fun&amp;quot; configuration happens. If the rectangle decays and goes away too fast then the game is too hard - if it&amp;#39;s too slow, it&amp;#39;s not fun.&lt;li&gt;render: Handles rendering entities based on their appearance component.&lt;li&gt;userInput: Allows the player to move around entities that have a PlayerControlled component.

In the &lt;a href='https://github.com/erikhazzard/RectangleEater/blob/master/scripts/systems/collision.js'&gt;collision system of our game, we check for collisions between the user controlled entity (specified by a PlayerControlled component and handled via the userInput system) and all other entities with a collision component. If a collision occurs, we update the entity&amp;#39;s health (via the health component), remove the collided entity immediately (the systems are data driven - there&amp;#39;s no problem dynamically adding or removing entities on a per system level), then finally randomly add some new rectangles (most of these will decay over time, and when they get smaller they give you more health when you collide with them - something else we check for in this collision system).

Like in a normal game loop, the order which the systems gets called is also important. If your render before the decay system is called, for example, you&amp;#39;ll always be a tick behind.

Gluing it all together

The final step involves connecting all the pieces together. For our game, we just need to do a few things:

&lt;ol&gt;&lt;li&gt;Setup the initial entities&lt;li&gt;Setup the order of the systems which we want to use&lt;li&gt;Setup a game loop, which calls each system and passed in all the entities&lt;li&gt;Setup a lose condition

1. Let&amp;#39;s take a look at the code for setting up the initial entities and the player entity:

var self = this;
var entities = {}; // object containing { id: entity  }
var entity;

// Create a bunch of random entities
for(var i=0; i &amp;lt; 20; i++){
    entity = new ECS.Entity();
    entity.addComponent( new ECS.Components.Appearance());
    entity.addComponent( new ECS.Components.Position());

    // % chance for decaying rects
    if(Math.random() &amp;lt; 0.8){
        entity.addComponent( new ECS.Components.Health() );
    }

    // NOTE: If we wanted some rects to not have collision, we could set it
    // here. Could provide other gameplay mechanics perhaps?
    entity.addComponent( new ECS.Components.Collision());

    entities[entity.id] = entity;
}

// PLAYER entity
// Make the last entity the &amp;quot;PC&amp;quot; entity - it must be player controlled,
// have health and collision components
entity = new ECS.Entity();
entity.addComponent( new ECS.Components.Appearance());
entity.addComponent( new ECS.Components.Position());
entity.addComponent( new ECS.Components.Collision() );
entity.addComponent( new ECS.Components.PlayerControlled() );
entity.addComponent( new ECS.Components.Health() );

// we can also edit any component, as it&amp;#39;s just data
entity.components.appearance.colors.g = 255;
entities[entity.id] = entity;

// store reference to entities
ECS.entities = entities;

Note how we can modify any of the component data directly. It&amp;#39;s all data that can be manipulated however and whenever you want! The player entity step could be even further simplified by using assemblages, which are basically entity templates. For instance (&lt;a href='https://github.com/erikhazzard/RectangleEater/blob/master/scripts/Assemblages.js'&gt;using our assemblages):

entity = new ECS.Assemblages.CollisionRect();
entity.addComponent( new ECS.Components.Health());
entity.addComponent( new ECS.Components.PlayerControlled() );

2. Next, we setup the order of the systems:

// Setup systems
// Setup the array of systems. The order of the systems is likely critical, 
// so ensure the systems are iterated in the right order
var systems = [
    ECS.systems.userInput,
    ECS.systems.collision,
    ECS.systems.decay, 
    ECS.systems.render
];

3. Then, a simple game loop

// Game loop
function gameLoop (){
    // Simple game loop
    for(var i=0,len=systems.length; i &amp;lt; len; i++){
        // Call the system and pass in entities
        // NOTE: One optimal solution would be to only pass in entities
        // that have the relevant components for the system, instead of 
        // forcing the system to iterate over all entities
        systems[i](ECS.entities);
    }

    // Run through the systems. 
    // continue the loop
    if(self._running !== false){
        requestAnimationFrame(gameLoop);
    }
}
// Kick off the game loop
requestAnimationFrame(gameLoop);

4. Finally, a lose condition

// Lose condition
this._running = true; // is the game going?
this.endGame = function endGame(){ 
    self._running = false;
    document.getElementById(&amp;#39;final-score&amp;#39;).innerHTML = +(ECS.$score.innerHTML);
    document.getElementById(&amp;#39;game-over&amp;#39;).className = &amp;#39;&amp;#39;;

    // set a small timeout to make sure we set the background
    setTimeout(function(){
        document.getElementById(&amp;#39;game-canvas&amp;#39;).className = &amp;#39;game-over&amp;#39;;
    }, 100);
};

&lt;a href='https://github.com/erikhazzard/RectangleEater/blob/master/scripts/game.js'&gt;View on github

Now, we can kick off the game (provided &lt;a href='https://github.com/erikhazzard/RectangleEater/blob/master/index.html'&gt;the html has been set up)!


    &lt;a href='http://erikhazzard.github.io/RectangleEater/' target='blank'&gt;
        Play Rectangle Eater
    &lt;img style='display: table; margin: 0 auto; width: 400px; height: 400px;' alt='Rectangle Eater' src='http://s3.amazonaws.com/vasir-assets/rectangle-eater/rectangleeater.gif'/&gt;


Conclusion

Programming is a complex endeavor by nature. We program in abstractions, and different frameworks for thinking can make certain problems easier to solve. Data driven programming is one framework for thinking of how to write programs. It&amp;#39;s not the best fit for all problems, but can make some problems much easier to solve and understand. Thinking of code as data is a powerful concept. Entity Component System is a pattern that fits game development well. Try taking the passenger seat. Try letting data drive your code.

&lt;a href='https://github.com/erikhazzard/RectangleEater'&gt;View the source code or &lt;a href='http://erikhazzard.github.io/RectangleEater/'&gt;play Rectangle Eater



&lt;link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/default.min.css"&gt;

hljs.initHighlightingOnLoad();&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/ILQi8jNWDa4" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/4H073m8cdSE" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/lPCYAGVtII0" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/JM1sYZM6wTw" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/game-development/how-to-build-entity-component-system-in-javascript</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/ILQi8jNWDa4/how-to-build-entity-component-system-in-javascript</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/4H073m8cdSE/how-to-build-entity-component-system-in-javascript</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/lPCYAGVtII0/how-to-build-entity-component-system-in-javascript</feedburner:origLink></item>
    
    <item>

        <title>Misleading Users to Create Better Experiences</title>
        <pubDate>Sun, 27 Jul 2014 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/K3LmIKWWC-4/misleading-users-to-create-better-experiences</link>
        <guid isPermaLink="false">http://vasir.net/blog/design/misleading-users-to-create-better-experiences</guid>
        <category>Design&gt;</category>


        <description>When trying to craft an experience, accuracy isn&amp;#39;t important. It can even get in the way. Often, a better overall experience can be created by misleading users. The way information is presented shapes what a user experiences, and the end user experience is more important than what the system is actually doing. Sometimes, it&amp;#39;s ok to force the users to wait in order to teach them something.

If your web application does some processing after receiving a request from the user, an obvious thing to do is to show a loading or progress bar. The obvious solution is to show a bar that is based on the actual time it takes to process the request. Sometimes, this is ok. Other times, this assumption can lead to a worse user experience.  I learned from a previous project that this can be more than just be a mistake. This assumption can damage the perception users have of the application. When creating an experience, everything must be analyzed and tailored for the app&amp;#39;s specific use case.

When I worked on Outline, we ran economic microsimulations to simulate public policy. In other words, we predicted financial impacts of changes to government taxes or spending. By running thousands of calculations for each person in a state, we were able to give a pretty good estimate of how you would be impacted by a cut or an increase to income tax. For instance, California has roughly 38 million residents, and a microsimuation would run thousands of calculations for each person. As you can imagine, this isn&amp;#39;t a trivial calculation. The other systems doing what we did required expert knowledge and would take on the order of hours, or even days for some expensive calculations. We did these these calculations on the fly - whenever you dragged a slider.

This is what our final version looked like. (&lt;a href='/projects/outline' target='_blank'&gt;Read the full project case study here).

&lt;a target='_blank' href='/static/img/posts/misleading-users/outlineprogress.gif'&gt;&lt;img src='/static/img/posts/misleading-users/outlineprogress.png' /&gt;

The progress bar is a lie. 

As soon as you dragged a slider, we ran simulations based on your inputs, in real time, on the backend. This all took under one tenth of a second. Less than 100ms. This was how long the slowest simulations took to run. For a quick technical overview, these calculations can largely run in parallel, so I was able to use a series of GPUs (video cards) to split up the data and run the calculations. This speed came at a cost.

Initially, we thought real time updates produced the best experience. Feedback should always be instant, but not all feedback is created equally. On a technical level it was impressive that we could run these simulations without the user noticing. On a user experience level, it was terrible. For our application, it was critical the users knew we were running a simulation. Even when we showed the product to technically-versed people, the reaction was always along the lines of &amp;quot;this is a neat demo - how long will it take to actually implement the simulation?&amp;quot; Maybe it should have been obvious, but we spent a lot of time pursuing near real time microsimulations without focusing as much on the user experience. 

Next, we put up a loading bar, but we had the same problem. Loading happened instantly, so the bar would only be visible for a split second. So, the loading bar was faked. Users had to click &amp;quot;Calculate Impact&amp;quot; to kick off the simulation. Even though everything was done by the time the user actually saw the loading bar, we enforced a few second manual delay. This created a much better experience. Not only that, it taught the user what we were doing. Anytime time a user was forced to wait, it was an opportunity to teach them how the system worked.

When the user sees a progress bar and numbers that go from &amp;quot;0 of 6 million&amp;quot; to &amp;quot;6 million of 6 million&amp;quot;, they immediately understand that we&amp;#39;re doing a calculation on every person in the state of Massachusetts. It&amp;#39;s a learning experience, not just an arbitrary wait time. Not everyone understands what the system is doing, but most people get it when we show them numbers whizzing by. It&amp;#39;s fast enough that it doesn&amp;#39;t feel painful waiting for it to calculate; but slow enough to allow you to understand it&amp;#39;s actually doing work. Another benefit is that we have no variance in the loading time. It always takes the same amount of time to see the results, so users develop an expectation of loading time that we always uphold.

Sometimes, faking progress is not just beneficial: faking can be critical. Any time the user has to wait for something, it is an opportunity to create an experience that teaches the user about the system. Sometimes, as strange as it seemed to me initially, the best option is to force a loading bar on the user. The user should never feel like your application is slow. But sometimes it&amp;#39;s okay to make them wait in order to learn.&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/YoQodRT3ELo" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/qEXjPq2BUJs" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/CYaJVO2jkxI" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/K3LmIKWWC-4" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/design/misleading-users-to-create-better-experiences</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/YoQodRT3ELo/misleading-users-to-create-better-experiences</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/qEXjPq2BUJs/misleading-users-to-create-better-experiences</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/CYaJVO2jkxI/misleading-users-to-create-better-experiences</feedburner:origLink></item>
    
    <item>

        <title>Enhancing Data Visualization with SVG Filters</title>
        <pubDate>Thu, 24 Jul 2014 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/5Xlq_On7GWU/enhancing-data-visualization-with-svg-filters</link>
        <guid isPermaLink="false">http://vasir.net/blog/data-visualization/enhancing-data-visualization-with-svg-filters</guid>
        <category>Data Visualization&gt;</category>


        <description>&lt;iframe 
        src='https://s3.amazonaws.com/vasir-assets/svg-filters/blur-mouseover-effect.html'
        class='center'
        scrolling='no'
        style='background-color: #cdcdcd;' 
        seamless='seamless'
        frameborder=0 width=450 height=310&gt;
    
    
        Mouseover image.
        &lt;a href='http://tributary.io/inlet/095cf3523279341f514e'
            target='blank'&gt;
            View Source
        
    




    SVG filters are a powerful and underutilized tool. Filters are a post processing step that allow you to create interesting effects by adding pixel-based effects. They can be chained together, manipulated on the fly, and applied to different elements to create powerful visual experiences. Pretty graphics aren't the only benefit to filters. Not only can filters enhance the visualization's story; filters can be used as another dimension to encode data.



How Filters Work


At a high level, filters take some input source and apply an effect. The input source can be a vector / graphic / text / etc. or another filter. They produce an output result which is then rendered (or used as the input to another filter).  Filters can work on an &lt;a href='http://www.w3.org/TR/SVG/intro.html#TermGraphicsElement' target='blank'&gt;individual element (rect, circle, text, etc.) or a &lt;a href='http://www.w3.org/TR/SVG/intro.html#TermContainerElement' target='blank'&gt;container element (a group, pattern, mask, etc.).



SVG provides numerous &lt;a href='http://en.wikipedia.org/wiki/SVG_filter_effects' target='blank'&gt;filter primitives, such as blur and turbulence, which  can be combined and merged togeter, allowing the creation of some really powerful and cool effects.  The &lt;a href='http://www.w3.org/TR/SVG/filters.html#Introduction' target='blank'&gt;W3 SVG Filter Spec goes into great technical detail about how filters work. Here are some examples of what can be created using filters:



    &lt;img
        src='https://s3.amazonaws.com/vasir-assets/svg-filters/game-filters.jpg'
        class='center' 
        width=380
        height=208 /&gt;
    
        WIP screenshot from my HTML game using filters to show explored area
    
 


 Filters can be used to create a variety of effects. Here are some examples which all use a single brown circle as their source image:

    &lt;a href='https://dl.dropboxusercontent.com/u/55434504/SVG_Gallery.html' target='blank'&gt;
        &lt;img
            src='https://s3.amazonaws.com/vasir-assets/svg-filters/filters.png'
            class='center' 
            width=400
            height=268 /&gt;
        
        Various filter effects. View source
        
    
 




Using Filters to Enhance Story-Telling


    Not all visualizations can benefit from the additional visual artifacts filters can add. In fact, they often will lessen the impact of a visualization. For many charts (perhaps even the majority of them), adding '&lt;a href='http://en.wikipedia.org/wiki/Chartjunk' target='blank'&gt;chart junk' can detract from the story a visualization tells. 

    

However, visualizations are not always presented in a vacuum. Often, a chart is embedded in an article or included in a presentation. Even when a visualization stands alone, it is used to tell a story. Form and function cannot be separated. The presentation of the chart, regardless of the accuracry or rigour that went into the research behind it, shapes the way a reader intreprets it. Choosing the aestethic aspects (or even the right visualization type) is difficult, and sometimes the line between data visualization and data art is thin.



Decorating a chart can often aide in the story-telling experience of the visualization because, at their core, visulizations tell a story about data. Of course, one must be very careful not to occlude the data with filters, or to obstruct the actual chart. Depending on the audience, the story, and the visualization's goal, adding filters (or chart junk) can create a more powerful experience. 



For instance, take this visualization of player data in &lt;a href='/projects/guild-wars-2-data-visualization' target='blank'&gt;Guild Wars 2, published a couple of years ago:



    &lt;a href='http://guildwars2viz.com/static/img/viz/gw2_data.jpg' target='blank'&gt;
        
        
        &lt;img
            src='http://guildwars2viz.com/static/img/viz/gw2_data.jpg'
            class='center' 
            width=400
            height=268 /&gt;
    
 


It's a basic chart that shows the total population of character types (races / classes / gender / tradeskills). The visualizations are straightforward, and while it isn't a shining example of data visualization (it does not include basic things like axes and numbers, annontations, information on if the scales are shared, etc.), it's not inherently bad. The purpose of the visualization was to communicate some data to players while representing the Guild Wars brand (hence the colors and symbols). However, for me, it does a poor job of that. 


In response, using the same data, I created a visualization that made heavy use of filters to fit in more with the theme of the game and the goal of the visualization - to communicate in-game statistics while maintaining the 'feel' of the game. The visualization itself, of course, is not 'correct' in some ways; however, it was very successful in reaching a large number of players and communicating data. Sometimes, making sacrifices of data visualization 'purity' can better allow people to experience the story the visualization is telling - and be more engaged and interested, ultimately understanding the data better than a non-decorated chart could.




    &lt;a href='/projects/guild-wars-2-data-visualization' target='blank'&gt;
        &lt;img
            src='https://s3.amazonaws.com/vasir-assets/svg-filters/gw2viz.png'
            class='center' 
            width=600
            height=283 /&gt;
        
        Filters can turn simple donut charts into data art. View source
        
    



This isn't the best example of how filters can be used either (and it can be fairly slow, even in more beefy machines) - but it does illustrate how filters can have a powerful impact on the experience of consuming data





    Aesthetic artifacts aren't the only value filters are able to provide. Filters can be useful for reasons apart from visual enhancements. Just as position on a y axis can encode a dimension of data, filters can be used to encode other dimensions of data, such as ambiguity.


Encoding Data with Filters

    How do you show ambiguous or nebulous data? What if you're unsure about the error range of the data (but you have a decent idea). Error bars are a common solution, but they're not the best fit for all visualizations.



    Most people are familiar with basic data visualization primitives: position, size, color, shape, etc. Different primitives can encode different dimensions of the data. For instance, imagine a simple bar chart.


    Here's some help: 
    &lt;img
        src='https://s3.amazonaws.com/vasir-assets/svg-filters/barchart.png'
        class='center' width=190 height=209 /&gt;



You can use various data visualization primitives to show different properties of the data. In this bar chart, category (A, B, C, ...) is encoded in the x dimension, and value (0 to 40) is encoded in the y dimension. This is pretty standard. However, it is possible to encode more information in this chart. Each bar could be color-based on another dimension of the data. The bars could also have different patterns (along with color) to show yet another dimension of the data. Color and patterns could be used to show either categorial data (e.g., use red/green/blue/etc to show different types of a value; e.g., 'Monday' or 'Wednesday'), or noncategorical / linear (e.g., use different shades of a color to show different degrees or ranges of a value; e.g, 0-10). The bars could be ovals, or have rounded corners, to encode another dimension (but I wouldn't recommend this madness).



One dimension that is sometimes overlooked is uncertainity. Many excellent visualization types exist to show ranges of error, such as error bars:

    &lt;img
        src='https://s3.amazonaws.com/vasir-assets/svg-filters/error-viz.jpg'
        class='center' width=440 height=150 /&gt;



    However, I think (depending on the application, audience, and data), SVG filters can be used to show ambiguity in an easier to comprehend way.  Imagine encoding uncertainity as the strength of a blur filter:


    &lt;iframe 
        src='https://s3.amazonaws.com/vasir-assets/svg-filters/bar-blur.html'
        class='center'
        scrolling='no'
        style='background-color: #cdcdcd;' 
        seamless='seamless'
        frameborder=0 width=480 height=280&gt;
    
    
        &lt;a href='http://bl.ocks.org/enoex/dc6f073143be30cf5ccb'
            target='blank'&gt;
            View Source
        
    



    Or, if a line chart visualizes some sort of uncertain data, showing wiggly lines could better communicate the uncertainity - as opposed to a title (that few will read anyway) that simply says 'This data contains some degree of uncertainity.' Simply presenting a normal line chart implies no ambiguity in the data: it's a sharp, crisp line chart like all other scientific charts, so of course it's right! Wiggly lines both communicate a more coherrent story telling experience and communicate the data's ambiguity.


    &lt;iframe 
        src='https://s3.amazonaws.com/vasir-assets/svg-filters/line-chart-wiggle.html'
        class='center'
        scrolling='no'
        style='background-color: #cdcdcd;' 
        seamless='seamless'
        frameborder=0 width=480 height=420&gt;
    
    
        &lt;a href='http://bl.ocks.org/enoex/d52decb877ed83e38eb8'
            target='blank'&gt;
            View Source
        
    





Going Foward


Keep in mind that not all browsers support SVG filters. If your goal is to reach as many people as possible, filters may not be the best option. However, if you are able to restrict your content to modern browers, filters can be a powerful tool.



Creating filters is a difficult task. It involves thinking about how filters can combine with each other, and is not very inuitive (for me, at least). &lt;a href='http://www.inkscape.org/en/' target='blank'&gt;Inkscape provides some great tools for visualizing filter creation and the output of created filters. Because Inkscape outputs SVG, you can directly use the filters created in Inkscape in the browser. Also, &lt;a href='https://github.com/visfest/notes/blob/master/Session3-Area5-SVGFilters.md' target='blank'&gt;here are some notes on a talk I gave about SVG filters at the D3 unconference.




SVG filters can be used also in CSS3 - allowing any element to receive any filter. Performance considerations aside, this is a powerful feature that is not commonly used (and not supported by all browsers). What excites me is not only seeing more widespread use of filters, but the &lt;a href='http://www.adobe.com/devnet/html5/articles/css-shaders.html' target='blank'&gt;CSS Shader spec proposed by Adobe. One must be careful when using filters (or using any kind of decoration) in data visualizations. In most cases, filters can be just chart junk and not add to the visualization in any way. However, depending on the goal and when used properly and carefully, filters (and possibly shaders) can enhance a visualization's story-telling power.






&lt;link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/default.min.css"&gt;

.hljs{display:block;overflow-x:auto;padding:0.5em;background:#fdf6e3;color:#657b83}.hljs-comment,.hljs-quote{color:#93a1a1}.hljs-keyword,.hljs-selector-tag,.hljs-addition{color:#859900}.hljs-number,.hljs-string,.hljs-meta .hljs-meta-string,.hljs-literal,.hljs-doctag,.hljs-regexp{color:#2aa198}.hljs-title,.hljs-section,.hljs-name,.hljs-selector-id,.hljs-selector-class{color:#268bd2}.hljs-attribute,.hljs-attr,.hljs-variable,.hljs-template-variable,.hljs-class .hljs-title,.hljs-type{color:#b58900}.hljs-symbol,.hljs-bullet,.hljs-subst,.hljs-meta,.hljs-meta .hljs-keyword,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-link{color:#cb4b16}.hljs-built_in,.hljs-deletion{color:#dc322f}.hljs-formula{background:#eee8d5}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}


hljs.initHighlightingOnLoad();&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/TU1UEyPO7xI" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/8L942-TC4vs" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/rvWAMRTIj5o" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/5Xlq_On7GWU" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/data-visualization/enhancing-data-visualization-with-svg-filters</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/TU1UEyPO7xI/enhancing-data-visualization-with-svg-filters</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/8L942-TC4vs/enhancing-data-visualization-with-svg-filters</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/rvWAMRTIj5o/enhancing-data-visualization-with-svg-filters</feedburner:origLink></item>
    
    <item>

        <title>Visualizing Nebulous Data</title>
        <pubDate>Sun, 20 Jul 2014 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/Lrx2bc4pIys/visualizing-nebulous-data</link>
        <guid isPermaLink="false">http://vasir.net/blog/data-visualization/visualizing-nebulous-data</guid>
        <category>Data Visualization&gt;</category>


        <description>The best data visualization choice is not always the "correct" one.  The most accurate representation of data is not inherently the best method of visualization.  How well the visualization represents the data is probably the most important facet to consider when designing a visualization, but it’s certainly not the only one. It’s about what's best for the data and what experience you’re trying to create.
Daily temperature measurements are objective. Either it was 76 degrees or it was not. You can graph the daily temperatures on a line chart and get a clear understanding of objective data.
&lt;img alt="Temperatures" src="/static/img/posts/nebulous-data/line-chart.png"&gt;
It isn’t always this simple. Sometimes, the data itself is more subjective or nebulous. Fuzzy. Sometimes, the story you’re telling can have multiple and equally valid interpretations.  For instance, personality data is a bit nebulous. It’s an attempt to measure and classify irrational human behavior; behavior which is affected by mood, emotions, or manipulation. Using a precise representation of “inaccurate” data is, to me, a bit like using a 3D pie chart to represent objective data (e.g., % of votes for a presidential candidate). When data is nebulous, a more nebulous data visualization choice is a better fit.
Five Labs uses Radar Charts (also known as Spider Charts). They're not the pinnacle of data viz. The first (among many) problems is that Radar Charts are in Polar Coordinates. (Don't worry - it's just a fancy way to say it's a circle.) Humans are bad at processing information encoded in circles. We see in x and y; length and width. We can’t easily process angles or radians.  
Cartesian vs. Polar Coordinates (Bar vs. Pie Charts)
Below is a pie chart. Don’t spend more than a couple seconds looking at it. By just glancing at it, can you tell how different "B" and "D" are? Are "A" and "C" equal?
&lt;img alt="Pie Chart" src="/static/img/posts/nebulous-data/pie-chart.png"&gt;
With pie charts, you get a fuzzy understanding of the data.  Even if you stare at it for a while, there's a good chance you can't tell that A is bigger than C. At least, I couldn’t.  When you look at a pie chart, your brain measures the angles of the slices. You can also try to measure the total area contained by each slice, but that’s even trickier. Donut charts (or ring charts - pie charts with a hole) suffer from this at an even greater level since it’s harder to perceive the angles. Perception is fundamental in data viz. If you can’t quickly and accurately perceive the represented data, the visualization fails.
Now, take a look at a bar chart which represents the same data. 
&lt;img alt="Comparing pie charts and bar charts" src="/static/img/posts/nebulous-data/pie-bar.png"&gt;
(from &lt;a href="http://faculty.utpa.edu/fowler/vis-papers/perception-cognition/Cleveland_1984_GraphicalPerception_JASA.pdf"&gt;Graphical Perception : Theory , Experimentation , and Application to the Development of Graphical Methods).
The representation of the data influences (or even determines) the conclusions you draw from it. When the bar chart and pie chart are side by side, it's hard to accept that they represent the same data. If some objective data is to be visualized, there’s little justification for choosing a pie chart over a bar chart. There may be artistic or aesthetic reasons for doing so, but pie charts are the inferior way to convey objective information. But, they may be better at representing subjective data.
Subjective Data
Let’s take a survey. Are you lonely? “Yes” or “No.” 
Imagine we ask ninety nine other people this question and chart the results. How many people are lonely? From the examples above, using a bar chart would give us a more accurate perception of the data. I argue that it wouldn’t be the best choice.
The problem with this kind of data is that it’s nebulous and abstract and subjective and fuzzy and open to interpretation. Does “loneliness” have the same meaning to everyone? Should you always answer “no” if you have close friends? Or if you're in a relationship? Is 47% lonely a “no” or “yes”?  Your answer also depends on the mood you’re in when you answered the question. There are a myriad of the other issues  with such a simple yes/no choice, but even if you could answer on a scale of 1 to 5, many of the same issues exist.
Bar charts give us a more accurate representation of the data, but the problem with this example is that the data is nebulous. Fuzzy.  Bar charts effectively communicate data in a clean, precise way.  In the previous bar chart example, it’s obvious that “A” was bigger than “C”. Bar charts seem to naturally imply a sort of “correctness” about the data they represent. 
From a perception perspective, is a bar chart the right fit for the data in this “lonely” thought experiment? I think they’re not, because it’s too tempting to draw the conclusion that the data is final or leaves no room for interpretation. In this scenario, a pie chart is a better choice because they give you a fuzzy representation of the data. In this case, the data itself is fuzzy.
Radar Charts
&lt;img alt="Radar Chart" src="/static/img/posts/nebulous-data/radar-chart.png"&gt;
Radar charts have similar problems that pie charts have: a radar chart is essentially a bar chart that looks like a line chart rotated around a circle. The dimensions in a radar chart are related, but they are not parts of a whole like a pie chart. The shape of a radar chart is arbitrary - you can change the order of the dimensions and get a different shape. Comparing values across dimensions in a radar chart is difficult. Alone, a radar chart isn't a great visualization choice for objective data.  
On the other hand, they create interesting shapes. This is the important part. When looking at many radar charts together (i.e., small multiples), they excel. They stand out because of their shape differences. When you look at a list of radar charts, it's easy to quickly spot outliers because they look so different. These differences represent differences in data. For objective data, a list of radar charts works wonderfully. Also, they’re my favorite type of visualization - even though I dislike pie charts.
For Five Labs, I wanted to use a visualization that was interesting and compelling on its own and worked great when looking at multiple versions of it. We use state of the art machine learning algorithms to predict your personality, but no matter how great they are, they are still just predictions. They’re predictions based on externally demonstrated behaviors of humans. How much rationality can we throw at an inherently irrational subject like human nature?
Conclusion
Sometimes, the stories that a visualization creates are more important than being able to accurately judge the data. This is especially true if the data you're representing is fuzzy. Personality data is some of fuzziest data you can represent. The nature of the data is not only subjective; it's ambiguous. What's the difference between 85% and 87% extraversion? What does that even truly mean? So, I think ambiguity in the visualization is more honest. In this case, the weaknesses of the radar chart are its strengths.
To me, a bar chart implies a high level of trust and accuracy in the data. No doubt about what the data shows. Even if you knew with full certainty someone's personality, how would you visualize it? Their behavior and actions on any given day are influenced by their mood, the weather, their health, etc. - factors that cause ambiguity.
There's no perfect chart for every situation. Listen to the data. Be aware of not only the results it gives you, but the source and reliability of those results. That reliability should be reflected in the visualization.&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/570YL0OeGN8" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/5zKs9Z91jNo" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/3piFJRJYMtw" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/Lrx2bc4pIys" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/data-visualization/visualizing-nebulous-data</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/570YL0OeGN8/visualizing-nebulous-data</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/5zKs9Z91jNo/visualizing-nebulous-data</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/3piFJRJYMtw/visualizing-nebulous-data</feedburner:origLink></item>
    
    <item>

        <title>Building Five Labs</title>
        <pubDate>Tue, 01 Jul 2014 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/QOtPc1CkA0o/five-labs-generating-200-million-personalities</link>
        <guid isPermaLink="false">http://vasir.net/blog/infrastructure/five-labs-generating-200-million-personalities</guid>
        <category>Infrastructure&gt;</category>


        <description>What we Learned by Generating 200 Million Personalities in One Week
&lt;a target="_blank" href="http://labs.five.com"&gt;Five Labs is an experiment from my startup, &lt;a target="_blank" href="http://five.com"&gt;Five.com. We used a &lt;a target="_blank" href="http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3783449/"&gt;scientific model to predict your personality from your Facebook wall posts. The model might sound complicated, but the web app is easy to understand. You log in with your Facebook account, then we analyze (but never store) your wall posts with &lt;a target="_blank" href="http://scikit-learn.org/stable/"&gt;machine learning and predict your &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Big_Five_personality_traits"&gt;personality. The stored result looks like this: { openness: 80, conscientiousness: 59, extraversion: 30, agreeableness: 40, neuroticism: 50 }.
The app we built went viral and generated personalities for over 200 million people. This post describes what strategies worked for me and what allowed us to handle, at the peak, over 12,000 new accounts per second while experiencing no downtime. (We had coffee breaks, but the app never went offline.)
Infrastructure
Five Labs is built on Amazon Web Services. What we built is not very complicated, and there is room for improvement, but it worked well for us. I had two primary goals:
&lt;ol&gt;&lt;li&gt;Cache everything.&lt;li&gt;What cannot be cached should be easy to scale. Growth should be handled by adding more of the same stuff. 
The tertiary goal was to log everything. We accomplished this through a mixture of server-side and client-side logging. On the server-side we used Graylog2. On the client-side we utilized a combination of Mixpanel, Google Analytics, and custom handling of error logs. 
By caching (almost) everything (we used Cloudfront's site-wide caching), we were able to use less servers and handle larger volumes of traffic. The end result looks something like this:
&lt;img alt="Five Infrastructure" src="https://s3.amazonaws.com/vasir-assets/archive/infrastructure.svg"&gt;
For the majority of requests, the process ends at step 3a. We accomplish this with HTTP caching. For the other steps, the biggest bottleneck is the prediction service.
App and Prediction Server
While most things are cacheable, personality prediction is not. The personality prediction server lives on the same instance as the NodeJS app server, along with RabbitMQ. The share page image generation process (using PhantomJS) also lives here. Each instance contains the entire stack. The personality prediction server is not publicly accessible - it can only be directly accessed locally.
We use RabbitMQ as an &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Remote_procedure_call"&gt;RPC message queue. This allows the NodeJS app server to send a request to the Python Prediction server without the server becoming overloaded if too many messages come in too quickly. 
This whole process (NodeJS &amp;lt;- RabbitMQ -&amp;gt; Prediction Server) is self contained in each instance. We can handle growth by simply spinning up more instances. Adding more capacity requires no additional configuration or overhead. We have an Amazon Machine Image ( &lt;a target="_blank" href="http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html"&gt;AMI - an image of a server )  created for the instance, so when we need more bandwidth we simply spin up more instances and tear them down when we don't need them. Scaling this component is fast; it's a short script which boots a new instance from an AMI, specifies the security group, and adds it to the load balancer. We use the "frozen pizza" model, where the AMI contains everything needed for the server. Everything is baked into the AMI, so we don't need to pull any code or updates. As soon as the instance boots up (or the pizza is heated up), it's ready to be added to the load balancer.
Alternatively, the prediction component could be its own service and have a separate RabbitMQ machine. For many applications this would likely be a better solution, but the architecture should fit the use case. For us, the extra overhead, scaling, and maintenance of a separate service would have been overkill.
MongoDB
With little configuration, MongoDB worked great for us. One consideration early on was to use short field names (e.g., "u" instead of "username"). This is painful, but the extra letters end up taking a lot of unnecessary space when there are hundreds of millions of records. Unfortunately, it's a micro optimization for us. We also store your friends list as an array for each user (our data model could be improved slightly, but either way we have to store the social graph for each user). Overall, the total database size is over 130gb, but since our indices still fit into memory we haven't noticed any performance hits in the app. 
Eventually, we would need to shard the database if the app continued to grow by around an order of magnitude, but we knew up front what the limitations and goals were. For our case, sharding would be a bit of over architecture. It's helpful to balance architecture solutions in terms of the product's goals - a large part of me wanted to build the most robust and "scalable" system, but it's not always the wisest solution when it doesn't fit the use case.
Redis
As Redis is a single point of failure for us, it's probably the most vulnerable part of our infrastructure. However, Redis is awesome. We use it used exclusively for caching and storing sessions. Redis is blazingly fast, and takes significant load off our database servers. While it is possible to &lt;a target="_blank" href="http://redis.io/topics/partitioning"&gt;shard and &lt;a target="_blank" href="http://redis.io/topics/replication"&gt;replicate Redis, a single node was adequate for our needs. With little configuration out of the box, it performed flawlessly, has yet to crash, and has never been a bottleneck. 
Frontend to Backend
Building a scalable backend requires building a scalable frontend. "Cache everything." You'll see this phrase throughout this post, as it's the core concept that allowed us to scale cheaply.
Separate API calls from Page Rendering
Five Labs is a single page Javascript app (built with &lt;a target="_blank" href="http://backbonejs.org/"&gt;Backbone + &lt;a target="_blank" href="http://marionettejs.com/"&gt;Marionette). The app server runs NodeJS. Rendering pages does not require a user's session (although some API endpoints do). For instance, the page &lt;a target="_blank" href="http://labs.five.com/barackobama"&gt;labs.five.com/barackobama can be requested by any client regardless of session, making caching extremely easy. Only after the page has been loaded does it make an ajax request to /api/user, an endpoint which does require a user's session ID to be passed in (e.g., via a cookie).  Essentially, all pages a user visits are completely cacheable. The front end app makes a separate API request for user specific content when necessary (e.g., to login), but many API calls are also cached (e.g., &lt;a target="_blank" href="http://labs.five.com/api/users/barackobama"&gt;http://labs.five.com/api/users/barackobama).
Cache All The Things
Five Labs was architectured around the idea that everything should be as cacheable as possible. So, using site-wide caching with CloudFront was easy. CloudFront will honor whatever HTTP headers you set.  This means the first request to http://labs.five.com/barackobama hits the database and gets cached, but every other request to that endpoint is returned directly from the CDN, without ever hitting our application servers. 
In general, there are three levels you can cache at.
&lt;ol&gt;&lt;li&gt;(Low level) The function level (functions / methods within your application code) with &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Memoization"&gt;memoization. An example would be storing the results of calls in a recursive function.&lt;li&gt;(Higher level) The application level - e.g., storing variables in memory or caching database results with something like Redis.&lt;li&gt;(Outside of your app) HTTP caching, which you can use to avoid hitting your app at all. &lt;a target="_blank" href="https://www.mnot.net/cache_docs/"&gt;A good caching tutorial.
A mixture of all three is ideal.
HTTP Caching
If your app is making many requests every time a client requests a page, you have to throw more servers and more money at the problem to keep the site up and responsive. There's another way. Even if your server has to receive a handwritten letter from the White House when you request &lt;a target="_blank" href="http://labs.five.com/barackobama"&gt;Barack Obama's Profile, if it can do it once and not every time his profile is accessed then you're not in terrible shape. Sure, the first person that requests the profile might have to wait a little while. However, as soon as server sends the response, it becomes cached for every subsequent call to that endpoint.
HTTP Caching Overview
One of the biggest things that allowed us to scale cheaply was making heavy use of HTTP Caching. HTTP caching gives many wins. 
First, any revisits to your site will be faster for the client because the browsers will use the locally cached content (also, taking load off your servers). 
Second (importantly for us), you can use an HTTP reverse proxy like &lt;a target="_blank" href="https://www.varnish-cache.org/"&gt;Varnish (or Cloudfront site-wide caching) to avoid your application servers being hit at all after the initial request was made.  We use Cloudfront, which not only does this, but also gives us a Content Delivery Network (CDN). With the CDN, servers are geographically closer to end users, making the site even faster.
A reverse proxy works like this:
&lt;img alt="Reverse Proxy" src="https://s3.amazonaws.com/vasir-assets/archive/proxy-example.svg"&gt;
A request is made to your domain (Step 1). If the same resource has already been requested and exists in the cache, the response is immediately returned without hitting your app server (Step 2a). If the response does not yet exist in the cache, the request is sent to your app server (Step 2b). Your server generates a response, saves it in the cache (Step 3), then sends the response to the client (Step 4).
The tricky part is cache invalidation. How long should the proxy server keep that page in the cache? If you want the cache to last for 7 days but change the page on day 4, you have to wait 3 days until the proxy server will hit the server for the freshest version. Here are a couple of ways to get around this:
&lt;ol&gt;&lt;li&gt;Set a short cache expiration for things that may change, and a long expiration for things that never change. This works, but is a manual process and prone to error.&lt;li&gt;Set a short cache expiration for the main page, and add a query parameter to all the resources that page references. The resources themselves have a long expiration. e.g, index.html could have an expiration of a few minutes, and all references to resources would have a query parameter (e.g., &amp;lt;link href="style.css?v=1"). Anytime you upload a new version of the resource, simply change the query parameter (e.g., to v=2, v=3, etc.). This way, the resources themselves can have a long expiration and you don't need to worry about invalidating the resource itself - a new resource is requested because it has a new reference. 
CloudFront Site-Wide Caching
I mentioned Cloud Front site-wide caching a few times. It worked fantastically for us. You can set custom error pages by status code, and even issue invalidation requests if you need to. You can also set up logging, allowing more visibility into what's going on. Lastly, you can set custom behaviors per route(s). 
Custom behaviors allow you to define how certain routes are handled. You can pass in cookies or query parameters to some routes but not others, force a route to have a specific &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Time_to_live"&gt;TTL, etc. Forwarding cookies is important so you can have an endpoint like /api/user to fetch your own information without seeing another user's info.  However, passing in cookies to a route also causes you to lose a huge benefit of caching. The request is cached based on the cookie, so it will only be cached on a per user level - other clients making a request with a different cookie will hit the server.
Setting the TTL specifies how long the resource should live on CloudFront before hitting your servers. To specify how long the resource should live on CloudFront, we set the Cache-Control header with a public, max-age=X property (where X is a number in seconds). For instance, to have a resource live in CloudFront for 15 minutes, we would set the Cache-Control header to public, max-age=900. &lt;a target="_blank" href="https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en"&gt;Postman is a useful Chrome extension that makes it easy to send any kind of HTTP request to an endpoint and view / set headers (Chrome's Network tab in the Developer Tools is helpful for this as well).
Conclusion
Initially, designing an app and the infrastructure for it to support 200 million profiles seemed daunting. However, proper planning early on makes it easier, even within a short timeframe. Leveraging HTTP caching was the right solution for us, and making it easy to spin up and down EC2 instances allowed us to smoothly scale to handle traffic. 
See anything that could be improved? Reach me on twitter &lt;a href="http://twitter.com/enoex" target="_blank"&gt;@enoex.
Five Labs was an experiment to demonstrate how people express themselves online. We'll be taking down Five Labs on July 20th and removing all stored personality data. You can &lt;a href="http://labs.five.com/download" target="_blank"&gt;download your generated personality as a PDF before all profiles are deleted. We believe online interactions can be better, which is why we're building &lt;a href="http://five.com" target="_blank"&gt;Five.com.&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/-oVg2IQihw0" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/IaSYz33bCyU" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/5YSd7U6FuoY" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/QOtPc1CkA0o" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/infrastructure/five-labs-generating-200-million-personalities</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/-oVg2IQihw0/five-labs-generating-200-million-personalities</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/IaSYz33bCyU/five-labs-generating-200-million-personalities</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/5YSd7U6FuoY/five-labs-generating-200-million-personalities</feedburner:origLink></item>
    
    <item>

        <title>Installing CUDA, OpenCL, and PyOpenCL on AWS EC2</title>
        <pubDate>Wed, 18 Sep 2013 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/ZjJ0Ysy1ndU/installing-cuda-opencl-pyopencl-on-aws-ec2</link>
        <guid isPermaLink="false">http://vasir.net/blog/opencl/installing-cuda-opencl-pyopencl-on-aws-ec2</guid>
        <category>OpenCL&gt;</category>


        <description>This post describes how to setup CUDA, OpenCL, and PyOpenCL on EC2 with Ubuntu 12.04. It took me a while to get working properly, so what follows are the steps I took to install CUDA and OpenCL on EC2. These steps should work for any machine with a &lt;a target='_blank' href='https://developer.nvidia.com/cuda-gpus'&gt;CUDA capable card.
If you'd just like to create an instance with everything preinstalled, I've created a public AMI named Ubuntu-12.04-GPU-CUDA-OpenCL-PyOpenCL with the ID ami-87377cee.
You can also &lt;a target='_blank' href='https://gist.github.com/erikhazzard/6602963'&gt;view the bash script to install CUDA and OpenCL.
CUDA, OpenCL, GPU Programming
&lt;a target='_blank' href='http://www.khronos.org/opencl/'&gt;OpenCL and &lt;a target='_blank' href='http://www.nvidia.com/object/cuda_home_new.html'&gt;CUDA are platforms for parallel programming.  Basically, you can use it to take advantage of GPUs to solve problems quicker (e.g., drawing pixels to a screen, mining bitcoins, or looping over a large data set and doing calculations on each item).  This post won't go into any more detail, but &lt;a target='_blank' href='http://http://vasir.net/blog/opencl/why-use-opencl'&gt;this post addresses the question &amp;quot;why use opencl?&amp;quot;.
The goal of this article is to describe how to set up OpenCL and PyOpenCL using CUDA 5.5 on an AWS EC2 instance running Ubuntu 12.04. 
Setup
At the time of writing, Amazon provides GPU instances Instances which are backed by two Intel Xeon X5570, quad-core with hyperthreading and two NVIDIA Tesla M2050 GPUs.  Let's install CUDA, Nvidia's parallel computing platform, which includes OpenCL.
&lt;ol&gt;&lt;li&gt;First, setup a GPU instance. Select Ubuntu Server 12.04 LTS for HVM instances, which will allow us to spin up a GPU instance.  Make sure to select the GPU instance type, CG1 Cluster GPU (cg1.4xlarge, 22GiB).&lt;li&gt;After the instance is setup, SSH into it and we'll setup CUDA.  We'll follow &lt;a target='_blank' href='http://docs.nvidia.com/cuda/cuda-getting-started-guide-for-linux/index.html'&gt;setting up CUDA guide, including with some extra steps to setup pyOpenCl:&lt;ol&gt;&lt;li&gt;
                Setup dependencies needed to install CUDA (gcc):  sudo apt-get update 
 sudo apt-get install gcc  
                &lt;li&gt;
                    Download and install CUDA. For the EC2 instance, grab the &lt;a target='_blank' href='http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1204/x86_64/cuda-repo-ubuntu1204_5.5-0_amd64.deb'&gt;64-bit Ubuntu 12.04 .deb file for CUDA 5.5.  Run the command to download it:
                    wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1204/x86_64/cuda-repo-ubuntu1204_5.5-0_amd64.deb
                    (This comes from the &lt;a target='_blank' href='https://developer.nvidia.com/cuda-downloads'&gt;CUDA Download Page. If this post is outdated and 5.5 is old, you can visit the &lt;a target='_blank' href='https://developer.nvidia.com/cuda-toolkit-archive'&gt;CUDA toolkit archive page to download version 5.5.)Then run: 
                    sudo dpkg -i cuda-repo-ubuntu1204_5.5-0_amd64.deb 
 sudo apt-get update 
 sudo apt-get install cuda  
                    &lt;li&gt;
                        Seutp environment; add cuda to PATH and LD_LIBRARY_PATH. Add the two following lines to ~/.bashrc  export PATH=/usr/local/cuda-5.5/bin:$PATH 
 export LD_LIBRARY_PATH=/usr/local/cuda-5.5/lib64:$LD_LIBRARY_PATH  
                        &lt;li&gt;Install CUDA samples (optional) to some directory (. here, which will install to the current directory): cuda-install-samples-5.5.sh .&lt;li&gt;
                    Verify an example works (after running this, it should show two CUDA capable devices): 
                     cd NVIDIA_CUDA-5.5_Samples/1_Utilities/deviceQuery 
 make 
 ./deviceQuery  
                            &lt;li&gt;Now that CUDA is setup, Install opencl headers and PyOpenCL dependencies: 
                                 sudo apt-get install opencl-headers python-pip python-dev python-numpy python-mako  
                                &lt;li&gt;&lt;a target='_blank' href='https://pypi.python.org/pypi/pyopencl'&gt;Download pyopencl, then install it: 
                                     wget https://pypi.python.org/packages/source/p/pyopencl/pyopencl-2013.1.tar.gz#md5=c506e4ec5bc56ad85bf005ec40d4783b 
 tar -vxzf pyopencl-2013.1.tar.gz 
 cd pyopencl-2013.1 
 sudo python setup.py install  

AMI and Bash Script
I've created an AMI following the steps above, named Ubuntu-12.04_GPU_CUDA-OpenCL-PyOpenCL with the ID ami-87377cee. You can select this AMI if you just want to create an instance without doing these steps yourself.
I also created a script containing all the commands, which you can &lt;a target='_blank' href='https://gist.github.com/erikhazzard/6602963'&gt;view and run the bash script to setup OpenCL / PyOpenCL and CUDA.
More Resources Now that you have OpenCL installed, the next step is learning how to use it.  For a great introduction to OpenCL, check out &lt;a target='_blank' href='http://enja.org/category/tutorial/advcl/'&gt;Adventures in OpenCL by &lt;a href='https://twitter.com/enjalot'&gt;@enjalot, or &lt;a target='_blank' href='http://www.drdobbs.com/parallel/a-gentle-introduction-to-opencl/231002854'&gt;a gentle introduction to OpenCL, or &lt;a target='_blank' href='http://documen.tician.de/pyopencl/'&gt;the PyOpenCL tutorial. In later posts, I'll go a bit more in depth why you might want to leverage OpenCL.  




&lt;link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/default.min.css"&gt;

.hljs{display:block;overflow-x:auto;padding:0.5em;background:#fdf6e3;color:#657b83}.hljs-comment,.hljs-quote{color:#93a1a1}.hljs-keyword,.hljs-selector-tag,.hljs-addition{color:#859900}.hljs-number,.hljs-string,.hljs-meta .hljs-meta-string,.hljs-literal,.hljs-doctag,.hljs-regexp{color:#2aa198}.hljs-title,.hljs-section,.hljs-name,.hljs-selector-id,.hljs-selector-class{color:#268bd2}.hljs-attribute,.hljs-attr,.hljs-variable,.hljs-template-variable,.hljs-class .hljs-title,.hljs-type{color:#b58900}.hljs-symbol,.hljs-bullet,.hljs-subst,.hljs-meta,.hljs-meta .hljs-keyword,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-link{color:#cb4b16}.hljs-built_in,.hljs-deletion{color:#dc322f}.hljs-formula{background:#eee8d5}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}


hljs.initHighlightingOnLoad();&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/KrrnS_GWSwQ" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/dLyglGPYpEM" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/rNzlzZhmgwA" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/ZjJ0Ysy1ndU" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/opencl/installing-cuda-opencl-pyopencl-on-aws-ec2</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/KrrnS_GWSwQ/installing-cuda-opencl-pyopencl-on-aws-ec2</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/dLyglGPYpEM/installing-cuda-opencl-pyopencl-on-aws-ec2</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/rNzlzZhmgwA/installing-cuda-opencl-pyopencl-on-aws-ec2</feedburner:origLink></item>
    
    <item>

        <title>Replace a String in Multiple Files in Linux Using Grep and Sed</title>
        <pubDate>Fri, 25 Jun 2010 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/2qGz-LzXQuQ/replace_string_in_multiple_files</link>
        <guid isPermaLink="false">http://vasir.net/blog/programming/replace_string_in_multiple_files</guid>
        <category>Programming&gt;</category>


        <description>I recently had to replace every occurrence of a certain word / string in a ton of files spanning multiple directories, and this is the quickest way I've found to do it.  It uses grep to search for a certain word and if it find its it runs sed to replace the strings you want.  Note: This may not work on windows systems


Basic Format

grep -rl matchstring somedir/ | xargs sed -i 's/string1/string2/g'

Note: The forward slash '/' delimiter in the sed argument could also be a different delimiter (such as the pipe '|' character).  The pipe delimiter might be useful when searching through a lot of html files if you didn't want to escape the forward slash, for instance. 


matchstring is the string you want to match, e.g., "football"


string1 would ideally be the same string as matchstring, as the matchstring in the grep command will pipe only files with matchstring in them to sed.  


string2 is the string that replace string1.  




There may be times when you want to use grep to find only files that have some matchstring and then replace on a different string in the file than matchstring.  For example, maybe you have a lot of files and only want to only replace on files that have the matchstring of 'phonenumber' in them, and then replace '555-5555' with '555-1337'.  Not that great of an example (you could just search files for that phone number instead of the string 'phonenumber'), but your imagination is probably better than mine.



Example

grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'

This will search for the string 'windows' in all files relative to the current directory and replace 'windows' with 'linux' for each occurrence of the string in each file.  



Conclusion

Any comments / suggestions for improvement are much welcomed.



&lt;link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/default.min.css"&gt;

.hljs{display:block;overflow-x:auto;padding:0.5em;background:#fdf6e3;color:#657b83}.hljs-comment,.hljs-quote{color:#93a1a1}.hljs-keyword,.hljs-selector-tag,.hljs-addition{color:#859900}.hljs-number,.hljs-string,.hljs-meta .hljs-meta-string,.hljs-literal,.hljs-doctag,.hljs-regexp{color:#2aa198}.hljs-title,.hljs-section,.hljs-name,.hljs-selector-id,.hljs-selector-class{color:#268bd2}.hljs-attribute,.hljs-attr,.hljs-variable,.hljs-template-variable,.hljs-class .hljs-title,.hljs-type{color:#b58900}.hljs-symbol,.hljs-bullet,.hljs-subst,.hljs-meta,.hljs-meta .hljs-keyword,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-link{color:#cb4b16}.hljs-built_in,.hljs-deletion{color:#dc322f}.hljs-formula{background:#eee8d5}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}


hljs.initHighlightingOnLoad();&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/YQRqrY6yaUo" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/0C2ikDzmU78" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/Mdns9qfa9Bo" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/2qGz-LzXQuQ" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/programming/replace_string_in_multiple_files</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/YQRqrY6yaUo/replace_string_in_multiple_files</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/0C2ikDzmU78/replace_string_in_multiple_files</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/Mdns9qfa9Bo/replace_string_in_multiple_files</feedburner:origLink></item>
    
    <item>

        <title>Removing ^M characters on ubuntu in VIM</title>
        <pubDate>Sun, 20 Jun 2010 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/YvWu7P8rftM/removing-m-characters-on-ubuntu-in-vim</link>
        <guid isPermaLink="false">http://vasir.net/blog/programming/removing-m-characters-on-ubuntu-in-vim</guid>
        <category>Programming&gt;</category>


        <description>It took me a while to figure out how to get rid of pesky ^M characters in VIM on ubuntu. ^M in VIM can be manipulated as it is an \r character. Often times other developers would edit python files in gedit or notepad and ^M characters would be inserted. I could not simply %s/\^M//g as "^M" was not a recognized character. 



The fix is really quite simple and I was frustrated it took me so long to find, but in case it gets to anyone else – the ^M is a line feed character that is inserted by gedit(among other editors) sometimes. In VIM, it shows up as ^M, but it is actually a "\r" character. So, doing a replace for \r characters will remove the ^M


%s/\r//g



&lt;link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/default.min.css"&gt;

hljs.initHighlightingOnLoad();&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/ickerCJ67Gw" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/7JD5YXBMl7o" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/Leh7zfD-m-A" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/YvWu7P8rftM" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/programming/removing-m-characters-on-ubuntu-in-vim</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/ickerCJ67Gw/removing-m-characters-on-ubuntu-in-vim</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/7JD5YXBMl7o/removing-m-characters-on-ubuntu-in-vim</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/Leh7zfD-m-A/removing-m-characters-on-ubuntu-in-vim</feedburner:origLink></item>
    
    <item>

        <title>Dijkstra's Algorithm - Shortest Path</title>
        <pubDate>Sat, 22 May 2010 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/YyL_fTxq6hM/dijkstras_algorithm_shortest_path</link>
        <guid isPermaLink="false">http://vasir.net/blog/game_development/dijkstras_algorithm_shortest_path</guid>
        <category>Game Development&gt;</category>


        <description>Note - This is not my area of expertise but I am very much interested in it and I welcome any corrections 

Outline 

This post will cover the basics of Dijksta's shortest path algorithm and how it can apply to path finding for game development. It is my opinion that understanding this algorithm will aid in understanding more complex AI algorithms, such as A*. This post is aimed more towards developers starting out in game development or those curious about Dijkstra's algorithm, but this will be a somewhat simplification of it and discuss mainly the concepts. 

Introduction 

What’s an algorithm?  

An algorithm is basically a system for solving a problem. For us humans, looking at a 2d grid with many objects we can easily tell which path the character should take to reach his or her goal without thinking much about it. What we want to try to do is translate those semi-subconscious mental steps to a list of steps that anyone (or a computer) can repeat to get the same answer every time.  

Finding the shortest route from one object to another when developing game AI is a very common problem and many solutions exist. At least in 2d grid / tile based games, perhaps the most common one is A*, with Dijkstra's being also quite good. Depending on the complexity of the game, Dijkstra's algorithm can be nearly as fast as A*, with some tweaking. A* is generally a better implementation, but can be slightly complex, so I'm going to discuss the fundamentals of Dijkstra's algorithm and in later posts talk about others, such as A*.

 

I'll be using the word graph here a lot, and it may not be immediately obvious how this translates to game dev, but you can easily translate this to 2d grid or tile based maps.



Dijkstra’s Algorithm

Let's first define what exactly the problem is.  Take this graph, for instance.




&lt;img src="https://s3.amazonaws.com/vasir-assets/archive/shortest_path1.png" alt="Shortest path example" height="400" class="center_image"&gt;




For the purposes of this post, the blue circles represent "nodes" or "vertices"  and the black lines are "edges" or "node paths".  Each edge has a cost associated with it.  

For -this- image, the number in each node in this image is simply a label for the node, not the individual node cost. 



Our problem is to find the most cost efficient route from Node1 to Node4.  The numbers on the node paths represent the "cost" of going between nodes.  The shortest path from Node1 to Node4 is to take Node1 to Node3 to Node4, as that is the path where the least cost is incurred. 



Specifically, the cost to go from Node1 to Node3 is (2), plus the cost of Node3 to Node4 (5) is 7 (2 + 5).

Now, we can see that the alternative (Node1 to Node2 to Node4) is much more costly (it costs 11, versus our 7).





An important note - greedy algorithms aren't really effective here.  A greedy algorithim would bascially find the cheapest local costs as it traverses the graph with the hopes that it would be globally optimum when it's done. Meaning, a greedy algorithm would basically just take the first low value it sees.  In this case, the lower value is 1 but the next value is 10.  If we were to simply just apply a greedy algorithm, we end up taking the more costly from Node1 to Node4. 



Figuring out the best path to take with this graph is pretty easy for us to do mentally, as if you can add small numbers you can figure out the best path to take.  For a small graph like the previous, it's quite easy.  The goal is translate the steps we take in our mind to steps a computer follow. 





Dijkstra's algorithm is an algorithm that will determine the best route to take, given a number of vertices (nodes) and edges (node paths).  So, if we have a graph, if we follow Dijkstra's algorithm we can efficiently figure out the shortest route no matter how large the graph is. 



Dijkstra's algorithm provides for us the shortest path from NodeA to NodeB.



This high level concept (not this algorithm specifically) is essentially how Google maps provides you directions.  There are many thousands of vertices and edges, and when you ask for directions you typically want the shortest or least expensive route to and from your destinations.



So, how does this apply to game AI?  Well, the correlation is quite strong.  In a 2d grid or tile based map, there are many nodes (or tiles) and each tile can have a value associated with it (perhaps it is less expensive to walk across grass than it is to walk across broken bottles or lava).  



You can set up your tiles so that each tile has a node path value associated with it, so if you put an non player character (NPC) in the map you can use Dijkstra's algorithm to compute the shortest path for the NPC to take to -ANY- tile in your map.



How it works

First we'll describe Dijsksta's algorithm in a few steps, and then expound on them furher:




Step 0. 

Temporarily assign C(A) = 0 and C(x) = infinity for all other x.

C(A) means the Cost of A

C(x) means the current cost of getting to node x



Step 1.Find the node x with the smallest temporary value of c(x).  

If there are no temporary nodes or if c(x) = infinity, then stop.

Node x is now labeled as permanent.  Node x is now labeled as the current node.  C(x) and parent of x will not change again.	



 Step 2. 

For each temporary node labeled vertex y adjacent to x, make the following comparison:

if c(x) + Wxy  &amp;lt; c(y), then c(y) is changed to c(x) + Wxy
assign y to have parent x


Step 3. 

Return to step 1.




Before diving into a little more tricky graph, we'll stick with the original graph introduced above.  Let's get started.





Step 0.



Temporarily assign C(A) = 0 and C(x) = infinity for all other x.

C(A) means the Cost of A

C(x) means the current cost of getting to node x





The following graph has changed a little from the one shown above.  The nodes no longer have labels, apart from our starting point NodeA and our goal NodeB.




&lt;img src="https://s3.amazonaws.com/vasir-assets/archive/sp_1_1.png" alt="Shortest Path Step 0" height="400" class="center_image"&gt;


Legend

Orange line – path to parent node

Yellow arrow – points to the node’s parent

Green node cost text – node cost is permanent

White node cost test – node is temporary

Yellow highlight – Current node



We assign a cost of 0 to Node A and infinty to everything else.  We're done with this step now.

 

Step 1. 



Find the node x with the smallest temporary value of c(x).

If there are no temporary nodes or if c(x) = infinity, then stop.

Node x is now labeled as permanent.  Node x is now labeled as the current node.  C(x) and parent of x will not change again.	



Since 0 is the lowest value, we set A as the current node and make it permanent.



Step 2.



For each temporary node labeled vertex y adjacent to x, make the following comparison:

if c(x) + Wxy  &amp;lt; c(y), then 

c(y) is changed to c(x) + Wxy

assign y to have parent x



There are two temporary nodes adjacent to our current node, so calcuate their cost values based on the current node's value + the cost of the adjacent node.  Assign that value to the temporary node only if it's less than the value that's already there. So, to clarify:



The top node is adjacent to the current node and has a cost of infinity.  0 (the current node's value) + 1 (the cost associated with the temporary node) = 1, which is a less than infinity, so we change it's value from infinity to 1.  This value is not yet permanent.



Now, do the same calucation for the next adjacent node. which is the bottom node. The value is 0 + 2 = 2, which is also less than infinity.  To illustrate:




&lt;img src="https://s3.amazonaws.com/vasir-assets/archive/sp_1_2.png" alt="Shortest Path Step 2" height="400" class="center_image"&gt;




So we now have looked at each temporary node adjacent to the current node, so we're done with this step. 



Step 3.

Return to step 1.

So, let's go back to step 1.  From this point forward, I'll be using the term iteration to describe our progression through the graph via Dijkstra's algorithm. The steps we previously took I'll refer to as iteration 0, so now when we return to step 1 we'll be at iteration 1.





Iteration 1

We’re back at the first step.  It says look for the smallest temporary cost value and set it as permanent.  We have two nodes to look at, the top node with cost 1 and the bottom node with cost 2. 

 

The top node has a cost of 1, which is less than 2, so we set it as permanent and set it as our current node.  We designate this by a yellow shadow in the image. Now, it is important to keep in mind that the bottom node still has a temporary cost assigned to it.  This temporary cost is what allows the algorithm to find actual cheapest route – you’ll see in a second.  



Step 1.

Find the cheapest node.  Done, it’s set as permanent and our current node is this one.  This node value will not change.  


&lt;img src="https://s3.amazonaws.com/vasir-assets/archive/sp_2_1.png" alt="Shortest Path Iteration 1 Step 1"&gt;


The yellow highlight indictates the node we are currently on, and the green text means the node cost is permanent.  The nodes with white text for their costs are temporary nodes.    



Step 2.

Assign cost values.  There is only one adjacent node to our current node.  It's current value is infinity, which is less than 1 + 10, so we assign 11 to it's temporary cost value.


&lt;img src="https://s3.amazonaws.com/vasir-assets/archive/sp_2_2.png" alt="Shortest Path Iteration 1 Step 2" height="400" class="center_image"&gt;


    

This is not the shortest path from NodeA to NodeB, but that's fine.  The algorithm traverses all nodes in the graph, so you get the shortest path from a node to any other node. You can see that the shortest path from NodeA to the top node is the line between NodeA and the top node - well, of course, you say, because that's the only possible path from NodeA to the top node.  And you are right to say that, because it's true.  But let's say we have a node above the top node (we'll call it Top2).  The shortest path to that would from NodeA to the top node to node Top2.  Even though our goal is to go from A to B, as a side effect we also get the shortest route to every other node.  If that's a bit unclear, it should clear up after we go through the next iteration.



Done with step 2, let's continue to step 3.



Step 3.

Return to step 1.



Iteration 2

Ok, so now we look again at the temporary nodes to see which has the lowest value.  Even though we calculated the temporary value of B to be 11, we are not done because that value might change (in this case, it will definitely change). 



Step 1.

Pick the cheapest node and set it as our current node and make it permanent, and assign it its parent.



We have two remaining temporary nodes with costs of 2 and 11.  2 is lower, so pick it and set it permanent and set it as our current node.  

Let’s take a look at the graph to elucidate a bit.



So, out of 11 and 2, as we said, 2 is cheaper so pick it.  We set this node’s value to be permanent and assign its parent is NodeA, demonstrated by the arrow.


&lt;img src="https://s3.amazonaws.com/vasir-assets/archive/sp_3_1.png" alt="Shortest Path Iteration 2 Step 1" height="400" class="center_image"&gt;




Step 2. 

Assign cost values to temporary nodes adjacent to the current node. 

Again, like in the previous iteration, there is only one node to do a cost calculation on, as there is only one temporary node adjacent to the current node. This adjacent node is NodeB.  So, we check to see if 2 + 5 &amp;lt; Node B’s temporary cost of 11.  It is, so we change Node B from 11 to 7.


&lt;img src="https://s3.amazonaws.com/vasir-assets/archive/sp_3_2.png" alt="Shortest Path Iteration 2 Step 2" height="400" class="center_image"&gt;


Step 3.

Return to step 1



Iteration 3

Almost done.

Step 1

Choose the cheapest temporary node value.  There is only one temporary node remaining, so we pick it and set it as permanent, set it as our current node, and set it's parent.


&lt;img src="https://s3.amazonaws.com/vasir-assets/archive/sp_4_1.png" alt="Shortest Path Iteration 3 Step 1" height="400" class="center_image"&gt;




Step 2.

Assign costs.  There are no temporary nodes adjacent to Node B (there –are- permanent nodes, but we don’t check them).

Step 3.

Return to step 1.



Iteration 4

Step 1 

Choose the cheapest temporary node.  If none exists or c(x) = infinity, then stop.  There are no more temporary nodes and no nodes have values of infinity, so we’re done.  Algorithm has finished, and we have our shortest path from A to B, but also from that node to every other node in the graph.  With such a small graph as this, it's not immediately obvious how powerful and useful this algorithim is.  



So, on to a more complicated graph now. 




 More Complicated Graph 



A is our starting point, and B is the ending point.  Now, we could just as well apply this to a 2d tile based game where A could represent an NPC and B could represent the NPC's desired destination.  



If you take a minute, you can probably find the least expensive route yourself.  As mentioned earlier, it's fairly trivial for us to come up with the answer, what we need to do is figure out how to convey the steps we take to more extensible steps that can be repeated by a computer for any graph.  For this graph, I won't be as thorough explaining every step, but the exact same process is applied.  Instead, I'll just provide an example of a slightly more complex graph and what it would look like using Dijkstra's algorithm.



Step 0.



Temporarily assign C(A) = 0 and C(x) = infinity for all other x.

C(A) means the Cost of A

C(x) means the current cost of getting to node x



So what's this mean? Well, our start point is A so c(A) = 0 means assign A a cost of 0 and set the cost of x for every other node to infinity.  Like the following


&lt;img src="https://s3.amazonaws.com/vasir-assets/archive/shortest_path2_1.png" alt="Shortest path step 1" height="400" class="center_image"&gt;


We assign a cost of 0 to our starting node A and a cost of infinity to every other node.  As before, none of these costs are permanent yet.





Step 1.

The node with the smallest temporary value is node A with a cost of 0.  Therefore, we're going to make it permanent - meaning c(x) and the parent will not change.


&lt;img src="https://s3.amazonaws.com/vasir-assets/archive/shortest_path2_1_a_selected.png" alt="Permanent node"&gt;


The 0 will not change now.



If there are no temporary nodes, or if c(x) is infinity, the algorithm stops. Now, step 2.



Step 2.

Basically, we're going to look at all the nodes that are connected to the currently selected node and calculate the cost to get to them.  If the cost of y is less than what it previously was, it will change - this will be discussed soon.



So, let's first calculate the cost to get to the adjacent nodes. The cost is based on the value of the current node code plus the edge (node path) cost.  Right now, since this our first go, the cost our current node is at 0 since we haven't done any traversals.  



So, let's start to figure out the c(x), the node costs.  


&lt;img src="https://s3.amazonaws.com/vasir-assets/archive/shortest_path2_1_a_selected_3.png" alt="Code of nodes" height="400" class="center_image"&gt;


Notice the yellow arrows.  I'm using them to designate what node it got its cost from.  Here, since there is only one possible parent node, they all point to the same place. 



 For the three nodes adjacent to A, we add the values of the edge and our current node (value of 0).  

So, the top node is 0 + 3 = 3, which is less than the current value (which is infinity), so we apply the value of 3 to the node.  Then, the middle node 0 + 7 = 7, also less than infinity. Finally the bottom node has a value of 0 + 5 = 5, which is less than infinity.  Therefore, the top node has a c(x) of 3, the middle a c(x) of 7, and the bottom a c(x) of 5.



Step 3.

Return to step 1



As before, we just iteratively go through graph applying the same steps.



So, walking through this - as step 1 says:



We find node x with the smallest temporary value of c(x).   So, out of the three temporary nodes with values 3, 5, and 7 that we just worked out, the smallest value is 3.  We then make this node permanent.




&lt;img src="https://s3.amazonaws.com/vasir-assets/archive/shortest_path3_2.png" alt="Second permanent node" height="400" class="center_image"&gt;




Now, this entire process just repeats itself over and over until there are no more temporary nodes.




    &lt;img src="https://s3.amazonaws.com/vasir-assets/archive/shortest_path_final.png" alt="Shortest path final" height="400" class="center_image"&gt;




And we're done.  We have the shortest path a node to any other node (or vice versa).  Pretty convenient.   



Conclusion

Hopefully that explains a bit about how Dijkstra's Algorithm works.  For game development, in particular overhead 2d tile based games, it is usually easier to implement Dijkstra's than A*, and not much worse performance wise.  

Performance


How well does Dijsktra's algorithm perform?  Well, in terms of big O notion it is O(n^2), which isn't that great. However, we must always consider what problem we're trying to solve, how big the desired input data is, and if we can make gains in other areas (e.g., caching). O(n^2) is like having a nested for loop.  



Specifically, suppose G has n vertices and m edges. Going through the steps, Step 0 has time n. Step 1 is called, at the very most, n times. Finding the cheapest vertex takes at most n steps, so step 1 has an upper bound time of n^2.  In Step 2, each edge / node path is examined, at most, twice.  There, the upper bound time is 2m.



So, putting it all together, it's no worse than n^2 + 2m.  Again, in "computer science" terms of algorithmic complexity, it is O(n^2); or: on the order of at most n^2 steps times a constant.




 Conclusion 


Better algorithms for NPC path finding certainly exist (see &lt;a href='http://theory.stanford.edu/~amitp/GameProgramming/' target='_blank'&gt;Amit's page on path finding algorithms, but in general Dijkstra's is often good enough and fairly easy to implement yourself.  A very good explanation of implementation in python can be found at (written by the guy who wrote python) &lt;a href="http://www.python.org/doc/essays/graphs.html" title="Python Dijkstra Shortest Path" rel="nofollow"&gt;http://www.python.org/doc/essays/graphs.html&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/puuHTHl5B4E" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/kD5jY7i-7y0" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/Fr10NAtN6k0" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/YyL_fTxq6hM" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/game_development/dijkstras_algorithm_shortest_path</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/puuHTHl5B4E/dijkstras_algorithm_shortest_path</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/kD5jY7i-7y0/dijkstras_algorithm_shortest_path</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/Fr10NAtN6k0/dijkstras_algorithm_shortest_path</feedburner:origLink></item>
    
    <item>

        <title>OpenLayers Tutorial - Part 3: Controls</title>
        <pubDate>Sun, 02 May 2010 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/nPq8OCeexLU/openlayers-tutorial-part-3-controls</link>
        <guid isPermaLink="false">http://vasir.net/blog/openlayers/openlayers-tutorial-part-3-controls</guid>
        <category>OpenLayers&gt;</category>


        <description>Controls allow interaction with OpenLayer maps.  Panning, zooming, switching layers, etc, are all handled via controls. Some controls, such as dragging the map around to pan it, while others, like the overview map, do have a visual appearance.



There are cases where you might not want any controls - these cases are actually fairly common; for instance, if you wanted to show a small section of a map, mimic a static image, allow only logged in users to navigate around the map, etc. then you might want to have no controls on your map.



This tutorial is broken down and aims to teach you how to do the following:



1. Adding Controls

2. Customizing Controls - Passing properties and customizing control appearances

3. Adding Controls / Panels Outside of the Map

&amp;gt;

We'll show how to create a map without controls shortly, but what kind of stuff can we do with controls?  There are many more examples on &lt;a href="http://openlayers.com/dev/examples/" title="OpenLayers Examples" rel="nofollow"&gt;OpenLayer.org's Examples page, simply search for "control" to get an idea of what various types of controls there are.  There are lots of simple ones, ranging from scale bars to full vector layer manipulations. 



While there are too many controls to cover in depth here in this post, I'll be focusing on a few different controls throughout this tutorial to exemplify how flexible OpenLayers is and give you an idea of what can be done.

Adding Controls

Most controls that are 'visible' (e.g. the layer switcher control) can be placed either inside or outside of the map.  The 'invisible' controls, such the control that allows you to navigate the map when you drag the map with your mouse, are either there are they aren't - so we can't really 'place' them outside the map.  Placing controls inside the map is the default behavior and is a bit simpler than placing it outside (although both are easy once you know how), so we'll cover that first.



Adding controls to a map can be done in two different ways. 

1. When the map is created, it can accept an array of OpenLayers.Control objects to be passed in when creating the map object, and controls can be added to the map after it has been created.  If no array of control objects are passed in, (like we've been doing in prior tutorials) OpenLayers creates the map with various default controls.  The basic format (psuedo code follows) is: 

controls: [OpenLayers.Control, OpenLayers.Control, etc...]

2. After the map is created, you can add controls individually by calling map.addControl(new OpenLayers.Control).



Before we get into that though, let's demonstrate how to add a map with no controls.

Map Without Controls

By default, OpenLayers adds a few controls to your map, such as mouse navigation and the pan / zoom bar, unless you tell it not to.  (The full list of default controls added are &lt;a href="http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Control/ArgParser-js.html" title="OpenLayers ArgParse Control" rel="nofollow"&gt;ArgParser, &lt;a href="http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Control/Attribution-js.html" title="OpenLayers Attribution Control" rel="nofollow"&gt;Attribution, &lt;a href="http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Control/Navigation-js.html" title="OpenLayers Attribution Control" rel="nofollow"&gt;Navigation&lt;a&gt;, and &lt;a href="http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Control/PanZoom-js.html" title="OpenLayers Attribution Control" rel="nofollow"&gt;PanZoom



Let's first create a map with no controls to demonstrate. The following code will create a map object with no controls.  The following line is the main relevant bit of code.

 


var map = new OpenLayers.Map('map', { controls: [] });



To see an implmentation of this code, view &lt;a href="http://vasir.net/static/tutorials/openlayers_part3/demo1_no_controls.html" title="OpenLayers Control Example"&gt;OpenLayers Control Part 3 - No controls.

What we're doing here is creating a new OpenLayers.Map object and passing in the ID of the element (typically a div element) that we want the map to appear in.  The next bit ,{ controls: [] } is where we specify additional parameters to pass in to create the map.  Keep in mind these parameters are called in such a way of key: value, with multiple 'keys' separated by commas.  The curly brackets denote that we're passing in key:value pair(s) (in this case, just one key:value pair).  

The key is controls, and the value is [], which is an empty array element in Javascript.  We are passing in no OpenLayers.Controls - basically, we're telling OpenLayers that we want this map object we're creating to have an empty array of controls; i.e. this map will have no controls.

Map With Controls

To add controls, we can either 

1. pass in an array of controls when we instantiate the map (create the map object from the OpenLayers.Map class, like we did above).  We do this by passing in the controls parameters such as { controls: [control1, control2, etc..] } when creating our map, 

 or 

2. add controls after the map has been created.  We do this by called map.addControl() and inside the paranthesis we pass in an OpenLayers Control object - e.g. new OpenLayers.Control.LayerSwitcher()



The second method is what I typically do when creating my maps; it comes in handy especially when you want to allow controls to be added or removed dynamically.  Let's cover how to add a control to the map using both methods.  I'll be using the OpenLayers Overview Map control (yes, the overview map is considered a control) to demonstrate. 

Method 1 - Passing in controls on map creation

There are really two ways to do this.  Because OpenLayers expects you to pass in an array, you can build the array before you actually pass it in, making the code a bit easier to read.  Trying to keep this as simple as possible to those not much experienced with Javascript, we'll use the above example code to demonstrate.  So, let's take a look:


var map = new OpenLayers.Map('map', { controls: [] });



The line here is controls: [] Again, we're passing in an empty array for the controls, so no controls will show up.  We can subsitute a previously created list here instead though, as follows:

var my_controls = []

var map = new OpenLayers.Map('map', { controls: my_controls });



Here we set my_controls equal to an empty array, and pass in my_controls to controls.  Although we have an extra line, we're doing exactly the same thing we did above, only this time we're passing in a previously created array instead of creating it in the map object call.  It doesn't make a lot of sense to do it this way in this example, but once you start adding more than one control to the map, you'll find it makes it much easier to read your code.  



Example

Alright, let's make an actual control now.  We're going to add it to the map the way we just described, by creating a list of controls first.  This will make it easier demonstrate how we can add controls after the map has been created too.  Now, doing it this method we will only have the controls we add to the map, so panning / zooming will not be enabled by default as we are overriding the default controls passed in.  We'll be using the Overview Map control here to demonstrate.

This is the relevant code.

map_controls = [ new OpenLayers.Control.OverviewMap() ];

map = new OpenLayers.Map('map', {controls: map_controls});





The full code can be found at &lt;a href="http://vasir.net/static/tutorials/openlayers_part3/demo2_overview.html" title="OpenLayers Control Example"&gt;OpenLayers Overview Map Control.





Notice the only control is the Overview Map.  We can add more controls by simply seperating them commas.  


map_controls = [ new OpenLayers.Control.OverviewMap(), new OpenLayers.Control.LayerSwitcher() ];

map = new OpenLayers.Map('map', {controls: map_controls});





A demo with this code can be found at &lt;a href="http://vasir.net/static/tutorials/openlayers_part3/demo3_overview.html" title="OpenLayers Control Example"&gt;OpenLayers Overview Map and Layer Switcher Control.



Here we have both the overview map and layer switcher; but nothing else.  Finally, before we move on, let's add those two controls and some of the defaul controls OpenLayers add to have a more functional map.


    map_controls = [ new OpenLayers.Control.OverviewMap(), 

                    new OpenLayers.Control.LayerSwitcher(),

                    new OpenLayers.Control.PanZoomBar(),

                    new OpenLayers.Control.MouseToolbar(), 

                    new OpenLayers.Control.KeyboardDefaults()];

    

    map = new OpenLayers.Map('map', {controls: map_controls});



Notice that the controls are seperated by commas, but I have also added new lines for readability.  The code will work the same if there are no line breaks, but it won't be as readable.  Again, you can see the demo at at &lt;a href="http://vasir.net/static/tutorials/openlayers_part3/demo4_somedefaults.html" title="OpenLayers Control Example"&gt;OpenLayers Adding Base Controls.



Now that we know how this works though, let's move on to something a bit more common.



Method 2 - Adding controls after map has been created

We're going to let OpenLayers add some of the basic controls for us.  You may not want to do this, depending on your own needs for the map - if you dont want to allow users to navigate around the map, for instance, then you should probably add controls manually like the method detailed above. 

Let's set up a map using the default OpenLayers controls and we'll add the Overview and Layer Switcher control to it.


    map = new OpenLayers.Map('map');

    map.addControl(new OpenLayers.Control.OverviewMap());





You can view the demo at &lt;a href="http://vasir.net/static/tutorials/openlayers_part3/demo5_addcontrols.html" title="OpenLayers Adding Controls Example"&gt;OpenLayers Adding Controls.

Since we didn't pass in controls to the map object, the default controls are added automatically.  The next line is where we actually add the control to the map.  

map.addControl(new OpenLayers.Control.OverviewMap()); 

map is our map object we just created, and addControl is a function call we make that -takes in- an OpenLayers Control object and adds it to the map.  In this case, we are passing in new OpenLayers.Control.OverviewMap().  OverviewMap is the class, and we are creating an object from the class by typing new before it.  



If this doesn't make too much sense, don't worry much about it for now - this concept is called Object Orientented Programming, and it is outside the scope of this tutorial.  Without trying to further confuse things, think of a class as a blueprint for a house, and an object as a house created by the blueprint.  This idea applies here; OpenLayers.Control.OverviewMap is a class, which is sort of like the blueprint for an overview map control.  We can't actually do anything with the blueprint though, to manipulate it we need to create an object by called new OpenLayers.Control.OverviewMap(), which basically takes the blueprint and generates an object from it - this object is what we pass into the map.addControl( ) function call, as passing in just the blueprint won't do much good (it'd be similar to opening a door of a house - you can't open a door on the blueprint (the class), but you can open a door on the house (the object)).



We can also make as many calls to addControl as we like, and we can use it in conjunction with any controls we pass in when we create the map...OpenLayers is pretty flexible like that.

RecapTo recap, we can add controls by



1. Passing in an array of controls creating the map

2. Calling the function addControl(Control) and passing in a single OpenLayer control object



Example

Adding controls when map is created

map = new OpenLayers.Map('map', {controls: [new OpenLayers.Control.OverviewMap()] });

Adding controls to an already created map

map.addControl(new OpenLayers.Control.OverviewMap());

There are a plethora of controls we can add to the map, and I won't cover them all, but you can see a list of them at &lt;a href="http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Control/ArgParser-js.html" title="OpenLayers Docs" rel="nofollow"&gt;OpenLayer's Doc Site.

Customizing Controls

So, adding controls is pretty easy, but often we want to customize them a bit.  This part can be a little tricky, as each control has its own set of configuration options - for instance, a permalink control and overview map control do not share the same configuration options.  Some controls can also be placed in an HTML element outside of the map, such as the layer switcher or vector editing toolbar.  We'll first cover configuration basics, and then discuss how to add a control outside a map.



Let's walk through how to customize an overview map control, and by doing so you'll have the necessary knowledge to customize any other control (hopefully).  I'm going to break down control customization into two parts:





1. Instantiation (creation) parameters - handles the actual control options

2. Style (CSS) customization - handles the look / feel / position / style of the control



For this section, I'll use the Overview Map control as an example.  The overview map control does not have the same properties of other controls, so be cognizant of this when adding your own controls.  The best place to find out what we can do when calling an OpenLayer control is at the OpenLayer documentation site, and for this we'll be using &lt;a href="http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Control/OverviewMap-js.html" title="OpenLayers Overview Map Control" rel="nofollow"&gt;OpenLayers Overview Map Control Doc.

1. Customization on Instantiation (creation)

When we create a control, we define what options we want it to be created with.  We can, however, manipulate the control after it is created, but for now let's just stick to defining everything when we create the control.

Here's some code to create an overview map control with a couple properties defined:


    map.addControl(new OpenLayers.Control.OverviewMap(

                {autoPan:true,

                layers: [new OpenLayers.Layer.WMS("OverviewMap",

                    "http://labs.metacarta.com/wms/vmap0", 

                    {layers: 'country_01'})]

                }

                ));





These are the most relevant lines, but you can take a look at the &lt;a href="http://vasir.net/static/tutorials/openlayers_part3/demo6_customize_overview.html" title="OpenLayers Adding Controls Example"&gt;customizing overview map control demo to see it in action.





This may look intimidating, but let's break it down.  

We already know map.addControl(new OpenLayers.Control.OverviewMap( this line.  map is our map object, and addControl is the same function we've been using.  Notice that we are calling the function add just one control, so we only pass one control into the function.  We're creating a new OverviewMap control object and passing it in - still, nothing new here.  The next line is new though.

{autoPan:true,

Notice the curly brackets - this denotes that we're going to start passing in key:value pairs, which are the options we want to set for this control.  autoPan is the key, and true is the value.  Notice the comma afterwards, which means we're going to pass in another key:value pair next.  Before we go to the next line, let's briefly discuss what autoPan:true means.



I'm going to quote the &lt;a href="http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Control/OverviewMap-js.html#OpenLayers.Control.OverviewMap.autoPan" title="OpenLayers Overview Map Doc" rel="nofollow"&gt;OpenLayer Overview Control Documentation page directly so you get an idea how to use it.

autoPan - "{Boolean} Always pan the overview map, so the extent marker remains in the center.  Default is false.  If true, when you drag the extent marker, the overview map will update itself so the marker returns to the center."



What this means is that {Boolean} is the -type- of value that is expected in the key:value pair.  Thus, this means that autoPan expects to receive either true or false for its value.  If we don't pass in autoPan:true when we create our overview control, OpenLayers assumes autoPan is set as false.  We could also explicitly say autoPan:false but this is not necessary, as we know from looking at the docs that OpenLayers assumes the value is false unless otherwise specified.



Ok - so moving along.  The next line looks a bit hairy


layers: [new OpenLayers.Layer.WMS("OverviewMap",

                    "http://labs.metacarta.com/wms/vmap0", 

                    {layers: 'country_01'}) ]



But let's take a look.  All that's going on here is that layers is the key and an array containing a single layer object is the value.  From the &lt;a href="http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Control/OverviewMap-js.html#OpenLayers.Control.OverviewMap.layers" title="OpenLayers Overview Map Doc" rel="nofollow"&gt;OpenLayer docs, layers expects an {Array(OpenLayers.Layer)}. 



What's this mean?  Well, the overview map expects an array of OpenLayers Layer objects to be passed in.  Layers are discussed in detail in the &lt;a href="http://vasir.net/blog/openlayers/openlayers-tutorial-part2-layers/" rel="nofollow" title="OpenLayers Layer Tutorial"&gt;previous tutorial, part 2 - layers. So without getting too detailed here, we're basically passing in a single OpenLayers WMS Layer.  This layer is the only layer in our array, but if we wanted another we could just add a comma and specify as many more layers as we want.  We are also passing in parameters to this new OpenLayers Layer object so we get a different layer for the overview map.  By default, the overview map uses the maps' base layer.



So, my lengthy explanations aside, we see that it isn't too tricky to pass in construction parameters.  We do it when we create our layers, so it's not new - but there are quite a lot of options, and the official OpenLayers docs describe all the options.  All other controls are called and defined the way we just did above, so it's only a matter of figuring out what control and what options you want to specify.  But after we do this, we might want to give it a custom style.  OpenLayers is generally pretty good with allowing customizable controls with CSS style sheets.  

2.Customizing OpenLayers Controls with CSS

Cascading Style Sheets (CSS) allow us to specify how HTML elements look and feel, their size, position, font size, etc. etc.  Anything related to the way the page looks can pretty much be handled via CSS; CSS is a way to customize appearance.  OpenLayers allows us to style our controls with CSS, which makes creating a slick looking map much, much easier.  



All OpenLayers controls have an associated CSS class where we can specify a style we want to apply to it. 



I won't cover much CSS in this post, but CSS basically expects an element with property : value pairs, which can be views as key:value pairs, separated by a semi-colon ( ;  ). Here's the basic structure:

element { key: value; }

Where element is an HTML element (can be an element like div (would apply to all div elements) or an ID (single element) or class (multiple elements) ), key is an attribute of the element (such as width or height) and value is, surprise, the value.  For things like width or height, the value is either a pixel value (like 500px) or a percentage (like 50%).



To define a style for an OpenLayers element, we must access it by class name.  The class names are set up in form of .olControlControlName.  

.olControl is always at the beginning of the classname, and the control name follows.  So, for our overview map, the classname we would need to override the default CSS style is 

.olControlOverviewMap

Notice the period at the beginning, to those unfamiliar with CSS that denotes that what follows the period is a class name.

Now we can override the default styles and make it look like however we want.  Here's an example CSS declaration you can add that will style the overview map on the page; feel free to mess around with the declaration and style it however you would like.


&amp;lt;style&amp;gt;

    .olControlOverviewMap {

        background:#ff0000;

        width:200px;

    }

    .olControlOverviewMapElement {

        background:#00ff00 !important;

    }

&amp;lt;/style&amp;gt;





View the &lt;a href="http://vasir.net/static/tutorials/openlayers_part3/demo7_customize_css.html" title="OpenLayers Adding Controls CSS Example"&gt;overview map css control demo.



Now, this is a good example although it is a little tricky, because styling the overview map is a little tricky.

You'll notice we have the olControlOverviewMap element's background set as red (#ff0000) but the olControlOverviewMapElement element's background as green (#00ff00) and has !important after it.  This is to ensure that the overview map element's background is not overwritten - if we don't include any background, it is blue by default.  This is because OpenLayer's Overview Map control contains another CSS element, namely the OverviewMapElement, and we need to define it also.  Most controls are not set up this way, but the overview map is fairly common and does not exactly follow the same style guidelines as other controls.  

Adding Controls Outside of Map

The last topic we'll cover is how to add a control outside the map.  With the previously discussed code, this should be quite an easy feat to accomplish.  

There are many cases where you might want a control outside the map - a toolbar of buttons in a div that sits on top the map, for instance.  You can also create custom buttons, which will be discussed in depth in a future tutorial.  

There are two main ways to place controls outside the map

1. Place the control itself outside the map

2. Place the control in a "panel" outside the map.  The panel contains a group of controls. 



Placing a control outside the map

To place a control outside the map, we need an element to place it in (we'll use a div with an id of "external_control") and we specify a div parameter when calling the control.  To demonstrate:

HTML Code


&amp;lt;div id="external_control"&amp;gt;&amp;lt;/div&amp;gt;



Javascript Code


var external_control = new OpenLayers.Control.MousePosition({

        div: document.getElementById('external_control') });



map.addControl(external_control);



You can &lt;a href="http://vasir.net/static/tutorials/openlayers_part3/demo8_external_control.html" title="External Controls" rel="nofollow"&gt;view the external control demo here.



We're basically creating a MousePosition control and setting the value of div to equal an HTML element with the element ID of 'external_control'.  The mouse position control is outside the div, in it's own div.  We could apply whatever style we want, either by styling the div itself (without using OpenLayers style classes) or style the control itself (using the .olControlMousePosition class), or both.



Placing a control outside the map in a panel

Panels are basically a collection of controls which can be placed inside or outside of the map.  These are useful for grouping related buttons together, such as pan buttons, zoom buttons, etc.  To demonstrate, we'll build a panel from scratch and add some controls as buttons to it.  We need an HTML element to hold our panel, so we'll do what we did above, but we'll get it an ID of 'panel'


&amp;lt;div id="panel"&amp;gt;&amp;lt;/div&amp;gt;



Now we just need to create the Panel control itself


    var external_panel = new OpenLayers.Control.Panel({

                    div: document.getElementById('panel') });

    map.addControl(external_panel);



The demo code will come shortly.  Right now, this does nothing but create an empty Panel control attached to our 'panel' div element.  We need to now add controls to it.



Control Types

There are three 'types' of controls OpenLayers provides for use in a panel.

1. TYPE_BUTTON

2. TYPE_TOOL

3. TYPE_TOGGLE



TYPE_BUTTON

These controls call an event / trigger an action when clicked.  An example would be a zoom in / out button; once clicked, an event is triggered to zoom the map in



TYPE_TOOL

These controls 'turn on' when clicked and 'turn off' when clicked again.  An example would be the editing buttons on &lt;a href="http://dev.openlayers.org/releases/OpenLayers-2.8/examples/editingtoolbar.html" title="OpenLayers Vector Layer Editing Example"&gt;OpenLayer's Editing Toolbar Example.  Once the control is activated (e.g. the pan button - the button with the hand icon), it stays activated until it is either clicked off or another control is activaed.



TYPE_TOGGLE

These controls are similiar to the TYPE_TOOL, as they are activated and deactived on mouse click; however, they do not affect the state of other controls - meaning, that if a TYPE_TOGGLE button is activated, it will not deactivate other controls.  Only one TYPE_TOOL button can be active at a type, but TYPE_TOGGLE buttons do not carry this restriction.



Adding controls to panels

Alright, so let's get to it.  We're going to put together what we've learned so far to add zoom in and out buttons to the panel outside the map and edit their class to make them look something like a button.  The first step, creating the panel, was done above.  The next step is to simply add two more controls now - one will be a zoom in control, the other a zoom out control.  By default, there is no style associated with these controls when we place them outside the map, as they are called normally by methods such as scrolling in or out.  

Before we describe exactly what we need to do, let's take a look at the docs for the zoom in and out controls - &lt;a href="http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Control/ZoomIn-js.html" title="ZoomIn"&gt;Zoom In control.  You'll notice there's not much there.  It doesn't have any special properties, although it does inherit everything from the base OpenLayers.Control class, so anything we can do to that class we can do to the ZoomIn class.  The ZoomOut class is the same way.  So, we don't need to worry about passing in anything extra really, we'll just create the two controls without passing anything in; here's how we do it.



1. Create and add a panel to the map

2. Create and add a zoom in and a zoom out control to the map

3. Add the zoom in and zoom out controls to the panel

4. Add a style to the two controls



1. Create and add a panel

We've done this above.  We need to create a div with an ID of "panel" and add the corresponding Javascript code.


    var external_panel = new OpenLayers.Control.Panel({

                    div: document.getElementById('panel') });

    map.addControl(external_panel);





2. Create and add a zoom in and a zoom out control to the map

All we have to do is create the controls


    var control_zoom_in = new OpenLayers.Control.ZoomIn();

    var control_zoom_out = new OpenLayers.Control.ZoomOut();



and then add them to the map


    map.addControl(control_zoom_in);

    map.addControl(control_zoom_out);



3. Add the zoom in and zoom out controls to the panel

Alright, so we have those two controls added to the map; we now need to add the controls to the panel.


    external_panel.addControls([control_zoom_in, control_zoom_out]);



You'll notice we call the function addControls.  To add any controls to a panel, we must call this function and pass in an array of controls - even if we only want to add one control (there is no "addControl" function, only addControls)



If we take a look at the map now, we can see that it doesn't look like there is a panel because we haven't applied any styles yet. &lt;a href="http://vasir.net/static/tutorials/openlayers_part3/demo9_panel_no_style.html" title="External Controls in Panel - No CSS" rel="nofollow"&gt;Controls outside map demo in panel - no style

This is because by default, there is no style associated with the zoomin or zoomout controls.  Let's finish up this demo though by adding some CSS

Adding style to controls in panels

The naming convention is the same as we mentioned above for naming controls inside panels, however, as these are controls inside a panel, they have 'states' attached attached to them.  ItemActive or ItemInactive is added to the end of the control's class name.  For example, our zoom in button has the class name

.olControlZoomInItemInactive

Because of the type of this control is a button, its only relevant class is olControlZoomInItemInactive.  When the button is clicked, it does not become active or inactive, but simply triggers the zoomIn event. 

So, let's add some basic style to our controls to make them look a little bit like buttons.  Here's the relevant CSS code I use in the demo below:

.olControlZoomInItemInactive {

    background:url(http://dev.openlayers.org/releases/OpenLayers-2.8/img/zoom-plus-mini.png) no-repeat;

    border:2px solid #232323;

    float:left;

    height:18px;

    margin-right:5px;

    width:18px;

}

.olControlZoomOutItemInactive {

    background:url(http://dev.openlayers.org/releases/OpenLayers-2.8/img/zoom-minus-mini.png) no-repeat;

    border:2px solid #232323;

    float:left;

    height:18px;

    margin-right:5px;

    width:18px;

}




I'm just using the zoom-minus and zoom-plus images from OpenLayer's website to represent buttons, but you stlye them however you'd like.  

Take a look at the finalized example here - &lt;a href="http://vasir.net/static/tutorials/openlayers_part3/demo9_panel_with_style" title="External Controls in Panel - With Style" rel="nofollow"&gt;Controls outside map demo in panel with CSS style



Conclusion

With this tutorial, hopefully you've learned how to add controls to an openlayers map, customize them a bit, give them some style, and add controls and panels outside a map.  Although this tutorial was a bit lengthy, it really just scratches the surface of what is possible to do with OpenLayers controls. The OpenLayers Event system can be used to create your own custom controls.






&lt;link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/default.min.css"&gt;

.hljs{display:block;overflow-x:auto;padding:0.5em;background:#fdf6e3;color:#657b83}.hljs-comment,.hljs-quote{color:#93a1a1}.hljs-keyword,.hljs-selector-tag,.hljs-addition{color:#859900}.hljs-number,.hljs-string,.hljs-meta .hljs-meta-string,.hljs-literal,.hljs-doctag,.hljs-regexp{color:#2aa198}.hljs-title,.hljs-section,.hljs-name,.hljs-selector-id,.hljs-selector-class{color:#268bd2}.hljs-attribute,.hljs-attr,.hljs-variable,.hljs-template-variable,.hljs-class .hljs-title,.hljs-type{color:#b58900}.hljs-symbol,.hljs-bullet,.hljs-subst,.hljs-meta,.hljs-meta .hljs-keyword,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-link{color:#cb4b16}.hljs-built_in,.hljs-deletion{color:#dc322f}.hljs-formula{background:#eee8d5}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}


hljs.initHighlightingOnLoad();&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/s6nbzZQyi1I" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/5yw9Nfxlt80" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/HPMTvSx1QRk" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/nPq8OCeexLU" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/openlayers/openlayers-tutorial-part-3-controls</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/s6nbzZQyi1I/openlayers-tutorial-part-3-controls</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/5yw9Nfxlt80/openlayers-tutorial-part-3-controls</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/HPMTvSx1QRk/openlayers-tutorial-part-3-controls</feedburner:origLink></item>
    
    <item>

        <title>OpenLayers Tutorial - Part 2: Layers</title>
        <pubDate>Tue, 02 Feb 2010 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/DUez7_Q4NDE/openlayers-tutorial-part-2-layers</link>
        <guid isPermaLink="false">http://vasir.net/blog/openlayers/openlayers-tutorial-part-2-layers</guid>
        <category>OpenLayers&gt;</category>


        <description>Layers are, basically, OpenLayer's way of showing different map services.  The term may seem confusing when combined with an individual map service's layer term.  The broadest explanation I can provide for the moment is that an OpenLayer Layer is an object inside OpenLayers that contains a single map service. 

This is going to be a rather in depth tutorial.  Here's how it's set up




Part A - URL Calls (Emphasis on WMS)

Part B - Layer Class





Part A - OpenLayers URL Calls





In essence, OpenLayers basically provides a nice way to automatically call other map services, get back a lot of results, and piece them together to form a map.  Now, for a map service like Google Maps or a vector layer the logic is a bit different, but for the WMS service and other map services that accept a URL this is the basic process.  This may seem a bit abstract, so let's look at how OpenLayers makes a map using a WMS layer.



OpenLayers Layer - WMS Process

OpenLayers is basically calling the URL you provide, adding parameters to the URL that act as GET variables (based off the parameters you pass in when you define the layer), getting back an image, and placing all the images together coherently as to form a large map image. 



To clarify - If you have a map div that is 500pixels x 500pixels big, OpenLayers would make four separate calls to the URL you provide to get back four different images and place the four images side by side to form the 500 x 500 map.  (You could also just tell it to get back an image 500 x 500 pixels big, along with telling it to get back more images outside the viewing area so the panning around is more seamless, etc. We will cover this later)



So, with that in mind, let's start taking a look at a WMS URL.

&lt;a href="http://labs.metacarta.com/wms/vmap0?request=getCapabilities&amp;amp;service=WMS" rel="nofollow" title="WMS Get Capabilities"&gt;http://labs.metacarta.com/wms/vmap0?request=getCapabilities&amp;amp;service=WMS





This is the url to get an XML that contains detailed information about the WMS service. The first part of the url, http://labs.metacarta.com/wms/vmap0 contains the actual URL you pass into the OpenLayers Layer url parameter.  



Next we have a ? followed by a key = value pair of variables.  If you go to the url without passing ?request=getCapabilities&amp;amp;service=WMS you won't see much.  But, by passing the a request of getCapabilities AND (&amp;amp;) a service variable with the value WMS you will get an XML file with a bunch of useful information in it (e.g., a list of layers you can use).



For a service like WMS, many layers can be specified in the WMS parameter calls, but OpenLayers considers the entire WMS service -one- layer (even though the request itself may ask for multiple layers). The WMS Layer is one of the more popular layers used, so I'll first spend a moment discussing it.



To elucidate this further, here's some example code that shows



1. A single OpenLayers WMS Layer object with only one WMS layer parameter specified



map = new OpenLayers.Map('map');

    var wms = new OpenLayers.Layer.WMS(

    "OpenLayers WMS",

    "http://labs.metacarta.com/wms/vmap0",

        {layers: 'basic'}

    );


Take note of the {layers: 'basic'} code.  This sets the "layers" parameter of the OpenLayers WMS Layer to "basic"





2. A single OpenLayers WMS Layer object with two WMS layer parameters specified


map = new OpenLayers.Map('map');

    var wms = new OpenLayers.Layer.WMS(

    "OpenLayers WMS",

    "http://labs.metacarta.com/wms/vmap0",

        {layers: 'basic, ground_01'}

    );




Notice the "layers" parameter is set to 'basic,ground_01'.  This means that the WMS service will return an image that has both the 'basic' and 'ground_01' layers turned on.  Those two WMS layers are grouped into the OpenLayer Layer and are considered one OpenLayer Layer.





What exactly is happening here though? 

Well, the parameters you define (explained later) such as layers: 'basic' are passed into the URL for the layer (in this case, http://labs.metacarta.com/wms/vmap0).  Thus, a url is generated from the layer definition you provide in OpenLayers.  Here's what one piece of the map looks like from the first example (you can test this yourself by opening the example map you created from part I and using the firebug addon for firefox to inspect the map element and get the img that is generated and copying the URL).



&lt;a href="http://labs.metacarta.com/wms/vmap0?LAYERS=basic&amp;amp;SERVICE=WMS&amp;amp;VERSION=1.1.1&amp;amp;REQUEST=GetMap&amp;amp;STYLES=&amp;amp;EXCEPTIONS=application%2Fvnd.ogc.se_inimage&amp;amp;FORMAT=image%2Fjpeg&amp;amp;SRS=EPSG%3A4326&amp;amp;BBOX=-180,-90,0,90&amp;amp;WIDTH=256&amp;amp;HEIGHT=256" rel="nofollow"&gt;http://labs.metacarta.com/wms/vmap0?LAYERS=basic&amp;amp;SERVICE=WMS&amp;amp;VERSION=1.1.1&amp;amp;REQUEST=GetMap&amp;amp;STYLES=&amp;amp;EXCEPTIONS=application%2Fvnd.ogc.se_inimage&amp;amp;FORMAT=image%2Fjpeg&amp;amp;SRS=EPSG%3A4326&amp;amp;BBOX=-180,-90,0,90&amp;amp;WIDTH=256&amp;amp;HEIGHT=256



If you copy and paste the above URL into your browser, you should see a map image of the Americas and Antartica.  OpenLayers makes numerous calls to the URL and gets numerous images like this back, pieces them together, and lets you manipulate them through the interface with controls (which is the topic of the next tutorial).  Don't get overwhelmed yet though.  Let's break apart the URL.



http://labs.metacarta.com/wms/vmap0  - This is the base URL that is defined in the OpenLayers Layer definition.  Everything after this is generated by OpenLayers based on the parameters you specify in the Layer definition. 



? - This is a question mark which signifies everything after it will be a attribute=value pair.  These are GET variables (what you're doing here is basically giving the server information through the URl.  For example, a GET call could look like http://server.com?username=Foo.  By calling that specific URL, you're passing in the username of 'Foo' to the server.  Multiple pairs are separated by &amp;amp;.  E.g., http://server.com?username=Foo&amp;amp;password=Bar)



LAYERS=basic - Look familiar?  The LAYERS parameter gets it value from the {layers: 'basic'} in the OpenLayers Layer definition.  



&amp;amp;SERVICE=WMS - The service is WMS.  OpenLayers knows this because the Layer definition is a OpenLayers.Layer.WMS object.  



The rest of the GET variables are automatically generated for you using default values.  You can, however, override them.

Let's skip a couple of attribute=value pairs and find the BBOX value.



&amp;amp;BBOX=-180,-90,0,90  - This is where you tell the service what part of the map you want to look at.  This is where OpenLayers does a lot of its magic too.  Imagine you have a map that is composed of two images.  Now, with this example it'd be trivial to determine what two URL calls you need to make to get those two images (that two URL calls would be identical except for the BBOX parameter, where one would be -180,90,0,90 and the other would be 0, -90, 180, 90. You can try this yourself by going to 

&lt;a href="http://labs.metacarta.com/wms/vmap0?LAYERS=basic&amp;amp;SERVICE=WMS&amp;amp;VERSION=1.1.1&amp;amp;REQUEST=GetMap&amp;amp;STYLES=&amp;amp;EXCEPTIONS=application%2Fvnd.ogc.se_inimage&amp;amp;FORMAT=image%2Fjpeg&amp;amp;SRS=EPSG%3A4326&amp;amp;BBOX=-180,-90,0,90&amp;amp;WIDTH=256&amp;amp;HEIGHT=256" rel="nofollow"&gt;http://labs.metacarta.com/wms/vmap0?LAYERS=basic&amp;amp;SERVICE=WMS&amp;amp;VERSION=1.1.1&amp;amp;REQUEST=GetMap&amp;amp;STYLES=&amp;amp;EXCEPTIONS=application%2Fvnd.ogc.se_inimage&amp;amp;FORMAT=image%2Fjpeg&amp;amp;SRS=EPSG%3A4326&amp;amp;BBOX=-180,-90,0,90&amp;amp;WIDTH=256&amp;amp;HEIGHT=256



and changing the BBOX parameters to see how the image is affected).   



So, pulling two images and piecing them together yourself is trivial.  But now imagine a more realistic situation where you map is composed of 10 of these images.  This would be a bit harder to do - but now imagine that the user zooms in, or pans the map around.  You would have to recalculate the BBOX parameters for every interaction.  OpenLayers does this automatically.



Go ahead and play with the parameters of 



&lt;a href="http://labs.metacarta.com/wms/vmap0?LAYERS=basic&amp;amp;SERVICE=WMS&amp;amp;VERSION=1.1.1&amp;amp;REQUEST=GetMap&amp;amp;STYLES=&amp;amp;EXCEPTIONS=application%2Fvnd.ogc.se_inimage&amp;amp;FORMAT=image%2Fjpeg&amp;amp;SRS=EPSG%3A4326&amp;amp;BBOX=-180,-90,0,90&amp;amp;WIDTH=256&amp;amp;HEIGHT=256" rel="nofollow"&gt;http://labs.metacarta.com/wms/vmap0?LAYERS=basic&amp;amp;SERVICE=WMS&amp;amp;VERSION=1.1.1&amp;amp;REQUEST=GetMap&amp;amp;STYLES=&amp;amp;EXCEPTIONS=application%2Fvnd.ogc.se_inimage&amp;amp;FORMAT=image%2Fjpeg&amp;amp;SRS=EPSG%3A4326&amp;amp;BBOX=-180,-90,0,90&amp;amp;WIDTH=256&amp;amp;HEIGHT=256





Remember, these parameters will correspond to the ones you define in the OpenLayers Layer definition.





Part B - Layer Class

The OpenLayers Layer class is what we use to specify the layers on the map.  OpenLayers provides support for a multitude of mapping services, including WMS, WFS, Google Maps, Bing Maps, even a Vector layer that supports KML and various other formats.  There's even an image layer that allows you to use an image as a map - e.g., you could use a high res picture of an antique map, an image of a map of a video game, or an image of something that's not a map at all.  





Let's take a look at OpenLayer's extensive documentation.  

&lt;a href="http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Layer-js.html" title="OpenLayers documentation" rel="nofollow"&gt;http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Layer-js.html

This is the place to go to find out information about what a specific function or class supports. We're taking a look specifically at the Layer class here though.



Notice that there's a summary of the properties, constraints, properties, and functions that are part of the Layer class. On the left hand side of the page, there's a Layer dropdown that provide even more specific information for the Layer service of your choice.  This part will focus on the base Layer class though, and the next part of the tutorial will cover the specific Layer classes.



Generally, the Layer class is defined with the following structure 


Title,

URL of WMS service,

{Params},

{Properties}





A concrete example would be, as we've seen before:


var wms = new OpenLayers.Layer.WMS(

    "OpenLayers WMS",

    "http://labs.metacarta.com/wms/vmap0",

        {layers: 'basic'}

    );


Let's first go through this line by line.  Now, keep in mind that code is specific for the WMS Layer class. &lt;a href="http://dev.openlayers.org/docs/files/OpenLayers/Layer/WMS-js.html" rel="nofollow" title="OpenLayers WMS Class documentation"&gt;WMS Layer Doc for a complete class description.



var wms = new OpenLayers.Layer.WMS(

var wms - will be an OpenLayer.Layer.WMS object.  i.e., wms is an instantiated object based on the Layer.WMS class.  (If you are unfamiliar with object oriented programming, the basic idea is that a class is similar to a blueprint of a house and an object is the actual house created based on the blueprint.  We interact with objects that are generated from classes.)

new OpenLayers.Layer.WMS - this creates a new object using the OpenLayers.Layer.WMS class.

( - Here we begin passing in parameters


"OpenLayers WMS", - This is the title of the layer.  The title what is displayed on the layer switcher control (which we'll cover in the next tutorial) and is completely arbitrary, you can call it whatever you'd like.


http://labs.metacarta.com/wms/vmap0", - this is the URL we'll be using for the layer

{layers: 'basic'} - Now we start passing in params (parameters).  We pass in key: value pairs separated by commas.  e.g., { layers: 'basic', transparent: 'true' }.  The params represent the GetMap url string discussed above.  The GetMap call will provide you with parameters you can define.

); - finish the call



Notice we did not specify any properties in this layer.  We'll get to that in a moment.





Now I'm going to shamelessly plug my Google Summer of Code 08 project, OpenLayers Architect.  I'll be using it occasionally to demonstrate various things.  You can reach it at &lt;a href="http://olarchitect.com/" title="OpenLayers Architect - Create a webmap"&gt;OLArchitect.com.

Now, if you select a layer from the drop down list and hit "create" further options will appear on the left hand side.  These are all the properties available for that layer that were in place as late 2008 with a prior version of OpenLayers.  Almost all, if not all, the properties should still work.  If you save the layer then click the save and create map button the right hand side of the page, code will be generated. You can play around with it to see how it generate code based on your input.







Now, let's take a look at some more WMS layer code


layer0 = new OpenLayers.Layer.WMS( 'Layer Name', 

    'http://labs.metacarta.com/wms/vmap0?',

        {layers: 'basic'},

        {projection: new OpenLayers.Projection('4362')}

    );


The code is the same as before but notice the new projection attribute.

Properties

We have neglected to mention properties yet.  They are, however, pretty important.  By default, most properties are inherited from the map - e.g., the projection.  Params and Properties of the WMS layer refer to different settings.  



Params, the first dictionary object ( which in Javascript looks like a set of brackets { }'s with key:value pairs) corresponds to the parameters for the WMS service itself.  These params not be usable for a Google map layer or most other layers.

Properties, the optional second dictionary object, contains OpenLayers Layer settings.



Let's look at some code.



{projection: new OpenLayers.Projection('4362')}

 This is the properties object which in this case specifies the current layer's projection.



Let's go back to the OpenLayers API docs &lt;a href="http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Layer-js.html" title="OpenLayers documentation" rel="nofollow"&gt;OpenLayers docs.



Notice the list of properties.  These are the properties you can use in that properties object in the OpenLayer Layer definition. Again, these are separated by commas and are key: value pairs.  E.g., the properties object might look like 


{ buffer:2, gutter: '1', isBaseLayer: 'True' }




The specific properties are described within the linked doc.  buffer is basically how many tiles the map will draw outside the viewing area so navigation is more seamless.  isBaseLayer determines if the map is considered a base or overlay layer.  The difference is subtle and the concept will pop up when we discuss the layer switcher control.  

The main concept is that an base layer is used for what it sounds like - being the base layer.  If the isBaseLayer is not defined, it will be on or by default, depending on the layer service and how many layers are in the map.  If there are two WMS layers, you could have one layer be the base layer, e.g., a map of the earth, and the second layer be toggle-able layer of weather data.  



Conclusion

There will be more tutorials about specific Layer Classes - such as Google Maps and Vector Layers, but each are broken into their own post.  The next general tutorial will be OpenLayers Tutorial Part III - Controls.  We'll discuss what a control is, how to implement them, and how to customize them.







Ready for the next post?  Continue to 

&lt;a href="/blog/openlayers/openlayers-tutorial-part-3-controls" title="OpenLayers Tutorial - Part 3 - Controls"&gt;OpenLayers Tutorial - Part 3 - Controls





&lt;link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/default.min.css"&gt;

hljs.initHighlightingOnLoad();&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/Zdk1a-IIeg4" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/ypHMB97E2l0" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/ZCJMjn4UbWs" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/DUez7_Q4NDE" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/openlayers/openlayers-tutorial-part-2-layers</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/Zdk1a-IIeg4/openlayers-tutorial-part-2-layers</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/ypHMB97E2l0/openlayers-tutorial-part-2-layers</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/ZCJMjn4UbWs/openlayers-tutorial-part-2-layers</feedburner:origLink></item>
    
    <item>

        <title>OpenLayers Tutorial - Part 1: Introduction</title>
        <pubDate>Sat, 03 Oct 2009 00:00:00 GMT</pubDate>
        <link>http://feedproxy.google.com/~r/ErikHazzard/~3/RJsU4SOAXkI/openlayers-tutorial-part-1-introduction</link>
        <guid isPermaLink="false">http://vasir.net/blog/openlayers/openlayers-tutorial-part-1-introduction</guid>
        <category>OpenLayers&gt;</category>


        <description>This is the first part in a series of OpenLayers tutorials.  The goal of this article is to provide an overview of OpenLayers, show what it can do, and begin working with the code.

OpenLayers is an OpenSource, javascript based web mapping platform.



OpenLayers easily supports a wide variety of various map sources - WMS, WFS, Google Maps, Microsoft's Bing, and many many more.  There are many built into tools, such as scale bars, overview maps, zoom bars, and many more; but OpenLayers also supports custom tools and allows for intricate configuration of existing ones.

Useful OpenLayers links

OpenLayers - &lt;a href="http://openlayers.org/"&gt;http://openlayers.org

OpenLayers API docs - &lt;a href="http://dev.openlayers.org/apidocs"&gt;http://dev.openlayers.org/apidocs

OpenLayers Examples - &lt;a href="http://openlayers.org/dev/examples"&gt;http://openlayers.org/dev/examples





OpenLayers Examples

The follow examples are pulled directly from http://openlayers.org/dev/examples



Simple WMS map- http://openlayers.org/dev/examples/wms.html

Vector layer manipulation - http://openlayers.org/dev/examples/vector-formats.html

Google Map layer - http://openlayers.org/dev/examples/google.html

ArcGIS 9.3 REST API Interaction - http://openlayers.org/dev/examples/arcgis93rest.html



Section 1 - First OpenLayers Map

We'll start with a basic map.  As OpenLayers is Javascript based, some working knowledge of how to program in Javascript is helpful, but expertise is by no means required.  First we'll take a look at the code then break it apart.



Create and show a simple OpenLayers Map

Step 1.  Create a folder called "OLTutorial".  If working in windows, this tutorial assumes you are placing the folder in your C:\ drive ( so the full path would be C:\OLTutorial )



Step 2. Create a file called index.html (If you're on windows, you will probably need to disable the "Hide extensions for known file types" option.  &lt;a href="http://www.wikihow.com/Disable-Hidden-File-Extensions-in-Windows-XP" title="File Extension Hiding" rel="nofollow"&gt;How to disable hidden file extensions in windows xp)



Step 3.  Input the following code


&amp;lt;html&amp;gt;

&amp;lt;head&amp;gt;

&amp;lt;script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"&amp;gt;&amp;lt;/script&amp;gt;

&amp;lt;script type="text/javascript"&amp;gt;

var map;

function init() {
    map = new OpenLayers.Map('map');
    var wms = new OpenLayers.Layer.WMS(
        "OpenLayers WMS",
        "http://labs.metacarta.com/wms/vmap0",
        {layers: 'basic'}
    );
    map.addLayers([wms]);
    map.zoomToMaxExtent();
}

&amp;lt;/script&amp;gt;

&amp;lt;/head&amp;gt;

&amp;lt;body onload="init()"&amp;gt;

&amp;lt;div id="map" style="width: 600px; height: 300px"&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;/body&amp;gt;



Step 4. Save the file then open it in your browser.



You should see a very simple OpenLayers map.

Explanation

The above OpenLayers example requires, essentially, only three things.

1. The location of the OpenLayers library

2. An HTML element (a div in this case) to hold the map

3. Javascript code to define the OpenLayers map and tell the map where to point to (again, in this case, a div)



The location of the OpenLayers library in this example points to the OpenLayers.js file on the OpenLayers server.  You are free to download the full OpenLayers code and run it locally, pointing your script src="..." equal to the location of the OpenLayers library on your harddrive.



Let's look at the code line by line.

&amp;lt;html&amp;gt;

&amp;lt;head&amp;gt;

&amp;lt;script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"&amp;gt;&amp;lt;/script&amp;gt;



Line 1 and 2 begin the HTML document and start the HEAD section of the index.html page.  The HEAD section is where our script code will reside.

Line 3 points to the OpenLayers library.  You must include the OpenLayers library before you try to use OpenLayers code.  The library contains the OpenLayers codebase - our code relies on the OpenLayers library, and without it our code would not work.



&amp;lt;script type="text/javascript"&amp;gt;

	var map;


Line 1.  begins a new script tag and will hold our Javascript code to create the OpenLayers map.

Line 2.  Creates a global variable called "map" which will act as our map object, which will hold the OpenLayers map itself.


function init() {
	map = new OpenLayers.Map('map');

	var wms = new OpenLayers.Layer.WMS(
		"OpenLayers WMS",
		"http://labs.metacarta.com/wms/vmap0",
        {layers: 'basic'}
	);


&amp;gt;This init function will initialize the map, creating the OpenLayers map and assign a layer to it.



Line 1.  Create a function called init without passing anything into the function.

Line 2.  We're using the map object previously declared above.  Here, we're assigning the previously empty map variable to an OpenLayers map object via



our code:  new OpenLayers.map('map');

general code:  new OpenLayers.map('ELEMENT NAME');



new creates a new OpenLayers map object.  We are passing in 'map', which is a string containing the name of element we want the OpenLayers map to appear in on the webpage.  In this example, we have a div element with the id of 'map'. If this div's id was named something else, we would pass in the that div's id name instead of 'map'.



Line 3.  Here we're creating a wms variable which will hold an OpenLayers layer object.  We call new to create an OpenLayers Layer WMS object.  For other layer types, such as WFS or Google Maps, the call is similar but WMS is replaced with the layer service.   The full list of support layers and how to call them can be found at http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Layer-js.html.



At the end of the line we have a opening parenthesis, which means that we're going to pass in some configuration stuff to this OpenLayers Layer object.



It is important to keep in mind that the following configuration code will of course differ for you, but also that the configurations will be different for different layer services.  Consult the linked documentation files above for more detailed information.



Line 4.  This line specifies an arbitrary title of the layer we're creating.



Line 5.  This is the URL of the WMS service



Line 6.  This is a dictionary of options the Layer object uses to generate the layer.  In this case, we want the "basic" layer from the layers of the WMS service we're calling.  You can call getCapabilities on the WMS url to view a list of layers the WMS service contains.  



    Note - we can specify as many WMS service layers we want to display in our OpenLayers Layer object.  For example, we could show three layers from the WMS service in a -single- OpenLayers Layer.  

    

    

    http://labs.metacarta.com/wms/vmap0?service=WMS&amp;amp;request=getCapabilities

    The above URL calls getCapabilities for the WMS service we're using for this OpenLayers Layer.  If we look at that URL in our browser it will show us an XML file.  We can see what layers the WMS service has by looking for LAYER tags and looking at the NAME.  For example, this XML files contains

    
    ...

	    &amp;lt;Layer&amp;gt;

		    &amp;lt;Name&amp;gt;basic&amp;lt;/Name&amp;gt;

    ...

    

    This 'basic' layer is the 'basic' layer we are referring to in { layers: 'basic'} 





Back to the code...


	map.addLayers([wms]);
	map.zoomToMaxExtent();
}


Line 1.  We're adding the newly defined wms layer to the map here.  We can add multiple layers at once, but in this case we are just passing in one.  Regardless, the addLayers function expects a list of layers, so we must pass in a list via ([ layername ])



Line 2.  After we've defined the map and added a layer to it, we need to tell the map what extent to display.  If we don't do this, the map doesn't know what to display.

So, in this case, we tell the map to zoom to the max extent - in other words, we are telling the map to show everything is can.



Line 3.   Finishes the init function.


&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;

&amp;lt;body onload="init()"&amp;gt;

&amp;lt;div id="map" style="width: 600px; height: 300px"&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;/body&amp;gt;


Line 1.  Closes the script tag



Line 2.   Closes the head tag



Line 4.  Starts the body tag and call init() when the body has finished loading.



Line 5.  Create a div with the id of map which the OpenLayers Map object will render to.  The div can be styled however you like.  We'll just make a 600 x 300px big map for this example though.



Line 6.   Closes the body

Conclusion

That's all that's required to get a map up and running!  There are a myriad of controls, layers, and options that we haven't even mentioned (yet!).  The next tutorial will discuss the OpenLayers Layer class more and touch briefly on controls.  Again, more examples and details can be found through the OpenLayers.com API or on the OpenLayers irc channel at irc.freenode.net in the #openlayers channel.




    Ready for the next post?  Continue to 
    &lt;a href="/blog/openlayers/openlayers-tutorial-part-2-layers/" title="OpenLayers Tutorial - Part 2 - Layer Class"&gt;OpenLayers Tutorial - Part 2 - Layers





&lt;link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/styles/default.min.css"&gt;

hljs.initHighlightingOnLoad();&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/hH-b5hs6-XE" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/TgISs-L6Rf4" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/Utmcbec3JJI" height="1" width="1" alt=""/&gt;&lt;img src="http://feeds.feedburner.com/~r/ErikHazzard/~4/RJsU4SOAXkI" height="1" width="1" alt=""/&gt;</description>

    <feedburner:origLink>http://vasir.net/blog/openlayers/openlayers-tutorial-part-1-introduction</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/hH-b5hs6-XE/openlayers-tutorial-part-1-introduction</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/TgISs-L6Rf4/openlayers-tutorial-part-1-introduction</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/ErikHazzard/~3/Utmcbec3JJI/openlayers-tutorial-part-1-introduction</feedburner:origLink></item>
    

    </channel>
</rss>