Dec. 15th, 2017 Nightly Build

So I'm staying true to my word with these nightly builds. And this second one fixes a couple of bugs from the last one and adds a few new features, so let's talk about 'em :D

New features

  1. "Quit to Desktop" button in main menu. It's come to my attention that not everyone likes to use their keyboards to close windows, and not everyone has access to the "Debug -> Stop Debugging" menu item in Visual Studio. So... I was nice and programmed a fancy new button in the main menu that throws you back into the main menu.
  2. You can only run one instance of the game at once. Watch this video from one of our players and you'll see why.
  3. Screenshot support! Now you can take screenshots while in-game. Press F3 at any time to take one, and it'll be saved to %AppData%\Watercolor Games\Peacenet\screenshots. Neat.

So that's cool. Now let's look at some bugfixes.


  1. Fix bug where GUI-based programs in Peacegate OS don't close before the OS shuts down.
  2. Fix a few race conditions in the user-interface engine causing some NullReferenceException crashes while shutting down.
  3. Moved the config files to %AppData%\Watercolor Games\Peacenet so I don't accidentally upload my config file to and leak my administrative API key.
  4. Fixed a race condition in the engine splashscreen causing some game instances to crash on boot (thanks RogueAI :D)

In conclusion...

Two major issues were detected today with the game that have yet to be fixed. One of them is in the process of being worked on and the other requires your help.

The first issue is with the Watercolor API rejecting passwords that indeed meet the minimum strength requirements that I have posted in our Discord. This is due to a few miscommunications on my part and on .NET Framework's. 

The API issue

First, here is the code which I use to validate passwords in the API.

private bool validate_pwd(string password)
    if (password == null)
        return false;
    bool hasCapital = false;
    bool hasSymbol = false;
    bool hasNumber = false;
    bool hasMinimumLength = password.Length > 8;
    bool hasLower = false;
    foreach(char c in password)
        if (char.IsUpper(c))
            hasCapital = true;
        if (char.IsDigit(c))
            hasNumber = true;
        if (char.IsSymbol(c))
            hasSymbol = true;
        if (char.IsLower(c))
            hasLower = true;
    return hasSymbol && hasCapital && hasLower && hasNumber && hasMinimumLength;

The C# programmers among you should immediately notice a few issues with that code, but in case you don't (or you don't understand what the code is doing), I'll explain.

We declare a function called "validate_pwd". Said function takes in a single string parameter called "password" (a string being a place to store text - like this sentence for example), and the function does something with that password parameter and returns a Boolean value (either true or false) when it's done.

In our case, what the API does relies on what this method returns. If it returns true, your account is created. If it returns false, you get a 403 Forbidden error in-game.

If the password string is equal to "null" (aka nobody put anything in the password string), we automatically return "false". The password is empty so we don't want to use it, so we don't let you create the account.

Then, we create 5 local Boolean variables in our code - hasCapital, hasSymbol, hasNumber, hasMinimumLength and hasLower. Every one of those variables (with the exception of hasMinimumLength) is set to "false" by default. For hasMinimumLength, it is set to true if the password length is greater than 8 (remember that one trick you were taught in school, the bracket always wants to eat the bigger number). If the bracket eats the number 8, hasMinimumLength is set to false. This is our first issue.

Next, we do a "for" loop - which basically says "Run this code this many times, and tell me which iteration I'm on starting at this number." In my case, I store the iteration number in a variable called "i", and I start at 0, increase by one each time and end when I've reached the password length. Each time I run this code, I grab the character that is at position in the password string. Then, I do various checks on that character to measure the strength of the password.

If the character is an uppercase letter (char.IsUpper(c)), then I set "hasCapital" to true. If it is a number (char.IsDigit(c)), I set hasNumber to true. I keep doing all these checks on the character until I hit the one where I check if it is a symbol character. And that's where the second bug lies.

At the end of the function, I simply make sure ALL those boolean variables are equal to "true", and if so, I return "true" as the function result and you get your account. If not, I return "false" and you get a 403 Forbidden error.

The first issue (and why I'm not fixing it)

So you know that line where I check if the password is above 8 characters in length? Well, I said that the password should have AT LEAST 8 characters in length...but my code disagrees. This is where my miscommunication caused a bug in the game for some of you. From a usability perspective I could fix it and make it so my words are true again, but from a security perspective I'm not going to. Personally, using 8 character passwords has gotten my online accounts compromised before. They really are not secure and put you at risk of having your account hijacked. And believe me, being hijacked is not fun.

There's a simple mathematical formula that can immediately tell you a rough estimate of how secure your password is. Of course it doesn't take into account details like entropy and whether or not your password is "abc123", but it can still tell you a lot.

And the formula is:   T=(C^L), where C is the amount of characters you could possibly store in a string (char.MaxValue in C#), and L is the length of your password string. T is the total amount of combinations of characters it'll take for a computer to brute-force guess your password.

So let's say that C is equal to 255. And our length is 1. Well, 255^1 = 255. Let's add an extra character to our string. 255 ^ 2 = 65025. And so on and so forth. If you keep increasing "L" by one and repeating the formula you'll notice a pattern. As the length of your password increases, the amount of guesses it'd take to crack it increases exponentially.

Now, an 8-character password run through that formula equals 1.787810334781289e+19 (the Windows 7 calculator can only display so many numbers at once). That's a HUGE number, but if someone hates you, and they have the computing power, they can crack that in a matter of weeks. Scary.

Some of my passwords nowadays are much larger, they have hundreds of characters in them, and they are cryptographically random. They have very high entropy, cannot be hit by dictionary attacks, and brute-force attacks on them can take multiple lifetimes of the Universe on most systems...well that is until quantum computers are perfected...then I'm screwed..

My point being is I could make you guys happy and just fix the bug, but then I could be putting you in danger of having your account hijacked. So, the most I can say I'll do is raise the minimum to 20 characters as that can still put you in the "you can't guess my password for a few millenia" leagues. Anyway, security ranting over.

The second issue - an ACTUAL bug.

Unlike last time where it was a simple miscommunication on my end, this is an actual bug which legitimately confused both me and RogueAI. You see, when I ask you to point out all the symbols on your keyboard (not letters or numbers), you'll probably end up pointing out these (standard US qwerty layout in my case):


However, a lot of those characters - at least to C# - are not called symbols, they're called punctuation. In fact "char.IsSymbol(c)" checks for odd Unicode symbols that you'd NEVER see on a keyboard unless your name is Tom Scott and you've got 14 full-sized mechanical keyboards with each and every key labeled with a different emoji. WHO ELSE EVEN HAS THAT!? ...anyway...

In C#, "char.IsPunctuation(c)" would be used to cover up the rest of that list of characters. Whether that was my fault for not RTFM-ing or C#'s fault for not writing the F'in manual clearly, I'll leave that up to you to decide, but we're going to be fixing that.

Now the important bit. I need your help.

So some of you have found that the game doesn't work on your system. It usually ends up trying to load engine modules, then it pops into the game, plays some Anders Jensen for a split second, and crashes. I've had some of you run the game under a debugger to find out what was really being thrown out by the .NET Framework, and it usually boils down to GPU incompatibility.

So, my estimated system requirements definitely need some work. However the only systems I have to test the game for compatibility on are my development environment and this old crappy Toshiba Satellite laptop from a decade ago that's somehow still booting into Windows.

So if you guys don't mind giving a helping hand, what I want you to do is to try the game on as many computers as you can (as long as YOU own them or the person that does gives you permission, so don't be doing this to school computers please :P) and make a note of the computer's specs - operating system, GPU, CPU, RAM, etc and whether or not the game runs and how well it runs. This data can help me and other players know the optimal system configuration to run The Peacenet and any other games written for The Peace Engine. You'll be saving me time figuring this stuff out and you'll be helping the community out by hopefully preventing more of these issues, plus you get to hear Anders Jensen even more. Win-win for all of us :D

Anyway, that's about it for this one.

 - Alkaline

Files 347 MB
Version 8 27 days ago 347 MB
Version 2 37 days ago

Get The Peacenet

Leave a comment

Log in with your account to leave a comment.