MonoGame is going strong

Oliver Brown
— This upcoming video may not be available to view yet.

When I recently started looking at getting Gravitas working again with MonoGame, I was concerned about whether MonoGame was still maintained. After all, I first got Gravitas working in MonoGame 14 years ago.

Apparently, not only is it still maintained, but I honestly think it is doing better now than when I first paid attention to it. So this is me doing my part to demonstrate continued community interest where I can.

What’s happening now

MonoGame is backed by the MonoGame Foundation, which keeps the project going as a community-governed open source effort rather than relying on a single corporate sponsor.

More recently, the team launched MonoGame Hub, a new tool primarily to “accelerate the creation of MonoGame projects” while also providing access to news, tutorials, and community resources.

There is also a YouTube channel with regular livestreamed coding sessions that are worth checking out if you want to see the framework in action.

Showcase

Interacting with this video is done so under the Terms of Service of YouTube
View this video directly on YouTube

MonoGame does not have the recognition of the bigger engines, even the ones often associated with indie development like Unity or Godot. But it has been used to build a remarkable number of well-known games.

The showcase includes titles like Celeste, Stardew Valley, Fez, Streets of Rage 4, Bastion, and Carrion.

And of course, it is being used in the continued development of Gravitas.

Gravitas updated to .NET 10 and MonoGame 3.8.5

Oliver Brown
— This upcoming video may not be available to view yet.
Interacting with this video is done so under the Terms of Service of YouTube
View this video directly on YouTube

Gravitas is a gravity-simulating space game I originally released on Xbox Live Indie Games, and developed using XNA.

Nearly six years ago I spent a few hours porting the game to MonoGame, but never took it further.

I recently decided to try and revive it, again. This time it took less than an hour to update it to MonoGame 3.8.5 and .NET 10.

As a small aside, my day job is mainly as an iOS developer. I’ve spent a lot of time working on CI and doing a lot of work to optimize the build time. Every job I’ve done that has involved mobile development has had problems with slow build times - that’s why things like hot reload and previews are so important.

A clean build of Gravitas on my Mac takes just two seconds.

Things to do

Before I can actually release it, there are some things I need to do.

Some issues are either because of the XNA to MonoGame porting, or just evolution in MonoGame:

  • Broken match options screen.
  • Weird duplicate UI in game.

Some issues that were in the original release that I always wanted to deal with:

  • Camera zooms in and out too quickly.
  • Some text hangs off the screen.
  • Some scoring glitches - you can get a double kill when the second kill is a suicide.

There are practical considerations about releasing it on more than just an Xbox:

  • Fix keyboard control.
  • Implement touch control.
  • Where to actually release it?

I also need to use some better fonts.

Ex Astris Scientia

Oliver Brown
— This upcoming video may not be available to view yet.

“Ex astris scientia” is a Latin phrase meaning “knowledge from the stars” and is the slogan for Starfleet Academy, in Star Trek.

It is also the name of what is probably the best Star Trek fan site there is. And honestly, “fan site” does not really do it justice.

Ex Astris Scientia is Bernd Schneider’s Star Trek reference site. It has been running since 1998, which means it’s also probably one of the oldest Trek sites still actively maintained.

The site has some “obvious” content, like:

It also contains a large amount of reference material:

But the sort of content that I find more interesting, and what made it first stand out for me, is a bit weirder.

For example, in Star Trek The Next Generation, captain Picard often had a book of Shakespeare open in his ready room. Did you know that the page it was opened on was usually different?

Or how about a comprehensive list of modern day items used as props? My favourite example is the prolific use of freezer spacers for creating dramatically lit backgrounds.

Or maybe just the simple fact that Kirk argued a computer to death 4 times?

Star Trek Voyager: Across the Unknown - DLC announced

Oliver Brown
— This upcoming video may not be available to view yet.

Daedalic Entertainment and Gamexcite have announced downloadable content for Star Trek: Voyager - Across the Unknown, including some that is already out now.

In my earlier post about the base game, I noted a few things I’d like to see in a DLC. Very little detail has been confirmed and I don’t really expect much of the specifics of my suggestions to make it.

However, one thing has been confirmed: a mode featuring the U.S.S. Equinox. And honestly I’m happy to see any extra support.

The first DLC is available now with the rest coming throughout the year. Hopefully if it is successful, there will be more.

DLC 1: Delta Chronicles – available now.

New missions, recruitable heroes, six new technologies and four NPC ships.

DLC 2: U.S.S. Equinox - soon

Contains a completely new, playable ship along with crew, technology and more.

DLC 3: later this year

Contains more missions, heroes, technologies and NPC ships.

DLC 4: New sector - later this year

Contains a whole new sector with storyline, missions, characters, NPC ships and technologies.

Official site

Interacting with this video is done so under the Terms of Service of YouTube
View this video directly on YouTube

Q War - Shockwave game

Oliver Brown
— This upcoming video may not be available to view yet.

At around the same time that I worked on Supremacy, I worked on another game called “Q War”.

Interacting with this video is done so under the Terms of Service of YouTube
View this video directly on YouTube

Both were inspired by the content of Gary Rosenzweig’s Advanced Lingo for Games book. But where Supremacy was a slight refinement and rebranding of a complete game, Q War takes one behaviour (the implementation of the bullet sprites from both the “Space Invaders” and “Space Rocks” games) and builds a different game, complete with “original” graphics.

I believe I worked on Supremacy first as a learning exercise, and then started Q War. But I made Q War available first. The only hard evidence I have is the remains of the Shocklive! site in 2001:

  • 8th February - Site created! Q War, a two level action shooter is playable
  • 18th February - A Completely re-done Q War has been uploaded!
  • 14th March - Supremacy, a new fun strategy game is now available!

The game has been submitted to the Flashpoint Archive but as of 27 May it is not yet available. It is also sort of playable directly on this site.

Gameplay

Each level puts you in control of a ship that can fly around and shoot, with limited shields that deplete as you take fire. The game supports one or two players working cooperatively.

The game is split into multiple levels, connected by a map screen between each one where you choose your next destination. Starting in the top left, the goal is to reach the bottom right. Levels can be blank, or they can contain obstacles — either an asteroid belt you need to survive for a set time, a powerful enemy station that is shooting at you, or a pair of enemy ships to defeat. Any combination of those can appear in a single level, including all three at once.

Online features

Q War features two online features.

Maps

The map is loaded from the map.txt file along side the game file on the server. An example map.txt file:

[["xxx","a1x","a1x","xxx","xs1","xxx"],
 ["axx","axx","axx","asx","x2x","xxx"],
 ["axx","xxx","xxx","axx","x1x","xxx"],
 ["axx","axx","xxx","xxx","x1x","xs2"]]

Firstly, that format is the default way Lingo serialised an object. That is an array of four elements, each of which is an array of six strings.

I think the game technically predates JSON (Wikipedia says it was first specified in March 2001). It certainly predates JSON being widely used for anything. As such, Director and Lingo do not support JSON and instead use their own format. However, for string arrays, the syntax just happens to be the same.

Each string controls one map cell with the following rules:

  • If it contains an “a”, the level contains asteroids.
  • If it contains an “s”, the level contains a station.
  • If it contains a “1” the level contains one enemy ship.
  • If it contains a “2” the level contains two enemy ships.

It seems the order does not matter.

The map is also absolutely required to be exactly 6×4. It just uses direct indexing and would crash otherwise (I think technically it could be bigger without a problem).

The reason the map is loaded from a file is so I could provide multiple maps. In fact, I had it so the maps were generated by a PHP script:

Complete map script
function createMap() {
    mt_srand(time()^2);

    $rand = mt_rand(1,4);

    if ($rand <= 1) {
        $a = array('x','a','a','x','x','x');
        $b = array('a','a','a','a','x','x');
        $c = array('a','x','x','a','x','x');
        $d = array('a','a','x','x','x','x');
    } elseif ($rand <=2 ) {
        $a = array('x','a','x','x','x','x');
        $b = array('a','a','a','a','a','x');
        $c = array('x','x','a','a','a','a');
        $d = array('x','x','x','x','a','a');
    } elseif ($rand <=3 ) {
        $a = array('x','a','a','x','a','a');
        $b = array('a','a','a','x','a','a');
        $c = array('x','x','a','x','x','a');
        $d = array('x','x','a','a','x','a');
    } elseif ($rand <=4 ) {
        $a = array('x','x','a','a','a','a');
        $b = array('a','x','x','x','a','a');
        $c = array('a','a','a','x','x','x');
        $d = array('a','a','a','a','x','x');
    }

    $file = fopen('map.txt', 'w');
    fwrite($file, '[');

    for ($j=0;$j<4;$j++) {
        fwrite($file, '[');
        for ($i=0;$i<6;$i++) {
            if ($j == 0) {
                $row[$i] = $a[$i];
            } elseif ($j == 1) {
                $row[$i] = $b[$i];
            } elseif ($j == 2) {
                $row[$i] = $c[$i];
            } elseif ($j == 3) {
                $row[$i] = $d[$i];
            }

            $rand = mt_rand(1,24);
            if ($i == 5 and $j == 3) {
                $row[$i] .= 's2';
            } elseif ($i == 0 and $j == 0) {
                $row[$i] .= 'xx';
            } elseif ($rand == 1) {
                $row[$i] .= '1x';
            } elseif ($rand == 2) {
                $row[$i] .= 'sx';
            } elseif ($rand == 3) {
                $row[$i] .= '1x';
            } elseif ($rand == 4) {
                $row[$i] .= '1x';
            } elseif ($rand == 5) {
                $row[$i] .= '2x';
            } elseif ($rand == 6) {
                $row[$i] .= '2x';
            } elseif ($rand == 5) {
                $row[$i] .= '1x';
            } elseif ($rand == 6) {
                $row[$i] .= '2x';
            } elseif ($rand == 7) {
                $row[$i] .= 's1';
            } else {
                $row[$i] .= 'xx';
            }
            fwrite($file, '"'.$row[$i].'"');
            if ($i <> 5) {
                fwrite($file, ',');
            }
        }
        fwrite($file, ']');
        if ($j <> 3) {
            fwrite($file, ',');
        }
    }
    fwrite($file, ']');
    fclose($file);
}

First the layout of asteroids was chosen from four possible layouts. Then each cell had a random chance of also gaining ships and a station. Finally, the first cell is always blank, and the last cell has a station and two ships.

And astute readers may not the $rand == 5 and $rand == 6 cases duplicated. I only noticed this while writing this post.

High score table

The reason why the maps were variable is because it also had an online high score table.

You could enter your name, and it would keep track of the high scores for the current map, including keeping solo and coop separate.

There were two different implementations of the high score server script, and considering the two shows some of my developing understanding of how to design systems (if not really any serious consideration of security).

Highscore server script version 1
<?php
include('../connect.php');

if (!$mode) {
        $mode = "Single";
}
if (!$player) {
        $player = "<i>No Name Entered</i>";
}
if (!$score) {
        $score = 120;
}

if ($score < 1000) {
        $score = "0$score";
}

connect();

$sql = "SELECT * FROM qwar ORDER BY number DESC";
$result = mysql_query($sql);
$row = mysql_fetch_object($result);

$num = $row->number;

$sql = "INSERT INTO qwar_".$mode."_".$num." VALUES('$player', $score)";
$result = mysql_query($sql);

print "Done\n";

function check() {
    connect();
    $sql = "SELECT * FROM qwar ORDER BY number DESC";
    $result = mysql_query($sql);
    $row = mysql_fetch_object($result);

    $time = $row->time;
    $num = $row->number+1;

    if ($time < time()) {
        $time = $time + 604800;
        $sql = "INSERT INTO qwar VALUES($time, $num)";
        $result = mysql_query($sql);
        $sql = "CREATE TABLE qwar_Coop_$num (name varchar(30) DEFAULT 'No name given', score smallint(5) unsigned DEFAULT '0')";
        $result = mysql_query($sql);
        $sql = "CREATE TABLE qwar_Single_$num (name varchar(30) DEFAULT 'No name given', score smallint(5) unsigned DEFAULT '0')";
        $result = mysql_query($sql);
        createMap();
    }
}

?>

In the first version I hadn’t really got database design at all.

The check function was called periodically to check if a new map should be generated (probably as part of some other page load).

If 7 days (604,800 seconds) had passed I generated a new map and I created a new table for the new high scores (actually two tables; one for single and for coop) I also stored the number that was part of the name for the tables so I knew which tables to store scores in.

Other than that, I just stored the name and score into the relevant table. It relied on the amazing feature PHP had back then called register_globals which just dumped GET and POST values into variables with the same name.

This obviously meant you could just craft a very easy GET request to post whatever score you wanted. Oddly enough, I don’t think anyone actually did.

Highscore server script version 2
<?php
include('../connect.php');

if (!$mode) {
    $mode = "Single";
}
if (!$player) {
    $player = "<i>No Name Entered</i>";
}
if (!$score) {
    $score = 120;
}

connect();

$time = time();
if ($score < 12000 and $HTTP_SERVER_VARS["REMOTE_ADDR"] <> '80.137.161.246' ) {
    $sql = "INSERT INTO qwar VALUES(NULL, '$player', $score, '$mode', '$time')";
    $result = mysql_query($sql);
}
print "Done\n";

?>

For version two, some things are better. Firstly, the high scores are now in a single table with extra columns of mode and time.

And… that was it. Everything else was the same.

Except for some reason I was blocking high scores from one specific IP address. I cannot remember why. Maybe someone actually did try cheating?

I did actually make one extra addition a few years later. Another parameter that identified what website you were on so it was possible to host the game in different places with unique high score tables. I even blogged about it:

Random trivia

The name

This game predates Galaxia, and as such it predates my online name “GalaxiaGuy”. Back then I used the name “Admiral Q”, a reference to the STCCG card Military Privilege which includes the quote: “Starfleet Admiral Q at your service!”

As such, I naturally named everything with a “Q”.

There are a few old posts on this blog mentioning Q War. Notably, my 2004 references spell it “QWar” rather than “Q War”. This is obviously wrong since the title screen clearly renders it as two words, but apparently past me was less bothered about such consistency.

Graphics

Unlike Supremacy, the graphics are “original”. And by original, I mean I didn’t just get them from the Lingo book and conceived of them myself. In reality they are lovingly based on existing Star Trek material.

Player ships

Player 1
Player 2

The player ship is the Bajoran Raider from Star Trek: Deep Space Nine. Weirdly, the original has a pair of struts connecting to the wings, but I’ve filled in the gap in the middle essentially making the wings wider.

I also added a tint to the ship which is blue and green for player one, and red and yellow for player two.

I would later reuse the ship graphic for Gravitas.

Enemy ships

Working this out took some time.

As a small aside I would like to call attention to the excellent Star Trek website Ex Astris Scientia by Bernard Schneider. In this case his Starship Gallery was an invaluable resource without which I would not have found the source of this ship.

The enemy ships are Vidiian ships, specifically the “Vidiian ship 3” from that link.

Possibly to introduce a bit more colour to the game, or maybe just to hide the source, I drastically changed the colour from the original brick red to the weird lilac cyan combo.

Enemy station

The space station is the Renegade Borg Ship from the Star Trek: The Next Generation episode Descent (the one with Lore and Hugh).

The only change I made was to make it green.

And honestly, I’ve always thought this shape makes much more sense as a station than a ship.

Asteroids

The asteroids actually are completely original creations I made in Paint Shop Pro 5, and for whatever reason I remember exactly how I made them.

  • Generate some random noise.
  • Apply Gaussian blur.
  • “Cut out” an asteroid outline.
  • Apply a circular gradient to add shadow.
  • Colourise.

Fonts

The main title and menu font is Trek Generation 1, which continues my theme of using Star Trek fonts in Shockwave games.

In this specific case, it was a surprise to me. For as long as I can remember I thought I’d used Copperplate Goth Bold (which does look similar) but when I actually explored the original source, I was wrong.

The longer text is Abadi MT Condensed Light.

Galaxia branding

Like Supremacy, some time after the initial release, I added the message “Brought to you by Galaxia”. Galaxia being another game I developed.

The future

Once DirPlayer has better support for my games, one of my goals is to recreate the Shocklive! site complete with both Supremacy and Q War. This would include a new, safer high score system to replace the original.

Screenshots

Oliver Brown, the civil rights activist

Oliver Brown
— This upcoming video may not be available to view yet.

Sharing a name with someone is usually unremarkable. Sharing it with the plaintiff in a landmark Supreme Court case is rather less so. I have Googled myself since before Google was even a thing, so I have known about Oliver Leon Brown for a while.

Oliver Leon Brown

Oliver Leon Brown was a welder and part-time minister in Topeka, Kansas. In 1950, the local NAACP recruited him as one of thirteen parents to sue the Topeka Board of Education over racial segregation in the city’s public elementary schools. His daughter Linda was among the children denied entry to the nearest white school.

The case made its way to the Supreme Court, consolidated with four similar cases from other states. Brown happened to be first alphabetically, so it became Oliver L. Brown et al. v. the Board of Education of Topeka.

The former Monroe Elementary School in Topeka, Kansas, now the Brown v. Board of Education National Historic Site
The former Monroe Elementary School, Topeka, Kansas (now a National Historic Site). Photo by Midwest National Parks, CC BY 2.0.

The decision

Eventually the court ruled unanimously on 17 May 1954 in favour of the plaintiffs, overturning the “separate but equal” doctrine established by Plessy v. Ferguson in 1896, holding that racially separate schools were inherently unequal and unconstitutional.

The Monroe School

The Monroe Elementary School, one of the four segregated Black schools and Linda Brown’s own, is now the Brown v. Board of Education National Historic Site. Oliver’s family founded the Brown Foundation in 1988 to preserve the case’s legacy.

Finding a historical figure who shares your name is not particularly surprising (especially with my surname). Finding one whose name is on a case that changed American constitutional law is. If I ever find myself in Topeka, I will certainly visit the historic site.

Supremacy now on 9o3o

Oliver Brown
— This upcoming video may not be available to view yet.

9o3o is a web-based version of Flashpoint Archive which provides a way to play old browser content without installing anything locally.

It has long had support for Flash content via Ruffle but has recently added support for DirPlayer, which means Shockwave content is now playable through it.

As a result, Supremacy is now available on 9o3o.

This is the same version of DirPlayer you can play here so you can’t actually play it properly yet, but things should improve over time.

Oliver Brown, the London tailor

Oliver Brown
— This upcoming video may not be available to view yet.

When I was born, “Oliver” was quite an uncommon name. I was the first one my primary school had. And even though “Brown” is a common name, the combination is still pretty rare. But not unique.

The popularity of “Oliver” has drastically increased. It has been the number one name for boys born in the UK several years recently. This has been a bit strange for me since I spent most of my life never being around other people with my name. This is obviously still true for adults, but as a parent who now spends time in playgrounds, hearing other people call “my” name is still strange.

For a long time that meant I ruled the web with regard to the name. But since then several others have cropped up.

The most prominent is Oliver Brown London, a bespoke tailor based, you guessed it, in London.

The brand has apparently been around since 1980 (older than me), and is not actually named after a real person, but named after the owner’s dog, who was called “Oliver” and was brown.

I have never visited, though I probably will if I ever get the chance. I did actually have a chance that I missed; the first shop was in Chelsea, where I used to work but I hadn’t heard of them at the time.

I would hope the staff would find that reason for a visit acceptable. I honestly don’t think I would ever be a customer, not least because they seem outside of my price range. Their whole approach reminds me of a quote from the Discworld book Maskerade about a dress shop:

This was not a shop where things were bought. This was an emporium where you had a cup of coffee and a chat. Possibly, as a result of that muted conversation, four or five yards of exquisite fabric would change ownership in some ethereal way, and yet nothing so crass as trade would have taken place.

Although suits are probably their biggest trade, they seem to have top hats as a speciality. They claim to have the largest collection of antique top hats and were initially the only company allowed to sell top hats within Royal Ascot.

Disney+ on Sky

Oliver Brown
— This upcoming video may not be available to view yet.

I used to post a lot about TV and Sky in particular. It was mainly about options around having a home media centre. The commercial options around this have improved (things like the Apple TV and streaming) and the DIY options have become less interesting to talk about.

So it is nice to have something relevant to say again…

Disney+ now included

Disney+ has been available as an app on Sky for a while, but recently they announced it would be included with your Sky subscription. I don’t have a Sky subscription myself, though my dad does. I have my own Disney+ account. I’d previously logged into Disney+ on his Sky TV box.

When he heard about Disney being included, he launched the app, which was still signed in to my Disney+ account. It then automatically connected his Sky account to my Disney account. I had to contact Disney+ support to disconnect them.

It’s probably a good thing to make the account management so seamless, but in this case it caused problems. One thing I would say is the support experience to get it fixed was actually good. I contacted them at about 20:30 on a Saturday, there was no difficulty in explaining the issue and it was all resolved in about fifteen minutes.

New highest break in snooker - 153 by Ronnie O'Sullivan

Oliver Brown
— This upcoming video may not be available to view yet.

I’m not especially into sports, but I am quite into weird quirks of sports, especially rules. Snooker in particular has a few odd ones that are not well known.

One of them is that it is possible to score more than the “maximum” of 147. Which Ronnie O’Sullivan has just done.

Interacting with this video is done so under the Terms of Service of YouTube
View this video directly on YouTube
If you know nothing about snooker but still want to read...
  • Players alternate turns, potting balls to score points. Pot one and you keep going; miss and it’s your opponent’s turn.
  • The consecutive points scored in a single visit to the table are called a break.
  • Balls are either red (1 pt each) or a colour — yellow (2), green (3), brown (4), blue (5), pink (6), black (7).
  • While reds remain on the table, you must alternate: pot a red, then a colour. Colours are respotted after being potted; reds stay down.
  • Once all reds are gone, you pot the colours in order from yellow through to black.

How to get 147

Under normal circumstances, 147 is indeed the maximum possible break:

Balls Total
15 reds 15
15 blacks 105
Yellow 2
Green 3
Brown 4
Blue 5
Pink 6
Black 7
Total 147

How to beat 147

A break higher than 147 only becomes possible through a free ball. If the incoming player is left snookered on all 15 reds as a direct result of an opponent’s foul, the referee awards a free ball. The player nominates any other ball on the table to act as a red for that shot, scoring 1 point if potted. Crucially, that ball is then respotted to its original position, and the player continues by playing a colour in the normal way.

The effect is that the player now has the opportunity to pot what is effectively a 16th red at the start of the break, gaining up to 8 bonus points (1 for the free ball plus 7 for the following black). The theoretical maximum with a free ball is therefore 155, though this has never been achieved in professional competition.

This means the player necessarily scores even more in total since they get the points from the foul too. But that is not part of the break. This also means there is no limit for maximum score since your opponent can just keep fouling.

Other 16 red clearances

Alex Higgins managed the first professional 16 red clearance in 1982, but only scored 135. For extra gravitas he did do it in the final frame of the final of the world championship.

Interacting with this video is done so under the Terms of Service of YouTube
View this video directly on YouTube

Jamie Burnett got the first professional break greater than 147, just, with a 148 in 2004.

Some other lesser known snooker rules.

References are to WPBSA - Official Rules of the Games of Snooker and English Billiards

  • If you foul while attempting the final black, the frame ends. §2 1.d
  • Being blocked by the jaws of the pocket does not count as being snookered. §2 17.e
  • You cannot be awarded a free ball if only the pink and black remain. §3 12.b.ii
  • It is okay for a ball to leave the table, as long as it ends up back on the table. §2 14

That last one has mattered occasionally when the ball runs along the cushion but drops back into the play area.

Any other situation is challenging since you have to make sure you don’t break other rules, for example:

  • No jumping over other balls. §2 20
  • No moving the balls. §3 16