An Exercise In Learning (to hate) c++ and OpenGL (Part 1)

Please complete the required fields.




How this all happened

I wanna make video games. Definitely as a hobby, but just maybe as a job too providing I can actually get hired. It’s because of that second bit that I’ve been working on getting familiar with c++ and OpenGL so I can apply for jobs that involve those, which seem to be the majority of jobs on offer at the moment, as well as slowly work towards putting together a custom engine to port my long term project Unbroken Dawn to, since I’ve now kinda fallen out with the idea of using unity for personal projects. (If you look around the site you can find a couple posts on Before Dawn, the earlier, janky, unity 2017 based, and broken beyond debugging tools even working after moving to unity 2018 version of the project).

At the crux of this effort is my current project NightJam, so called because when I started it I wanted to power through and get things running by the end of the night, and given that was 3 months ago, suffice to say that would have been a very dumb prediction of how long it was gonna take. It’s a simple game engine, pretty much custom built for a specific intended demo game, and it’s been a bit of an uphill battle to get working.

a definitely well edited together image of the c++ and OpenGL logos that isn't just a screencap of when they showed up next to each other on google images.

A few reasonable demands

So I guess I should first off talk about what kind of game I’m trying to end up with with all this. The story starts with GMTK Jam 2022. I attempted Game Jams a lot, go super ambitious, overestimate what I can get done, and rarely end up with a finished product to submit. These days I figure it’s less demoralising if I don’t. Anyway, the theme for the Jam was Roll of the Dice, and my idea for it was an RPG where the player was a cruel ttrpg Game Master thrown into a hellishly hard module of his own creation with nothing but his player’s characters and the ability to manipulate probability (the choice to add a limited pool of extra dice rolls to the other character’s attacks each turn) to keep him alive. The idea was it’d have walk around overworldy bits, a monochrome(ish) 3D series of halls and corridoors, more traditional RPG battle screens, and triggerable conversations with the other characters during the overworld bits. Seems simple enough, more or less, to put together. Unfortunately, literally 2 days before, my standard engine Unity announced they were merging with some shitty mobile game monetisation/malware company and I’d sworn off using it for personal projects. So… trying to put together an engine quickly in Silk.Net and make the game at the same ended up being way more than I could do in 50 hours. Left me in a bad mood afterwards.

Years Later (August) I was in a different bad mood. Like I said I want to make video games as a job, but most of the industry uses c++. Fun fact: I hate c++. I’ve tried to learn it so many times since starting gamedev and every time I get pissed off at it a couple days in and stop. Well, not this time. I’m stuck between a rock and c++ and unfortunately c++ is the better option.

CC BY-SA 3.0 dice image uploaded to wikimedia commons by Diacritica.

Learning good by learning bad

How do you learn a new programming language, API or set of tools? This is a question that has haunted me since presumably some point before learning my first programming language, and for a long time my answer would have been “set a goal and use google to work out what you need to add to go from not having any code to having code that does what you set out to do”. I feel like this is better than just following through with tutorials, as you’re not just following steps, you have both a clearly defined (and quite possibly impossible) end goal and the steps to it require finding out what does what. That’s not to diss tutorials in any way, and they’re generally good reference material too, it’s just goal/project based learning has always gelled with me a little better.

Problem: this doesn’t always/quite often doesn’t work. And I think the reason it doesn’t work is because it’s not exactly a full solution. It’s sometimes fatal flaw is that it doesn’t address a pretty important human concern: motivation. Yeah, that’s right. Turns out trying to do something frustrating, incomprehensible, and hard to make progress on for a while kinda sours you on doing it. Now, there’s a lot (including a lot of crap) to be said on self-motivation, habits, getting in a good state of mind to do work, etc.. What that’s not doing though is addressing the root cause of the problem, being that doing something that sucks… sucks. In other words, I think it’s more productive when you’re starting out to write code that is easy for you to write rather than code that is in any way good at its job. Now, you could definitely say that this teaches bad practices, yes, but at the end of the day after maybe 8 or so attempts to learn c++ “the right way”, it’s the one time I just decided to just kinda write c++ code as I would write c# code (a language I’m more familiar with), all in the header files, is the one time I end up with anything working to show for it… kinda. I did eventually have to go over things and try and fix them to work with how it’s actually supposed to work. But, at the end of the day it really wouldn’t have gotten started if I hadn’t just ignored “best practices” and did things in a way I was used to and was within my comfort zone. I think the second prong to my “learning stuff” method should be that it’s better to do things badly than to waste time trying to do them good, when you’re learning, of course.

Another thing that massively helped too was keeping scope down. Scope is always the enemy and I went into this thing very much with the idea in mind that I wasn’t gonna make a game engine, I wasn’t gonna make something elegant, I was just gonna throw together a “working” solution to the bits I needed for the planned game, bare bones and hard-coded-ish like it’s a game jam. It’s still been 3 months one of which I’ve spent entirely getting angry at framebuffers, part of that was me having a lot of other projects to do, but still, scope is a constant enemy and you should always watch out for it.

What was also pretty pivotal here though was the help I had from several other good peeps from my friend group discord server. At the end of the day, social learning is one of those things that’s been pivotal to human evolution and how we all got here so might as well. Obviously, not everyone has the time or motivation or spoons to help you, but being afraid to ask on the grounds that you don’t think anyone will want to/be available doesn’t make any progress at the end of the day and who knows, maybe some day you’ll be being bugged by kids on how to do something. It all comes back around. But yeah, massive shoutout to RubyNova, lead dev of NovelRT for sharing with me his c++ knowledge, as well as galaxylittlepaws, mhoff and Kennuckles, and probably some other people who further helped me along the way with this.

Oh and jotting down things on sketchbook pages. Turns out paper was a pretty good invention in terms of sorting out complex thoughts.

OK but what’s actually been done thusfar?

Well, since starting the project I’ve

  • Set up OpenGL
  • Mesh rendering
  • Jotted down what I want data structures (such as levels, dialogue scripts, models, enemy/encounters) to contain and implemented both them and a way to load them from a resources folder
  • Set up fonts based on this one tutorial. (see, I said they’re useful for cross reference stuff)
  • Refactored everything so it isn’t all in one file
  • implemented some rudimentary character controller code
  • Tried to set up framebuffers so I can mantain the aspect ratio regardless of what the user does with the window
  • Refactored it again so it’s not causing multiple definition errors
  • Refactored it again so that it’s not using global variables for most things considering the project, and so it finally builds again
  • Finally got framebuffers working and the code for aspect ratio correction in there and have it render in the centre of the screen.
  • Replace some of the copyrighted test images and fonts I was using, apart from two very specific pngs that aren’t used by the game where if they get significantly altered, everything breaks, so I had to manually make them into grey crusty squares.

So, where we’re at today is a project that shows some text on the screen when ran, altered to always show in a letterboxed 4:3 aspect ratio, but with the internals set up so it’s on the verge of being ready to set up a test bit for a walky-aroundy bit. I’d have waited til I had that set up but I figured I need to get something out on the site now that I’m using it anyway so I can make this post focusing on the learning journey and future posts can focus on the current development of the actual game, so look forward to those.

A rotating cube on a blue background. In red tect on top, coordinates are listed. At the bottom in white text is the phrase 'The quick brown fox jumped over the lazy dog' - confucious, this text is slightly horizontally squashed.

Game at native resolution

 

a rotating cube (matching the previous image) letterboxed to fit a windowed 1920 by 1080 screen (1030 as the windows bar is cropped out)

Game adjusted for wide(er) screen letterboxed.

Also, check it out on github if you wanna see the current status of the project code, and have a mess around with resizing the window in the first demo if you want.

For now, I shall continue and see y’all next devlog… or whatever I post yet.

-Matt