Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Professionalize your development

A topic by Lyaaaaaaaaaaaaaaa created Jan 29, 2022 Views: 788 Replies: 17
Viewing posts 1 to 8
(8 edits) (+2)

Professionalize your development

Contents

  1. Introduction
  2. Git
  3. Anti patterns
  4. Documentations
  5. Semantic versioning
  6. Continuous integration (workflows)
  7. Unit test
  8. Technology intelligence
  9. Style guide (BONUS)
  10. time tracking (BONUS)
  11. resources

1. Introduction

I followed software engineering at university and did a few open source software. I’m proud to say, when I make a project, it’s always better realized than the previous one. (Of course this guide is biased. I’m more a software engineer than game developer. HF reading it though :))

Now I’m getting into game development. I’m no big name (not even a name) but I have many things to tell to novices. Sadly, I’m no teacher, therefore I will not teach you how to use all the tools or methods introduced in this article.

The goal here is to introduce you to tools, concepts and techniques. There are very good resources online, I will try to list some of them for you.

Feel free to add links to resources or suggest improvements in the comments! Lets create a cool guide for the novices :), any contribution is welcome!

All these tools/techniques/concepts can be used with any technology.

2. Git

Intro

If tomorrow I should choose only one tool to use, I would take Git without any hesitation.

Git is a “distributed version control system”. Basically, with my words, I would describe it as “how to sleep at night and remain Zen whatever happens to project”.

Git will allow you to:

  • Record changes (called commits) to your project.
  • Undo changes.
  • Split in less than a second your project into two separate environments to experiment, implement, patch. (We call it “branching”).
  • “Return” to ANY previous state of your project.
  • View the commit history.
  • Work on remote projects.
  • Mark any point of the history as important (Called tagging, we usually create tags to track releases).
  • And much more.

Git is also usable in cloud for the safety of your project. Check:

Branching

Branching might be difficult to apprehend for novices. At least it was for me. But after some time you will create multiple branches every day.

This article taught me a way to use the branches. It’s not the only way, there are different techniques, but it’s a great one! I recommend you to read it.

3. Anti patterns, AKA what you shouldn’t do

I believe we learn very well from bad examples. I won’t list you all the anti patterns. I will only show you one.

The blob.

What is the blob? The blob is a script that is WAY too big. A script of 1000 lines is most certainly a blob.

The blob does everything and is hard to maintain or understand.

You should read the articles on sourcemaking.com about anti patterns. In fact, you should read everything on this website, but if you don’t have the time just read Software dev anti patterns

Refactoring

Refactoring is a disciplined technique for restructuring an existing body of code

Again, sourcemaking.com will teach you all you need to know with figures and humour.

It will help you identify the problems in your code and how to improve it.

4. Documentations

This one might seem obvious to some of you, but I see many people asking for videos to learn programming.

It might be me, but I never managed to learn much with the videos. Most of the time I ended up stupidly copy pasting and wasting my time. Moreover, videos are slow and harder to find than proper documentations (Even more if you don’t speak English).

Investigation is an important skill for a dev. Your best friend is the official documentation and the quality of this documentation will weight a lot in your decision to use the technology A over the B.

Semantic versioning

The point of semantic versioning (except it looks cool) is to avoid the dependency hell. It might not fit all projects though.

The version number is in this format MAJOR.MINOR.PATCH. And to summarize it increments like this:

MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards compatible manner, and
PATCH version when you make backwards compatible bug fixes.

If you need to add some pre-release or additional info add them as extensions to the MAJOR.MINOR.PATCH format.

If you want to use the semantic versioning you should read the Semantic Versioning website

5. Continuous integration(CI) or the implementation of automatic workflows

Continuous Integration refers to both the continuous compiling and building of a project tree and the continuous testing, releasing and quality control

From lone wolf to big teams, CI will make your life easier. It will require some (or a lot) of work, but once done, you will never want to go back to the stone age.

You can use CI to build your game, control the form of the code (to enforce a style guide), upload the files to itch.io, and run unit tests.

You can set up “simple” CI with Github actions

6. Unit test

Unit tests are used in CI (they can be manually used though). The point of the unit testing is to write simple and easy to verify scripts that will test your code. With each change you will run the tests and increase your chance of spotting a bug before you release into in production.

Because testing your whole code might be a waste of time you can write tests for key functions or objects on which you rely a lot. We call this “test coverage”

Moreover, when writing a test you will find out it is hard to test a badly designed function. It will encourage you to write easy to test code, which is a good thing.

Now you might ask, “how do I write unit tests?”

Well, there are A LOT of tools out there for writing unit test and a lot of tools to add them in your CI workflow. But just type “unit test [your technology here]” in your favourite search engine.

See the research “unit+test” on Github results

7. Technology intelligence

This one is very important. Let’s be honest, we are not very good programmers. There are way more competent people out there. But the good point is we, the developers are sociable and like to share our work.

The point here is to not reinvent the wheel. One of the simplest way to search for a library or anything is to type key words on Github or Gitlab. You will find amazing open source work. And the best part is, you can actually help them to improve it!

Save yourself time and effort, use libraries made by fellow devs. If you don’t find a perfect solution you can always fork and modify an existing one. Or you can make a brand new one and share it to help your fellow programmers ;)

8. Style guide (BONUS)

A style guide will allow you and your team to be consistent with the style of coding. You can even use one if you are alone.

This guide will be the bible of your project. You might use the one recommended by your engine or technology, make a new one, or modify an existing one. The point is to be consistent to the rules you want to use for your project.

Here is an example of the style guide from Godot Engine.

var party = [
    "Godot",
    "Godette",
    "Steve",
]

var character_dict = {
    "Name": "Bob",
    "Age": 27,
    "Job": "Mechanic",
}

enum Tiles {
    TILE_BRICK,
    TILE_FLOOR,
    TILE_SPIKE,
    TILE_TELEPORT,
}

It shows how you should format, name or write things, from files, to variables.

9. Time tracking (BONUS)

Tracking the time you spend on each task might come handy if you need to bill someone, want to make stats or efficiently plan a project. I recommend using simple and non intrusive software.

Here is a quick list of time tracking apps

10. Resources

Git

Anti patterns

Semantic versioning

Continuous integration

Unit test

Bonus

(+1)

Git is great but I disagreed with feature branches. They interfere with continuous integration/continuous delivery. You are better off having everyone work on the main branch in my opinion. If a new feature isn't ready yet just make sure it is disabled. Only time I find branches useful is if you need to maintain old versions.

Semantic version is useful for libraries but is of little value in games. Unless you have modding capability, there is no API to break. If you have modding capability, the modding community is still not going to be happy with semantic version. They want backward compatibility. Unreal developers considered that an advantage during the development of their engine. (I suspect they have broken compatibility sometimes and it is something you may need to do but it should be as rare as possible.) Linux doesn't use semantic versioning. Instead they maintain backward compatibility.

(1 edit)

Thanks for your contribution! I ignored most of these things about modding and semantic versions. I will see how I can update the semantic version chapter. In my opinion, I find feature branches to be a nice way to not let unready features be a nuisance for the main branch. And when it is ready, a pull request with a review will make sure it correctly merges with the main one. And yes, it can also be used to maintain old versions.

(+1)
I might sound harsh, but I can judge in a few seconds if a project looks pro by looking at the versioning they use.
While browsing in the store, I saw a few examples of bad versioning:
“Name.zip” - No version at all.
“Version2” - That’s better, but it’s still not good.
“V4_Windows.zip” - At least the platform is specified.

Butler does not change the filename assigned to a channel or append anything to it when a new version is uploaded. Instead, it indicates the latest version separately on the page, like so:


I suppose you could manually change the display name every time you upload a new build, but the version is already displayed there and the actual downloaded filename will not change, so I don't think there's any benefit to doing that.

And I do strongly recommend using Butler:

  1. It enables automatic patching for Itch app users.
  2. It creates and uploads a delta instead of overwriting the entire zip file, which saves time and bandwidth.
  3. You can easily script your deployment process from the command line, which saves a lot of time.


As for semantic versioning, I've looked into it before and decided that it had limited applicability for my games.  I'm not publishing an API, so the only real potential breaking change would be incompatibility with older saved games, which should never happen in a production release anyway unless it is absolutely unavoidable.  I could technically use it to distinguish bugfix releases from feature releases, but I don't know that it's that important; players don't care about version numbers, and most of my releases thus far have included new features anyway.  With all that in mind, I decided just to keep it simple.  More power to you if you find utility in it, of course, I'm just not sure it offers much benefit for most projects.

I edited the semantic version part. I will take a look at Butler and might add a chapter about it in the guide as it seems very useful!

(1 edit) (+2)

No offense, a lot of this seems like cargo cult practice you happened to absorb without thinking about it critically.

Git is only one of many version control systems, and it happens to be among the most complicated. It’s justified by its distributed nature, but game development is almost never distributed, it’s centralized in the developer’s HQ.

Your description of the blob makes sense, but it’s not what the article states:

Procedural-style design leads to one object with a lion’s share of the responsibilities, while most other objects only hold data or execute simple processes.

This isn’t just untrue, it makes no sense - procedural-style software almost never has objects to begin with. Instead, there are generic functions that operate on data, thus a clear separation. This is how I write my software, and any antipatterns or bad code in there are just that, not to do with the procedural style. If you want a good example of a procedurally-written game engine, I recommend checking out Sauerbraten. I checked it last before they moved the minimum requirement to GL2.1, and I found the source pleasant to read.

Technology is changing so rapidly that developers often have trouble keeping up with current versions of software and finding combinations of product releases that work together

I haven’t seen this to be a problem. Technology may be changing rapidly, but who said I should be keeping up? Technology should approach people, not the other way around.

Others have already commented on semantic versioning.

but once done, you will never want to go back to the stone age

Oh, you’re one of those.. well now yes offense. Sorry, but I’m not pathetic to the point of not being able to type make in my command line. If my team doesn’t have the mental capacity to check whether something works then they’re not worth putting up with.

This one is very important. Let’s be honest, we are not very good programmers.

This is supposed to be a bad thing.. why are you accepting this, instead of improving? You may call it technology intelligence, but really it is human stupidity. At what point do you stop pulling code you yourself will never check? Have you heard of the recent colors.js case? Will you also pull in a library to add two numbers? Where do you draw the line?

Ultimately, this is all reminiscent of the kind of character that favors quantity over quality. But, I am not that. I don’t dumben myself so that my machine or some random people on the other side of the planet may know better than me. I improve myself, and so, I improve my work.

(+1)
This is supposed to be a bad thing.. why are you accepting this, instead of improving? You may call it technology intelligence, but really it is human stupidity. At what point do you stop pulling code you yourself will never check? Have you heard of the recent colors.js case? Will you also pull in a library to add two numbers? Where do you draw the line?

A ludicrous slippery slope, particularly given that the original statement said little more than "other people might have made things that you can use."  They can draw the line wherever they damn well please.

Slippery slope arguments are fallacious only when given without evidence.

People do draw lines, but their lines only ever appear as they age and stop being purely hedonistic. This “convenience” movement, on the other hand, is driven only by hedonists, and so doesn’t draw any lines, which is my entire problem with it. Each new generation pushes the line further towards progressively pathetic, petty behaviour before normalizing it. My evidence is all of history from when science became people’s religion.

Before talking about convenience, think about whether it’s actually justified, and what you’re losing because of it. Programmers are short-sighted individuals, so it’s no surprise they don’t think to do so.

(1 edit)
Before talking about convenience, think about whether it’s actually justified, and what you’re losing because of it. 

The high-handed moralizing does not interest me, but this line is valid, and is really the only thing you needed to say in the first place.  Yes, all software development is about tradeoffs.  In this case, weighing the balance between the control, comprehension, and self-reliance of implementing something yourself, and the speed and convenience of using off-the-shelf parts.  Of course, the exact ratio one prefers for one's own projects is neither a measure of character nor the remit of other developers.

Hi, I’m sorry if you don’t appreciates the off-the-wall tone. My intention was only to make it easier to read and not to hurt anyone’s feeling. Though, I appreciate your feedback and the contradictory opinion of your answer :).

I updated the guide and removed some off-the-wall statements to avoid further confusion.

(1 edit)

I don't think this fits very well into hobby game development.

Git

The need to branch , merge or rollback rarely occurs. One disadvantage of rolling back a week is that you lose all progress you've made during that week and as such just manually undoing the change is usually faster.

Github charges 252$ per user per year for 50 GB. Gitlab charges 60$ per month for 10 GB past the initial 5 GB.

We're doing this as a hobby and spending 252$ per year per team member on a cloud service is definitely not a priority when that money could be better spent on hiring artists and voice actors.

If your project grows above 50 GB that means paying Gitlab 300$+ per month. Most creators here don't have the kind of revenue to justify that expense. If you want version control it needs to be self hosted.

Unit Tests

Unit tests are suitable for functions that are:

  • Pure
  • Hard to test manually
  • Independent

Games are all about world state, manipulating and querying the world state.

Here are a few real life flaws that I've encountered during development.

  • Dolphin spins around in a circle
  • Mouse cursor doesn't hide and you need to hold the LMB to rotate instead of just moving the mouse when starting the game
  • Level number renders to wrong UI element
  • The generated level is impossible to finish
  • The generated level "leaks"
  • The selected font doesn't support the symbol I want to render
  • Kitune animation doesn't play
  • Killing the boss at a certain phase of attacking will cause it to resume attacking (while dead)
  • Snow deformation from footprints doesn't work for client
  • High score table doesn't fit into the allocated space
  • Animation self-penetration
  • Climbing through ceiling
  • Unable to ascend stairs
  • Unable to move through doorway

None of these are suitable for a unit test and even if you could pull it off the time and effort isn't worth it.

MVP

What I've found most important is this:

You want a minimum viable product running ASAP. Something you can send to a friend and tell him this is a game I'm working on, tell me what you think. Typically you'd want this MVP on day 1.

(+3)

Is the 50GB limit a problem?? Then look into your asset sizes (proper file formats), your gitignore (no temporary files!), and git LFS (for binaries), or just keep the biggest binaries (movies?) out of your repository.

For nearly any hobby or indie game dev team, git hosting is free if you do it correctly.

I agree with the rest though.

(2 edits)

50 GB currently isn't a problem for me. Iruka content folder is currently at 4.63 GB and Whitewatt did prune unused assets from it. That just about barely fits into gitlab free leaving very little space for changes.

Git LFS looks promising, but it would mean I would need to self host the files themselves and as such I might as well self host my own repo and keep things simple.

Edit:

I want to give Git LFS a chance, but my concern is that I will end up micromanaging which files goes where. That is time spent that could be used for actual development. If there is a way for Git to automatically dispatch files to the appropriate storage that would go a long way.

It’s true unit testing is time consuming and not suited for everything. Yet, unit tests can be used for functions that are easy to test too. It will save time once set up and running 100 times your automated test will be faster than doing it manually 100 times.

(2 edits) (+2)

I think this is a good writeup, and helpful for developers who taught themselves from video tutorials. I also agree with most things.

Regarding git: it's not mentioned here, but I use bitbucket to host my repositories. I think it used to be the only one that allowed for free private repositories. Git has a learning curve, but it's worth it, even for solo developers.

Regarding unit testing: it's done a lot less in game dev, compared to other fields. Not because game devs are knuckle draggers, but because it makes little sense for real time systems that interact with other real time systems (how do you unit test your player controller? I'm sure someone can come up with a theoretical, academic solution, but that's just not practical). That said, if I have an isolated, discrete system, I add unit tests (or at least I know that I should ;-) ).

I liked this blog post about professional testing methodology for games: https://tomforsyth1000.github.io/blog.wiki.html#%5B%5BLogging%2C%20asserts%20and...

Obviously unit testing the controller will be difficult xD. But you might be able to test some low level libraries you made yourself or something like it. I thought it was worth talking about unit tests in this guide.

(+1)

Updated the guide: