DEV Community

loading...

Being too ambitious

hunterfehlan profile image Beau ・4 min read

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
  8. Timers
  9. 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. 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.

Discussion (4)

pic
Editor guide
Collapse
pgradot profile image
Pierre Gradot

Hey!

"What is the scope of the projet?" is indeed an excellent question.

But there is a far more important question: "why are you starting this project?".

Let's take the game engine as example. To understand your motivations, answer questions like:

  • Do you want to create features that don't exist in existing game engines?
  • Do you want to just to learn how a game engine works?
  • Is it just a way to improve your skills in C++ / Git / CMake / OpenGL / etc?
  • Is it just a way to implement complex algorithms?
  • Do you really want people to use your game engine?
  • Do you want to create the next Unreal or Unity?

Answering questions like these help you understand what is your level of expectations.

Sometimes, the project is just a pretext to learn something. Sometimes, you need something that doesn't exist. Sometimes, you want to create something better that what exists.

For both you @miguelmj and @Beau, as students, I guess your real goal was simply to improve your skills. And probably you multiple attempts were successful: you did learn a lot!

Collapse
miguelmj profile image
MiguelMJ

Exactly! I never intended anyone to use my engine/s, but I thought of my future self (and my potential projects) as a "client"... not sure if that make sense 😅
The last time I left that project unfinished I didn't feel bad or defeated, because I had learn a lot about different tools, software architectures, etc.

Collapse
hunterfehlan profile image
Beau Author • Edited

If I look at it from a perspective of learning something, I've learned so much over the course of these projects. My understanding of OpenGL is at a point far beyond what I ever even hoped for, and my C++ skills have improved as well, especially with knowing more about modern features of the language. CMake is also less awkward for me now.

I think I my motivation in many ways was trying to make something better than what currently exists. Doing graphics in C++ felt like it had two options--either bare metal or something really high level like Unity--and looking back at it that's not really true. I'm still working on my project, but I think dialing back my expectations and focusing on why I actually want to do it is helping a lot.

Collapse
miguelmj profile image
MiguelMJ

I can relate to this so much. I have started like 3 game engine projects. All of them were as you said: the worked, but they were too ambitious and I was never happy. What I realized is that as a single person it made no sense to make a general purpose library. However, it taught me two alternatives to general purpose projects.

  1. Projects with a scope limited by function. From the last game engine project I recycled the lighting module and turned it into a separate library; now it has more attention and recognition in GitHub that my own engine would ever have.
  2. Projects with a scope limited by goal. I also started a new engine, but this time with a specific game in mind (a 2D platformer, to be exact). This let me decide what features make it into the engine by the criteria of "will I use it in my game?". No more headaches with infinite features to implement. It is definitely not good to be unrealistically ambitious, but it's also true that if it weren't for that, I wouldn't have learnt enough to get to my current (and future) projects.