I always wanted to talk about 3D development using game maker but I never really found a format that I liked. I made some small courses in spanish over Youtube but I never was quite happy with how it was scalling, so this is a new attempt to bring this topic to the people.
Now, I know, why would you even attempt to create 3D games with Game Maker when tools like Unity, Unreal and Godot are much better for this task and have very good license deals?
Well, I don’t really have an answer to that, those engines are obviously much better than Game Maker will ever be for 3D. with that being said, there is still knowledge to be gained with this experiment.
While Unity and the others are really powerful, they remove a big chuck of the pipeline involved in the 3D rendering. This is great for businesses obviously, since you want to use the shortest path possibble to release your product, but if you want to improve your skills as a programmer then you should really tackle this and many other difficult tasks.
This mini course is just going to talk about how to set up a 3D dev environment using Game Maker Studio 2, any tutorial beyond that will be made in a general OpenGL/WebGL engine.
You don’t need any previous experience doing 3D, but you should be confortable using the Game Maker Engine before continuing.
CREATING OUR FIRST TRIANGLE IN GAME MAKER
It may sound like a simple task, but this is the most important step. It happens more often than not that when you set up your 3D environment you don’t get to see anything you drew to the screen. Debugging an OpenGL application can be a real pain. That’s why it’s important to make sure you can draw things.
You can find a Github repo for this course in at the end of this post.
Let’s start by creating our assets in the project. Open Game Maker Studio 2, create a new project and add this files:
- A script called scrInitSystem, this one will be used to initialize all the global variables needed for this project.
- A shader called shd3D, Since Game Maker uses a 2D shader by default, we will create our own shader.
- An object called objSystem, this is the main object for the game, it’s going to handle all the 3D functions.
- An object called objTriangle, This is our object to be displayed.
- A room should be added by default by the engine.
By now, your hierarchy should look like this:
Let’s start by modifying our shader. Now, if you don’t know how to use shaders, they are a whole topic on their own. We will discuss them on time but for now I just want you to copy what I’m going to show you.
This is how a shader looks by default when you create a new one:
What we are going to do is to eliminate all of the unnecesary data and leave only the attributes needed to place our triangle, and then add color to it.
Make sure you are on the first tab shd3D.vsh this is the vertex shader, and paste this code.
Then, go to the second tab shd3D.fsh which is the fragment shader, and add this.
As I said, don’t worry too much about what we just added, because we will talk about shaders in detail in another post. Basically what this shader does is: It receives 2 types of parameters: a position, and a color. Then, it interpolates between the colors from vertex (position) to vertex. Finally it draws it to the screen.
Let’s continue with this script, the objective is to initialize all the global variables that we are going to need, this script should be executed at the beginning of the game by the objSystem. This is how it should look:
Since we added a custom shader that receives a position and a color, we need to make sure that we are going to send that same data. So what this script does is to create a new format (vertex format) and then we tell it that we are going to first send a position (vertex_format_add_position_3d) and then a color (vertex_format_add_color). This order is extremely important because later when adding our primitives (the triangle in this case) we need to create it using the same order.
This is the object that will control how things are going to be draw in the future. For now it is a really simple object.
Add the create event for this object and add this lines:
The first line calls the scrInitSystem script and the second line creates the objTriangle. Nothing more.
Finally, the star of this tutorial. The objTriangle Is going to create the primitive and then it will send it to the shader where it will be draw.
Add the create event and add the next content:
Lines 2 and 3 are used to tell Game Maker that we are going to build a primitive. Note the use of global.VERTEX_FORMAT this is the format we created in the script scrInitSystem. Remember that it has an order that we need to respect.
The lines 6-7, 10-11 and 14-15 are used to create the geometry of the triangle, we will talk more about this in another post, but you can see that we kept the same order always: first position_3d, then color
The last line is to indicate that we are done building our object.
Now, let’s move onto the draw event
First, in line 2: we are setting our custom shader to be used.
After that in line 4: we are submitting our geometry (created in the create event of the objTriangle) to the shader, (don’t worry about the pr_trianglelist and the -1, we’ll talk about that in the primitives tutorial).
Finally we reset the shader to use the default of Game Maker, this is so to avoid any conflicts with other things being draw.
Adding things to the Room
The last thing left to do is to add the instances to the room. You only need to add the objSystem since that object is the one that creates the triangle after the global variables are initialiazed.
And that’s it! if everything was added correctly, this is how your game should look when you run it:
It may not look like much, but as I said, this is the most important step. The next tutorials will talk more in focus about specific topics: Matrices, Shaders, Cameras, Primitives, etc.
Congrats if you made it this far! If something maybe didn’t work then you can ask me in the comments section or you can download the source code for this and the other tutorials:
Continue now to part 2
Thanks for stopping by and have a nice day!