Game Development Best Practices

In another thread, @athousandships pointed out this in the Godot docs. I highly recommend it for anyone designing a game because they will help you not get bogged down in design of your game and focus on implementation - actually getting something working.

6 Likes

There is an idea there, but the article as a whole appears to address an entirely different concern. Perhaps it is better to elaborate what you mean, so as to not mislead the people.

4 Likes

@rpahut Yeah, I felt this way too. That link goes into the official best practices for engine contribution.

I read the whole thing, and MAYBE they can be applied to game design, but that’s a very strong maybe. It’s just hard to decontextualize.

@dragonforge-dev could you elaborate more on what you meant with this post? Like, any tips for game design specifically?

2 Likes

This is an article on open source engine development, and I don’t see how it’s broadly applicable to game design. the “problem first” model only applies if you’re seeking to solve a problem in the first place. Sure, problems that need solving do arise when making games, but most people aren’t making games that solve problems in of themselves.

Are you meaning we should implement these principles into our game programming? When I think “game design best practices” my first thought is stuff along the lines of making sure the player is clearly defined, giving variety in experiences, setting clear goals for the player. You can apply the “problem first” model to game design to an extent, but game design problems are often abstract and feelings-based, applying a rigid system for solutions doesn’t always work.

2 Likes

Problems in the game design context would be how do I translate this idea or concept into a game system (code), how to flesh out an NPC (stats become data)

If you’re a programmer, the cross over of notions and concepts is obvious.

Maybe not so for the rest of the spectrum of game developers.

Oth, cheers !

3 Likes

Some apply more than others, but here’s my thoughts on it.

#1: The problem always comes first

Come up with gameplay and game features that benefit the game. Don’t just add them in because they’re cool and try to shoehorn them in to your existing game. That makes for a crap player experience.

#2: To solve the problem, it has to exist in the first place

Do not future proof your code. This is the #1 mistake I see people making on here (myself included). In therapy, it’s called borrowing trouble from the future, or just plain worrying. Our brains get endorphin hits when we solve problems. So it can be very tempting, and comforting, to solve a problem for the future. Especially if the problem right in front of us is feeling intractable.

Future problem solving creates overly complex code. It is inevitable, but when we notice ourselves doing it, we should stop and wait to solve the problem when it exists.

The same problem comes when people over-architect systems. I see people make complex architecture decisions based on what they think they know about Godot, without knowing how Godot’s systems work. They plan themselves into a corner instead of building and iterating. Going for a waterfall approach instead of an agile approach.

I also see this when people come up with a solution to a problem without understanding the problem. This comes with posts where someone says, “I need to know how to do X.” Then someone asks why, and slowly, the problem comes out. And then a different solution is presented that reduces code complexity. But if the responders hadn’t asked about the actual problem being solved, the answer would’ve been morecomplex.

An example of this is people not knowing when it is best to use a CharacterBody, RigidBody, StaticBody, AnimatableBody, or Area (2D or 3D). They often want help with complex physics calculations that they’ve figured out how to handle something, but can’t quite get it to work. When if they switched the type of base object, the solution and most of their math would be handled for them.

#3: The problem has to be complex or frequent

Be careful of going down rabbit holes. It is possible to get myopic about a solution, doing something “the right way”. For example, wanting to use an AnimationPlayer instead of a Tween, or vice-versa because that’s what you’ve used everywhere else.

It also rears its head as perfectionism. Trying to make one’s code perfect the first time around, instead of getting it working and refactoring.

#4: The solution must be discussed with others

No matter how experienced you are as a developer, there are always things you do not know. With an engine like Godot, which is constantly getting updates, there are literally new and better ways to do things every few weeks in some area or another.

As I mentioned in the last step, it can be a good idea to talk about not only the help you need with your solution, but the problem you are trying to fix, and why you chose that solution. This should also be followed by everything you have already tried, and everything think someone might need to know to help you solve your problem. People who do this get much better answers out of the gate, and more often get a solution with the first reply instead of the 20th.

When people get mad at having their solution questioned, they are typically shortchanging themselves. Even if someone else’s solution isn’t what they need, the act of the discussion itself, can help you to formulate why you came up with your solution and lead you to the solution on your own.

#5: To each problem, its own solution

Don’t create complex objects to solve every problem. It can be tempting to be clever about coding. This cleverness can come in a number of ways. For example, creating a single Item class that everything in the game that’s not a Character, inherits from. This typically comes from a newfound love of Object-Oriented Programming (OOP). Which is great, but everything has its place.

One of the new ones I’ve seen in Godot is people using the abstract keyword without understanding how it’s used. A common one in any programming language is people cleverly using ternary operators all over their code to make their code more concise.

Likewise, people try to shoehorn object into a single solution. For example, trying to create a single node that handles a problem for 2D and 3D games. There’s a reason those node types are separate and have different colors. (This is a trap I’ve fallen into more than once.) The opposite is also a problem. Making a Node, Node2D and Node3D version of the same solution to cover your bases, when only a single Node solution is necessary because the problem doesn’t actually address location in 2D or 3D space - or can handle that kind of operation without itself having a location in space.

This often rears its ugly head with new programmers, when they attach giant scripts to objects. The most often culprit being the player, which often has a state machine shoved into it, sometimes a HUD, inventory, plus all the physics, and input handling. When a system is that complex, it’s a good idea to simplify the problem through refactoring. Take each of those pieces and separate them into objects that handle specific tasks. They can all be in the player scene, but they shouldn’t all be in one mammoth player script.

#6: Cater to common use cases, leave the door open for the rare ones

This is more about the tools one creates for oneself. For example, creating a signal bus autoload, and then shoving everything in there whether it belongs there or not because it is easy and convenient to use.

As the article points out, this is also a continuation of the previous case.

#7: Prefer local solutions

Another way of putting this is “don’t hack your code” or “refactor after you get something new working”. This is something that requires one to be somewhat proficient with the language and programming concepts, so is more intermediate level. Another way of putting it is, “Make that LLM-generated code your own.”

Newer developers will add something to their code and then leave it. They do not understand how it works, and they don’t want to mess with it because it works. Get over this, or it will bite you in the behind down the road.

Getting something working is good. Figuring out why it’s working so you can refactor it is even better. For me this often looks like me throwing something into a CharacterBody2D/3D script to make sure it works, and then moving it to a State or some other Node on the Player object.

#8: Don’t use complex canned solutions for simple problems

Be picky about what add-ons you use. If there’s one that solves your problem, go ahead and use it. But be careful. If a Godot plugin isn’t maintained, it will eventually stop working. If it does a lot more than you need, you are going to bloat your code and the size of your final game.

A good example of this is Dialogic vs Dialogue Manager. Dialogic caters more towards Visual Novel games. It has a LOT of bells and whistles, but is complex to learn and takes more to integrate into your game. BUT, if you want a more Visual Novel feel, even if it’s just portraits for every line of dialogue - that’s the way to go. However, if you want a more simple old-school JRPG style dialogue system, Dialogue Manager is much simpler to use - especially since the maintainer has created video tutorials and linked them in the Readme.

When I make my own add-ons, I try to keep them small, and specific to what they do. This means that if I’m not using one, I don’t have to add it to my game. Following the advice for the last few points, I’m currently breaking my Game Template plugin out into a 2D and 3D version. Because while the size of the template doesn’t change (there’s only one tiny duplicated script for 2D vs 3D in the whole plugin), I am trying to make the user experience (namely mine) easier to start a 2D or 3D game.

Conclusion

Ultimately, the advice you get out of these will depend, as @OleNic said, in your experience. I appreciate people asking for clarification. It took me a few days to find the time to finish this post.

6 Likes

Yeah… all of this is for programming. Not game design.

Game design is a completely different skill. You don’t start designing a game around a problem, you design them around an idea. Then, you flesh that idea into a cohesive, and more importantly, fun game loop via iteration.

Game design is based on FEEL. You create your own rules, and then follow those rules.

2 Likes

Ah so it was a semantic difference. Well that was a waste of my time.

Yeah, you’re right. Poor title choice on my part.

No worries. I think your general sentiment is pretty good. It just got lost in translation.

2 Likes

The very second you have an idea that you want to create, you have a “problem” to solve.
As you carry on in designing your game, the single problem becomes multiple problems.
And those tips are apropos to solving those problems.

2 Likes

You’re not technically wrong, it’s just that this has a lot of different interpretations.

I personally think making your core game into a problem is a pretty toxic mindset to have. Your not solving a “problem” you created, your fleshing out an idea. The latter perspective is a lot more fun.

Side note: What that heck does “apropos” mean?! I can barely pronounce it.

Apropos mean “very appropriate to a particular situation”.

I think that the word “problem” can have a negative connotation.
A problem is not necessarily negative such as a math question.

One of the definitions of “problem” is

a question raised for inquiry, consideration, or solution

When you are designing a game, one of the first things you are going to decide is the approach you are going to take in creating that game. That question satisfies the definition of “problem”.

2 Likes

Not at all, that was a handy writeup. It explained some painful mistakes I’ve made and was good for reflection.

2 Likes

It is pronounced “ah-pro-poe”, and is derived from a French word, which is why the “s” is not pronounced.

Glad to hear it. That was the point of me posting it.


As a clarification about design vs. development, when I posted this I didn’t expand like I usually do because I was really tired and wanted to get the idea out there before I forgot.

Keep in mind that I am not only a professional developer, but worked on professional games for a number of years. Sometimes I forget to make sure I explain everything that goes on in my head.

In software development, there are traditionally two paradigms we use for designing a piece of software - game or not. The first is called Waterfall, and the second is Agile. There are many different versions of Agile, but most people use it synonymously with Scrum, which is the most popular version of Agile - so much so that most people even in the software industry do not know they are different things.

At any rate, when designing a piece of software in detail before writing it, you are following the Waterfall method. In that method, first you create a Design Document. This is what you are thinking about @Demetrius_Dixon when you talk about “game design”. The next step is the Technical Design Document. It lays out how you are actually going to program the piece of software. What language and technical choices are you making, how are you structuring your objects, etc. I believe this is what @sancho2 was getting at. The last is the Test Plan. This lists how you are going to test your project to make sure that it meets the specifications laid out in the first two documents.

No one does this anymore.

When I made the post I was thinking primarily about the Technical Design of your game, because we talk a lot more about programming here than Game Design.

1 Like

I have to agree with dragonforge-dev about most of what was said. Would comment that the Agile method is very popular because it involves a lot of team interaction. I like the paradigm by one of the creators of Agile that goes :”evaluate your position,think of where you would like to be in the future, take a step in that direction, then repeat”.

The waterfall method deserves commenting on, because there is also some evidence that it can be better for certain types of project - a project with veey clear goals and a linear development path. If there is a task like ‘write 500 lines of code to print a list of dialog texts to the screen for the game prologue’ then this can be achieved best with straightforward labour and the waterfall method is suitable. A task like ‘design a flexible dialog system with the clients requirements’ could be non-linear and could require iterative refinement and modification as requirements change or emerge, so the correct spanner for this task would be an agile process.

Generally projects that work like unhindered waterfalls can be much faster and very successfully completed (doubling the memory of a chip?), but the reality of most projects is that they are non linear and setbacks and loops can occur. Scheduling is also an issue, as the team may have to wait for assets and components to be completed.

I think a design doc is important regardless of what method is used - if you use agile then the design doc could be under daily review. For people working on their own i would suggest working from a plan of some type, maybe multiple documents like “task list”, “bug list”, "budget” etc.

The design doc is where you formulate a clear picture of the game you are creating. You can edit and change it depending on factors like ‘scope’, ‘time to release’ etc. But most importantly it allows you to reassess what you have designed and also to make a clear plan of what needs to be done. You can find areas of weakness during the project as you compare the actual game to the doc. You can see from the start how much gameplay there is going to be, you can estimate the time it will take to develop (for any mini waterfalls can be added up) and the doc (or directory) is a useful place to keep images, concept art, plans, diagrams, story parts etc.

2 Likes

I realized this morning that in fact the Godot editor (and probably any editor ) works as a great project management tool. The node tree and the scene shatem xan be built up as a skeletal framework for the game, and therefore can also reduce some load on the documentation i would reccommend for the “best practices”.

Im considering making scenes that are just purely documentation for putting ideas somewhere.

1 Like

Also, use regular testing on the target platform. The process is called continuous integration.

Also the statement “premature optimization is the root of all evil” is probably false nowadays, especially since there is no point in building an enormous mobile game only to find out that it only runs at 5 FPS and cannot be optimized without rebuilding all the assets.

The optimization should be continuous and works in parallel with what you do, or you just use an established technology and dont worry about optimizing.

1 Like

Actually, “agile development” refers to a paradigm how to write software. It’s more of a philosophy and a mindset.

SCRUM is an implementation of agile development best practices and defines a framework for teams to structure the day to day, the sprints, how to plan, how to execute, how to make decisions, how to assess the state of the project. It’s popular because it provides the control many crave for, respectively which is necessary once teams reach a certain size or when cultures clash. As such, SCRUM is often applied incorrectly, modified in ways that lessen its worth, and may even be abused like any framework.

Worth noting: not planning ahead is not agile development, it’s running with eyes closed. :wink:

That’s a bad example. It’s not a clear goal, and if it were clear enough for waterfall to work well, it would be a task like “write 500 lines of dialogue to .. (insert mood, characters, setting, etc)” for an already existing dialogue/cutscene system.

Otherwise: “print a list of dialogue text” might end up getting printed in the game’s debug console, or without any consideration for who is talking, how to portray them, how to “assign” text to a specific character, how to advance the conversation, whether there’s spoken audio, whether localization and which languages need to be considered, and so forth. Waterfall would try to spec all of that up-front, only to end up writing 500 lines of code. That process might take weeks, while an agile developer would have briefly talked to project manager, designers and artists, made a first draft, and consulted back with them - they’d have a good working solution in under a week.

And when management or marketing decides they need to have “crawling” text (appears letter by letter) and arabic language support with RTL, the agile developer is already prepared to make that change - secretly knowing that Godot already handles that, taking the time instead to finally fix the launch delay everyone’s annoyed by but doesn’t get prioritized because it’s an ‘internal’ task. Also agile. :smiley:

To a degree, but this has severe limits. Try searching for a specific part of the design for instance. It might be buried in some “notes” node in the Inspector.

Use the right tool for the job. Creating a game skeleton => editor. Project management (in its actual meaning) => anything but the editor.

You seem to have missed the point slightly, what i am trying to explain is that my interpretation of the term ‘waterfall method’ is that of a simple linear project consisting of pre defined tasks.
I was just making the point that if that is the truth about the project then it can be better to use the waterfall method - there is no need for the agile approach.

A better example is for a tool that requires the manual export of 10-15 assets. The batch export script does not work for the file type required, so somebody has to either fix the batch export script, or export the assets. The project deadline is in 30 minutes and those assets will be automatically imported. Its ok, its a waterfall and each file takes about 10 seconds to export.

Of course in practice, the waterfall method could be employed for a project that would be better solved with agile methods.

I think its a great tool for the job anyway because you can store the concept art, maps, idea sketches in 2d scenes, and its easy to engineer a way of putting notes near images, or a checkbox todo list.

I see, thanks for clarifying that.

But who pre-defined those tasks? :wink:

What you describe is a “straightforward task the initiated developer understands well enough to just sit down and implement it”. And that is agile development, not waterfall!

To clarify, you said:

a project with very clear goals and a linear development path

By definition that cannot be a game project, in fact - and that is the thought behind agile development - it cannot be any software project.

Software never has very clear goals (requirements), and it never follows a linear development path (surprise!).

In order to make those goals as clear as possible, and implementation as linear as possible, waterfall demands a lot of frontloading prior to the 30-minute implementation. The idea comes from making the unpredictable as predictable as possible, ideally (ideologically) removing ALL ambiguities upfront. Since that very rarely worked in practice when computing become ubiquitous, agile development took over.

Historically, waterfall was once a sound approach. At the time, it still took a programmer 30 minutes to write the code, but then it had to be printed to punch cards, carried over to the data center (possibly even sent across country), someone had to install the punch cards, run the program, print the output, send it back, only for the programmer to receive days later something like “syntax error in line 13”.

A proper waterfall methodology thus tries to ensure proper runtime behaviour by speccing out a process that happens prior to writing and running the code:

Schedule a meeting and sit down together, put all the facts on the table, analyze problem according to past specifications (you got guidebooks), flesh out new specifications according to customer and technical requirements, derive tasks from that and plan them, possibly even write pseudocode and test it on paper, then implement (the 30 minutes) and there better be no more open questions or else the process starts anew. Oh and don’t forget to update the documentation and get the code reviewed, the changes tested, and all of it signed-off before it can be merged with the mainline.

That’s waterfall in a nutshell: a ton of bureaucracy.

Agile accepts that there cannot be “very clear goals” and that implementation is never “linear”. Waterfall is the best proof of that fact. :wink:

1 Like