Discussion in 'Work in Progress' started by Joe Ellis, Mar 12, 2018.
That's pretty cool.
I've made a first person player object and laser projectiles with collision. Also cool oldskool sprites that always face the camera like on doom and things. I've done that with a special sprite shader that gets set at the end of the draw begin event after the 3d stuff is rendered, so the entire main draw event is reserved for instances with sprites and they can be drawn using the normal draw_sprite functions in their draw event like normal, the only extra thing that's needed is to set a uniform for the sprite's position eg.
shader_set_uniform_f(global.uid_sprite_pos, x, y, z)
draw_sprite(sprite_index, image_index, 0, 0)
Next week I'm gonna make some enemy ai, I've got it all planned out on paper
I've created a saved game system, with files called Profiles.
Each profile is a node like all the other resources, and contains all the things needed for a saved game
eg. the current world, player variables like health ammo and armour, the inventory, and any global variables you wish to save.
The variables that a profile contains are fully customisable, and profiles can be edited in the editor,
they can also be created, saved and loaded in game, which is ideally what they're for,
eg. you can load and create them in the main menu and save them during gameplay, or at the end of a level.
The only thing you can't do with them yet is save the state of a level while your playing it, so every time you load a game you would have to start at the beginning of the level or at a certain checkpoint or save spot, which alot of games work like anyway, but I will eventually try to create a system for saving the state of a world, by making variable overrides for the instances and overriding whether each one is active or not, for if an enemy has been killed or an item has been collected.
I've also made a new resource type called a Preset, which is for saving instances, this is ideal for inventory items like weapons, cus they can all use the same object_index (obj_gun) but have different variables to make them the weapon they are.
You can spawn instances of presets during gameplay, which is ideal for projectiles, effects and any instances that are created dynamically during gameplay.
I've also improved the way collision is handled, by splitting it into 3 main parts\scripts:
collision_static, collision_dynamic and collision_precise.
Upon a collision, a second script is executed, which is a more specific script for that certain object_index. All of these scripts are easily defined in an instance's create event, or you can predefine them globally.
Collision_static is to check for instances that stay in the same place throughout gameplay,
like weapon pickups, health, ammo, triggers, teleporters and any static solid objects.
They get added to a grid when they are created, and any dynamic instances that need to check collision with them only have to check the current cell
they're in, so this ends up making them only need to check collision with 1 or 2 static instances at a time (if any), so this is a huge optimization
compared to every dynamic instance having to check every static instance in the level.
Collision_dynamic is to check collision with moving objects, like the player, enemies and moving platforms. These also get added to a grid but are updated dynamically ei. removed and added to\from grid cells every time they change cell.
This script is mainly used by dynamic instances to check collision with other ones, but is also used by projectiles and things that can harm characters, even though they aren't added to the grid themselves, cus characters shouldn't check for collision with projectiles cus there are potentially alot compared to the number of characters, so its much faster for the projectiles to check collision with characters in their current cell.
Collision_precise is the script I've already covered, for the polygon level collision.
It's mainly characters, projectiles and physical moving objects that use this.
For projectiles, they use a ray projection for triangles in their mask_radius.
I will have some footage of all these new things in action pretty soon.
Here's the current list of object indices, there may be a few more added but these cover almost every type of instance the template game needs.
And don't forget, they're designed to work with the preset system to make specific things, so these are very broad, general objects that are versatile.
And here's a picture of a blank inventory display:
I haven't yet finished the part where it renders the item's models, but that's next.
The inventory itself is just a 1d array, not a grid, so this makes it very versatile with whatever way you choose to draw the inventory,
there's not a set grid resolution so it can be displayed in any sized grid you want.
The inventory is designed to be a list of instance presets, which get created whenever an item is equipped.
A good thing about this is that when a preset is loaded ei. when the inventory is loaded at the start of the level,
it automatically loads the model it uses, so this stops any lag from loading models during gameplay when you spawn an instance of a preset.
Here's some new stuff I've been working on this last month or so: (sorry no screenshots)
Made saving game during gameplay possible, saving exact states of levels
Improved dynamic light handling, allowing instances to emit light and made an automatic sorting system to deal with the max light limit
Improved variable handling, reduced cpu and ram usage
Reduced amount of node types, converted alot of them to instances instead
Made better way of calculating smooth vertex normals, using more of a median approach instead of mean, which illiminates bias from faces with the same normal and makes shading on quads and blocks look alot better.
Worked out how to do deferred rendering using the application surface alone (no extra surfaces)
Created a "pre depth pass" option, which writes the world's models to the depth buffer but not the pixels' rgba, then when rendering normally it eliminates overdraw and optimizes rendering a ton when using complex shaders.
Made a pathfinding algorithm, for using with navmeshes (points linked together)
Worked out how to build vertex buffers gradually while rendering them, which has made it possible to load models during gameplay without having to make instances that use it invisible while it's loading
Improved polygon-level collision method, roughly twice as fast as it was
Everything looks great and tidy! I have seen that you make use of Constrained triangulation .
Have you implemented it in GML or is it a dll? You have done a great job with the Ui and the tools. The implementation of 3d models is great! I'm thinking of implementing something like that in my editor, it could do very well for a 3D sidescroller like Donkey Kong or Trine 1.
Thanks It's all in gml. That sounds good, I'm sure you'll have no trouble implementing 3d models, the stuff that you've done so far is more complicated than that
That's cool! For performance issues I decided to use the Ear Clipping technique, but I see your script very useful, especially for texture handling. Like your project I have decided to do everything in GML, I cannot resist the temptation to run the editor on a tablet and other compatible platforms. On the 3d, I put in the list to make a function to import models in Json format, it can be very good for the easy sending of information. Thank you very much for your comments, the same I say about your excellent work.
I've finally worked out how to do the skeletal system I wanted to use, where rotations are applied in absolute space instead of being relative to the parent bone's rotation. They're applied directly to the bone's absolute rotation matrix and the relative matrix is then recalculated. (by multiplying the absolute rotation by the inverse of the parent's absolute rotation)
You can rotate the bones to be at any angle & orientation you want quickly and easily, without being restricted to only the x, y and z rotation values.
no more gimbal lock
no more having to wrap your head around how the bone rotates due to it being relative to the parent bone.
However, under the hood it still uses relative matrices, so it's still fully compatible with other model formats.
Here's a screenshot showing the bone heirarchy, which displays in the same tree like structure as the world editor:
When you click on or move the mouse over a bone(in either the heirarchy or in the 3d view), you can rotate it using the keyboard:
< >: twist
holding ctrl will switch it to "tilt" rotation:
(which uses the view angle as the axis (can be snapped to a certain amount eg. 90 degrees))
left\right: tilt sideways
up\down: tilt forwards\backwards
You can also hold alt and use the arrow keys to move the bones' positions in world space, and it recalculates the rotation matrices and bone length based on the change. This makes it really easy to construct a skeleton and the bind pose
However if you use this while animating, the lengths of the bones will likely change alot, so I've added a "preserve bone length" option, cus normally changing the length of bones in an animation will make the characters skin stretch quite unnaturally. But this might be a cool thing with cartoony characters which is why I've made it as an option.
I'll post a video soon showing this stuff in action, hopefully it'll show how much better this new setup is.
I wanted to give abit of an update, although I've hardly got anything to show for the last few months work. I've been doing alot of deep engine level stuff that hasn't made anything look any different, but it's still alot of good stuff that I wanted to tell everyone.
One screenshot I've got is that I've added "smoothing edge threshold" as a setting for each mesh.
So it's able to have smooth shading and hard edges:
I've also merged the windows of each tool into the settings panel, so it just changes with what tool you're using. I think it's alot neater and more concise.
The rest of what I've done is technical engine things, that are getting it as good as possible.
The level editor is mostly complete, minus some functions for applying settings to all selected instances, and other handy things like that.
It now has infinite undo\redo. Although it doesn't work with deleted instances yet, you can't un-delete something, but I'll try to add that by keeping them in a "deleted items" list. There's also no undo\redo in the model editor yet, I'm starting to work out how I'm gonna do it though.
I've also started making an fbx importer from scratch in gml, so it won't need the dll anymore.
This will only work with the text\asci version, but I don't think this is a problem cus blender and most other model editors allow this.
Also with paths, created by joining points together, I've made it so you're able to make "flow" for each link between points (the direction you're supposed to move along it) which is essential for a game with cars and roads, consider police cars chasing you, every police car in the map is notified of your wearabouts and each has to plan a path along the roads to get to you. Without being able to know the direction you're supposed to drive along each road they'd end up crashing into all the other cars.
So now the pathfinding algorithm is able to [optionally] check that a link from point A to B is the right direction. By checking that point A is the 1st point in the link and B is the second, and if not, it will not consider this as a possible route and treat it as a dead end if there are no links that are in the right direction.
Also the final thing, (stop reading now if your not interested in files and data)
I've done a pretty huge optimization to the file format,
it used to work with strings for saving the type of each variable, it would save the name of the type as a string then interpret it when loading.
Now instead I've made every file save a "type list", with all the names of the types that file uses. When loading it, it creates a list of real type indices by interpreting each type name. So this has cut down the file size imensely and made it so there are only 20 or so strings that need interpreting, instead of 20 per instance.
Now all variable tables are saved with the name of each variable, and a single byte for the type index.
Also before, each instance would save it's variable table, with the name, type and value of each variable.
But the variable tables have identical var names & types per object, so only the values are unique to each instance.
So now I've made it save each table used by instances only once at the beginning of the file(the var names and types) and each instance now only saves the values of it's variables. So this has also cut the file size down alot, and made loading faster.
I've also added backwards compatibility measures, when each instance's variables are loaded from the file, it afterwards checks through the current variables table(not the one saved in the file, the one configured in the project) and checks that each variable exists,
if it doesn't it creates it and sets the default value from the table.
If it does exist, it checks the value is the correct type, eg. if it's a number it will return false if the value is a string or array.
If it's not the correct type it will set the default value instead.
So this has made all level files backwards compatible if you decide to change certain variables for objects after the file was made;
it will forget about ones no longer used that were saved in the file and add new ones that weren't saved in the file.
Fantastic, I hope the world is aware of the unique value of the new tools that are yet to come for game maker. A need that many people were asking for is being met. Keep up the great work Joe !!