Let me start with a bit of a narrative first:
Around a year ago, I released a C#/.NET Core library called Bassoon. I was looking for a cross platform (Windows, OS X, and Linux) audio` playback library for C#, but I couldn’t find one that was suitable. So I did what any normal software developer would do: make your own. Instead of going full C# with it, I opted to take some off the shelf C libraries and use P/Invoke to chat with them. It uses libsndfile for decoding audio formats (sans MP3, but that might change soon). And PortAudio for making speakers make noise.
If you look at the repo’s README’s
section, you might notice that I’m not telling anyone one to do a
sudo apt install libsndfile libportaudio (or some other package
manager command for another OS). I’m not the biggest fan of baked
dev environments. They can be a pain to reproduce for others. I
like to have my dependencies per project instead of being installed
system wide if I can help it.
The only downside is that you need to
then create some (semi-) automated way for others to set up a dev
environment for the project. E.g. all that “Download package from
nonsense. At first, I tried to make a simple bash script, but that
got kinda ugly pretty quickly. I’m not the best shell programmer
nor am I too fond of the syntax. There was a consideration for
Python too, but I assumed that it could get a bit long and verbose.
I found out about CMake’s
feature and set off to make one
surely disgusting CMakeLists.txt file. After a lot of
pain and anguish, I got it to work cross platform and generate all of
the native DLLs that I desired. Some things that stick out in my
- having to also run the
autogen.shin some cases
- needing to rename DLLs on Windows
- finding the correct
./configureoptions to use on OS X
These all reduced the elegance/simplicity. But hey, it works!... Until about a month ago…
While it was still good on Linux to set up a clean build environment. After some updates on OS X, it stopped building. Same for Windows/MSYS2 as well. This has happened before for me with MSYS2 updates (on other projects) and I waslooking for an alternative solution.
C++ specific package managers are a tad bit of a new thing. I remember hearing about Conan and vcpkg when they first dropped. After doing a little research, I opted to use the Microsoft made option. While it was yet another piece of software to install, it seemed quite straightforward and easy to set up. PortAudio and libsndfile was in the repo as well. After testing it could build those libraries for all three platforms (which it did), I was sold on using it instead. There were a few caveats, but well worth it for my situation:
- Dynamic libraries were automatically built on Windows, but I needed to specify 64 bit. It was building 32 bit by default
- For Linux and OS X, static libraries are built by default. If you want the dynamic ones all you have to do is something called overlaying tripplets
The generated file names of the
DLLs were not always what I needed them to be. For example, in my
C# code I have
[DllImport(“sndfile”)]to make a P/Invoked function. On Windows, the DLL name must be
sndfile.dll, Mac OS is
libsndfile.dylib, finally Linux is
libsndfile.so. On Windows I get
libsndfile-1.dllbuilt by default. Linux nets me
libsndfile-shared.so. For these a simple file renaming works. OS X is a bit of a different story:
You see, every operating
system has their own personality quirks. The Apple one is no
exception. When I tried renaming
dotnet run crashed saying it couldn’t find
the library. I know that I had all of the path & file locations
correct, as the previous CMake built libraries worked. I was kinda
trying another run I got a little hint.
being loaded and then unloaded almost as soon as it was
dyld: loaded: /Users/ben/Desktop/Bassoon/third_party/lib//libsndfile.dylib dyld: unloaded: /Users/ben/Desktop/Bassoon/third_party/lib//libsndfile.dylib
It also should be loading up
libvorbis.dylib, etc. but that wasn’t happening. Looking at the
vcpkg generated libs, running
otool -L (OS X’s version of
I got the reason why things weren’t the way I expected:
$ otool -L * libFLAC.dylib: @rpath/libFLAC.dylib (compatibility version 0.0.0, current version 0.0.0) @rpath/libogg.0.dylib (compatibility version 0.0.0, current version 0.8.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1) libogg.dylib: @rpath/libogg.0.dylib (compatibility version 0.0.0, current version 0.8.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1) libsndfile.dylib: @rpath/libsndfile-shared.1.dylib (compatibility version 1.0.0, current version 1.0.29) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1) @rpath/libogg.0.dylib (compatibility version 0.0.0, current version 0.8.4) @rpath/libvorbisfile.3.3.7.dylib (compatibility version 3.3.7, current version 0.0.0) @rpath/libvorbis.0.4.8.dylib (compatibility version 0.4.8, current version 0.0.0) @rpath/libvorbisenc.2.0.11.dylib (compatibility version 2.0.11, current version 0.0.0) @rpath/libFLAC.dylib (compatibility version 0.0.0, current version 0.0.0) libvorbis.dylib: @rpath/libvorbis.0.4.8.dylib (compatibility version 0.4.8, current version 0.0.0) @rpath/libogg.0.dylib (compatibility version 0.0.0, current version 0.8.4) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1) libvorbisenc.dylib: @rpath/libvorbisenc.2.0.11.dylib (compatibility version 2.0.11, current version 0.0.0) @rpath/libogg.0.dylib (compatibility version 0.0.0, current version 0.8.4) @rpath/libvorbis.0.4.8.dylib (compatibility version 0.4.8, current version 0.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1) libvorbisfile.dylib: @rpath/libvorbisfile.3.3.7.dylib (compatibility version 3.3.7, current version 0.0.0) @rpath/libogg.0.dylib (compatibility version 0.0.0, current version 0.8.4) @rpath/libvorbis.0.4.8.dylib (compatibility version 0.4.8, current version 0.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1)
From this, I was able to identify two problems:
- The “id” of a dylib didn’t
match it’s filename. E.g.
libvorbis.dylib’s id was set to
- The dylibs were looking for
non-existent dylibs. E.g.
libvorbisenc.dylibwas looking for
As to why this
wasn’t happening with the previously CMake build native libs, it’s
because they were configured/compiled with
vcpkg, I wasn’t able to set this when building
OS X toolkit does have a utility to fix the rpaths;
install_name_tool -id "@rpath/<dylib_file>" <dylib_file>is used to set the id we want
install_name_tool -change "@rpath/<bad_dylib_path>" "@rpath/<good_dylib_path>" <dylib_file>can fix an incorrect rpath
Since I wanted the setup process to be
fire and forget I still needed to write a script to automate all of
this. At first I considered bash again, but then I thought “I
don’t want to force someone to install the entire MSYS2 ecosystem
for Windows. What else can I use?...” Python came to mind.
Any developer is bound to have Python on their machine. I know
that’s what I tried to avoid in the first place, but looking at the
built in libraries for Python 3.x (.e.g
pathlib, etc) it was a better choice IMO. I also like the syntax
more; I’ll always trade simple and easy to understand code any
day over something that’s complex and shorter. For an example,
here is how I have the dylibs for OS X fixed up:
To run this 3rd party dependency setup script, all you need to do is set an environment variable telling it where vcpkg is installed and then it will take care of the rest!
Now that all of the native library dependencies have been automated away, the next challenge was packaging them for NuGet. Before, I told my users to “clone the repo and run the CMake setup command yourself”. That wasn’t good for many reasons. A big one being that no one could easily make their own program using Bassoon and easily distribute it. I know that I needed to also have the native libs also put inside the NuGet package, but what to do…
If you search for “nuget packaging
native libraries” into Goggle you get a slew of results telling
you what to do; all of it can seem overwhelming from a quick glance.
“Do I use
dotnet pack or
nuget pack? Do I need to
make a separate
.nuspec file? But wait,
dotnet pack does that
for me already… What is a
.targets file? What is a
.props file? How many of those do I need? What is this whole
native/libs/* tree structure? Oh man, all that XML looks
complicated and scary. I have no idea what I’m reading.”
Throwing in cross platform native libraries adds a whole other level
of trouble too. Most tutorials are only written for Windows and for
use within Visual Studio. Not my situation, which was all three
major platforms. Even peeking into other cross platform projects
to see how they did it, makes it look even more confusing. Too many
configuration files to make sense of.
Then I found NativeLibraryManager.
It has a much more simpler method to solve this
problem: embed your native libraries inside of your generated .NET
DLL and extract them at runtime. I don’t want to copy what it says
in it’s README, so go read that. But I’ll summarize that I only
had to add one line for each native library to the
embedding). Then for extracting at runtime, a little bit of code.
For people who want to use
directly, they only need to call the function
before doing anything else. And as for the nature of Bassoon’s
initialization, they don’t have to do anything!
I cannot thank @olegtarasov enough for creating this. I’m a programmer. I like to write code; not configuration and settings files.
At the time of writing,
libsndfileSharp package is partially broken for OS X due to a bug
in NativeLibraryManager. But
a ticket has been filed explaining what’s wrong and
most likely what needs to be fixed. It should be good soon :P
If anyone wants to help out with Basson (e.g. adding multi-channel support) or the lower level libraries (adding more bindings to libsndfile and PortAudio), I do all of the development over on GitLab.
I’d like to mention that I’m a little less employed than I would like to be; I need a job. My strongest skills are in C/C++, C#/.NET, Python, Qt, OpenGL, Computer Graphics, game technologies, and low level hardware optimizations. I currently live in the Boston area, so I’m looking for something around there. Or a company that lets me work remotely is fine too. I’m also open to part time, contract, and contract-to-hire situations. If you send me an email about your open positions, I’ll respond with a full resume and portfolio if I’m interested.
Please; I’m the sole provider for a cat who’s love is motivated by food. Kibble ain’t free.
If you want to go ahead and skip to the game I made, it's over here.
About 4+ years ago I heard about a new(-ish) game engine called Godot. I thought that it was kinda neat to have another open source one around, but I didn't think too much of it. In the past few years I'd hear about it again from time to time (e.g. when it gained C# support, making it a Unity contender). I was kind of interested in making something with it, but at the time I had no ideas.
Recently, I thought "It has sure been a while since I worked on a personal (technical) project. Not to mention a video game. I'm kinda itching to try out that there Godot thingy...". So about two-ish months ago, I decided to build something with this engine. Thinking about what could be small, short, but good enough to get my feet wet, I settled on reimplementing my Linux Game Jam 2017 entry Pucker Up.
Lemme take a brief aside to tell you about Pucker Up. As stated before, it was for a jam. My first Jam in fact. At that time, I was a bit more into tinkering with the Nim language. I kinda wanted to be a bit more HARDCORE™ with my approach in the jam. Luckily the only restriction was "Make a game that runs on Linux". No theme whatsoever; quite nice. We had 72 hours to finish and submit it. Then it would be live streamed by the jam creator.
I originally planned out a much more complex game (i.e. what was a tower defence). Then being HARDCORE™ I set out to grab some GLFW bindings, write my own game engine/framework, graphics/shaders, physics, etc. At the end of the first day, I realized how much of a difficult decision that I had made. All I got done were the initial windowing and input management, being able to draw flat coloured debug circles, and circle intersection algorithms; it was absolutely piddly. Realizing the pickle I had put myself into, I reevaluated what I could do with the toolkit I had made from scratch. I threw out my 99% of my original idea. Thinking instead about some sort of arcade-like game. The result was a sort of Pong with the goal in the center, where you had to keep the puck out of it. The QWOP control scheme happened by accident (I swear). Turned out it was kind of fun.
After the Jam was over, leveraging Nim's compile to JS feature, I was actually able to make a web browser playable version of the game in a short amount of time. I didn't have to force users to download a sketchy executable which was nice. That took me about two weeks since I needed to also add some extra Nim to JS/HTML5 bindings and work out a few kinks and bug or two. But it actually was quite simple. (Speaking about Nim, it also has some Godot bindings too.)
I've been looking at that JS/HTML5 version of Pucker Up for the two-ish years, discovered some bugs here and there, I thought it would be best to give it a little refresh. So instead of trying to wracking my brain to think up a new game, I settled on renewing something old I had.
Back to Godot-land. What I would say that originally drew me to the engine is it seemed like a nice professional project that was very liberal with it's licensing and it is openly developed. Linux being a first class citizen for the project is very sweet too. I tried out the Unreal engine on Linux and wasn't too happy with it. I've also had some serious issues with playing Unity made games on Linux.
I'm a person who has probably made more game engines than games. I don't know why this has been the case for me, but it just has. Maybe it's that feeling of being closer to what's going on in the whole program, or rather knowing 100% how something was made. Looking at the source for Godot (and the docs, which has A+ tutorials), I appreciate how easy and hackable this engine is. And to boot, the community is quite friendly.
The tutorial section of the Docs are quite good, but the API docs don't feel like they are fully here right now. For example if you look at much of Microsoft's C# docs, many methods usually have an accompanying example with them. This isn't always the case with Godot. For instance, to spruce up Pucker Up, I wanted to add some directional sound. Doing some googling I was led to the docs for AudioEffectPanner. Looking through, it's super sparse, and doesn't have a simple example of how it can be used. Not nice.
The main draw of using any engine is "Look at all the stuff we provide for you." When I started make games, it mostly was only a set of APIs. Tooling was something you had to do on your own. Godot provides a pretty nice editor (UI, level, animation, etc...), but it does take some learning.
I'm also a pretty big fan of Animation (go look through some of my other posts to see). The builtin framework for Animation that Godot provides I think is nice, but the editor isn't the most intuitive. I've used programs such as Flash (R.I.P.), Moho, Clip Studio Paint, and even Unity. They were always pretty easy to get started with. In Godot, I had some trouble figuring out how to key properties. I didn't know what kind of interpolation I was initially using. And the curves editor was difficult when it came to zooming it's viewport(.e.g I needed to work on a value in the range of [0.0, 1.0], it was a bit of a struggle). One of the other things that drove me nuts: If you didn't reset the playback head to `0` before running your game, the animation would start where the head was left in the editor. I can see how this is handy for Animations that are longer (.e.g 5+ seconds). Though if you notice in video games, many actions/effects are on the quick side (e.g. 1/4 of a second). When you're doing this, you tend to what to see the whole thing. I will admit that my digital animation experience it a bit lacking (I think I've spend more hours with a pencil and paper than with a Wacom tablet), but some stuff didn't feel that natural. I also ran into a bug: when tabbing through options to adjust properties, sometimes the editor would freeze. Not fun.
Godot also has a minimal UI framework is built in. Adding custom skinning can be quite the hassle though. A CSS like way to skin the UI would be wonderful (which is that the Qt and Gtk frameworks already do). This might be a time sink for the engine (and would add much extra complexity) for what is only a minor feature. I can dream though...
After about two-ish months of work, I had a more sophisticated version of Pucker Up ready. I had some extra animations, more sound variation, smoother movement, improved score reporting; I could go on for a while. Without Godot, these would have taken much longer. There was one last hurdle to overcome: Exporting to HTML5. I was hoping for this to be a few clicks and done, but it wasn't quite that easy. Retrieving the HTML5 export was simple enough. IIRC, there was a one-click download button. Export prep was a breeze too. The issue arose when I then went to run the game in my browser. When I loaded up the
game.html file in my browser, the scaling and placement of my assets were not where I expected them to be. Even across browsers (and different machines) it all appeared vastly different. I got some of my other friends to help me test this out. I did file a ticket on the Godot issue tracker about my problem. I also asked the Godot Reddit community for their experiences with targeting HTML5. From there, someone was able to suggest I tinker with the "Stretch" settings for the project. Voila! It gave me the result that I wanted and order was fully restored. This was quite the frustrating experience and I think it could be remedied by mentioning these "Stretch" settings in the "Exporting for the Web" doc page.
I've also noticed that the performance of Pucker Up is much smoother in Chrome(ium) than in Firefox. That isn't good. The later browser has some semi-choppy movement of the puck (and high speeds), and the sound effects (such as the bounces) weren't playing at the exact moment that they should. They were off by a few milliseconds. While this doesn't grandly impact the game (as it's still playable), I don't like having to add a "Plays slightly better on Chrome based browsers." footnote to my game page.
All in all, it may seem that I'm be a little extra critical of Godot here, but in earnest it's been a very pleasant experience (re)making Pucker Up with it. With were it stands right now, things can only get better with the framework as time goes on. I'm looking forward to the next game jam I'll enter because I'm sure enough to use this tool. Or maybe I go on with a more grand idea. Godot only knows. :P
You can find the Godot version of Pucker Up over here. Please enjoy.
In other news, about a month ago I started a daily Japanese practice blog (毎日日本語練習ブログ). I call it 日本語ベン強 (nihongo-benkyou). It's a pun; you won't get it unless you know some of the language. Since February of 2018, I've started taking Japanese classes. Foreign languages have always been an affinity of mine, and I was looking for a new hobby that's not related to tech. I created the blog so I could get some practice writing Japanese. Even if it's not the most correct. So far it's been fun.
I created this since I wanted to be able to do audio playback in C# on Linux, Windows, and OS X. While there were some packages available on NuGet, they were not preferable to me, so I took the time to make my own. It's hobbled together using P/Invoke bindings to `libsndfile` and PortAudio. At the moment it does not support MP3 decoding (though that is planned), which is one of the main drawbacks. And you also need to build the native dependencies yourself, but a CMake file is provided to handle that. In the future, I hope to also add some more features such as audio recording and some minor effects. So far I am happy with it.
I like to call myself a "hobbyist game developer." One, because I'm very interested in video game design (mechanics, art, story, structure, etc.) and development (software implementation, physical hardware, etc.). Two, I don't do it professionally. And three, I kind of always approach things the wrong way.
Sure, I do like to draft up design documents of how I'd like the game to function. But I have this really bad notion of "I'm going to do everything by myself, and do it The Hardcore Way™!" Which always ends up (probably,) being that wrong way. What is The Hardcore Way™ you might ask? That's the little evil voice inside my grey matter saying such adorable things like "You should build your own game engine & framework around low level libraries! It would be way more efficient and fun!!"
Well, I don't think he's completely incorrect. But it's something I need to stop doing if I actually want to make games. A few weekends ago I was participating in the Linux Game Jam 2017 where I made Pucker Up. I decided to build the thing in Nim w/ SDL2 and raw OpenGL calls. And since Nim is quite young, I also had to make things for myself like a geometry and collision system. There's a common joke in the game dev scene, is that when you're at that tier, you're not even making a game. For a good two thirds of the jam, that is what all I was doing; no actual game mechanic implementation, just framework stuff. It sucked. And because of that time sink, I had to forgo adding a lot of content to Pucker Up that I wanted. All I could do were the basics.
I've always had the idea of sitting down and taking some time to learn an off the shelf game engine. But my experiences with the LGJ2017 is what prompted me to actually now try that. I know Unity is very hip and hopin' with the young and popular cool kid indies. Though playing games made with the engine, I have always had some issue with it running under Linux. So: pass.
What other engine has a massive following, loads of documentation, spectacular tooling, great performance, works on Linux and commercial success? Unreal. As a bonus, Epic Games is nice enough to let people peek into the source! Pretty cool.
I'm also someone who likes to learn from taking classes or reading books. I'm not totally adverse to reading online tutorials, but I don't mind paying money for words. After taking a few minutes to query the Amazon for "Unreal Engine 4 book," I found this; Unreal Engine 4 for Beginners. It's written by a David Nixon. He looks quite young and it seems like this is his first book that he has ever written. Props to him doing that so early in his life. I couldn't find too much more about him online except for this snippet:
David Nixon is a professional software developer and amateur game developer who holds a degree in Computer Science from Florida Atlantic University. He started his career developing websites and providing SEO services for companies nationwide. He then dove into the world of mobile gaming. Recently, he worked as a web developer for a major SaaS company.
It was $50 for a print copy or $10 for a kindle. Being cheap, I went for the later option. Here's a special feature about the Kindle Edition of this book: You cannot read it in the Amazon Cloud Reader; you have to use a physical device. Normally when I'm reading a book that I assume has code samples, I like to read it on a computer and have it side by side with my text editor. I tried using emulation systems such as Shashlik and ARChon, but none of them worked. I wanted to try to contact the author, asking him why this was so or if he could provide me with a non-kindle copy, but he doesn't have a personal website setup or any public email address. I'm lucky enough to have a tablet where I was able to read this on, but this really sucks for programming books.
Anyways, so what is actually in the book? Here is the table of contents:
- Getting Started
- Basic Concepts
- The Level Editor
- Players & Input
- User Interfaces
- Additional Topics
All of the chapters have the same structure: Introduce the chapter topics, divide into sections, then divided into further subsections, maybe a small example, and a quiz at the end. That's it. Rinse and repeat nine more times for nearly five hundred pages. That many pages might also seem like a lot but to be honest, I think I read the entirety of the book in less than an hour and a half. If you're wondering how I did that so fast, take a look at page 20:
I think this page is the one that has the most text on it, and it's not that much. Many of the other pages contain a lot of spacing for headers, paragraph breaks, images, section spacers, etc. If this book were to be in something like pt. 12 font size Times New Roman, I think it could be pegged at 150 pages maximum.
As for the actual quality of the content, there is not that much I can really say for it. It was an underwhelming read for me. Aside from the quizzes there was no engagement with the reader whatsoever. Sure there were some examples but they were sparse and all of them were with using the Blueprints Visual Scripting (more on that later).
I bought this book expecting it to be a sort of in depth tutorial. Every other game development book I have bought in the past 10+ years has been walkthrough where you build a game from the ground up. Unreal Engine 4 for Beginners left me with nothing other than a few common mechanisms (e.g. how to do simple character movement). Most of the content too was just mentioning what something does for you; not really much how to use it along with other things. The entire time I felt like I was reading simplified reference documentation. Nothing was detailed or highly constructed.
Now about the Blueprints. I'm not going to lie and say I'm fond of visual programming languages; I am very much so not. All of the entire code for this book was with Unreal's Blueprints. I was hoping to do some of that C++, but nope. It was dragging nodes and connections all of the way. I can understand the importance of visual scripting languages for people who work with Unreal yet don't have a traditional programming background but it was a real disappointment for me. On top of that Chapter 5, which is dedicated to introducing Blueprints was 1/6 of the entire book. And by no means is it a good introduction to how programming works. Most of the sections of this chapter would simply state "This is an <x> node, it functions like so." Most sections didn't have an example tied to them to better explain how the statement would work.
And… That's all I can really say about the actual content of the book. There was nothing that really made me a massive impression on me or gave me a good insight on how the Unreal Engine works or good practices with using it. Most of the information presented could have been scoured from the official UE4 documentation. In fact, I would say that this book was nothing more than a light reference manual than an actual tutorial. I really wanted to have this book show me how to build a game with Unreal; it did not do that.
I don't feel as if I got my money's worth out of this purchase. It was only $10 so it's not too much out of my wallet. But do avoid dropping $50 on the hard copy. I will cut Nixon some slack because this is his first book and does seem like a recent graduate. I wish him the best. He does also offer a course on Udemy about UE4, but I have not paid for it so I can't judge the quality of the content.
My conclusion is that I don't recommend getting it. I'll be looking for a different Unreal book in the future.