Category Archives: Programming

Building software.

A New Save System – Easy Save To The Rescue

With Into The Inferno development, I reached the point where it was time to get a better save-game system than the existing hacked-together-in-an-hour XML file. It had been on my to-do list for a while as part of evolving past the “you get one save slot, and that’s it” stage.

I have a ton of experience with C#, so throwing something in an XML file is second nature. That’s not necessarily a good or bad thing, but some of the legacy bits are strongly disrecommended by Microsoft at this point (BinaryFormatter for example).

I decided to “do what everyone else does” and get a copy of Easy Save from the Unity Asset Store. It’s immensely popular and highly recommended and it seemed like it’d be the shortest time-to-implement of the available options.

Fast-forward 8 hours later. I have a working save system with three save slots and it’s better in every way than the previous system. I was able to re-use a lot of my existing data code, rewrote some of it to be cleaner, and have “summaries” that are saved as part of the game saves that say where and who the party was at the time of save, and the interface changes necessary to support all of this.


Into The Inferno Main Menu Load Game - Before

Loading From the Main Menu – Before

Into The Inferno Save Game - Before

Saving At The Inn – Before\

As you can see, there’s just “Load Game” but you have no idea what you’re loading. Similarly, saving the game is just “Save Game” with nothing beyond that.

After implementing Easy Save, this is what I have:

Loading From the Main Menu - After

Loading From the Main Menu – After

Into The Inferno Save Game - After

Saving At The Inn – After

The first screenshot shows what comes up after you click “Load Game” on the menu. The summary text is localized in realtime, so in Spanish you’ll see that Archie is a “nivel 1 guerrero” even if you saved the game in English.

The second screenshot is saving the game from the inn. Saves at this point are an intentionally-limited resource (for better or worse), but at least now you have more control over them, and it’s easy to customize the number of slots that there are.

In the future I’d like to add Steam cloud save synchronization, but I have no idea how tough that will be. In any case, Easy Save made what I thought was a 40-hour task into a single day project, testing and UI changes included, and I definitely recommend it.

Log 15: Added Shops and New UI Style to Into The Inferno

Here I demonstrate a bunch of progress — new things like character creation, shops, an inn where you can save your game, a mana recharger, and a new style for the user interface.

I also made a small change to the graphics – a new floor and ceiling style. I’m in the process of customizing the dungeon graphics, and plan to show an update on that in the next demo video.

Disabling Automatic Closing Braces in Visual Studio Code

I really like Visual Studio Code as an editor, but it has some annoying defaults.

When working in C# (and a lot of other languages), it tries to be “helpful” by automatically adding closing braces, brackets, and parentheses when you type the opening ones.

An Automatic Closing Brace

Automatic closing brace added when typing an opening brace.

For some people, this is great. For me, no. It just doesn’t work with my typing and coding style, and ends up being something that gets in the way and I have to move or remove later.

Fortunately it’s easy to turn this off.

Go to File –> Preferences –> Settings

Search for “auto closing brackets”.

Change “Editor: Auto Closing Brackets” to “never”.

Auto Closing Brackets Setting

Turning off the auto closing brackets setting.

Problem solved. Happy coding!

Coming Full Circle With Game Development (Unity)

The very first programming I ever did was game programming.

It started with my Commodore VIC-20 in 1984. The computer’s manual had some BASIC programs you could type in and run. One was a Space-Invaders-type game.

Well, naturally, after typing in this game and playing it for a bit, I wanted to start making changes to enemy colors, speed, and score values. This was how I started programming.

It continued when I got a Tandy 1000 EX that ran MS-DOS and started writing games in GW-BASIC. By now I was coding much more detailed and complex programs. They were still text-only (ASCII), but I was creating them from scratch, and they had much more detailed mechanics.

I remember well a text-based gladiator combat tournament game that I spent the better part of a year working on, at about age 10, in addition to a few text-based adventure games.

Later, as the Internet started to grow, I became interested in multi-user dungeons. There were various codebases — Diku, Merc, Envy, Circle, and others. Not only did I work on some existing games, I also created my own, starting with Illustrium Arcana, and later with the Basternae  rewrite, Basternae 3: Phoenix Rising. If you look at the “Basternae and ModernMUD” topic on this blog, you’ll see that I was working on them well into 2013.

When I was finishing my college degree in 2004, I took some classes for credit at The Game Institute and got a job with a company working on simulators for the US Army (among other government contracts). It was basically a video game company, but replace “fun” with “realism”. I didn’t really work on any graphics code, and ended up specializing in audio and network communications. This was the first and last job I had in video games.

My strong knowledge of audio programming and networking protocols took me on to develop parts of the Authentic8 SILO browser, work on a home automation system, and build the various audio applications I released as Zeta Centauri.

Now I’m returning to my roots and learning Unity. It’s incredibly intuitive, and the programming is easy and natural thanks to the many years I spent writing C# code.

I’ve started with the “Complete C# Unity Game Developer 2D” course available through Udemy. I’m about 50% of the way through, and the deep, thorough coverage coupled with real hands-on coding projects has been great for the learning process. I’m definitely going to take more of the courses because they really know how to teach.

PostgreSQL Command History

The command-line PostgreSQL database client keeps a command history.

Much like on a Linux console, you can use the up arrow to scroll back through previous commands. This can be handy if you want to repeat a command, or to change a parameter on a long query.

One other thing that is less widely-known is that you can view the ENTIRE history by typing “\s”. Backslash-s will function pretty much the same as the Linux “history” command, and can give you multiple pages of commands.

Much like the history of the Bash shell, the Postgres command history is stored in your home directory in the hidden file .psql_history. Although this is handy, it can also be a security risk to keep old commands where prying eyes can find them. You can easily delete this file, or clear it using the command:

 truncate -s 0 .psql_history

I like the truncate command because it’s a nice, clean, one-step way to clear a file without deleting it.

How to Insert Values Into a Table from a Select Query in PostgreSQL

I recently had to do a data migration where I needed to populate a new table with some data from another table.

Rather than perform some sort of export, transform, and import, it was much easier to do this via a select query within Postgres itself.

Although you can use the star operator, it’s safer and smarter to name fields specifically, in order. In addition, you should manually verify your select query first.

In my case, there were a set of a few fields I wanted to insert, and converted into a select query, looked like this:

SELECT date_added, description, last_updated, name, type FROM information;

This gave me all of the fields I wanted, and I verified that the data looked good.

Next, I added this to an insert query:

INSERT INTO information_subset (date_added, description, last_updated, name, type) SELECT date_added, description, last_updated, name, type FROM information;

Although it’s something that seems like it might be complex, inserting into one table using data from another is quite simple in Postgres and most other databases.

Using Location to Assume User Language

My first language is English. I live in Uruguay, and while I’m comfortable and nearly fluent in Spanish, sometimes I’d rather use a website in English.

It is EXTREMELY common for a website to see the location of my IP address and assume they should send me a page in Spanish. This is perfectly fine, because everyone in Uruguay speaks Spanish. Not everyone has it as their first (or preferred) language given the number of immigrants here (especially from Brazil), but everyone speaks at least SOME Spanish here.

The other thing that sites may use is the language setting of your web browser. This is also a reasonable approach, although less common. I have one computer set to English and one set to Spanish, and I’ll sometimes get different versions of a site depending on which computer I use. This is mostly OK, but there are an unreasonable number of computers that have the language set to English (the most common default) even though the users don’t prefer English. There are also computers used by multi-lingual households, so using the computer’s language setting is an assumption at best, and probably less accurate than using someone’s location.

Of course, the right thing to do after you’ve made an assumption about the user’s language is allow them to change it. Typically this is a link or button somewhere along the top of the site. Although sometimes this will be a flag icon, that’s less than ideal when you’re dealing with countries that have multiple languages (Belgium, for example). People from that country have learned to adjust, and can pick the French, Netherlands, or even German flag if they need to.

The problem comes when a website doesn’t give someone the chance to change the language they’re viewing. Not only are geolocation services not 100% accurate, but just because you are IN a place doesn’t mean you are OF a place.

Sure, auto-translation tools are nice, and they get you 80% of the way there, but they rarely understand context, words with multiple meanings, regional word usage, or any of the other Human nuances. Maybe some day, but not today. So it’s important to allow a user to select their preferred language.

Sometimes it’s easy to change the language manually by hand-editing the URL. For example, these urls:

Can easily be changed to:

Where it gets really ugly, and I’ve seen this with media/streaming sites more than anything else, is when you deliberately visit a page in a specific language, and you are force-redirected back to the language you didn’t want.

The only hope for sites like that is to use a proxy server. Or close the browser tab. You should never force a language on a visitor if your site is available in other languages.

And if you find a site with this bad behavior, please send them a message letting them know the error of their ways. Maybe they’ll eventually learn.


Why Do So Few People Develop Apps for Windows?

There are a lot of reasons so few people develop for Windows anymore.

We’ll skip the obvious ones:
– There’s a whole lot more growth in mobile apps.
– Most of the apps that people could want or need on Windows have already been written.
– Many apps make more sense as websites, so every platform can access them.

For apps that make more sense on a desktop PC, such as audio/video production and 3D design, and all of the other sorts of things that are not optimal on a 5-inch screen or in a stateless system, there’s a much more painful reason:


For example, the answer to this question:

What framework should I build my app with?

It is almost impossible to answer, and the official answer changes every year or two.

Universal Windows Platform (UWP)?
Windows App SDK?
Progressive Web App (PWA)?
MSIX, MSI, or EXE installer?
Are any of these things different names for the same thing? (yes)

Good luck. Microsoft has come out with many new technologies that were “almost finished”, and each one has had some glaring omissions and dropped some important technologies or features that will probably never be finished before the system is replaced with something else. I know this pain all too well since I’ve worked with text-to-speech and audio applications extensively.

And, of course, when one system supersedes another, they don’t put a disclaimer on the docs saying “you should use this new thing instead” and provide a migration guide, and many of the docs don’t even have a date so you at least have some idea whether it’s current.

In some of the latest nonsense: In the Windows Store, you can submit an app with an MSIX installer or an MSI/EXE installer. You can set an app with an MSI/EXE installer as paid, but you CANNOT ACTUALLY CHARGE MONEY FOR IT. I don’t know who designed a system like that, but they were probably drunk at the time. Of course, I didn’t learn this until after I went through the entire process of getting an app approved for the store.

Another aborted effort was enabling ad-based monetization of free apps distributed via the Windows store.

Why is it that every mobile operating system (even the ones with only a handful of users) has managed to get this right, and Microsoft just can’t figure out how to build a system that people actually want to build a business around?

I like building desktop apps, but Microsoft has done everything they possibly can to make it a nightmare to support Windows. Nowadays you can probably only make money writing Windows apps if you’re writing malware.

Fixing OSError: cannot write mode RGBA as JPEG in Python

I have an application that was originally written in Python 2.7 and used the Python Image Libary (PIL). Now it uses Python 3.x and Pillow (the PIL replacement). One of the things it does is automatically generate .jpg file thumbnails of uploaded files.

It does this by resizing the uploaded image, and then saving it with the filename extension changed.

I started getting an error when uploading a .png file:

OSError: cannot write mode RGBA as JPEG

A bit of research told me that the behavior has changed. Now you need to discard the alpha (transparency) channel of an image before you’re allowed to save it as an image type that doesn’t have an alpha channel. Since PNG files normally have a transparency layer, it makes sense why I would hit that error. It’s trying to protect me from losing data I might potentially want to keep. However, I don’t want or need alpha channel data for my thumbnails.

The solution is just to convert the image before saving.

thumbnail = im.convert('RGB')"my_image_filename.jpg", 'JPEG', quality=92)

It’s a simple fix, but slightly annoying that the behavior has changed over the years.

Fixing Error LNK2038 In a Visual Studio Project

While building a Visual Studio C++ project in Visual Studio 2022, I received this error while linking to a library:

Error LNK2038 mismatch detected for ‘_MSC_VER’: value ‘1800’ doesn’t match value ‘1900’ in MidiPlayer.obj MIDIPlayer E:\code\MIDIPlayer\wxmsw30ud_core.lib(dlgcmn.obj)

In case you’re not familiar with this error, Visual Studio wants to link with libraries that were built with the same version of Microsoft C (same toolset) as the code you’re compiling. In older versions of Visual Studio that meant that they had been built with the same version of Visual Studio, but now that versions aren’t as tightly-coupled to Visual Studio, it’s also possible that you can get this with libraries built with the same version of Visual Studio that you’re using.

The solution is to rebuild the library with the same MSC version as your project.

For reference, here are the different MSC, MSVC, and toolset versions:

Microsoft C 6.0: _MSC_VER == 600
Microsoft C/C++ 7.0: _MSC_VER == 700
Microsoft Visual C++ 1.0: _MSC_VER == 800
Microsoft Visual C++ 2.0: _MSC_VER == 900
Microsoft Visual C++ 4.0: _MSC_VER == 1000
Microsoft Visual C++ 4.1: _MSC_VER == 1010
Microsoft Visual C++ 4.2: _MSC_VER == 1020
Microsoft Visual C++ 5.0: _MSC_VER == 1100 (Visual Studio 97)
Microsoft Visual C++ 6.0: _MSC_VER == 1200 (Visual Studio 6.0)
Microsoft Visual C++ 7.0: _MSC_VER == 1300 (Visual Studio 2002)
Microsoft Visual C++ 7.1: _MSC_VER == 1310 (Visual Studio 2003)
Microsoft Visual C++ 8.0: _MSC_VER == 1400 (Visual Studio 2005 – v80)
Microsoft Visual C++ 9.0: _MSC_VER == 1500 (Visual Studio 2008 – v90)
Microsoft Visual C++ 10.0: _MSC_VER == 1600 (Visual Studio 2010 – v100)
Microsoft Visual C++ 11.0: _MSC_VER == 1700 (Visual Studio 2012 – v110)
Microsoft Visual C++ 12.0: _MSC_VER == 1800 (Visual Studio 2013 – v120)
Microsoft Visual C++ 14.0: _MSC_VER == 1900 (Visual Studio 2015 – v140)
Microsoft Visual C++ 14.1 – 14.16: _MSC_VER == 1910 – 1916 (Visual Studio 2017 – v141)
Microsoft Visual C++ 14.2 – 14.29: _MSC_VER == 1920 – 1929 (Visual Studio 2019 – v142)
Microsoft Visual C++ 14.3: _MSC_VER == 1930 (Visual Studio 2022 – v143)

It’s interesting that starting with Visual Studio version 2017, Microsoft started incrementing the MSC version with each “micro” build change.

Telling Git To Ignore File Mode Changes

It’s possible for Git to think there have been changes to files when only permissions have changed. This is something that is pretty common if you work across multiple operating systems, and it can be annoying.

For example, running “git status” showed that two of my icon files had changed, but hadn’t edited them. Running “git diff” showed that it was just the file mode properties (permissions or “props”) that had changed.

$ git diff
diff –git a/images/samplitron_largeicon.png b/images/samplitron_largeicon.png
old mode 100644
new mode 100755
diff –git a/images/samplitron_largeicon.xcf b/images/samplitron_largeicon.xcf
old mode 100644
new mode 100755

To make Git stop treating this as a change, there’s a command you can run:

git config –global core.fileMode false

Now when you run “git status” or “git diff”, file mode changes will be ignored.

Fixing Error MSB3843 in a Visual Studio Project

I updated my DrumPads code project to the latest version of Visual Studio 2022 and received this error when trying to build:

Error MSB3843 Project “DrumPads” targets platform “Windows”, but references SDK “Visual C++ 2015-2019 Runtime for Universal Windows Platform Apps v14.0” which targets platform “UAP”. C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets

I’m not sure whether the project was actually set to be UAP, or whether the migration set something to that.

Visual Studio Solution Explorer Showing "Universal Windows"

Solution Explorer Showing “Universal Windows”

To fix the error, I edited the DrumPads.vcxproj file manually. In the PropertyGroup sections for the build configurations I changed this:

<PropertyGroup Condition=”‘$(Configuration)|$(Platform)’==’Release|Win32′” Label=”Configuration”>

I removed the line <WindowsAppContainer>true</WindowsAppContainer> entries from all of the configurations and reloaded the project. It no longer showed up as “Universal Windows” and I was able to build without the error.

Solution Explorer Without "Universal Windows"

Solution Explorer Without “Universal Windows”

Changing the Remote URL for a Git Repository

Maybe the repository has been moved, or maybe you have an old repository that was checked out with username and password authentication, and you can’t push to it anymore because GitHub requires ssh authentication now. That was true in my case, since I was going back to work on code I hadn’t touched for a few years.

Although you could just re-check-out the repository, that is unnecessary, and can be annoying if you have changes that you want to push.

Changing the remote URL for a git repository is a simple thing to do, but it’s not necessarily obvious. It’s done using the “git remote” command.

To display the URL of the remote repository:

git remote get-url origin
To change this to a new URL:
git remote set-url origin
With this one-line change I was able to continue working as normal without needing to re-check-out the repository.

What Programming Is Like

A friend of mine posted this on their feed the other day.

My spouse (an artist, not in tech), working her way through a C++ class (part of a Digital Arts cirriculum). I: Let me know if you need help. She: Will do. Two hours later.. I: How's it going? She: Fine. I'm cheating. I: ??? She: I google for stuff I don't know. ... Do I tell her?

As a professional programmer with decades of experience, I can describe the full process:

Step 1: Google it. Find no applicable answers.

Step 2: Rephrase the question. Find search results that look relevant. Open them all in new tabs.

Step 3: Find that all of the results ask the exact question you’re trying to answer, but none have answers.

Step 4: Rephrase the question again using the extra keywords you found in other people’s questions. Get search results that are 80% the same. Click on the top new result.

Step 5: Find a solution that almost fits your problem and gets you 80% of the way there. It’s either missing a step or is outdated by a version of whatever you’re working on.

Step 6: Use that 80% solution to trial-and-error your way across the finish line.

Windows Software by Lambda Centauri

I’ve written a lot of apps for Windows (and other) PCs. Originally I published everything as Zeta Centauri, but it was a weird combination of audio apps and utilities that didn’t mesh well with audio apps (calculators, word processing, image viewer, browser). I’ve launched a new website for the utility apps to keep them separate from the audio apps.

Check it out here: