• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Explain C/C++ concepts using Gamemaker?

A

aliasts

Guest
I'm having a hard time understanding exactly how to build a program/game in C. I know most of the concepts and what they do, but I don't really understand when and where to use things based on what I want to create. For example, I have no clue when classes are useful, namespaces, etc. Could someone explain some of these concepts as if I were working in GM:S? (as a basic example, step event with a script surrounded by an if statement = while loop)
 

poliver

Member
classes are the same as a gamemaker objects. when you instantiate a class you define its variables, methods(functions etc.)
once you've created a class(a blueprint for an object) you can then create individual different objects of that class in code.
gamemaker automatically gives your object a tonne of predefined variables like x y speed gravity physics stuff etc. so you don't have to deal with the implementation.

you know the dot operator? like when youre trying to access a variable of another object from a different one. like object1.variable3
it's same in c++. if you want to access something from a specific object you use the dot operator.

if you want to access something from a class blueprint itself(a namespace) you use the scope resolution operator :: . class1::function1()
 

Mercerenies

Member
First off, I suggest deciding whether you are going with C or C++. They aren't the same language; they're not even close. And whenever someone writes "C/C++", a C++ programmer somewhere dies inside. C is a low-level procedural language with little support for OOP. C++ is a higher-level procedural language with classes, anonymous functions, and several other convenient abstractions. If you're referencing classes and namespaces, you're probably talking about C++, as C has neither of those things.

Also related: C++, despite an unfortunate bout of misinformation spreading the Internet, is not a superset of C.
 
M

MishMash

Guest
This is a rather heavy question and a short answer would not really do it justice. Approaching C or C++ with the wrong mindset and lack of understanding will inevitably lead to all kinds of problems down the road.

First and foremost, before ego's get in the way, and before you go away and read something online that praises C++ as being the "gold standard" or "the only language for gamedevelopers", you first have to understand a little bit about programming languages in general. It is true that C++ is likely going to have the POTENTIAL to be the fastest or most efficient means of implementing a game, however that does not mean it is the best option. Lower level programming, with explicit memory control and direct access to APIs does give you a lot of power, but it equally opens up a lot of opportunities for mistakes. The whole reason why different programming languages exist is because they cater to different things. Scripting languages like GML are used to abstract away the complexities of the machine from the actual programming of game logic. The back-end engine process is completely disjointed from what you as the game programmer actually have to deal with. This is why it isn't always smart to draw parallels between "how GM features equate to C++", because the fact of the matter is, they are two fundamentally different languages which aim to achieve two different objectives.

GML has an event loop which is ingrained into the behaviour of all objects in your world. Similarly, there is a whole set of engine level functions which provide a clean interface between GameMakers internal engine. This means that as a GM programmer, you never need to touch the internals, but can manipulate them in CONTROLLED ways. Once your whole game enters the C++ domain, this clean disconnection can become blurred, especially if you do not adhere to good design and code organisation practices.

I'm telling you this to try and lay a bit of fundamental understanding down before we get too deep into how C++ actually works. Far too many developers on here try and go away and write their own engines in C++, or their own custom graphics wrappers, expecting that things will magically be faster just because its C++. They then inevitably finish writing the extension only to realise that what they have written actually ends up being slower than GMs own rendering pipeline. Part of the reason for this is because having native access to OpenGL or DirectX functions will only give you a very very marginal speed up vs just calling equivalent functions from GM. The reason for this is that the GM virtual machine already runs off a C++ back-end and thus the function calls are almost direct anyway. However, GM has the added benefit of knowing exactly what types of interactions the programmer can make (Draw calls using draw_sprite*, state changes using draw_set*, blend mode/shader changes etc;) and it can optimise the rendering process in many different ways. GM automatically manages dynamic batching of your sprites so as to significantly speed up rendering. C++ is not a substitute for your own code being slow, and is quite a lot more time consuming to write in. Again, i'm mentioning all of this because ultimately, I don't think you are really at a point where you want to be writing a game in C++. Just using C++ alone is not significantly going to improve your understanding of how to structure a game engine vs just gaining more experience working with an engine like GameMaker.

To give you an example, you can learn ALOT about low-level graphics programming and rendering optimisations by working with Shaders. You can learn a lot about how data is represented in memory by working with gamemaker buffers. You can learn a lot about networking architecture by writing multiplayer games that utilise buffers and communication paradigms. I think that ultimately learning C++ is actually a less valuable skill than just gaining proficiency at working with any established game engine. When you gain more experience, a lot of these concepts do start to transfer well.
Having said that, if you are going to learn another language, whether it be C, C++, Java, C#, Javascript, Python, etc; It is worth learning that language in isolation, and starting by just using that language for its own applications. Lots of languages have different features that do not exist in other places, and trying too hard to force one to be like another means that you can miss out on some of the features that can make a language so powerful. C# and Java for example are quite good at teaching you how to structure and organise code with respect to interactions between objects.

I would then say that the major benefit of C++ over a language like Java is the explicit control you get over memory. Being able to work with pointers means you are programming very close to the metal, writing code almost exactly as it is performed on the CPU. I would advocate for learning C++ so that you can learn how the machine works (which is a great transferable skill to all programming), but not so that you can immediately use it to make games, understanding how to do that will simply come with time and experience. The design patterns and coding practices you use for that are not unique to C++, and you may even find yourself using similar ideas elsewhere.

Though, as you did ask, a basic run-down of C++'s features you asked about and their purposes:

Classes: Classes are used for object-oriented programming. This is somewhat similar to the idea behind GM objects, but GM isn't a great example as it is not very strict. In simple terms, a class is a collection of encapsulated data upon which a series of defined functions can be performed. The idea here being that a "class" can represent some form of real-world object, and "methods" or "functions" can be used to interact with that object. Classes are primarily used to organise code, and "encapsulate" data (the variables inside the class) so that only that instance of the class can manipulate the data. They can be used with inheritance (in a similar vein to GM's parent system) so that sub-classes can copy behaviours from their parents.
E.g. if you had a class to represent Animals "Animal", it may have a variable for number of legs. You could then have a child class "Dog", which inherits all behaviour and variables common to all animals, but then overrides the legs variable and sets it to 4. The class could have a "getLegs()" function which returns the number of legs. In order to really get an idea what the purpose of all of this is for, and how it relates to overall code organisation, it would be wise to do some reading on object-oriented programming. (Classes are common among many languages)

Namespaces: It would seem that namespaces are primarily used to avoid naming conflicts between different areas of code. It is common when using libraries that a given library may declare global variables, functions or class names that are the same as those defined in another library (Library functions are defined inside headers which are imported using #include, each included C++ module can be treated as a "library"). The namespace is simply used to distinguish between which one you are intending to use at any given moment.

For a wacky exampleLets say you had a math library and a bible library. They both define a function called sin which does drastically different things but has the same name. Now in your code, how does the language know which version of the function you intended to use if you just write "sin" alone? Short answer, it doesn't (there can be times its inferred from context, but keeping things simple). In order to avoid this, each library should wrap itself up into a namespace, lets say "namespace math" and "namespace bible". Then in order to distinguish, you would write "math::sin" and "bible::sin" in your code.

The "using namespace" directive assigns one namespace to be the global default. Most modern programming practices heavily advice against this because it can make your code ambiguous to an initial read (if they aren't looking at the segment of code which assigns the global namespace). The global namespace just means that if for example you did "using namespace math", you wouldn't have to write math::sin, it would just be assumed that "sin" on its own would be math::sin. Though a problem here is that it can then start to conflict with global functions/classes/variables that aren't declared as part of a namespace.

--
But yea, getting back to the purpose of my post, I don't think its a great idea to try and compare GM functionality to C++ functionality. While there are parallels between objects and classes, datastructures and manual memory management; you are better off trying to learn C++ with a fresh perspective and understanding it in its own right. From there on, you can start drawing your own comparisons between the two. Far too many programmers on the GMC take this odd willy-nilly approach to C++, where they don't really take the time to understand what they are doing, but manage to bodge out code that somehow works, without really actually understanding why. For any programming language this is the wrong approach. C++ shouldn't be complicated, if it is then its time to adjust your mindset and approach to learning it until it becomes easier to reason about. The last thing you want is to get stuck with a misguided, or incomplete, understanding of the language.
 
Top