Current Bloggers

Sponsors

Wikis

  • You have not yet contributed to any pages.

Building a Game With JavaScript: Start Screen

Posted by Christopher Bennage, Monday, January 14, 2013 (4,311 views)

This is a continuation from the previous post.

Specification

Many games have a start screen or main menu of some sort. (Though I love games like Braid that bypass the whole notion.) Let’s begin by designing our start screen.

We’ll have a solid color background. Perhaps the ever lovely cornflower blue. Then we’ll draw the name of our game and provide an instruction to the player. In order to make sure we have the player’s attention, we’ll animate the color of the instruction. It will morph from black to red and back again.

Finally, when the player clicks the screen we’ll transition to the main game. Or at least we’ll stub out the transition.

Here’s a demo based on the code we’ll cover later in this post (as well as that from the previous post.)

Implementation

Here’s the code to implement our start screen.

(Go look at the Gist.)

Explanation

Recall that our start screen is meant to be invoked by our game loop. The game loop doesn’t know about the specifics of the start screen, but it does expect it to have a certain shape. This enables us to swap out screen objects without having to modify the game loop itself. The shape that the game loop expects is this:

{
    update: function(timeElapsedSinceLastFrame) { },
    draw: function(drawingContext) { }
}

Update

Let’s begin with the start screen’s update function. The first bit of logic is this:

hue += 1 * direction;
if (hue > 255) direction = -1;
if (hue < 0) direction = 1;

Perhaps hue is not the best choice of variable names. It represents the red component for an RGB color value. The range of values for this component is 0 (no red) to 255 (all the reds!). On each iteration of our loop we “move” the hue towards either the red or black.

The variable direction can be either 1 or -1. A value of 1 means we are moving towards 255 and a value of -1 means we are moving towards 0. When we cross a boundary, we flip the direction.

Keen observers will ask why we bother with 1 * direction. In our current logic, it’s an unnecessary step and unnecessary steps in game development are generally bad. In this case, I wanted to separate the rate of change from the direction. In order words, you could modify that expression to 2 * direction and the color would change twice as fast.

This leads us to another important point. Our rate of change is tied to how quickly our loop iterates; most likely 60fps. However, it’s not guaranteed to be 60fps and that makes this approach a dangerous practice. Once way to detach ourselves from the loop’s speed would be to use the elapsed time that is being passed into our update function.

Let’s say that we want to it to take 2 full seconds to go from red to black regardless of how often the update function is called. There’s a span of 256 discrete values between red and black. To make our calculations clear, let’s say there are 256 units and we’ll label these units R. Also, the elapsed time will be in milliseconds (ms). For a given frame, if were are given a slice of elapsed time in ms, we’ll want to calculate how many R units to increase (or decrease) hue by for that slice. Our rate of change can be defined as 256 **R** / 2000 **ms** or 0.128 R/ms. (You can read that as “0.128 units of red per millisecond”.) This rate of change is a constant for our start screen and as such we can define it once (as opposed to calculating it inside the update function).

Now that we have the rate of change , we only need to multiply it by the elapsed time received in update to determine how many Rs we want. A revised version of the function would look like this:

var rate = 0.128; // R/ms

function update(elapsed) {
    var amount = rate * elapsed;
    hue += amount * direction;
    if (hue > 255) direction = -1;
    if (hue < 0) direction = 1;
}

One consequence of this change is that hue will no longer be integral values (as much as that can be said in JavaScript.) This means that we’d really want to have two values for the hue: an actual value and a rounded value. This is because the RBG model requires an integral value for each color component.

function update(elapsed) {
    var amount = rate * elapsed;
    hue += amount * direction;
    if (hue > 255) direction = -1;
    if (hue < 0) direction = 1;

    rounded_hue = Math.round(hue);
}

Draw

Let’s turn our attention to draw for a moment. One of the first things you generally do is to clear the entire screen. This is simple to do with the canvas API’s clearRect method.

ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

Notice that ctx is an instance of CanvasRenderingContext2D and not a HTMLCanvasElement. However, there is a handy back reference to the canvas element that we use to grab the actual width and height.

There are other options other than clearing the entire canvas, but I’m not going to address this in this post. Also, there are some performance considerations. See the article listed under references.

After clearing the screen, we want to draw something new. In this case, the game title and the instructions. In both cases I want to center the text horizontally. I created a helper function that I can provide with the text to render as well as the vertical position (y).

function centerText(ctx, text, y) {
    var measurement = ctx.measureText(text);
    var x = (ctx.canvas.width - measurement.width) / 2;
    ctx.fillText(text, x, y);
}

measureText returns the width in pixels that the rendered text will take up. We use this in combination with the canvas element’s width to determine the x position for the text. fillText is responsible for actually drawing the text.

The rendering context ctx is stateful. Meaning that, what happens when you call methods like measureText or fillText depends on the state of the rendering context. The state can be modified by setting its properties.

var y = ctx.canvas.height / 2;
ctx.fillStyle = 'white';
ctx.font = '48px monospace';
centerText(ctx, 'My Awesome Game', y);

The properties fillStyle and font change the state of the rendering context and hence affect the methods calls inside of centerText. This state applies to all future methods calls. This means that all calls to fillText will use the color white until you can the fillStyle.

Notice too that we are calculating the x and y values for the text on every frame. This is potentially wasteful since these values are unlikely to change. However, if we want to respond to changes in canvas size (or even changes to the text itself) then we’d want to continue calculating these on every frame. Otherwise, if we were confident that we didn’t need to do this, we could calculate these values once and cache them.

Now let’s use the red component calculated in update to render the instructional text.

var color = 'rgb(' + hue + ',0,0)';

ctx.fillStyle = color;
ctx.font = '24px monospace';
centerText(ctx, 'click to begin', y + 30);

fillStyle can be set in a number of ways. Earlier, we used the simple value white. Here were are using rgb() to set the individual components explicitly. Any CSS color should work with fillStyle. (I won’t be too surprised if some don’t though.)

Now you might be wondering why we bothered calculating hue inside update since hue is all about what to draw on the screen. The reason is that draw is concerned with the mechanics of rendering. Anything that is modeling the game state should live in update. The tell in this example is that hue is dependent on elapsed time and the draw doesn’t know anything about that.

Update (again)

Moving back to update, the next bit deals with input from the player. In the sample code I’ve extracted the input logic away. The key thing here is that we are not relying on events to tell us about input from the player. Instead we have some helper, input in this case, that gives us the current state of the input. If event-driven logic says “tell me when this happens” then our game logic says “tell me if this is happening now”. The primary reason for this is to be deterministic. We can establish at the beginning of our update what the current input state is and that it won’t change before the next invocation of the function. In simple games this might be inconsequential, but in others it can be a subtle source of bugs.

var isButtonDown = input.isButtonDown();

var mouseJustClicked = !isButtonDown && wasButtonDown;

if (mouseJustClicked && !transitioning) {
    transitioning = true;
    // do something here to transition to the actual game
}

wasButtonDown = isButtonDown;

We only want transition when the mouse button has been released. In this case, “released” is defined as “down on the last frame but up on this one”. Hence, we need to track what the mouse button’s state was on the last frame. That’s wasButtonDown and it lives outside of update.

Secondly, we don’t want to trigger multiple transitions. That is, if our transition takes some time (perhaps due to animation) then we want to ignore subsequent clicks. We have our transitioning variable outside of update to track that for us.

More to come…

Reference

Comment on this post at dev.bennage.com
Discuss ()

Chocolatey Automatic Packages

Posted by Rob Reynolds, Thursday, January 03, 2013 (4,176 views)

I updated three packages this morning. I didn’t even notice until the tweets came in from @chocolateynuget.

How is this possible? It’s simple. I love automation. I built chocolatey to take advantage of automation. So it would make sense that we could automate checking for package updates and publishing those updated packages. These are known as automatic packages. Automatic packages are what set Chocolatey apart from other package managers and I daresay could make chocolatey one of the most up-to-date package manager on Windows.

Automatic Packages You Say?

You’ve followed the instructions for creating a Github (or really any source control) repository with your packages. All you need to do now is to introduce two new utilities to your personal library, Ketarin and Chocolatey Package Updater (chocopkgup for short).

Ketarin

Ketarin is a small application which automatically updates setup packages. As opposed to other tools, Ketarin is not meant to keep your system up-to-date, but rather maintain a compilation of all important setup packages which can be burned to disc or put on a USB stick.

There are some good articles out there that talk about how to create jobs with Ketarin so I am not going to go into that.

Ketarin does a fantastic job of checking sites for updates and has hooks to give it custom command before and after it has downloaded the latest version of an app/tool.

Chocolatey Package Updater

Chocolatey Package Updater aka chocopkgup takes the information given out from Ketarin about a tool/app update and translates it into a chocolatey package that it builds and pushes to chocolatey.org. It does this so you don't even have to think about updating a package or keeping it up to date. It just happens. Automatically, in the background, and even faster than you could make it happen. It's almost as if you were the application/tool author.

How To

Prerequisites And Setup:

  1. Optional (strongly recommended) - Ensure you are using a source control repository and file system for keeping packages. A good example is here.
  2. Optional (strongly recommended) - Make sure you have installed the chocolatey package templates. If you’ve installed the chocolatey templates (ReadMe has instructions), then all you need to do is take a look at the chocolateyauto and chocolateyauto3. You will note this looks almost exactly like the regular chocolatey template, except this has some specially named token values.

    #Items that could be replaced based on what you call chocopkgup.exe with
    #{{PackageName}} - Package Name (should be same as nuspec file and folder) |/p
    #{{PackageVersion}} - The updated version | /v
    #{{DownloadUrl}} - The url for the native file | /u
    #{{PackageFilePath}} - Downloaded file if including it in package | /pp
    #{{PackageGuid}} - This will be used later | /pg
    #{{DownloadUrlx64}} - The 64bit url for the native file | /u64
  3. These are the tokens that chocopkgup will replace when it generates an instance of a package.
  4. Install chocopkgup (which will install ketarin and nuget.commandline). cinst chocolateypackageupdater.
  5. Check the config in C:\tools\ChocolateyPackageUpdater\chocopkgup.exe.config  (or chocolatey_bin_root/ChocolateyPackageUpdater). The PackagesFolder key should point to where your repository is located.
  6. Create a scheduled task (in windows). This is the command (edit the path to cmd.exe accordingly): C:\Windows\System32\cmd.exe /c c:\tools\chocolateypackageupdater\ketarinupdate.cmd
  7. Choose a schedule for the task. I run mine once a day but you can set it to run more often. Choose a time when the computer is not that busy.
  8. Save this Ketarin template somewhere: https://github.com/ferventcoder/chocolateyautomaticpackages/blob/master/_template/KetarinChocolateyTemplate.xml
  9. Open Ketarin. Choose File –> Settings.
  10. On the General Tab we are going to add the Version Column for all jobs. Click Add…, then put Version in Column name and {version} in Column value. 
       Create a Custom Field (Ketarin)
  11. Click [OK]. This should add it to the list of Custom Columns.
  12. Click on the Commands Tab and set Edit command for event to “Before updating an application”.  Ketarin settings - Commands Tab - Before updating an application
  13. Add the following text:
    chocopkgup /p {appname} /v {version} /u {preupdate-url} /u64 {url64} /pp {file} 
    REM /disablepush
  14. Check the bottom of this section to be sure it set to Command
    Command selected
  15. Click Okay.
  16. Note the commented out /disablepush. This is so you can create a few packages and test that everything is working well before actually pushing those packages up to chocolatey. You may want to add that switch to the main command above it.

This gets Ketarin all set up with a global command for all packages we create. If you want to use Ketarin outside of chocolatey, all you need to do is remove the global setting for Before updating an application and instead apply it to every job that pertains to chocolatey update.

Create an Automatic Package:

Preferably you are taking an existing package that you have tested and converting it to an automatic package.

  1. Open Ketarin. Choose File –> Import… 
  2. Choose the template you just saved earlier (KetarinChocolateyTemplate.xml).
  3. Answer the questions. This will create a new job for Ketarin to check.
  4. One important thing to keep in mind is that the name of the Application name needs to match the name of the package folder exactly.
  5. Right click on that new job and select Edit. Take a look at the following:
    Ketarin Job Notes
  6. Set the URL appropriately. I would shy away from FileHippo for now, the URL has been known to change and if you upload that as the download url in a chocolatey packages, it won’t work very well.
  7. Click on Variables on the right of URL.
    Variables
  8. On the left side you should see a variable for version and one for url64. Click on version.
  9. Choose the appropriate method for you. Here I’ve chosen Content from URL (start/end).
  10. Enter the URL for versioning information.
    Ketarin Variable Details
  11. In the contents itself, highlight enough good information before a version to be able to select it uniquely during updates (but not so much it doesn’t work every time as the page changes). Click on Use selection as start.
  12. Now observe that it didn’t jump back too far.
  13. Do the same with the ending part, keeping in mind that this side doesn’t need to be too much because it is found AFTER the start. Once selected click on Use selection as end.
  14. It should look somewhat similar to have is presented in the picture above.
  15. If you have a 64bit Url you want to get, do the same for the url64 variable.
  16. When all of this is good, click OK.
  17. Click OK again.

Testing Ketarin/ChocoPkgUp:

  1. We need to get a good idea of whether this will work or not.
  2. We’ve set /disablepush in Ketarin global so that it only goes as far as creating packages.
  3. Navigate to C:\ProgramData\chocolateypackageupdater.
  4. Open Ketarin, find your job, and right click Update.  If everything is set good, in moments you will have a chocolatey package in the chocopkgup folder. 
  5. Inspect the resulting chocolatey package(s) for any issues.
  6. You should also test the scheduled task works appropriately.

Troubleshooting/Notes

  • Ketarin comes with a logging facility so you can see what it is doing. It’s under View –> Show Log.
  • In the top level folder for chocopkgup (in program data), we log what we receive from Ketarin as well and the process of putting together a package.
  • The name of the application in ketarin matches exactly that of the folder that is in the automatic packages folder.
  • Every once in awhile you want to look in Ketarin to see what jobs might be failing. Then figure out why.
  • Every once in awhile you will want to inspect the chocopkgupfolder to see if there are any packages that did not make it up for some reason or another and then upload them.

Conclusion

Automatic chocolatey packages are a great way to grow the number of packages you maintain without any significant jump in maintenance cost by you. I’ve been working with and using automatic packages for over six months. Is it perfect? No, it has issues from time to time (getting a good version read or actually publishing the packages in some rare cases). But it works pretty well. Over the coming months more features will be added to chocopkgup, such as been able to run its own PowerShell script (for downloading components to include in the package, etc) that would not end up in the final chocolatey package.

With full automation instead of having packages that are out of date or no longer valid, you run the small chance that something changed in the install script or something no longer works. The chances of this are much, much lower than having packages that are out of date or no longer valid.

It takes just a few minutes longer when creating packages to convert them to automatic packages but well worth it when you see that you are keeping applications and tools up to date on chocolatey without any additional effort on your part. Automatic packages are awesome!

Filed under: ,
Discuss (0)

Running Typescript tests via Jasmine and Chutzpah on Teamcity

Posted by Derik Whittaker, Tuesday, December 25, 2012 (4,051 views)

In my prior post I talked about how I setup my environment for testing my Typescript source via Jasmine and Chutzpah.  That was just the beginning.  Now that I had the ability to create unit tests I needed the ability to run them on our CI server, which happens to be Teamcity).  I did a bunch of looking around and could not find anything that seemed to work for me, but I did notice that Chutzpah had the ability to run via the command line… GOLD.

Armed w/ the knowledge that I can run my tests from the command line I gave it a whirl.  After looking at the docs it appeared I could run get the results I wanted w/ the following.

chutzpah.console.exe /path “c:\path_to_my_typescript_folder_here /teamcity

However, when I ran the above command I got the following output

image

If you look at the above you will see 33 total test, 22 failures.  This is odd because I only have 11 tests.  Turns out the command line tool is running my .js files (ones generated via Typescript) and my .ts files. I only wanted to run my .ts files.  I figured there had to be a command line switch, but there was not.  This sucked because inside of Visual Studio i can set it to ONLY run typescript files as seen below.

image

I figured I would take a peek at the source to see if I could add support for TestingMode via the command line, turns out I could (side note, I created a fork here and have submitted a pull request for my changes so i hope they are consumed soon)

Now I can run the command w/ the new “/TestMode Typescript” option as below

chutzpah.console.exe /path “c:\path_to_my_typescript_folder_here /testMode TypeScript /teamcity

When I run the above command I get below

image

With my commits you will see the /testmode option via the help as below

image

Once I had a working version of Chutzpah which can output my test results all I needed to do was add it to my build script (we use pSake) and bam, I now have Typescript/Javascript tests showing up in my Teamcity builds as seen below

image

or as shown from from our Teamcity logs

image

Hope this helps

Till Next Time,

P.S. If you need a copy of my .exe before my changes are added to the master branch let me know.

Filed under: , ,
Discuss (11)

Setting up Unit Testing w/ Jasmine, Chutzpah and Typescript

Posted by Derik Whittaker, Sunday, December 23, 2012 (5,257 views)

Recently I got back into writing html/javascript code as part of my day job and boy-o-boy have things changed since the last time i did any of this.  One thing that has not changed for me however was my belief in unit testing, so it was very painful for me to be writing hundreds of lines of javascript (ok really TypeScript) code with NO tests supporting them.  At first I was able to live with this feeling because I was too busy trying to relearn how to do javascript development.  However, I have not reached a comfort level where the lack of tests is killing me again.

No of course in client/server land of .Net development getting started testing is dead simple, however in the Javascript/html world things are still in the toddler stage, IMO, and there are many, many options to testing and I had no idea which is the best.  After doing some searching and asking on twitter I settled on Jasmine as my test runner. 

Now that I picked Jasmine, how did I get started?  Here is what I did (this post is a merging of many, many posts I looked at to get me pointed in the right direction)

Step 1: Create a new test project

Open up Visual Studio 2012 and create a basic MVC 4 application (empty)

Step 2: Get Jasmine

Install the Jasmine NuGet Package
image

Step 3: Run your application in order to validate that jasmine is running correctly

image

Yup, we are good

Step 4: Get Chutzpah

I wanted a way to run my tests inside of Visual Studio and this plugin seemed to do the trick. I opted to install the test adapter which can be found here

Step 5: Validate that Chutzpah adapter was setup correctly

image

As you can see from above, it is setup correctly.

Now I wanted to be able to author my tests in Typescript and have them run as well.

Step 6: Download the Jasmine typescript definition file.  I put this inside my scripts folder as seen below

image

Step 7: Create my Test Spec

The trick to getting this to work of course is that I need to include the jasmine-1.2.d.ts definition file inside my .ts file as below

image

I also need to reference my class under test file inside my .ts file as below

image

Once I did both of these I could write my first test as below

image 

Bam, now I have a jasmine test written via Typescript and runnable via the Chutzpah test running.  Of course I am sure there are other ways to get this to work, this is just what worked for me.

Till next time,

Filed under: , , ,
Discuss (2)

Asp.Net Web Api MediaTypeFormatter Error for x-www-formurlencoded data

Posted by Derik Whittaker, Thursday, December 20, 2012 (3,465 views)

As I was breaking out some of my MVC controllers to use Web Api I ran into a not so fun error (seen below) when doing a jQuery Post.

image

I was trying to post a model via jQuery to my Web Api Endpoint and it was failing and it made no sense because when I used Postman via Chrome it would work just fine.  My jQuery code is below

var model = {
    GroupId: self.SelectedGroup().GroupId,
    Name: self.SelectedGroup().Name,
};

$.ajax({
    url: route,
    type: 'Post',
    dataType: "json",
    data: model,
    success: function(data){ 
        alert("passed");
    },
    error: function(data) {
        alert('There was a (' + data.status + ') returned due to ' + data.statusText + '.'); //or whatever
    }
});

My Postman setup looked like

image

Turns out to find my issue i needed to inspect the error result passed back to jQuery which pointed me towards the real error of

"No MediaTypeFormatter is available to read an object of type 'GroupSelectionModel' from content with media type 'application/x-www-form-urlencoded'."

Now that I knew that jQuery was trying to do a FormUrlEncoded post, not a pure json post I had an idea what the root cause was… ME.  I was trying to be clever and only allow for the JsonMediaTypeFormatter and removing ALL other formatters, see below.

image

What I needed to do was the following

image

Once I added the correct formatter it all just WORKED.

Till next time,

Filed under: ,
Discuss (3)

this.Log– Source, NuGet Package & Performance

Posted by Rob Reynolds, Wednesday, December 19, 2012 (4,374 views)

Recently I mentioned this.Log. Given the amount of folks that were interested in this.Log, I decided to pull this source out and make a NuGet package (well, several packages).

Source

The source is now located at https://github.com/ferventcoder/this.log. Please feel free to send pull requests (with tests of course). When you clone it, if you open visual studio prior to running build.bat, you will notice build errors. Don’t send me a pull request fixing this, I want it to work the way it does now. Use build.bat appropriately.

To try to cut down on the version number being listed everywhere, I created a SharedAssembly.cs (and a SharedAssembly.vb for the VB.NET samples). That helped, but it didn’t solve the problem where it was in the nuspecs as dependencies. So I took it a step further and created a file named VERSION. When you run the build, it updates all the files that contain version information. Having one place to handle the version is nice.

NuGet

When moving this.Log to a NuGet package (or in this case 9 NuGet packages), I was able to play with some features of NuGet I had not previously, symbol servers and packing a csproj. With packing a csproj, I was able to quickly (well mostly) set up the build to package up every project with NuGet packages.

All packages can be found by searching for this.log on NuGet.org.

NOTE: If you’ve installed any of these prior to this post, you will want to uninstall and reinstall them (there was an particular issue with the version on the Rhino Mocks version). I’ve fixed and updated quite a bit on them from version 0.0.1.0 to 0.0.2.0.

Performance

Performance testing with log4net showed this only has an overhead of 42 ticks tested over 100,000 iterations. That’s a pretty good start given that it has a reflection hit on every call.

Filed under: , ,
Discuss (0)

Deploying Asp.Net 4.5 site to IIS Error: ManagedRuntimeVersion to v.45

Posted by Derik Whittaker, Tuesday, December 18, 2012 (3,067 views)

Today I was trying to publish a Asp.net 4.5 site to our server and I received the following error;

The Application pool that you are trying to use has the ‘managedRuntimeVersion’ property set to v4.0. This application requires ‘v4.5’

I thought this was odd so I went to change the App pool, only to see there is no v4.5 option.  After a bit of Goggling my suspicions about v4.5 not having an app pool as v4.5 of .net is inplace update and does not have a new ‘version’.

After a bit more Goggling and looking at StackoverFlow answers I found the solution, although it was not the ‘selected’ solution but oh well.

See I am doing my deploy via a powershell script using pSake and my deploy looked something like this

&$msBuildpath /verbosity:m $projectFileAndPath /T:Rebuild /T:Package /p:"Configuration=$buildMode;Packagelocation=$packageFolder" 
/p:DeployOnBuild=True /p:DeployTarget=MsDeployPublish /p:CreatePackageOnPublish=True
/p:MSDeployPublishMethod=RemoteAgent /p:MSDeployServiceUrl=$deploymentServer /p:DeployIisAppPath=$deploymentAppPath 
/p:UserName=$deployuser /p:Password=$deploypassword   

 

What I needed to add was the /P:VisualStudioVersion=11.0 switch to force the right compiler.  Once I added this switch my deploy was right as rain.

Till next time,

Filed under: , , ,
Discuss (3)

How to make non-observable properties observable in Knockout.js

Posted by Derik Whittaker, Saturday, December 15, 2012 (3,513 views)

I am working on a project which is using Knockout.js to give us MVVM style binding between our data model (view model) and our views.  We are also MVC4 and Web API.  This means that my ViewModels will be making calls in to our Web API endpoints to get json back.  When we receive this json back we are using the property from the resulting json to bind to our UI.  This works great in a read-only scenario, but what happens when I want to update my UI via binding?

If you need to update the values AFTER the initial binding you have 2 choices (there may be more but these are what I know)

1) You can create a new property, mark it as being observable, and set the original value from the json result as the seed value in your new property.

item.newProperty = ko.observable(item.OriginalProperty)

2) You can simply overwrite your original property as make it observable (gotta love how javascript is dynamic, right)

item.(item.OriginalProperty) = ko.observable(item.OriginalProperty)

In my opinion option 2 is the way to go, I feel it is a bit cleaner and ‘it just works’

Thoughts?

Till next time,

Discuss (7)

Introducing this.Log

Posted by Rob Reynolds, Saturday, December 15, 2012 (7,726 views)

One of my favorite creations over the past year has been this.Log(). It works everywhere including static methods and in razor views. Everything about how to create it and set it up is in this gist.

How it looks

public class SomeClass {
 
  public void SomeMethod() {
    this.Log().Info(() => "Here is a log message with params which can be in Razor Views as well: '{0}'".FormatWith(typeof(SomeClass).Name));

    this.Log().Debug("I don't have to be delayed execution or have parameters either");
  }

  public static void StaticMethod() {
    "SomeClass".Log().Error("This is crazy, right?!");
  }
 
}

Why It’s Awesome

  • It does no logging if you don’t have a logging engine set up.
  • It works everywhere in your code base (where you can write C#). This means in your razor views as well!
  • It uses deferred execution, which means you don’t have to mock it to use it with testing (your tests won’t fail on logging lines).
  • You can mock it easily and use that as a means of testing.
  • You have no references to your actual logging engine anywhere in your codebase, so swapping it out (or upgrading) becomes a localized event to one class where you provide the adapter.

Some Internals

This uses the awesome static logging gateway that JP Boodhoo showed me a long time ago at a developer bootcamp, except it takes the concept further. One thing that always bothered me about the static logging gateway is that it would construct an object EVERY time you called the logger if you were using anything but log4net or NLog. Internally it likely continued to reuse the same object, but at the codebase level it appeared as that was not so.

/// <summary>
/// Logger type initialization
/// </summary>
public static class Log
{
    private static Type _logType = typeof(NullLog);
    private static ILog _logger;
 
    /// <summary>
    /// Sets up logging to be with a certain type
    /// </summary>
    /// <typeparam name="T">The type of ILog for the application to use</typeparam>
    public static void InitializeWith<T>() where T : ILog, new()
    {
        _logType = typeof(T);
    }
 
    /// <summary>
    /// Sets up logging to be with a certain instance. The other method is preferred.
    /// </summary>
    /// <param name="loggerType">Type of the logger.</param>
    /// <remarks>This is mostly geared towards testing</remarks>
    public static void InitializeWith(ILog loggerType)
    {
        _logType = loggerType.GetType();
        _logger = loggerType;
    }
 
    /// <summary>
    /// Initializes a new instance of a logger for an object.
    /// This should be done only once per object name.
    /// </summary>
    /// <param name="objectName">Name of the object.</param>
    /// <returns>ILog instance for an object if log type has been intialized; otherwise null</returns>
    public static ILog GetLoggerFor(string objectName)
    {
        var logger = _logger;
 
        if (_logger == null)
        {
            logger = Activator.CreateInstance(_logType) as ILog;
            if (logger != null)
            {
                logger.InitializeFor(objectName);
            }
        }
 
        return logger;
    }
}

You see how when it calls InitializeFor, that’s when you get something like the following in the actual implemented method:

_logger = LogManager.GetLogger(loggerName);

So we take the idea a step further by implementing the following in the root namespace of our project:

/// <summary>
/// Extensions to help make logging awesome
/// </summary>
public static class LogExtensions
{
    /// <summary>
    /// Concurrent dictionary that ensures only one instance of a logger for a type.
    /// </summary>
    private static readonly Lazy<ConcurrentDictionary<string,ILog>> _dictionary = new Lazy<ConcurrentDictionary<string, ILog>>(()=>new ConcurrentDictionary<string, ILog>());
 
    /// <summary>
    /// Gets the logger for <see cref="T"/>.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="type">The type to get the logger for.</param>
    /// <returns>Instance of a logger for the object.</returns>
    public static ILog Log<T>(this T type)
    {
        string objectName = typeof(T).FullName;
        return Log(objectName);
   }
 
    /// <summary>
    /// Gets the logger for the specified object name.
    /// </summary>
    /// <param name="objectName">Either use the fully qualified object name or the short. If used with Log&lt;T&gt;() you must use the fully qualified object name"/></param>
    /// <returns>Instance of a logger for the object.</returns>
    public static ILog Log(this string objectName)
    {
        return _dictionary.Value.GetOrAdd(objectName, Infrastructure.Logging.Log.GetLoggerFor);
    }
}

You can see I’m using a concurrent dictionary which really speeds up the operation of going and getting a logger. I get the initial performance hit the first time I add the object, but from there it’s really fast. I do take a hit with a reflection call every time, but this is acceptable for me since I’ve been doing that with most logging engines for awhile.

Conclusion

If you are interested in the details, see this gist.

Extensions are awesome if used sparingly. Is this.Log perfect? Probably not, but it does have a lot of benefits in use. Feel free to take my work and make it better. Find a way to get me away from the reflection call every time. I’ve been using it for almost a year now and have improved it a little here and there.

If there is enough interest, I can create a NuGet package with this as well.

Filed under: ,
Discuss (13)

Super D to the B to the A – AKA Script for reducing the size of a database

Posted by Rob Reynolds, Friday, December 14, 2012 (2,749 views)

The following is a script that I used to help me clean up a database and reduce the size of it from 95MB down to 3MB so we could use it for a development backup. I will note that we also removed some of the data out. I shared this with a friend recently and he used this to go from 70GB to 7GB!

UPDATE: Special Note

Please don’t run this against something that is live or performance critical. You want to do this where you are the only person connected to the database, like a restored backup of the critical database. Doing it against something live will most definitely cause issues. I can in no way be responsible for the use of this script. You should understand what you are doing before you execute these scripts.

So what does it do?

  • It gives you a report of what tables are taking up the most space.
  • It allows you to specify those tables for cleaning.
  • Gives you that same report of space used up by tables after the clean.
  • It rebuilds and reorganizes all indexes with reports before and after.
  • It runs shrink file on the physical files (potentially unnecessary due to the next thing it does, but hey, couldn’t hurt right?!).
  • It runs shrink database on the database.

The Script

Provided it shows up correctly, here is the gist:

/*
 * Scripts to remove data you don't need here  
 */


/*
 * Now let's clean that DB up!
 */

DECLARE @DBName VarChar(25)
SET @DBName = 'DBName'

/*
 * Start with DBCC CLEANTABLE on the biggest offenders
 */


--http://stackoverflow.com/questions/3927231/how-can-you-tell-what-tables-are-taking-up-the-most-space-in-a-sql-server-2005-d
--http://stackoverflow.com/a/3927275/18475
PRINT 'Looking at the largest tables in the database.'
SELECT 
 t.NAME AS TableName,
 i.name AS indexName,
 SUM(p.rows) AS RowCounts,
 SUM(a.total_pages) AS TotalPages, 
 SUM(a.used_pages) AS UsedPages, 
 SUM(a.data_pages) AS DataPages,
 (SUM(a.total_pages) * 8) / 1024 AS TotalSpaceMB, 
 (SUM(a.used_pages) * 8) / 1024 AS UsedSpaceMB, 
 (SUM(a.data_pages) * 8) / 1024 AS DataSpaceMB
FROM 
 sys.tables t
INNER JOIN  
 sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
 sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
 sys.allocation_units a ON p.partition_id = a.container_id
WHERE 
 t.NAME NOT LIKE 'dt%' AND
 i.OBJECT_ID > 255 AND  
 i.index_id <= 1
GROUP BY 
 t.NAME, i.object_id, i.index_id, i.name 
ORDER BY 
 OBJECT_NAME(i.object_id) 

 --http://weblogs.sqlteam.com/joew/archive/2008/01/14/60456.aspx
PRINT 'Cleaning the biggest offenders'
DBCC CLEANTABLE(@DBName, 'dbo.Table1')
DBCC CLEANTABLE(@DBName, 'dbo.Table2')

SELECT 
 t.NAME AS TableName,
 i.name AS indexName,
 SUM(p.rows) AS RowCounts,
 SUM(a.total_pages) AS TotalPages, 
 SUM(a.used_pages) AS UsedPages, 
 SUM(a.data_pages) AS DataPages,
 (SUM(a.total_pages) * 8) / 1024 AS TotalSpaceMB, 
 (SUM(a.used_pages) * 8) / 1024 AS UsedSpaceMB, 
 (SUM(a.data_pages) * 8) / 1024 AS DataSpaceMB
FROM 
 sys.tables t
INNER JOIN  
 sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
 sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
 sys.allocation_units a ON p.partition_id = a.container_id
WHERE 
 t.NAME NOT LIKE 'dt%' AND
 i.OBJECT_ID > 255 AND  
 i.index_id <= 1
GROUP BY 
 t.NAME, i.object_id, i.index_id, i.name 
ORDER BY 
 OBJECT_NAME(i.object_id) 

/*
 * Fix the Index Fragmentation and reduce the number of pages you are using (Let's rebuild and reorg those indexes)
 */


--http://ferventcoder.com/archive/2009/06/09/sql-server-2005-sql-server-2008---rebuild-or-reorganize.aspx 
PRINT 'Selecting Index Fragmentation in ' + @DBName + '.'
SELECT 
  DB_NAME(DPS.DATABASE_ID) AS [DatabaseName]
 ,OBJECT_NAME(DPS.OBJECT_ID) AS TableName
 ,SI.NAME AS IndexName
 ,DPS.INDEX_TYPE_DESC AS IndexType
 ,DPS.AVG_FRAGMENTATION_IN_PERCENT AS AvgPageFragmentation
 ,DPS.PAGE_COUNT AS PageCounts
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, NULL) DPS --N'LIMITED') DPS
INNER JOIN sysindexes SI 
    ON DPS.OBJECT_ID = SI.ID 
    AND DPS.INDEX_ID = SI.INDID
ORDER BY DPS.avg_fragmentation_in_percent DESC


PRINT 'Rebuilding indexes on every table.'
EXEC sp_MSforeachtable @command1="print 'Rebuilding indexes for ?' ALTER INDEX ALL ON ? REBUILD WITH (FILLFACTOR = 90)"
GO
PRINT 'Reorganizing indexes on every table.'
EXEC sp_MSforeachtable @command1="print 'Reorganizing indexes for ?' ALTER INDEX ALL ON ? REORGANIZE"
GO
--EXEC sp_MSforeachtable @command1="print '?' DBCC DBREINDEX ('?', ' ', 80)"
--GO
PRINT 'Updating statistics'
EXEC sp_updatestats
GO

SELECT 
  DB_NAME(DPS.DATABASE_ID) AS [DatabaseName]
 ,OBJECT_NAME(DPS.OBJECT_ID) AS TableName
 ,SI.NAME AS IndexName
 ,DPS.INDEX_TYPE_DESC AS IndexType
 ,DPS.AVG_FRAGMENTATION_IN_PERCENT AS AvgPageFragmentation
 ,DPS.PAGE_COUNT AS PageCounts
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, NULL) DPS --N'LIMITED') DPS
INNER JOIN sysindexes SI 
    ON DPS.OBJECT_ID = SI.ID 
    AND DPS.INDEX_ID = SI.INDID
ORDER BY DPS.avg_fragmentation_in_percent DESC
GO

/*
 * Now to really compact it down. It's likely that SHRINKDATABASE will do the work of SHRINKFILE rendering it unnecessary but it can't hurt right? Am I right?!
 */

DECLARE @DBName VarChar(25), @DBFileName VarChar(25), @DBLogFileName VarChar(25)
SET @DBName = 'DBName'
SET @DBFileName = @DBName
SET @DBLogFileName = @DBFileName + '_Log'

DBCC SHRINKFILE(@DBLogFileName,1)
DBCC SHRINKFILE(@DBFileName,1)
DBCC SHRINKDATABASE(@DBName,1) 

References

Here are some of the references in the gist:

Filed under: ,
Discuss (4)

Refresh Database–Speed up Your Development Cycles

Posted by Rob Reynolds, Wednesday, December 12, 2012 (3,175 views)

Refresh database is an workflow that allows you to develop with a migrations framework, but deploy with SQL files. It’s more than that, it allows you to rapidly make changes to your environment and sync up with other teammates. When I am talking about environment, I mean your local development environment: your code base and the local database back end you are hitting.

Refresh database comes in two flavors, one for NHibernate and one for Entity Framework. I’m going to show you an example of the one for Entity Framework, which you can find in the repository for rh-ef on github.  One note before we get started: This could work with any migrations framework that will output SQL files.

What is this? Why should I use this?

How long do you spend updating source code and then getting your database up to snuff afterward so you can keep moving forward quickly? Do you work with teammates? Do you have multiple workstations that you might work from and want to quickly sync up your work?

It’s a pain most of us don’t see and an idea that was originally incubated by Dru Sellers. He wanted a fast way of keeping his local stuff up to date right from Visual Studio. Out of that was born Refresh Database. We are talking a simple right click and debug to a synced up database.

Others have talked in the past about how you want to use the same migration algorithm and test it all the way up to production. Refresh DB allows you to test that migration from a local development environment many times a day. So by the time you hand over the SQL files for production (or use RoundhousE), there is no guess work about whether it is going to work or not. You have a security in knowing that you are good to go.

It’s definitely something that can really speed up your team so you never hear “I got latest and now I’m trying to sync up all the changes to the database.” This should be easy. This should be automatic.

You should never again hear “I made some domain changes but now I’m working to get them into the database.” This should be easy. This should be automatic.

Whether you decide to look further into this or not, it doesn’t matter to me. It just means my teams will get to market and keep updated faster than you (given the same technologies, Winking smile).

How does this work?

This is the simple part. Convincing you to look at it in the first place is the hard part. I have put together a short video to show you exactly how it works. You will see that it is super simple.

Conclusion

Refresh Database has been around for over two years. It’s definitely something that has paid for itself time and again. It’s something you might consider looking at it if you have never heard of it.

If you don’t do something with migrations and source control for your database yet, please start now. This will save you countless hours in the future. I’ve walked into more than one company that was hurting in the area of database development b/c they didn’t treat the database scripts as source code in the same way that they did the rest of the code. It’s a must anymore. I also see teams doing shared development database development. This is a huge no no (except in certain considerations) due to the amount of lost time it causes. That however, is a discussion for another day.

Getting Typescript setup on your build server

Posted by Derik Whittaker, Monday, December 10, 2012 (3,481 views)

In my prior post I talked about how to compile all your typescript files down to a single .js file.  One issue I did not mention was that if you are going to use this AND you have a build server you will need to setup the Typescript installer.

This can be done 2 ways.

  1. Install the Visual Studio 2012 plugin – But I hate having my ide on my build box so this is not my preferred approach
  2. Install the command line tools – This is my preferred approach.

How to get this installed on your build server?

  1. Open a command prompt and ensure you do not have the node package manager installed by typing npm, you should see something like

    image
  2. If you do not have the npm installed head over to the download page to install it
  3. Once you have npm installed open up command prompt and install the typescript compiler using

    npm install –g typescript
  4. now that you have typescript installed you should be able to type tsc on the command line and see below

    image


Now that you have node and typescript installed you should be able to build your projects via your build server.

Till next time,

Filed under: ,
Discuss (2)

Building a Game With JavaScript

Posted by Christopher Bennage, Monday, December 10, 2012 (3,805 views)
update: I just realized that the gist was not being rendered here. I've added the code inline.

See the introduction post for context.

The Loop

In general, game development begins with the game loop. If you come from the business world of software development, this will be strange. You don’t rely on events. Phil Haack once asked me “why a loop?”, to which I responded “uh…”. However, a much better answer would have been this one on stackoverflow.

Okay, so we should use a master loop. If our runtime is the browser, how do setup this loop? There’s a relatively new API called requestAnimationFrame and that’s what most folks recommend. Check out these for details:

(I do recall reading something negative along the way about the API, but I couldn’t find it again.)

I used the requestAnimationFrame shim referenced in the Paul Irish post above. The shim is only necessary for older browsers that have not implemented the API. By the way, we refer to each iteration of the loop as a “frame” because of the analogy with traditional animation.

Implementation

Now that we’ve ensured that requestAnimationFrame is present we can get to our game loop. Here is my game’s bootstrap code (well, an early version of it):

var canvas,        // the visible canvas element    
    surface,       // the 2d context of `canvas`
    currentScreen; // the currently rendered screen for the game

function beginLoop() {
    var frameId = 0;
    var lastFrame = Date.now();

    function loop() {
        var thisFrame = Date.now();

        var elapsed = thisFrame - lastFrame;

        frameId = window.requestAnimationFrame(loop);

        currentScreen.update(elapsed);
        currentScreen.draw(surface);

        lastFrame = thisFrame;
    }

    loop();
}


canvas = document.querySelector('canvas#board');
canvas.setAttribute('width', 800);
canvas.setAttribute('height', 600);

surface = canvas.getContext('2d');

currentScreen = startScreen;
beginLoop();

The gist is also available.

The heart of this the loop function. It has the following step:

  • capture the current time
  • calculate the time that has elasped since the last frame
  • execute the game’s logic for the frame (that’s the update and draw invocations)
  • request the next invocation of loop using requestAnimationFrame
  • record the current time of the this frame for calculations in the next one

N.B. This code doesn’t use frameId yet. The idea is that this handle could be used to halt the loop.

The beginLoop function is there merely to provide a closure for some of the variables used to track the state of the loop. It kicks off the loop with its initial invocation of loop.

The big mystery inside of loop is the currentScreen object. Here I was thinking ahead (which can be dangerous). I know that my game will have at least two “screens”, possibly more:

  • start menu screen
  • main game screen (where the action takes place)

I wanted the loop logic to work with both (as well as any future screens). I expect screen objects to have two methods:

  • update takes the time elapsed since the last frame and is responsible for updating the state of the game.
  • draw takes the drawing context (from the canvas) and is responsible for rendering the current state of the game.

You’ll also see that I grab a canvas element and capture its drawing context. If you are not familiar with the canvas APIs, I recommend that you start here.

Why two different methods for game logic?

Keeping the update and draw functions separate is important. When frames becomes expensive to compute, the game may respond with lag or non-deterministic behavior. Too avoid this, you might want your game to skip over some logic during a particular iteration of the loop. However, it’s very likely that you won’t want to drop calls to update. It’s not necessary a big deal if you skip rendering a couple of frames, however if skip calculating the location of a projectile then it might mysteriously “pass through” its target. This will become more relevant to us in particular, because I’d like to all the player to control the speed of game (a common feature of many tower defense games).

Right now update and draw are always called for each iteration of the loop, so the distinction is academic in this context. We could though calculate our frame rate in loop and occasionally skip invoking draw if the rate slowed down.

Now we have enough in place to begin working on our start menu screen.

Comment on this post at dev.bennage.com
Discuss ()

a n00b’s Look at HTML5 Game Development

Posted by Christopher Bennage, Saturday, December 08, 2012 (3,855 views)

Preamble

Something disgusting, like six years ago, I listed on 43Things that I wanted to write a video game. I’ve actually made numerous arrested attempts ever since I started programming with my TI-94a back in 1983. My last attempt has been much less arrested (though still incomplete).

I’ve learned a lot in my most recent endeavor, so it’s time to share. You can follow the actual work in progress, but my plan it to recreate the steps I’ve gone though over the course of a few posts.

Goals

I am too ambitious. With that in mind, I created a set of constraints for making a game.

  • keep gameplay simple
  • don’t worry about art (that can come later)

I started off wanting to make a game for the Windows 8 store. I decided afterwards that I will target modern browsers in general. This means that I took no dependencies on the WinJS libraries. (Though the Windows store is still my endgame.)

I also decided to not use any frameworks (such as ImpactJS). Not because they are bad, but because I want to learn why I need them.

Gameplay

This is my spec (well, more or less).

I decided to make a simple tower defense game. My inspiration is The Space Game from the Casual Collective, as well as plenty of influence from StarCraft.

The player will build structures in an asteroid field. Waves of enemy ships will attempt to destroy those structures. The player has to manage resources such as minerals and solar power, and fend of the attacks. Structures will cost minerals to build and require power to operate.

The player can navigate the map (up, down, left, right) as well as zooming in and out. There will be a minimap.

Graphics will be sprite-based. The game should be touch-friendly (really, I want touch to be primary).

Resources

  • Build New Games, a collaboration between Microsoft and Bocoup, is an excellent set of articles on HTML/JavaScript game development.

  • My friend, Matt Peterson, currently a graduate student at DigiPen, who’s advice and guidance has been most useful.

Comment on this post at dev.bennage.com
Discuss ()

How to compile all your TypeScript .ts files into a Single .js file

Posted by Derik Whittaker, Saturday, December 08, 2012 (4,903 views)

Recently our team has been using TypeScript for all our Javascript work.  To be honest it has been a complete pleasure as it ‘just works’.  However one annoyance we quickly found was that we had to choose what was the best approach for using TypeScript.  Do we have a single .ts file which compiles down to a single .js file or do we have multiple .ts files which each compile down to their own .js file.  There are clearly pros/cons to both approaches

Single .ts file pros/cons

Pros:

  • Means keeping all our javascript in a single place, making it a bit easier to find/update
  • Means that we only need to reference on .js file in our bundles

Cons:

  • Means that our .ts file could become very large and unmanageable over time
  • Means that we are increasing our risk of merge issues when we commit it to git

Multiple .ts files pros/cons

Pros:

  • Means we have smaller files to work w/ which should allow for better manageability
  • Means we could include a given .js file in a view if we so chose
  • Means we could reduce our .js file size for downloads if we so chose

Cons:

  • Means we have multiple .js files which need to be references in our bundles

After weighing the pros/cons of each we decided the we better liked the idea of having multiple .ts files, but we also wanted a single .js output file.  Yea we want our cake and be able to eat it to.

The good news is that this is 100% percent doable.  One of my kick ass devs on our team spent a bit of time working on this problem (read that as THIS IS NOT MY DISCOVERARY) and found a solution.

The trick was finding out that the command line tool for compiling .ts files has an –out options.  Below is what he did to get this to work

 Step 1: setup the correct content type

Open up your .csproj file and look for all references to your .ts files.  They should look something like below

<Content Include="ViewModels\Authentication\LoginViewModel.ts" />

You will want to change the type from ‘Content’ to ‘TypeScriptCompile’ as below

<TypeScriptCompile Include="ViewModels\Authentication\LoginViewModel.ts" />

Step 2: Add the property group below to your .csproj file

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
  <TypeScriptSourceMap> --sourcemap</TypeScriptSourceMap>
</PropertyGroup>

You will want to add this towards the top of the .csproj file

Step 3: Add a Before Build Step to your .csproj file

Open your .cspoj file and add the block below to the bottom of your file

<Target Name="BeforeBuild">
  <Message Text="Compiling TypeScript files - $(TypeScriptSourceMap)" />
  <Message Text="Executing tsc$(TypeScriptSourceMap) @(TypeScriptCompile ->'&quot;%(fullpath)&quot;', ' ')" />
  <Exec Command="tsc$(TypeScriptSourceMap) @(TypeScriptCompile ->'&quot;%(fullpath)&quot;', ' ') --out Scripts/MySingleFile.js" />
</Target>

You will want to change the path in the Exec command.  I have mine set to Scripts/MySingleFile.js, you may have a different need

Step 4: Add this .js file to your MVC Bundles

bundles.Add(new ScriptBundle("~/bundles/projects").Include(
            "~/Scripts/MySingleFile.js"));

Step 5: Include the new bundle in your view

@Scripts.Render("~/bundles/projects")

The only issue we have found so far is that unless you use the TypeScript project template you will have to manually switch your Content type for all .ts files each time you add a new one.  This is a PITA but i am sure there is a solution for this to but we have not spent the time or energy to solve it.

Till next time,

Discuss (5)
More Posts « Previous page - Next page »