Being too ambitious
Tags: gamedev, cpp, opengl
Published: 2021-02-24 19:42:38

I willing to bet any developer who's been developing for longer than a few minutes has experienced something like this cycle:

1. Come up with new project idea
2. Get really excited about new project
3. Start working immediately, little to no planning
4. Work for a few days or weeks and get a lot done
5. Realize scope of project way too late
6. Try to put too many features in to meet expectations
7. Burn out, start to work much less
8. Go back to step 1

It's hard to avoid sometimes, a new project can be very exciting and you want to start making progress immediately. The problem is that sometimes it's difficult to realize how involved a project is going to be until you're already into it.

This happened to me recently with my graphics library, Nyx/Baphomet/Eos/Nyx. You'll notice there are 3 names there, 1 of them repeated because I went back to it, and that's because I started and restarted the project 4 separate times because of this cycle. Each time I'd start over I thought I'd solved the issue of why feature X was just not good enough, and I'd jump right back in and do the same thing again. 

This last time, I decided to step back and examine *why* exactly I was failing each time. It's not that my code wasn't working, it did, and it worked well, I just always felt something was wrong with it once I got any substantial amount of functionality in. One time I even made it as far as making a basic Minesweeper clone to test it out, and still something felt off. I finally realized that the issue was the *scope* of the project, how much I wanted it to be able to do, and how calling it a "graphics library" wasn't even accurate at that point.

I wanted whatever-you-want-to-call-it-this-time to be capable of these things in no particular order:

1. OpenGL abstraction
2. Drawing primitives--points, lines, triangles, rectangles, ovals, etc
3. Drawing textures--static and animated
4. Window management
5. Keyboard/mouse/gamepad input--extra game-like features for these too
6. Sound/music
7. Particle systems
9. Timers
10. Tweening

Probably other things I'm forgetting...

Point is, it wasn't feasible. I'm a single person who hasn't even graduated college yet (almost, 2 more months), much less worked on a project with a scope that large. Each time I'd make it as far as managing the window, abstracting parts of OpenGL--though never as much as I wanted--events, timers, drawing primitives, sometimes textures, and then...nothing. I'd look at what I made and hate it. I'd think about how it's missing a specific feature, or you couldn't initialize a type in a convenient way, or whatever, and not know what to do.

Each time I restarted I'd use some of the code I wrote from the previous attempt. I figured that for some parts there was no reason to completely rewrite it--things like a utility file to get random numbers, or the timer class that didn't have any real dependencies. These things were portable enough that I felt like I could reuse them.

As you can tell from the list, calling it a "graphics library" is a bit misleading. Yes, it was definitely capable of that, but in all reality it had a graphics library buried under a lot of game development features. If someone wants to make a game, they're probably going to just use Unity or GameMaker or something already existing that's more mature, has examples, and can do a lot more. I was struggling to see the forest for the trees, and getting blinded by my own goals somehow at the same time.

Rather than trying again and hoping I somehow fix the problem, I'm going to go for a different approach. This time, I'll be focusing primarily on only a single goal in the list: abstracting OpenGL. While working on this project, I actually considered using Python instead of C++ because of a really nice library I found called [moderngl](https://github.com/moderngl/moderngl). It abstracts the low level OpenGL concepts into much nicer to use pieces, and I realized quickly how useful something like that could be in C++. One of the big questions I kept asking myself while developing was "how can I implement feature X if I don't really want to use it myself but someone else might. How can I plan for that?" The answer is that realistically, by yourself, you can't.

And that's okay! Trying to please everyone isn't possible, you'll eventually have to make decisions and live with them, and if whatever you make isn't a good fit for another developer, then they'll just have to move on. Unfortunately that's just life.

Starting today I'll be working on a new project, hlGL - High Level OpenGL. The goal will be to create a library with a similar feel to moderngl, but in C++. I can still use some of the code from the previous graphics library/game engine/whatever as well.

Even better, the original goal isn't out of the question, it'll just be more than a single piece. hlGL should be useable as a dependency on its own to make something higher level still, and that can be a goal for the future. For now, I need to keep my goals lower so they're attainable.