Morgemil Game Update #2

I’ve been working off and on making a video game in F#. I thought I’d drop an update saying my progress.

Github

I’ve done 68 commits since the beginning of the year according to GitHub. Although progress technically started on Mar 15, 2015.

Github progress

Progress

The player may move around the game level on screen with the arrow keys. This is a square level surrounded by walls, and in either corner are stairs up to the previous level and down to the next level.

Moving around


I’m filling out a set of CLI commands to interact with the game engine. A first use-case is to validate a directory containing game data in JSON. Validation and any errors are specified at both individual item, and the game data file, and then the aggregate levels.

> dotnet run -- --gamedatavalidate -d "../Morgemil.Data/Game" > validation.txt

Validation 2


Also, I validate all base-game data as tests during builds. A build isn’t valid if the associated JSON game data isn’t acceptable. Anybody who makes a mod/alternate later is responsible for validating their custom game data themselves. I’m hoping the CLI commands will make it as easy as possible for them.

I’ve generalized data validation to be fairly customizable with as little code as possible. It’s not perfect, but it validates all use-cases I have so far.

/// Validate Floor Generation Parameters
let private ValidateDtoFloorGenerationParameters (item: DtoValidResult<FloorGenerationParameter[]>) (tileTable: IReadonlyTable<Tile, int64>) : DtoValidResult<DtoValidResult<FloorGenerationParameter>[]> * IReadonlyTable<FloorGenerationParameter, int64> =
    item
    |> ValidateGameDataWithTable (fun acc element ->
        [
            ExpectedUnique element (fun x -> x.ID) "FloorGenerationParameterID" acc
            DefinedEnum element.Strategy
            tileTable |> AllExistsInTable element.Tiles "Tiles"
            tileTable |> ExistsInTable element.DefaultTile "DefaultTile"
        ]
    )

The command line has a few levels of usage right now, from merely just trying to read game data, to trying to validate game data, to trying to transform game data from raw format to the domain.

> dotnet run --
USAGE: Morgemil.Console.exe [--help] [--workingdirectory <workingDirectory>] [--gamedataread] [--gamedatavalidate]
                            [--gamedatafinal]

OPTIONS:

    --workingdirectory, -d <workingDirectory>
                          specify a working directory
    --gamedataread        read game data from a directory
    --gamedatavalidate    validate game data while still in raw format
    --gamedatafinal       create final game data to be output
    --help                display this list of options.

The gif of a character moving around above is the most naive and terrible game-loop possible and a starting point from which I will refactor and refine and rewrite.

type LoopEvent =
    | MoveWest
    | MoveEast
    | MoveNorth
    | MoveSouth

type Loop(characters: CharacterTable, tileMap: TileMap) =

    member this.Process(event: LoopEvent) =
        let vec1 =
            match event with
            | MoveWest -> Vector2i.create(-1, 0)
            | MoveNorth -> Vector2i.create(0, -1)
            | MoveSouth -> Vector2i.create(0, 1)
            | MoveEast -> Vector2i.create(1, 0)
        let moveCharacter = Table.Items characters |> Seq.head
        let blocksMovement = tileMap.Item(moveCharacter.Position + vec1) |> TileMap.blocksMovement
        if not blocksMovement then
            Table.AddRow characters {
                moveCharacter with
                    Position = moveCharacter.Position + vec1
            }

Summary

My code is here. I’ve got validation and transformation of game data down pretty well. I just need to keep working on the event loop.