Saturday, June 4, 2011

DotNetFish - Editor Minimap

Added the basic part of the minimap to the editor. Also added the ability to move more than 1 square using the shift and ctrl keys.

I'd still like to add the following features before going to work on the game itself.
  1. Need the ability to change a tile on the map
  2. Be able to navigate through the error tiles
  3. Need to be able to runs a check to make sure every edge tile is connected
I still think there is some bugs in the map generator, but I think I can wait on fixing those until I get further along.

Tuesday, May 31, 2011

DotNetFish - MVVM Part Deux

I only thought I was done refactoring the Projects to use the MVVM pattern. Turns out that two of the three views in the level editor were not converted yet. The Map Select window will not be converted anytime soon either, but its very simple to begin with and not a big deal if it isn't. It cannot be converted at this time because the GMap control does not support MVVM. The other page that I needed to convert is the Edit Level Window, where all of the map editing will be done. It took quite a bit of doing, but I finally forced it into compliance. I am not happy with the results though, and I think some more refactoring is in order.

The biggest challenge that I ran into was getting the my ViewModel for the page, and the custom Map Control to play nicely together. The custom canvas control that I am using does not support any sort of bindings, so I was forced to write my own.

Here is what a dependency property looks like

public static readonly DependencyProperty CurrentPointCommandProperty =
        DependencyProperty.Register(
            "CurrentPointObject",
            typeof(Point),
            typeof(MapCanvas),
            new PropertyMetadata(new PropertyChangedCallback(OnPropertyChanges))
            ); 

Dependency properties are quite easy once you get the hang of it. The string in the example above, is the name of a public property. The first type is the type of the property being referenced, and the second type is the type of whatever object the property resides in. This also contains a Callback when the property changes


private static void OnPropertyChanges(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
 (obj as MapCanvas).InvalidateVisual();
} 

So anytime a property changes the Visual on the mapCanvas is overwritten.

Nothing much to it so far. My biggest concern is the number of  DP's that I have to register just to do something simple.


Now, the second change I made here, was to use the MVVM Light Toolkit instead of the custom implementation I created to handle the commands. This toolkit allowed me in conjuction with the Blend SDK to wire up commands to events that fire on the page rather than the control.

For example

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
 
<i:Interaction.Triggers>
        <i:EventTrigger EventName="KeyDown">
            <cmd:EventToCommand Command="{Binding OnKeyDown}" PassEventArgsToCommand="True" />
        </i:EventTrigger
</i:Interaction.Triggers>    

This code allows me to bind to the KeyDown Event. It allows my viewmodel to recieve the eventArgs as well. Very useful.

My next step is probably going to involve some refactoring. I think that I can use the MVVM Light messages to help pass information from ViewModel to ViewModel, and also ViewModel to View. Doing so should cut down on the amount of code and Dependency Properties required. Even if most of them are refactored out, I learned a ton about using them and debugging them!



Friday, May 20, 2011

DotNetFish - Sweeping Changes

Got a healthy dose of optimization finished in the map builder. It now approaches each tile from a much lower zoom level, and only goes to a higher zoom level when the map tile has a water/land edge. I'm still not 100% sure that this is the best approach to take., and it may be faster and simpler to process the tiles at a higher zoom level. This is only possible now due to the other changes I made to the build process. For a body of water that has a lot of water and long compared to edges should see a pretty significant improvement, although it will be slower when testing using only edge tiles.

Tiles are now processed much simpler than they were before. Its always difficult to make something simple. I realized that my design was much too complicated when it didn't need to be, so I simplified it significantly. I am now getting much better results, and far fewer error tiles.


I am almost ready to move away from the map generation process, and start focusing on some additions to the editor to allow you to fix error tiles, add spawn locations, etc. I have a few bugs to look at in the build process, and then I plan to focus on the editor.

Monday, May 2, 2011

DotNetFish - Headed towards optimization land

Looks like its time to take a trip towards optimization land.

I knocked one of the items off of my list, which was adding some directionality into the path finding to help it out. Then I attempted to process a small pond. This didn't go so well, as it ground to a halt. The problem I was having is that during debug I was saving each image I was processing. 800 tiles produces 200,000 images in a single directory which was a major source of the slowdown.

After fixing this issue, I will still need to increase the performance. I don't want to spend 4-5 hours building the map of a small lake. So far, I have followed the advanced rule of optimization which states

Don't Optimize Yet

You see, I have not done much performance tuning up to this point, although I did optimize the actual process of processing the tile. I think its important to know when to optimize. I'm now to the point where I need to start processing larger maps, so it makes sense to address this issue now.  I could have made these changes earlier of course, since I understood where the bottleneck was occurring, but there were more important things to work on.

I may have touched on the optimizations that I need to perform, but what it comes down to is processing the edge tiles at the largest magnification, and processing everything else at a much smaller magnification.

Currently, I am processing each 256 tile at the largest zoom setting into  256 tiles. Each of those tiles is having its borders processed as well. A good first optimization would be to only break a tile down into smaller tiles if it actually has an edge on it. Add in zooming out a few levels, and the performance should increase several orders of magnitude.

Currently it took about 6-7 minutes to process 1200 tiles which was about 1000x1000 feet. Given that even a fairly small lake hear my house  is 52,800x 26,400, you can easily understand why this is so important.


On a final note:
After the second run, I had approximately a 4% failure rate. Now I have something to shoot towards beating.

Sunday, May 1, 2011

DotNetFish - A* PathFinding First Pass

It took me a full day to implement, but the map builder can now find a path to an unconnected edge.

The map builder is coming along nicely. I have a few more issues to iron out with the path finding in general that need to be fixed. Once that is done the generation part will be finished for now. Maybe next week I'll be able to hammer out the rest of the path finding.

Current Items of interest
  1. Double edge connections. Loops need to be implemented. For example, is tile A has 2 connections on the same side but nowhere to go, then the tile next to it needs to have a loop added to it,this will require some new tiles.
  2. Need directionality for finding potential matches when looking for target tiles to pathfind to. It should travel away from the starting side first. Only if no potential matches are found should it look behind it.

Friday, March 25, 2011

Appfabric Caching Admin Client

http://mdcadmintool.codeplex.com/Been doing some work with appfabric. One of the things I don't like about it, is the lack of a way to mange the cache with a GUI. Currently, you can only manage your cache and clusters with powershell. One thing that I haven't been able to do is visualize the items inside the cache. But I did find a great solution to this.

http://mdcadmintool.codeplex.com/

The client seems pretty stable, although there are still some issues with it. I hope that the guy that wrote it continues to improve it. Maybe in the future MS will provide a easy to use client but until then, this will have to do.

Saturday, March 12, 2011

DotNetFish - We've got MVVM

Just a quick status update. Implemented MVVM pattern for the TileBuilder Project. It was the most time consuming of the WPF projects to do. The other ones should fall quickly now. Won't be able to work on it this weekend, as I am going to do some research(IE real fishing). Real fish taste better anyways.