Log in with to leave a comment.

Are the walls made of d3d_draw_wall or d3d_draw_block or something else ?

Depends a bit depending on which object, but most block-type objects are 4 d3d_draw_wall and 2 d3d_draw_floor calls (so the top, bottom and sides can have different textures).

thanks. I'm making a 3D game and drawed walls wih d3d_draw_wall but it caused performance issues. I found a way to draw blocks with vertex buffer, it's a lot faster.

Does this work if you export it as HTML5?

(2 edits)

No idea, I've never tried. The engine is quite a performance hog and the HTML5 version of GM doesn't have super good performance since it's doubly interpreted, and you'd lose out on both hardware-accelerated 3D rendering and hardware lights. Also I'm pretty sure the way the mouse position is read to let you aim with the mouse just wouldn't work in HTML5 (since you can't control the mouse position other than on the desktop ports, and the code is based on resetting the mouse to the center of the screen all the time so you get motion from its absolute position).


Awesome stuff! Thank you! 



Error in Script collide_slope_x_bottom at line 0 : no references to argument 0 but references argument 1 (Idem for _x2)

Is no a serious problem, just replace argument1 by argument0
According to GM versions, the bug does not appear...

Otherwise very good engine!

Thanks, I'll look into it... arguments checking is a relatively new thing compared to how long the YaruFPS code base has been around. I don't remember exactly how the script works, it might be that it uses the same argument signature as the other collide scripts but doesn't actually USE all the arguments.

(1 edit)

yes I have the same error in 1.4.999, might be older versions don't have it


Yeah, I looked into the code and there's commented-out code that used argument0 in the script. Change the first line into "var a = argument0, b = argument1;" (instead of "var a = argument1;") and the error should be fixed. (The collision scripts need a certain format because they're called using script_execute() depending on the object's terrain type, but not every script uses both arguments)


Would be great if dear Yal improved this package more, so far it's bare bones. But I see the potential in here.

I searched but seems there isn't yet sort of main menu+ levels selection asset in the store here, so throwing an idea


Hello, I just downloaded the source code and I'm having trouble understanding a lot of the code. Mainly with the whole terrain and Level Grid stuff. I was wondering if you could maybe comment the code there a little more or elaborate on those a bit here? Thanks! I very much like this asset, there's a lot of good things here!

(1 edit)

Shouldn't be impossible, I'll see what I can do!

The main idea is that you make the level in "layers" corresponding to different Z layers, then the engine puts them together when the room loads (moving everything to the first layer, and adapting their Z values accordingly). It's mainly there to make it easier to design 3D levels in GM's room editor and doesn't have any benefits other than that.

(There's a bunch of backgrounds that add a grid to the Room Editor; those backgrounds are used to figure out the size of the Z-slices, so it gets a bit more WYSIWYG than if you had to keep track of a "slice_width" variable or somesuch)

There's also the terrain/ceiling-terrain (which is probably what I named "Level Grid" originally... was a while since I touched the source code last!), which is essentially support for less rectangular ground, and which can be randomly generated. Its purpose is to make the ground in outdoors / cave areas look less like it's made out of cubes, but I couldn't figure out good ways to CONTROL it from within the editor, so it's a bit of an experimental feature. There's special objects that will generate (and draw) terrain if you place them in a room, TERRAINCONTROL and TERRAINCEILCONTROL, look into the init_terrain() script (which has a commented-out block of code that randomly generates terrain) and the "field" room for an example of how to use it.

The "layers that get stacked on top of each other" and polygonal terrain features aren't mutually exclusive, either, so this could be used for levels like a tower in the middle of a forest, or such. (In Dearelict, the trees are actually just very tall cylinders with a bark texture, players just ASSUMES they're trees that stretch so far into the darkness they can't see any of their leaves. Tricks like this can be useful to save CPU power for enemies and stuff like that, GM and 3D rendering isn't really a match made in heaven...)


Wow. Okay I get it now thanks for your help and very quick response haha! This is a really awesome asset!

Another quick question, if you increase the view distance and darkness then everything works good except the lighting still seems to pop in. How can I fix this?

(2 edits)

Did you increase the size of the active region as well? (Lighting is controlled by objects, so it won't happen until they load in)

If you did that and it still doesn't work, there's a few things you could try...

  • Have lighting objects always be active, it shouldn't add too much of a performance penalty and it'll prevent them from popping into existence too abruptly. (But it WILL add a bit of performance penalty, so be careful about not having hundreds of lighting objects in the same room)
  • Try to avoid clustering too many lighting objects together, since only the 8 nearest ones are used (since there's a hard limit to how many lights the rendering system can handle) and which are the nearest ones can change suddenly.
  • It could be worth messing around with lighting sources' radius so they light stuff up less when they're far away (e.g. some code like radius = min(normalradius,<big number> - <number smaller than 1>*point_distance(x,y,player.x,player.y) ), but it could be a bit of work to fine-tune it. (The small number is the factor light radius changes with compared to distance, something like 0.25 should work well, and the big number should be the distance the light radius is fully restored, divided with the small number... if I didn't get the maths wrong, at least x3)

Okay so the problem was that only 8 lights are used at once.  Its not that big of a deal though again thanks for the help. You and your asset are making learning 3d a lot easier for me!

Hello I downloaded the source game file but whenever I boot up the game by running it in Game Maker Studio Pro. I receive this error when I press start on the main menu.

action number 1
of Draw Event
for object obj_wall_sandstone_block64:

Fatal Error: Can not create vertex buffer of size 147456 bytes
6386 vertex buffers allocated with total size of 919104 KB
 at gml_Object_obj_wall_sandstone_block64_DrawEvent_1 (line 5) - d3d_draw_wall(x  ,y  ,zbottom+0.01,x + sprite_width,y     ,ztop-0.01,my_wex,image_xscale,1)

Any solutions? I would really like to play around with the engine after paying for it.

This is the second time I've seen this thing appear, so I did a bit of research. Found this GMC topic that suggests that you should call d3d_set_identity() every 10,000 draws, when you're using an integrated graphics card you have less VRAM and that puts a hard-cap on how much 3D drawing you can do. (And I use a dedicated graphics card, so I never ran into this issue myself while developing the engine)

One way to see if it works is to just add a d3d_transform_set_identity() to the first line of the drawing code of the terrain blocks (e.g. the obj_wall_sandstone_block64 and perhaps a couple of its relatives) so that it flushes the vertex buffers occasionally... it's going to be overkill to do it before you draw EVERY piece of terrain, and it could have a performance impact, but it should solve the problem. If it solves the problem, you're pretty much good to go, and what you'd do is something like this (to reduce the performance impact):

  • Add a script called "flush_the_vertex_buffer" and set up a global counter variable
  • Reset it to 0 every step in the controller object
  • add the flush_the_vertex_buffer script to every terrain block's draw event
  • The script should increment the global counter, and if it's above a certain value (e.g. 10,000), set it to 0 and call d3d_transform_set_identity().

If you can confirm adding in some d3d_transform_set_identity() calls solves the problem for you, I'll get a fix for this into the source file ASAP.

Deleted post

Thanks, glad you like it so far! ^__^

To extend the range of sight: obj_titlescreen's Create event, the code block labelled "Init global variables". There's two variables that controls this: global.darkness (which controls how far you can see) and global.activate (which controls when stuff is loaded in). Make sure global.activate is always bigger than global.darkness, or stuff will just visibly load in and it just looks weird.

(3 edits) (+1)

Hi Yal,

I'm loving the engine and the work you've put into it, thanks!

I have two things I need help with:

-I want to alter the starting position of the bullet so it doesn't always spawn in the center of the screen, and instead I can alter it's starting coordinates so it always spawns at the tip of the gun (so I can move it left/right, up/down relative to screen, so no matter the size of the gun sprite I can always center it at the end of the barrel); I'm at work at the moment so I can't recall the exact names of the scripts but there was one with cx, cy, cz variables that I figured defined the bullet starting position, but no matter how much I played around with them I just couldn't get the desired result.

*The yellow circle is the bullet - I need it to spawn at the very end of the gun barrel*

-Another thing I need helping with is - I can't seem to find where I can set the size of the "level grid", that is, how do I define where is the border of the level itself and where the upper layers of the level begin within the room (I hope this question makes sense).

Any help is greatly appreciated!
Best regards,

First of all,  the easy thing: the level grid size is based on the width of the background you use for the level grid. (See the script terrain_flat_to_3d for the details). So basically, if you want a grid that's 2560 pixels wide, use a background that's 2560 pixels wide. Any size should work, but unless it's a multiple of your room grid size it's gonna be hard to keep objects from different layers aligned :P

For the second question... the 3D maths is kinda hard... which is why I skipped that part in the engine :P You'll need to find a reference point (e.g. the player's x, y and zbottom), then find the delta X/Y/Z to the tip of the gun, then spawn the bullet there. If you know the length of all the 'moving parts' (e.g. "spine", "shoulders" and "arm+gun"), you could just compute the X/Y/Z vectors of each part individually and then the tip of the gun should be there.

For each thing...

  • X coordinate should be lengthdir_x(1,angle against 'forwards')*lengthdir_x(1,angle against 'up')*(length of thing along X axis)
  • Y coordinate should be lengthdir_y(1,angle against 'forwards')*lengthdir_x(1,angle against 'up')*(length of thing along Y axis)
  • Z coordinate should be lengthdir_y(1,angle against 'up')*(length of thing along Z axis)

And since the spine is always just Z coordinate and shoulders are always just XY coordinates, this should be possible to simplify a bit. But yeah, it won't really get any easier than this, so guess why games like Wolfenstein and Doom had the gun in the middle so you didn't need to keep track of anything other than the Z coordinate :P


Thanks Yal! The "layering" level 3D system is very clever. Regarding the positioning of the bullets - I got that eventually resolved on the GM forum, and you are right - it's very hard and I don't think I'm yet at the level to properly utilize them complex maths and matrices needed for what I'm trying to achieve. So I guess for now I'll just stick with the "gun at the center of the screen"


Sounds like a plan... it's always possible to change it later in case you get better at 3D maths later, and working with 3D is a good way to learn about 3D, I guess :P

IMO the hardest part is figuring out how 3D vectors work (which needs linear algebra so you can actually do math with them - but you need to learn visualizing them as well in order to figure out HOW to use them for any given problem), once you've got that part down you can solve more or less any problem by doodling down a few lines on paper and putting variable names at all angles and lengths you'll need to use in the game. Don't underestimate doodling on paper, it helps visualizing stuff MUCH better than the maths formulae on their own :3


Indeed, doodling (& writing) on paper does wonders for me. Good to know that it's helping you out too, Yal :)

What is the easiest way to add a smooth crouching feature into this engine?

Nice and smooth engine btw ;)

I'd probably go about it this way, editing obj_player a bit:

  • Add a new variable iscrouching which defaults to false, is set to true in the step event whenever the crouching key is held (you'll need to edit the get_keys script to add in checks for the new crouch key) and false otherwise.
  • Add in a new code block in the Begin Step event:  when the crouching variable is true, lower zheightmovespeedmax and jumpspeed to something lower than their defaults, when it's false set them back to their default values. zheight in particular influences both the player's collision checking and where the 3D camera is located.
  • If you want the camera position to smoothly move up and down, you could use the lerp function rather than setting the zheight variable directly to the values for crouching/standing.
  • In order to avoid collision issues where the player crouches, gets under something low, and then un-crouches, you'll probably want to only allow switching from crouching to standing when there's enough free space over you that you can stand there with your original zheight. Depending on how you design your levels, though, this might not be a problem (e.g. if the player never crawls under anything and all ceilings are so high you can't bop your head into them, they can't get into a situation where this collision thing becomes an issue)

Let me know if something's unclear, and good luck :)

Would this work on GMS2?

It should work in theory (since there's compatibility scripts converting the old 3D functionality into new), but I've had some issues converting other 3D engines to GMS2 so I can't say with certainty it will. (For instance, there's a bug with drawing transformed models with <1 scaling factors that causes massive slowdowns). Still a bit torn whether it'd be better to make a GMS2 version from scratch of all my engines or convert them and try to deal with version differences.


Your call :P I bought your other engine to learn GML. There's not a lot of great source material out there. So, I'm trying to learn it all (last GM i used was 8)

At least it shouldn't be too hard to relearn Studio, it's basically GM8 with some stuff removed (execute_string() being the most important loss, a lot of people used that, and also sleep() and screen_redraw())... and some stuff added, like room/image editors where you can scroll and pan with the mouse wheel. Also, you can resize instances in the room editor now, which is wonderful for a lot of cases.

...oh, wait, you were talking about Studio 2. Derp. How do I forget things like this so easily x3

Studio 2 definitely is a bigger step up since it's based on the new stuff in Studio 1 more than it's based on its GM8 roots, but it's still mostly the same core loop. All the changes done from GM8--->GMS1 still apply, but on top of that:

  • Layers is a pretty major feature, and can be used in various ways... there's functions to only check a particular layer for instances/tiles, so you can have layers for each floor of a building etc.
  • Views has been generalized to cameras, which basically is the d3d_set_perspective() function except it now can view 2D planes as well. You can have more cameras than you have views and switch what cameras are displayed in which view on the fly, letting you make dramatic camera movements and stuff more easily.
  • Tiles has been revamped to allow autotiles and animated tiles, but this is mostly an editor thing.
  • Backgrounds and sprites have been merged into one resource.
  • Sprite editor supports layers for each subimage and you can draw while a sprite is animated, which lets you do some animations much easier.

I'm pretty new to GMS2 myself, but hopefully this helped you in some way :P

Yea, I've been trying to learn GMS2. It's a bit different than GMS 1.4 (I have both anyways so it doesn't really matter) Converting some of my projects has worked "successfully" but things dont function as they should. So just trying to figure things out xD

So am I free to use all these assets? Anyway, nice engine. I actually recently got my own FPS engine working with slopes so it's neat to see how you did it :)

Yup. They're so placeholder-y that I don't see why you would want to use them, but they're included in the price :)

are the codes commented?