Thanks to suggestions in the Reddit CSharp subreddit (you can view the entire thread here), I fixed the missing file issue and SkiaSharp is now happily outputting graphics on the VPS. I’m referring to the More Programming Joys blog entry I posted yesterday.
There were two things that were needed to fix it.
Add a package to the solution. This was the SkiaSharp.NativeAssets.Linux package and I used Nuget to add it to my Windows solution. If you haven’t used Nuget, it’s a great package manager and makes it very easy to add packages.
On the Visual Studio Publish page, I needed to change the Target Runtime to linux-x64. That’s the dialog above. When I clicked the Publish it put all the files including the library that was missing (libSkiaSharp.so) into the Target location and once uploaded it worked.
So I’ve been doing some .NET programming. First on Windows because I can debug it there then “Publish it” which puts all the files (compiled in release) needed, including any dlls into one folder and upload it to a VPS using WinSCP. I’ve also got a terminal session connected by Putty. I use Serilog for logging and SkiaSharp for graphics.
First bug was a missing file but it was a stupid error on my part. I had the file in a path under the home folder and had used ~ in the file’s path. You can use ~ in Bash- it means your home folder, but not in a file path in an application. Putting in the full path fixed the bug. D’oh.
Because it’s .NET (6) that I’m using, you don’t get configuration stuff the same as you did with .NET Framework. I store some config information in a file and define the path with these lines of code which work on both Linux and Windows.
I like Serilog ( with project on Github at ). Nice and simple logging but flexible enough. As this application is a command line app run whenever, it’s easier to view the logs afterwards.
Why use SkiaSharp?
I was quite happy to use System.Drawing but according to this, There are issues with libgdiplus. So I thought I’d try SkiaSharp as I’m doing stuff with Flutter and Skia is the library that underpins that. This is what it takes to create a 100 x100 grey coloured Bitmap in SkiaSharp, add yellow dots and save it to disk as a .jpg. That’s what you see up above.
internal void SaveBitMap(int id, string filename, Gang gang)
{
var info = new SKImageInfo(100, 100);
using var surface = SKSurface.Create(info);
SKCanvas myCanvas = surface.Canvas;
// clear the canvas / fill with white
myCanvas.DrawColor(new SKColor(0x99, 0x99, 0x99));
// draw the dots, one for each block
foreach (var block in Blocks)
{
if (block.Owner == id)
{
myCanvas.DrawPoint(block.X*5/2, block.Y*5/2, SKColors.Yellow);
}
}
// Now save to filename
var mainCanvasImage = surface.Snapshot();
var TempTIFbitmap1 = SKBitmap.Decode(mainCanvasImage.Encode());
using (var image = SKImage.FromBitmap(TempTIFbitmap1))
using (var data = image.Encode(SKEncodedImageFormat.Jpeg, 100))
{
// save the data to a stream
using (var stream = File.OpenWrite(filename))
{
data.SaveTo(stream);
}
}
}
It works fine on Windows but on Linux, (Ubuntu 20.04) I hit bug #2. “System.TypeInitializationException: The type initializer for ‘SkiaSharp.SKImageInfo’ threw an exception.”. And that’s where I am at the moment. This is similar. I’ll keep you informed.
Back in May 2020 (nearly two years ago) it was originally announced and the updated release date now looks to be late 2022. Also it’s $179 not $149. But they have given a lot more details; you can for instance see the hardware spec.
Also more relevant is the way of creating games. Either in Lua + C or just C. The dev tools illustrated are running on a Mac but according to this Twitter thread (worth a read), they’re available for Windows, Mac and Linux. The SDK looks impressive enough- “It includes helpful functions for things like font handling, drawing, animation, sprites, tilemaps, collision detection, A* pathfinding, audio synthesis, crank handling and more. You can download the SDK which includes a simulator now from the dev page..
Would I get one? I’m toying with the idea. A mono display of 400 x 200 is a bit retroish and my days of creating those types of games are probably long behind me, but it’s tempting.
A few years back I owned a calendar made up of two dice (a bit like the image from Wikipedia) to show the day of the month. The two dice had all the digits needed to display any number from 01 to 31. It’s a neat little puzzle to ask someone if they can figure out what the numbers on each of the two dice must be for this to work.
You can probably find the answer on the web, and it took me just 30 seconds to find one. But still, it is a fun little puzzle.
What I thought was, could I write a program to solve it? So I’m going to try it. It will be in C# to start with but if that works, I’ll redo it in C and publish both on here.
I’m working on three game projects (my side projects), One is Flutter front end plus C# back end, another is the same but a different type of back end and the third is a mobile game with C# backend but its put to one side until the others are done. These are all side projects.
I’ve bought graphics and they do up to a point- e.g. kenney.nl is very good. But sometimes you need something a bit better or that’s not covered by that library.
Now one of the things I’ve done is use low costs artists from sites like Fivesquid.com and fiverr.com. Many of these artists are very good but live in countries where things are a lot cheaper than here in the West. Exploitation? Maybe, but they are happy to do the work and it saves me a fortune. What might cost me a couple of hundred pounds here in the UK can be done for say £20.
But I’ve found when dealing with them that you can’t take anything for granted. You have to have a bit of patience and explain everything including your expectations. And make sure you nail the price down exactly. I had arranged everything with one to do 35 small graphics and he wanted £35 for each graphic. Despite his advert saying 5 graphics for £10!
So I’ve found, you need to specify file format (.png or .jpg), layout- single files or in a sheet in a grid. Also fivesquid have a thing where when the order is delivered, you have three days to mark it complete or asks for changes. One artist said it was complete but hadn’t quite got it ready and the three day period expired before I’d received anything. So I could hardly accept nothing. It was though a genuine mistake on the part of the artist and I did get the graphics eventually.
One of my favourites and one that I actually bought twice in my life and of course I have mentioned before. Originally I bought it back in 1982 and more recently in 2015 along with the sister “More Computer Games” book. The reason I mention it because there’s an ongoing project to do the games in it in languages other than BASIC.
The languages they’ve chosen are:
Java
Python
C#
VB.NET
JavaScript
Ruby
Delphi / Object Pascal
Perl
I no, it’s sad. No C… But given that it includes C#, I’ll let them off.
For some not too complex applications, JSON can be a very handy way to store data rather than say using a database. It also has the advantage of storing data of varying sizes. For instance Lists with varying numbers of items. I created a Saveable generic class below that you use as an ancestor class for that you wish to Save/Load an IList of whatever.
public class SaveAble<T>
{
private string _error = "";
string LastError()
{
return _error;
}
public IList<T>? Load(string filePath)
{
if (!File.Exists(filePath))
{
Log.Error("Missing file {filePath}");
_error = $"Missing file {filePath}";
return null;
}
var content = File.ReadAllText(filePath);
if (string.IsNullOrEmpty(content))
{
Log.Error("{filePath} file is empty");
_error=$"{filePath} file is empty";
return null;
}
return JsonSerializer.Deserialize<IList<T>>(content, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
})!;
}
public bool Save(string filename,IList<T> collection)
{
var options = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNameCaseInsensitive = true
};
try
{
var bytes = JsonSerializer.SerializeToUtf8Bytes(collection, options);
File.WriteAllBytes(filename, bytes);
return true;
}catch (Exception ex)
{
_error = $"Exception:{ex.Message}";
return false;
}
}
}
Just define your class MyClasses from SaveAble<MyClass>
where MyClass is the class you have a List of. Then you can do
MyClasses myclasses;
myclasses.Save("filename",List<MyClass>) and
List<MyClass> list = myclasses.Load("filename");
It is fast. On my PC (now six years old), it can load a 99,000 line JSON file in well under a second.
There are plenty of other programming languages that would do. Programming languages are just tools but C# comes with several advantages.
I know it pretty well, having been using it since 2005.
With .NET 6 (and 5), it’s easy to create applications that run on Linux. This lowers the cost for hosting. I’m setting the game on a low cost VPS.
Also on Linux, ASP.NET works pretty well for both Websites and Web Apis.
I like some of the recent changes in C#. And Visual Studio 2022 Community Edition is pretty good. For instance the JSON handling has got better and better.
Do you know what Hello World in C# looks like now? Here it is in its entirety.
Console.WriteLine("Hello, World!");
That’s a console application. One line! Follow the link for more details about the C# templates. Note, there’s no usings there either. That’s because applications now start with a default set in C# 10 and .NET 6 (you get both if you install VS 2022). And if you want a particular namespace that you’ve written to be available to all source code in a project, you can just add this:
global using xyz;
And it becomes available everywhere without needing any more usings.
You may have noticed, I stopped posting here a while back because basically I ran out of ideas for C related games stuff plus I was doing other stuff that wasn’t relevant (Delphi, C#).
I will get back to finishing my 2nd eBook, but for now, I’m working on a web/mobile game that isn’t really C related. However I thought I’d cover development of it here. as (a) part of it is C# (so technically it’s C and (b) it’s a game. The backend part is C#, the front end Flutter which is Dart. I’m also going back to my old game design roots as the game architecture is ‘Postal Game’.
What is ‘Postal Game’ architecture?
Well first a little potted history.
Back before the web existed (late 80s), people used to play games by post. They’d fill in a postcard with the orders, post it to the game provider who would enter the details in a computer, process the game then print the results out and post that back. I discovered this (in the UK) back in 1986 and created a postal game: Casus Belli. A 16 player version of Empire. It ran for a year or so and I even attended a postal games conference with a stall back at the start of 1987 in London. By chance, the stall next to mine was run by KJC Games and we got chatting. Kevin J Cropper (The KJC of KJC Games) said “If I ever wanted to sell the game contact me” and at the end of 1987 I did and found myself working for KJC Games as a game designer and programmer in Cleveleys (just North of Blackpool). It was a small cottage industry in the UK and KJC Games was the biggest fish in this admittedly small pond.
Over the next two and a half years I created the 100 player version of Casus called Warlord. Long after I left they ran games across the web and though they don’t run it any more you can still see the page for it. My big creation was a 1,000 player postal game called Quest which KJC still runs. Not bad for a game created in 1989! They still have my name in the Advanced rules which is nice as I last did some work on it in 1996. It took me a year and 40,000 lines of code (Turbo Pascal 5) to create. The others listed helped test it, made suggestions and Steven Fairbrother who came along after I left, fixed my bugs. When you write 40,000 lines of code in a year, there are a few bugs included…
So each turn gets posted in, processed, printed and posted back. The architecture is the same except its all now sent across the web. There’s a front end programmed in Flutter. This makes it possible to use the same code for Web and mobile development. The game is processed at a fixed rate. In this case I’m going for every three hours but slower or faster is possible. When it’s time, all orders are processed and the results made available to be fetched from the web or mobile device.
Pros and Cons
A Game Processing Engine (GPE) is a completely different kettle of fish from your traditional multi player game server. Hardware requirements are much less and you don’t manage multiple players all at once. Basically the game web/mobile uploads a zip file from each player to send in the orders and then fetches one containing the results. The GPE maintains game state, processes all orders, outputs all results and backs up the game, both before processing each turn (in case it goes wrong so it can be fixed and rerun) and afterwards,
So I’ll be posting here about my progress, programming issues and so on. If you have any queries, please don’t add them as comments – I delete any non-technical comments so instead use the contact form via the About me link on the top.
I’m slowly getting back to normal. This is a ten minute long video I saw today on creating a falling sand simulation (not just sand but water, oil, fire and other materials). Nice to see someone describing how to code things in C.