January 2009 - Posts

Jan 16 2009

fallout_3_logo.jpg

I'm using use a videogame as an example for this post, but there are a lot of other examples available.

Fallout 3 is a recent videogame released by Bethesda, a mature RPG maker company. Fallout 3 is an RPG settled in a post-apocalyptic future, based on Oblivion's engine.

The engine has been upgraded to support 2x polygons than the original, the mechanics are more complex (but still similar), but more important, the game has a lot of content. You can find dozens of terminals with notes, logs and messages that just add lore to the game. Hundreds of conversations (with multiple paths), hundreds of npcs, world-shifting decisions (for example, you can blow a bomb and take out a whole town for the rest of the game, and the story keeps being logical after that)...

If they decided to rebuild from scratch a new engine, we would probably haven't seen the game until a year or two later. By using an existing, improved one, they have clearly focused on making the content as rich as possible.

 

Sometimes the best solution is to create something new. But sometimes the best approach is to take something that really works, and use it (using does not mean not being able to make it better).

 

Note: The game engine is not free of flaws. For example, on pc there are some problems with graphic drivers that I myself have suffered when downloading and installing the latest NVidia drivers (at least it was all fixed fast). But the overall is a better game that it would have been if developed with the same resources and time constraints with a fully new engine.

Jan 13 2009

Lately I’ve been plauing a bunch of games. Most of them are the typical “best of the moment” ones: GTA IV, Fallout 3, Left 4 Dead, Gears of War 2… But also, both from friend advices and from trying the demos, I’m playing a few quite interesting and unusual games, and as not everything is coding, here they are for those who love playing too:

  • World of Goo: A perfect combination of fresh logic game with cute graphics and sounds. Yoo have to join “goos” (sticky balls of different types) to reach an exit pipe, with dozens of levels and increasing difficulty.
    World of Goo
  • Crayon Physics Deluxe: Another fresh idea: Painting boxes, circles, ropes you have to make a red ball touch a star. All with incredible physics (that allow a lot of different ways of finishing each level) and nice (but simple) graphics. An interesting feature is that it is done with TabletPCs in mind.
    crayon_physics_deluxe.jpg
  • Defense Grid: It would look at first as a simple commercial Tower Defense game, but I can’t remember the last time that I played for 7 hours non-stop a game, and it happened with this one. Nice graphics, well designed levels, adjusted difficulty and “challenge modes” provide lots of hours.
    defense_grid.jpg
  • Patapon: This is the most strange game of the list. A mixture of 2D real-time strategy and rhythm matching, with some RPG elements. Has great Flash-like graphics, tiny (it’s for the PSP) but full of detail. Beware, after playing it for a while, you will start singing the drum commands (pata-pata-pata-pon!).
    The only failure of the game is the apparent lack of variety in those commands (but I have only played a few levels and discovered 3 drums yet).
    patapon.jpg
  • Defcon: Did you ever wished to see a nuclear war strategy game like the one from WarGames film? Defcon is your dream come true. And now with a new bot API to create true computer wars.
    defcon.jpg

 

 

 

 

Except for Patapon (which I’m not sure), all the four others come from indie game companies, so my message is: Triple-AAA games look gorgeous and “almost everybody plays them”, but if you want really fresh or addicting games, look out for indie ones ;)

Jan 06 2009

I've been using Feedburner for a few years to keep track of RSS statistics (and as a proxy to be able to move my blog without feed readers being affected).

Until last week, I used a third party free tool, Feed Analysis, to show a public graph of the stats of all blogs in Kartones.Net (in the Stats page). But after Google bought Feedburner, I decided to migrate the account to Google, and that tool stopped working.

I knew the existence of Feedburner's Awareness API before, but hadn't touched it because I don't know Flash or any other way of creating a stats chart easily.

Recently, Microsoft released the new ASP.NET Charting Control, and I went the "do it yourself" way of implementing my own stats using it.

I requested an upgrade of my hosting provider to ASP.NET 3.5 SP1 + installing the chart control (it's a bit dumb to force you to install it instead of deploying an assembly, but ok, I can live with that), and started developing the "chart" page that would display the stats.

First, accessing the Feedburner API. You have to activate it in each of your feeds configured in Feedburner:

feedburner_awareness_api.jpg

Then, a simple HTTP Request + Response will fetch the results in XML (I will only list the important fragments of code, not all, and almost no error catchings):

private const string feedburnerAPIURL =
   
"https://feedburner.google.com/api/awareness/1.0/GetFeedData?uri={0}&dates={1},{2}";

...

HttpWebRequest request;
HttpWebResponse response
;
string
responseXMLString
;

request =
(HttpWebRequest)WebRequest.Create(
   
string.Format(feedburnerAPIURL, feedURI, statsStartingDate, statsEndingDate))
;
request.Method = "GET"
;

...

response = (HttpWebResponse)request.GetResponse();
StreamReader streamReader
=
    new
StreamReader(response.GetResponseStream(), Encoding.GetEncoding(1252))
;
responseXMLString = streamReader.ReadToEnd()
;
streamReader.Close()
;
response.Close();

...

 

statsStartingDate and statsEndingDate must be in YYYY-MM-DD format.

We should then check that response code is OK:

...

responseXML = new XmlDocument();
responseXML.Load(new StringReader(responseXMLString))
;
XmlNode node = responseXML.SelectSingleNode("/rsp")
;
return
(node.Attributes.GetNamedItem("stat").Value == "ok");

...

 

I store the opened XmlDocument for the actual stats entries parsing (to avoid reopening it).

I've built two tiny structs to store an individual entry and the list of entries (along with max. and min. values of each field). So I fill it:

...

XmlNodeList entries = responseXML.SelectNodes("/rsp/feed/entry");

results.Entries = new FeedburnerEntry[entries.Count]
;
for
(int index = 0; index < entries.Count;
index++)
{
    results.Entries[index].Date
=
       
DateTime.Parse(entries[index].Attributes.GetNamedItem("date").Value)
;

    results.Entries[index].Circulation
=
        long
.Parse(entries[index].Attributes.GetNamedItem("circulation").Value)
;
            
    results.Entries[index].Hits
=
        long
.Parse(entries[index].Attributes.GetNamedItem("hits").Value)
;

   
results.Entries[index].Reach
=
        long
.Parse(entries[index].Attributes.GetNamedItem("reach").Value)
;
}

...

 

I won't go into details of creating a new chart, the samples are quite good for it, so I'll just point that a lot of configuration can be made in the markup definition of it (2D or 3D, transparency, colors, labels, data types...):

<asp:Chart ID="feedChart" runat="server" Height="480" Width="640" BorderDashStyle="Solid" 
    imagetype
="Png" BorderWidth="1" BorderColor="#6F5F08" TextAntiAliasingQuality="Normal"

    Palette
="BrightPastel" BackSecondaryColor="#FFFFFF" BackGradientStyle="TopBottom" 
    backcolor
="#DDDBC7" AntiAliasing="All" >

   
<borderskin skinstyle="Emboss" />
    <
legends>

       
<asp:Legend IsTextAutoFit="False" Name="Default" BackColor="Transparent" 
            BorderWidth
="1" BorderColor="#000000" BorderDashStyle="Solid"

            Font
="Trebuchet MS, 8.25pt, style=Bold" Alignment="Near" Docking="Bottom" />
        </
legends>

       
<series />
        <
chartareas>

           
<asp:ChartArea Name="chartArea" BorderColor="#404040"
                BackSecondaryColor
="White" BackColor="96, 189, 182, 124" 
                BackGradientStyle
="TopBottom" Area3DStyle-Enable3D="true">

               
<area3dstyle Rotation="10" Perspective="10" Enable3D="True" 
                    LightStyle
="Realistic" Inclination="10" PointDepth="200"
 
                    IsRightAngleAxes
="False" WallWidth="0" IsClustered="False" 
/>
                <
axisy LineColor="32, 64, 64, 64" Interval="50">

                   
<LabelStyle Font="Trebuchet MS, 8pt" />
                    <
MajorGrid LineColor="32, 64, 64, 64" 
/>
                </
axisy>

               
<axisx LineColor="32, 64, 64, 64" Title="Date" TitleAlignment="Center"
                    TitleFont
="Trebuchet MS, 12pt" IntervalOffsetType="Days"
                    IntervalType
="Days">

                   
<LabelStyle Font="Trebuchet MS, 8pt" />
                    <
MajorGrid LineColor="32, 64, 64, 64" 
/>
                </
axisx>

           
</asp:ChartArea>
       
</chartareas>
</asp:Chart>

 

The chart area is where the chart will be painted, and the series (which I leave empty because I fill define and fill it via code) are the groups of points (for example, a series can be one curved line plus one bar graph).

 

Filling the data at code is pretty easy too:

FeedburnerEntryList feed = feedburnerFeed.GetEntries();

Series circulationGraph = new Series("circulation")
;
circulationGraph.ChartType = SeriesChartType.Spline
;

...

Series hitsGraph = new Series("Hits")
;
hitsGraph.ChartType = SeriesChartType.Spline
;

...

for
(int index = 0; index < feed.Entries.Length;
index++)
{
    circulationGraph.Points.AddXY(
        feed.Entries[index].Date,
        feed.Entries[index].Circulation)
;
   
hitsGraph.Points.AddXY(
        feed.Entries[index].Date,
        feed.Entries[index].Hits)
;
}

feedChart.Series.Add(circulationGraph)
;
feedChart.Series.Add(hitsGraph);

 

And that's all... a fantastic graph appears:

feedburner_mschart_graph.jpg

You can check a live example of this blog's last 30 days of feed activity here (by supplying a different valid Feedburner's feed URI via the QueryString you can change the output).

 

I still have to learn how to do some small details, but as anyone can see it is very very easy to use this new control.

Jan 02 2009

twitter.png
Twitter is based on talking, either to "everybody" (who follows you) or to specific recipients (people you follow).

This works fine, but has some nasty bugs:

  • If someone mentions more than one twitter account ("@person1 and @person2"), only person1 will be notified of the reply perfectly.
  • If someone mentions a twitter account that is not following him, they won't see the tweet (message).

This is something that should be fixed, but until twitter folks decide to do so, there are other ways to find all messages sent to you, even if you don't follow the senders.

The easiest way is to use the Twitter Search page in advanced mode. The "Referencing this person" field is where you place your twitter account name... and that's all!

You can save the url to check it often, for example this is mine: http://search.twitter.com/search?&ref=kartones

And you can also feed the query to your RSS reader (this is what I do so I don't have to check any page). Once again, quite easy to modify the querystring to your account without even entering the search page: http://search.twitter.com/search.atom?q=+@kartones

 

Simple, once you know it.

 

Another nice way to get them is to use a reply notifier, like TWPLY, which sends emails when someone mentions you. Thanks to Angus Logan for pointing it out via twitter!

Jan 02 2009

One of the things I love is to improve and optimize things. Kartones.Net is the best example, and although I usually only use the "news twitter account" to notify of improvements (and most times just don't say anything), at least once a month I try to make modifications to the Community Server engine to adapt it more to the portal objectives.
An example is my KartonesNet CS2007 Addon Pack, which I evolve slowly.

 

One of the things I didn't liked about CS is how the main post list presented the latest posts, giving focus to comment count and ratings (which are disabled in our community). In my opinion it is better to see the date of posts, and leave the comment count to the details (in smaller font).

So, after a bit of ASP.NET controls reorganization and CSS changes, now I've learned how to modify the post list and achieved giving focus to the post dates:

kartonesnet_new_bloglist.jpg

Now it is way easier to see the dates of the posts, and comment count is still there but smaller. I've also improved speed internally by removing unneeded checks (CS sometimes does too many things for simple tasks).

 

From now on, I'll probably post some changes I make to the portal (and not just to the addon pack) just in case someone else has a Community Server portal and wants to see how to customize or adapt it to their needs.

More Posts: « Previous page