Can i use this for commercial projects?
YaruFPS Basic FPS Engine
A downloadable engine for Windows
A simple first-person shooter engine (Game Maker Studio 1.4 and 2.x source file) that can be used to quickly get a FPS game project up and running. Not very advanced and pretty low on features, but that means it's easier to understand how all of the code works!
- Moving around with different footstep sounds depending on what you step on.
- Slopes in all directions.
- Two example weapons: ammo, reload animation, bullet physics.
- Fire bullets in any direction in three dimensions: the boring 3D maths is already done for you!
- Example enemy.
- Shield and health systems, dying when falling off the map or running out of health.
- Pickups for ammunition, health, and armor.
- Doors that open when you get near them and close again when you get far away.
- Levels can be designed in layers, giving simple 3D functionality to Game Maker's default room editor. Layers are placed on top of each other when the level loads.
- Seamless transition between different rooms letting you build levels made up from several small rooms.
In order to download this engine you must purchase it at or above the minimum price of $4.99 USD. You will get access to the following files:
- GameMaker:Studio 2 support update!Dec 06, 2019
Log in with itch.io to leave a comment.
Trying to add new weapons. I see your logic in the script init_weapons. However, where are you declaring the "wp_UNARMED" or "wp_PISTOL"? I can clearly see how you added items, just can't get those wp_ declared to allow more than the two weapons you have in the example.
Using GMS2 FYI
They're defined in the default compatibility location, scripts --> macros. (Lines 22-25). There's a machine gun example weapon as well, but it's sort of hidden so it's easy to miss.
Thanks Yal, great engine!
Hey Yal, nearly got it all figured out. I was trying to make some of the walls more rectangular and less squared. I used the below to do so in the draw event and it looks perfect. However, the collision box is still the full square. I made sure to also change the tops and bottoms.
d3d_draw_floor(x ,y+32 , zbottom+0.01,x + sprite_width,y + sprite_height,zbottom+0.01,my_fex,image_xscale,image_yscale)//Floor
d3d_draw_floor(x ,y+32, ztop-0.01 ,x + sprite_width,y + sprite_height,ztop-0.01,my_fex,image_xscale,image_yscale)//Ceiling
d3d_draw_wall(x ,y+32 ,zbottom+0.01,x + sprite_width,y+32 ,ztop-0.01,my_wex,image_xscale,1)//Back wall
d3d_draw_wall(x ,y + sprite_height,zbottom+0.01,x ,y+32,ztop-0.01,my_wex,image_yscale,1)//Left
d3d_draw_wall(x + sprite_width,y+32,zbottom+0.01,x + sprite_width,y + sprite_height,ztop-0.01,my_wex,image_yscale,1)//Right
d3d_draw_wall(x + sprite_width ,y + sprite_height,zbottom+0.01,x,y + sprite_height,ztop-0.01,my_wex,image_xscale,1)//Front?
Yeah, the collision code first does a standard Game Maker collision and then does a Z collision check (using a per-instance collision function to allow for things like slopes) to see if the overlapping objects are colliding vertically as well... so the collision mask of the terrain object's sprite is used for the XY collision check regardless of what you draw. If you make the walls more narrow than the sprite, you should change the collision mask to match this (either by giving the walls a new sprite, or changing the existing sprite's collision mask to not cover the entire sprite).
Neat stuff. why does the lighting appear weird at times, kind of flickers if you're not looking at a wall directly or not as bright. Also there is a little z-fighting between two floor panes, in the first room. When it switches from walking on floor_sqr256 to floor_sandstone, i have to jump a little to continue to move or it 'sticks'.
I looked into the lightning code. The problem seems to be caused by the lighting using per-vertex lighting instead of per-pixel (so the entire polygon gets the exact same lighting), which was the old "basic" lighting model... and I can't find the function to use advanced lighting in the GMS2 manual... so it might've been deprecated in GMS2, so everything uses the bad lighting model now :<
Not sure about the "floor sticking" you mention... there is floor sticking I'm aware of (go through the door to dungeon_test2 and turn right, and then exit through the archway onto the stone void), but that's caused because you end up in the void outside the level and the collision checking is simplified (no slope checks - and floors have a height of 1 so their top ends up at z = 1 while the void is at z = 0). When I test play the first room, the transition between the small hedge maze and the indoors area works flawlessly.
Hello, I just try to open with GM2 on MAC but when I try to run the game nothing happens. The workspace is empty. This is normal? Do I need to do something? Thanks.
No, it's not normal. Are there any error messages while importing the project?
Also, make sure the compile target isn't set to "Windows (VM)", it might default to that since it's what I had selected when exporting the source file.
Hi Yal !
I try to integrate the deltatime function to your engine (essential for an action game)
delta = 60/1000000*delta_time; (in obj_player's Begin_step)
What do you think is the most appropriate place to integrate him?
xspeed = median(-movespeedmax,movespeedmax,xspeed*delta + lengthdir_x(accel,direction))
But not very convincing...
It might be better to keep the internal speed computations as-is (measured in 60 per second), but have anything that changes x/y/z (e.g. "x += xspeed") take the delta into account instead ("x += xspeed*delta"). Changing the internal speed computations won't feel right until you change every acceleration, friction, maximal speed, etc... if you just change the "make speed affect coordinates" bit there's a lot less things that needs changing.
Great engine, but a few small questions:
- When you shoot straight, the bullets go straight from the center of the screen, but how do you keep them centered when you look up (ztilt)?
- The collision between the walls and the bullets doesn't seem to work...
- What's this script?
?!?!?!?????!!!!???? The script is not visible in the script list? It's a ghost script and yet it works ?!? I must have missed something...
Ditto for zcheck_script_bottom: I don't understand...
Scripts can have multiple tabs, collide_3d_circle is a tab of collide_3d. zcheck_script_bottom is a variable that's set to different variables for each terrain object, there's no actual script with that name. (Blocks use collide_block_bottom, slopes use the collide_slope_*_bottom family)
I think the collision-checking bug with bullets is because collidecheck() uses place_meeting() to check for collisions, so the bullets need to have a sprite to be able to collide with the terrain.
I think bullets might leave you off-center when shooting upwards/downwards because of the coordinate computation in the ss_pistol / ss_machinegun scripts... right now they're created at 60% off the player's height instead of in their absolute center, but the camera is placed at 80% of the player's height. (I suppose 60% felt like the height you'd have your hands at when holding a gun, if your eyes are at 80%? Or maybe it's just an oversight)
Thank you very much for the answer!
The multiple tabs of scripts I didn't know, I'm learning thank you!
For the bullets collision with walls, even putting a sprite it doesn't work (parent_bullet). But by putting code in obj_bullet_pistol it seems to work. To be seen...
Otherwise to make the bullets always centered on the screen according to the ztilt doesn't seem so obvious to me. When the ztilt is at its highest value, ztilt=-90: dividing it by 2 pulls in the middle, unfortunately it doesn't work for the other ztilt values. Anyway, I'm going to look for...
Tabbed scripts is removed in current GMS2, so don't get too used to them, I guess :P (But they will be a thing again once the 2.3 update is released, when you can define "functions" and scripts are changed into source code files)
Yes, that's correct, the different bullet types (pistol, machinegun etc) needs to have the sprite, because those are the objects that actually spawn. The parent just is a container for code / behavior they have in common.
As for making bullets always spawn in the center of the view: go into ss_pistol and ss_machinegun and change the line
n.z = z + cz + zheight*0.6
n.z = z + cz + zheight*0.8
and they will now be in sync with the camera.
A thousand thanks! Everything's working fine now! (For the bullets, I had put a sprite too small)
Sorry, two more things:
- For bullets colliding: OK, but then, if I'm on a wall, it won't shoot... but well, not too hard to correct...
- For the shooting in the middle of the screen, I wanted to say that when you shoot with the titlt at 0, the bullet goes to the middle of the screen, it's OK (imagine that your sight is in the middle of the screen). But if you shoot higher, the bullet doesn't conform to the middle of the screen anymore (it's as if your sight is no longer in the middle of the screen).
I was just making these remarks because it's important for an fps, but the engine is already remarkable!
Hi there! I purchased and downloaded the engine but when I ran it and clicked play I got this error :S
Could you please upload the screenshot directly (or copypaste the error as plaintext) instead of using a URL shortener? I have no way of knowing if that link is a valid image or a site that will steal all my credentials.
Aah yes that is completely fair enough lovely ^_^ Here ya go!
Change the first line of both the affected scripts like this and it should work:
var a = argument1, b= argument0;
Basically the problem is that the collision scripts need to take two arguments (x and y) but some shapes don't have collisions based on the x/y values, so they don't use the arguments. We can work around this using dummy variables. When the engine was originally made, it didn't matter that every argument was used, just the last... and then in the latest version(s) this was changed to require using every argument.
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).
Does this work if you export it as HTML5?
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.
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!
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?
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)
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.
FATAL ERROR in
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)
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.
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.
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!
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
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 zheight, movespeedmax 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?