Making it up as I go

My very first action on this new post was to tweak the color scheme. Not because it provides any utilitarian purpose yet, but because I have a fondness for the dark theme and is my favorite Visual Studio theme. So I have spent fifteen minutes playing around with different color combinations as provided by MahApps.Metro.

Now that pretty colors are sufficient to continue, I’m actually going to make some functionality. Well, after I explain this post’s name. I have a bad tendency to think up an idea and just go start working on it, making it up as I go. This started out as one of those times before realizing that a couple of pieces of paper outlining the general flow is not a bad idea. So I have a lot of scrap paper scattered about my desk with scribblings so incomprehensible that future archeologists are going to frame them in a museum and claim the use of hieroglyphics didn’t end until a much later time period than previously believed.

Continue reading Making it up as I go

Because I can

Without exception, my best and worst ideas are motivated by the reason “because I can”. This is likely poor motivation but I stand by it. Unfortunately, this is not this post’s motivation, which is “because it could be useful”. So, I’m taking a detour from my usual topic of my video game.

Today’s topic is rather customized Data Transfer Object (DTO) generation. This is definitely a matter of utility.

This part is where “because I can” comes in. I shall use C#, WPF, Akka.NET, and Visual Studio 2015 RC.

The minimal viable product for me is the ability to connect to a database, and then dump all tables into a DTO C# class. Now the first question you might ask is “is that not the entire scope of this?” And you would be mostly right, except that I also have a wishlist a mile long but that will come later if at all.

So here I go:BecauseICan_2

First order of business is the NuGet Package for one of my favorite libraries: MvvmLight. BecauseICan_3

Actually, I’ve installed a couple of packages.BecauseICan_4

Data Connection Dialog because I’m lazy and this seemed the easiest and quickest way for me to get a generic sql connection going. MahApps.Metro because they are great and make visual design easier on me. Akka.NET because I’m planning on farming out the file creations to Actors (ha, never heard of actors farming). MvvmLight to simplify my WPF. And the others are supporting packages.

I’ve made a very simple form to start off with BecauseICan_5

The creator of MvvmLight has an interesting blog post here which I used and butchered the concept for my own purposes.

There is now a static resource ViewModelLocator, of which one is in App.xaml

      <locator:ViewModelLocator x:Key="VmLocator"/>

That class looks like this

    public class ViewModelLocator
    {
        static ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
 
            SimpleIoc.Default.Register<ActorSystem>(() => ActorSystem.Create("LeastCost"), true);
            SimpleIoc.Default.Register<AnalysisViewModel>();
        }
        public AnalysisViewModel AnalysisVm
        {
            get
            {
                return ServiceLocator.Current.GetInstance<AnalysisViewModel>();
            }
        }
    }

And is used like this

<Controls:MetroWindow x:Class="LeastCost.MainWindow"
                      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                      xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
                      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                      xmlns:local="clr-namespace:LeastCost"
                      mc:Ignorable="d"
                      DataContext="{Binding Source={StaticResource VmLocator}, Path=AnalysisVm }"
                      Title="LeastCost DTO Generation" Height="350" Width="525">
  <Grid>
    <Button Content="Connect to DB" Command="{Binding CmdConnect}" Width="150" Height="30"/>
  </Grid>
</Controls:MetroWindow>

The viewmodel being used in the window is this

    public class AnalysisViewModel
    {
        private readonly ActorSystem _actorSystem;
 
        public AnalysisViewModel(ActorSystem actorSystem)
        {
            _actorSystem = actorSystem;
            CmdConnect = new RelayCommand(DialogConnect);
        }
 
        public RelayCommand CmdConnect { get; private set; }
 
        private void DialogConnect() ....
    }

So when I click the button I get
BecauseICan_6
BecauseICan_7

Next post on this topic will deal with how to use that sql connection to get all the data I need and dump it to custom C# class files.

Before I forget, all my code on this is here on github.

Morgemil Part 11 – Someone has to live in this world

The first inhabitant of every game world should be the player himself. Not because he might have something interesting to do yet, but to do Usability Testing. The most important thing to a game is how the users view it. Games receive little points for being technically sound but magnitudes more for how fun it is.

Know who the first player is? The developer(s) should be the first player. The most effective builders of a product are those who use it themselves.

Continue reading Morgemil Part 11 – Someone has to live in this world

Morgemil Part 9 – BSP Dungeon Generation Part 2

I’ve started a list of tiles to be found

module Morgemil.Map.Tiles
 
let DungeonFloor = TileDefinition(1, "Floor", "Dungeon floors are often trapped", false, false, TileType.Land)
let DungeonWall = TileDefinition(2, "Wall", "Dungeon walls are built from the prisoner's bones", true, true, TileType.Land)

I’ve also changed the coloring slightly which is reflected in the header image.

      let tileColor =
        match tile with
        | _ when TileDefinition.IsDefault tile -> Color.Black
        | _ when Tiles.DungeonFloor.ID = tile.ID -> Color.White
        | _ when Tiles.DungeonWall.ID = tile.ID -> Color.Red
        | _ -> Color.Gray

Continue reading Morgemil Part 9 – BSP Dungeon Generation Part 2

Morgemil Part 7 – A whole new world

My first order of business is to create a world. So before I go off typing up a code-storm, I want to give the one defining rule:

Interesting results is more important to Morgemil than consistent or realistic results. I will leave making an amazingly complex believable world up to the genius making Ultima Ratio Regum.

Now that the rule is out of the way, I’m going to start: The portion of the world I’m building today is a simple dungeon. The generation of this dungeon will be absurdly simple. The bigger concern is storage of this dungeon.

Continue reading Morgemil Part 7 – A whole new world

Morgemil Part 6 – RNG

Morgemil can be loosely defined as a roguelike. Indeed, I’ve drawn much inspiration from some roguelikes of which the first I ever played was Angband eight years ago. The largest influence is ToME 2 “Troubles of Middle Earth” which is now mostly defunct and replaced by ToME 4 “Tales of Maj’Eyal”.

Now something most roguelikes have is procedural generation placing the player at the mercy of the Random Number Generator (RNG). This, simply put, determines whether the player lives or dies by creating unique dungeon levels, the level’s population of monsters, and the loot dropped by monsters.

My search’s first action was to check RogueBasin’s article on RNGs which quoted the Mersenne Twister as a good candidate “which produces fast and high-quality random numbers“. This is a sufficient recommendation for me so I then started searching for an implementation. I am fortunate in that there is an existing Mersenne Twister implementation in F# from a reputable source, the Math.NET Numerics library. So armed with the NuGet package I set to work.

module Morgemil.Math.RNG
 
open MathNet.Numerics.Random
 
/// <summary>
/// Type alias for a System.Random implementation
/// </summary>
type DefaultRNG = MersenneTwister
 
let SeedRNG(seed : int) = DefaultRNG seed
 
/// <summary>
/// Given an RNG and likelihood, returns the success
/// </summary>
/// <param name="chance">[0.0, 1.0]</param>
let Probability (rng : DefaultRNG) chance =
  match chance with
  | 0m -> false
  | 1m -> true
  | _ -> (rng.NextDecimal() >= chance)

This is not perfect, but it is at least a placeholder while I figure out what is needed. Testing this is a problem. All I know to test is the edge cases of 0.0 and 1.0.

module Morgemil.Test.RNGTest
 
open Morgemil.Math
open NUnit.Framework
 
[<Test>]
let ``RNG Probability test``() =
  let seed = 150
  let rng = RNG.SeedRNG seed
  Assert.IsFalse(RNG.Probability rng 0m)
  Assert.True(RNG.Probability rng 1m)

With pseudo-random numbers I shall create a world generation equation that will dwarf any amount of creative content I could create myself.