Category: C#

More Thoughts on the Blazor game design

More Thoughts on the Blazor game design

OpenGameArt
OpenGameArt

This is the latest in a series on the design of a web game based loosely on a no-longer-run game called Inselkampf. It won’t be exactly the same as the original game, I have my own ideas. To see other articles in this series, click here or on the category: Blazor on the right hand side.

There are two models with Blazor. Server and WebAssembly. Both are similar but the crucial difference is that WebAssembly can run completely standalone whereas Server needs a connection to a webserver. Server uses SignalR technology.

The danger with using the Server model is that each person playing the game implicitly creates a connection. With the WebAssembly version, there is no direct connection though it makes sense to have a connection of sorts perhaps a Restful type interface.  This means running a query to fetch game data and then running update queries.

So Blazor with WebAssembly it is. Why Blazor? Because it simplifies updating controls on the page.

Looking after Time

The nature of this type of game is any construction (buildings and units) takes a finite length of time. which can range from seconds to a day or so  I want to see how long before my gold mine goes up a level and so on. It’s normal to have all times countdown in the browser. This should put no strain on the server as its running in the browser. Keeping server and client in sync needs a bit of care in case someone figures out how to make the browser code run faster. Once it reaches 0, an update should be sent to the server which should do a quick comparison with its time and if shenanigans has occurred, return an update status and resync the browser to the server. The rule is “If you give em a chance to cheat- they will“.

Procuring Graphics

Much though I like the Inselkampf graphics for all the buildings, I’m not going to use theirs. It’s infringing copyright (reimagining the game is not copyright infringement BTW!) . As well as the free kenney graphics that I’ve mentioned before and various other websites such as opengameart, (shown in the screenshot) there is also the Reddit game assets subreddit so between these and some others I hope I can find what I’m looking for.  My requirements are quite modest.

 

Amazing multi-platform Asteroids in C#

Amazing multi-platform Asteroids in C#

Android asteroidsAsteroids was the first full arcade game I ever wrote in C. Asteroids in C# takes things to a whole new level.  The solution contains 12 projects in all: Three Blazor projects, a WinForms version, a WPF version, a UWP (Universal Windows Platform) and a Xamarin Android Forms version (shown).

You can compile and run any of the projects though you will need to install and setup a suitable SDK and emulated (or a real device) for the Android.

Written by Howard Uman and ported by Ernie Salazar, this is a wireframe asteroids, more true to the original than my own raster version. Out of curiosity, I created an Android 9.0 emulator (I don’t have a recent Android phone) and compiled then deployed it to the emulator. The screenshot is grabbed directly from the emulator which has a less than ideal screen ratio. This would work better on a tablet.

The structure of the C# Solution is interesting. All of the game code is in the Base project. All of the other platforms just host the main game window. The game uses the SkiaSharp graphics framework for Android Forms.

This is a very nice open source project and an excellent way to see how Blazor works in both Wasm and Server mode, not to mention the Android, WinForms/WPF and UWP versions.

I have an interest in Blazor which lets you write C# code that runs in the browser very easily.  With a bit of workj, this should be runnable on a Linux webserver as well. Something for me to try…

 

 

A newish game platform

A newish game platform

Blazor DungoonWeb games have been largely Flash in the past though that took a nosedive in the ‘tens (2010 onwards) and Flash is officially no more as of 2021. The spirit lives on in JavaScript games and there are innumerable games in JavaScript. That said, I’ve never been that keen on JavaScript. I talked about Web games in a post back in December and particularly that I saw Blazor as a possible game platform.

Today though I discovered Awesome Blazor on GitHub and it includes 18 Blazor web games including a multiplayer dungeon which is shown (I think it looks like a bit Pacmanish personally) . Most of these are ASP .NET Core 3.1 (which became .NET 5 late last year).

Some games will use wasm (Web Assembly) while other use C# in a terminal. As a simple proof of concept but nicely done, have a look at the virtual train set online.  You can lay track and then run one or more trains along it. Impressive as a demonstration of what you can do with C# and Blazor in a browser.

Time to upgrade Visual Studio?

Time to upgrade Visual Studio?

>NET 5
Visual Studio assembly versions

It’s more relevant if you are a .NET developer ie C# or VB.NET, but .NET 5.0 (including C# 9) has just been released. It was an almost 4 GB download and followed by a reboot but I’m now on .NET 5. No more .NET Core or .NET Framework unless you are developing GUI applications on Windows.

But you can also develop on Linux or Mac, but not using WinForms or WPF. Those are Windows only.  This page has downloads, or you can do what I did and upgrade through the Visual Studio Installer.

Also if you are on C (on Windows) you get C11 and C17 if you specify a compiler flag. You’ll see this on the Visual Studio 16.8 release notes.  I like to be on the (bleeding) edge of things. Maybe it’s FOMO (Fear of Missing Out). But I do find it interesting to see where the Linux support is going.

My other side project continues

My other side project continues

Smartphone
Image by Gerd Altmann from Pixabay

This is the social mobile multiplayer game I have mentioned before. The initial game creation program is mostly working. I say mostly because I will still be adding to it. It does however create all of the game data in about 30 seconds for a game that can hold up to 10,000 players. It then creates the output files which are read by the mobile apps. These apps have yet to be created but I’ve decided to do some early testing using non-mobile apps that I’m working on.

What I want to do is prototype the mobile app, not particularly visually but functionally. To this end I’m creating a C# client desktop app that does everything that the mobile app will do. It can read the data (directly rather than via a webserver) and let me create new orders and upload them back to the server (or in this case my development PC).

This client will be crude and not great looking but lets me test that data is coming and going correctly. I use JSON for everything, as a data transfer format as well as storing all game data at rest as opposed to a database. It lets me hold all game data in dictionaries (with a bit of tweaking it is possible to save/load lists of objects to JSON. After loading I convert them to Dictionaries using an Id field.

                var bytes = File.ReadAllText(Lib.PeopleFilename);
                var list = new List();                
                list = JsonSerializer.Deserialize<List>(bytes);
                persons = list.ToDictionary(x => x.Id);

It works and is quick. The downside of using a Dictionary is that it occupies more bytes per element than a List. How many? Well it’s never easy to figure. .NET does not really encourage discovering how things are implemented. This GitHub project by developer Ludovit Scholtz shows the memory used by various .NET Generic Collection Types (HashTable,  Dictionary, ConcurrentDictionary, HashSet, ConcurrentBag, Queue and ConcurrentQueue) with various string lengths in a TestObject which as string, an int and a DateTimeOffset.

Storing a million objects in a Dictionary <int,TestObject> with a null string occupies 48,222,240 bytes so roughly 48 bytes per entry. I believe a List is closer to 20 bytes overhead per element. So for slightly more than double the memory use, using a Dictionary gives a tangible performance yield.

,

How to visit many many places in one go

How to visit many many places in one go

green points
Image by Gerd Altmann from Pixabay

No this isn’t turning into a travellog.  Imagine a huge square. It has 33,554,432 points along an edge. The entire square would thus have 1,125,899,906,842,642 points in it. That’s 250 or 3210 points. (Yes those two numbers are the same!)

Now how about contriving an algorithm that will pick a random point in this square and keep picking each point but never more than once? Eventually it will have picked every point.  If it could visit a million points every seconds, it would take something like 35.7 years to visit each and every point.

So assuming you could create an algorithm, how large would it be? How about three lines?

        public static ulong Nextulong()
        {
            ulong result = ((aUVal * ULast) + bUVal) % aUVal;
            ULast = result;
            return result;
        }

That’s in C#. The values for aUVal and bUval are

        const ulong aUVal = 1125899906842597;
        const ulong bUVal = 1051122009542795;

A uLong is just an unsigned long. That’s a 64 bit unsinged int.
This is an example of a Linear Congruential Generator BTW.

Posted in C#
How to count lines of code in Visual Studio

How to count lines of code in Visual Studio

Calucating Code metrics in Visual StudioUntil this morning, I didn’t realise that Visual Studio (even the free Community Edition) has this built in. I was curious to see how much code I’d written so far for my game processing engine.  Development comes in leaps and bounds during evenings and weekends.

Visual Studio has Code Metrics in it. You can do this for any project that builds correctly. To show this you have to do View => Other Windows => Code Metrics Results. That displays the window. Then you have to go on the Analyze Window, and click Calculate Code Metrics.

Lines of code

However you might want to take these with a pinch of salt. As I understand it, Lines of Source Code is calculated from the il code output from the compiler. The last column (Lines of executable code) suggests that most of my program is comments which is wrong! There is however a fair amount of data in the form of Constructor initializations, and one file of 1290 lines has over 1,000 such initializations.  You can read what the other columns mean and everything you ever wanted to know about code metrics on the Microsoft site.

Out of curiosity, I manually counted the number of lines in this project. There are 15 files and they added up to 3700 lines but that includes comments and blank lines.  A quick search for // found 119 which probably means I should improve my commenting. Blank lines is probably something similar. So we’re talking 3700-1000 (constructor initializers)-119 (comments) -119 (blank lines) = 2462 lines of code so far. That’s working tested code mind you.

 

A list of open source physics engines

A list of open source physics engines

Chipmunk Color matchIt’s not uncommon to have 2D games (and 3D) incorporate a physics engine. So when objects move and hit each other they behave realistically. The code that deals with “physical” interaction, objects bouncing or rolling off other objects is usually all parcelled up in a game physics engine.

Doing that means the programmer doesn’t have to worry about objects interacting. Your character moves into a room and knocks a vase; the vase falls over and breaks. Imagine how complex it would be if you had to program all the interactions. Instead, all objects in the room are predefined. As objects move and hit other objects they behave according to the predetermined rules. Balls drop to the floor and bounce. Breakable objects break.

An indie game studio called Tapir Games has put together a pretty comprehensive list of open source game physics engines. There’s even a couple in C though many are programmed in C++, C# and so on.

The picture comes from Chipmunk color match, one of the games using the (C library) Chipmunk physics library.

Microsoft appears to reembracing game development again

Microsoft appears to reembracing game development again

Image from Microsoft learn games

They have just set up this webpage according to the announcement on one of their dev blogs. Of course there’s irony that they include MonoGame, because if it hadn’t been for MonoGame, all of the XNA library code would have been lost. XNA was Microsoft’s own game development technology that got to version 4 and was then abandoned.

There’s also a page of tutorials teaching Godot, Unity and a backend service called PlayFab. It never ceases to amaze me that Microsoft don’t invest just a little bit more into their games development. They’ve got lots of different platforms including various XBox consoles, PCs, Mobile and so on that can all be programmed using Microsoft related technologies using Microsoft supplied software that is very good and often free.  It often feels like they’ve backed off from the days when they were publishing games.

Actually going schemaless in C#

Actually going schemaless in C#

JSON Image
Image from json.org

Back in August I talked about going schemaless and I’ve made some progress since then. I’ve created a number of C# classes, many of which include single and in one cases a 2D array of things I want persisted to disk.

I use JSON (JavaScript Object Notation) files to hold the data.  So long as I’ve defined those classes with Properties using Get and Set, the JSON converters in .NET handles it all very nicely.

For example, in my game I have a CityArea class which includes a List<BuildingType> as well as several public properties.

This saved out as JSON like this:

[
  [
    {
      "buildings": [
        {
          "Name": "College",
          "Size": 2,
          "Percent": 60,
          "Cost": 50,
          "Type": 11
        },
        {
          "Name": "Gallery",
          "Size": 2,
          "Percent": 40,
          "Cost": 150,
          "Type": 23
        },
and ends...
      ],
      "State": "R",
      "Type": "F",
      "Density": "L",
      "Points": 46,
      "AreaName": "Newfane"
    },

The whole JSON file has 1500 buildings scattered amongst 100 areas (10 x 10) and is 11422 lines long. The file is 234Kb long. Though that’s with indentations. I could remove that but for now, during development, it makes the file easier to read.

These are the two class definitions (I’ve removed extraneous stuff from them),

class BuildingType : ICloneable {
        public string Name { get; set; } = "";
        public BuildingSize Size { get; set; } = BuildingSize.bsNone;
        public int Percent { get; set; }
        public int Cost { get; set; }
        public BuildType Type { get; set; }
}

class CityArea {
        public char State { get; set; }
        public char Type { get; set; }
        public char Density { get; set; }
        public int Points { get; set; }
        public string AreaName { get; set; }
        public static List AllBuildings = new List();		
}

This is the code to save out areas (which is List<CityArea> areas to the file. I found this by reading the Microsoft documentation about Serialization and deserialization. It’s pretty good stuff and the code for saving these structures are these pretty short methods.

        public bool SaveToUTF8(string filename)
        {
            var options = new JsonSerializerOptions
            {
                WriteIndented = true
            };
            var bytes = JsonSerializer.SerializeToUtf8Bytes(areas, options);
            File.WriteAllBytes(filename, bytes);
            return true;
        }

and this is the code to Load it.

        public bool Load(string filename)
        {
            try
            {
                var bytes = File.ReadAllText(filename);
                areas = JsonSerializer.Deserialize<CityArea[][]>(bytes);
            }catch(Exception e)
            {
                Error = $"Failed to load {filename} because {e.Message}";
                return false;
            }
            return true;
        }

I haven’t timed either Load or Save but they are fractions of a second.