Support Me on Patreon

Tuesday, April 30, 2019

Stepping through the halls.

I'm currently working on buildings for Adventures' EDGE. There are almost a dozen I have to complete before I can build the towns. This will allow me to quickly build most of the maps and test the world data. Afterwards, I'll be adding content. I'm cautious about creating a save/load system in case I have to add information to it later. Might draw the character portraits to practice raster drawing.

I'll be able to record videos again soon, I've got an area to do it. I'll be posting them on my youtube and here as soon as I start. This will include gameplay, tutorials, and me just showing my assets for the games I make.

While assets take the longest time, buildings are especially tough. They tend to be large and unwieldly. I'm not using separate interior maps, so that make things a bit harder. The lazunas will also take some time, since they also need animations, but I can add them individually. I want to complete the buildings because I don't feel like re-doing towns every time I complete a building.

Monday, April 22, 2019

Why, Godot?

Not that anyone's asking.

No game engine is 'perfect', they all have flaws.

I started with the blender game engine, sometime around 2.37a (or b). At the time, the game engine seemed great and I'd defend it in forums. Blender's 3D modeling and rendering was great, the game engine sucked. It was slow, laggy, and took quite a bit of work to get anything good, but it was my first.

I still use blender because it is a great free modeling  program. They mostly dropped the game engine to focus on what makes blender shine.

I learned many tricks for increasing framerate. From faking rain by shuffling the position of existing raindrops, to optimizing the improvised menus. You had to build the menu out of 3D objects; quite laggy. Blender did allow you to layer scenes to make easy skies. Godot doesn't do that.

Later I tried a few other engines. Unity was 'good', but large. It was faster to get results than blender, but very large. Menus had to be laid out in code. You had to log-in even for the free version, and I don't have internet at home. The engine did allow you to set-up a camera trick to easily create dynamic skies, Godot doesn't allow that.

I've used Godot since it went public, and the sky has always sucked. You have to use 3D objects and a shader for dynamic skies. The environmental sky is quite laggy when you change its parameters while the game is running.Godot has a few other quirks that I have to program around.With its nodal setup, creating levels is easy. What it excels at is menus. You can make a robust dialog system using just the rich text label, a couple scripts, and a bit of bbc code. It auto-wraps the text and can grab meta-data passed from dialog choices. Tabbed menus are easy with little to no coding and the resource preloader links to any resource you could need (texture, text, script, scenes). Replacing a scene with one from a resource preloader causes a crash, but it is great for scenes being added.

Godot's small size and quick scene creation is great. I've been able to use most of the tricks I used from blender and have even created new tricks. The nodal setup gives more control than most engines. Replacing nodes is easy in games, but it doesn't replace the children. Navigation through meshes is spot-on, as long as the nodes are arranged correctly. You can re-arrange nodes during gameplay to help with navigation. In the end, I use Godot because it handles most of the minor stuff I don't want to (like word-wrap and resource handling).

You just need to code around it's flaws and features.

Friday, April 12, 2019

Godot 4 it animation discussion.

This post is for the 3D aspect of the Godot Engine and contains heavy speculation.

Skeletal animations tend to be the biggest bottleneck in game development. Despite the power of an engine, it always seems we need more. Here I'll speculate about improvements that could be made along with some tips to squeeze out those last few frames.

Let's look at how I understand the workings of animations.

Skeletal animations usually have groups of vertices 'attached' to specific bones. Every frame those bones move, the engine has to recalculate the entire mesh. That is the main reason animated objects give more lag than static objects.

2D animations just replace a sprite/image with the next frame. It is similar to a flipbook and nothing has to be recalculated. Even 2D animations using skeletons just rotate images, so there is less to recalculate for each frame.

Non-skeletal animations for 3D objects (Rotation, changing scale) have less impact on the engine. Thus, having slimes just change their scale as an animation can help you achieve more slimes on screen. I haven't tried this in Godot, but I assume this is how slime rancher handled animations.

If the engine recalculates each mesh, why can't it keep the mesh frames and just reuse the data? This seems like a good idea, baking the poses into separate meshes, but it could consume too much data.

Blender can turn animation frames into shape keys. Deleting that shape key last freezes a mesh in that pose.
I've tried this, swapping the different meshes, with mixed results. This method is useless if you need to combine animations. Swapping meshes doesn't conserve many frames either, but it could be useful for very small animations.

Animation baking just fills in keyframes between frames or makes keyframes for simulations, resulting in slightly less calculations.

If all of your characters weren't animating every frame you could get some more characters onscreen.

If you cannot re-use a frames calculated mesh (I'f tried and failed), then maybe you could split the animations across frames.

Most game engines can update an animation by an amount (usually the Delta or a single frame). The Delta is the time between frame draws.

In an autoload script, you can setup a variable (boolean works best) and have it bounce between two different values each frame.

var frameGroup = false


frameGroup = !frameGroup

Then  just give each animated character a variable for the 'group' it is in and set it true or false. You can load each character individually and make sure the groups are distributed evenly.

var animGroup = true
or
var animGroup = false

Load character
get current  group variable from autoload script
Set character group variable
change group variable in autoload script

Or you can just randomly set the animated character's group variable on load.

Now you just update the animation when the frameGroup and the character's group are equal. Remember to double the amount you progress the animation to cover both frame's updates. This allows you to split the animation load across frames.

More than two groups can be used, but the animations start to look jerky depending on the framerate.

I have tried this in a few versions of Godot with a 25%-50% framerate increase. It doesn't exactly double the amount of characters you can have on-screen, but it does give a good boost for minimal work I plan to include this in Adventures' EDGE soon.


Other options to reduce load from animations is just not running them. Only run the animations when near the player. You can put the player node into an actual group, look for that, and check the distance to the player.
(most games have a copy of the player in each map and the player never 'leaves' the map. If the player ever has to be removed from the map, look into using weakref() )

Hiding objects that are too far away from the player can also help, but I think animations are still calculated (not sure).

Tuesday, April 9, 2019

Navmeshes and YOU!

Navmeshes and YOU!



Godot 3.1 tutorial

You should be familiar with the basics of the Godot Engine.
If you cannot make a moving character this tutorial may be too advanced.

This does not cover gridmaps, tilemaps, or 2D maps. Some of this might apply anyway though.



Chances are that you've looked at the navigation demos for godot. It shouldn't matter if you have, but it can help.
That demo just has a single navigation mesh. This will cover tips when you have more than one navigation mesh.
Let's look at some basics.

A navigation mesh, or navimesh, is basically a path that objects/NPCs/enemies can use to navigaet around a map.
Navimeshes can be generated from scenes or existing meshes. I prefer to model my own navimeshes and create them from a mesh instance.
Just add a mesh instance and set the mesh you want to make a navimesh from.
Select the mesh instance and use the mesh button in the top center of the 3D viewport.
Choose Create Navigation Mesh and move the navimesh where you want it, or save it to a file.


If you select a navigation mesh node you can bake a mesh from a similar menu.
You must have a new navmesh to do this.
I won't be covering this as I've never done it satisfactorily.



The navigation node is the powerhouse of path-finding. It can be used to generate paths.
All you have to do is add it. Here comes the complications.

Let's go over the problems you might find working with navigation nodes and some solutions.

Navimeshes must be children or grandchildren of the navigation node. Any deeper and they won't work.
If your scene is comprised of smaller scenes, this can be a problem.
You can add the navimeshes to a single group and make them direct children of the navigation node.

*Since godot gets direct references to nodes, changing their parent is relatively safe.
**You should be able to do this for most nodes, but be careful if you rearrange too many nodes.
***I haven't tried this with weakref()

This script is a bit of a hack, but it works well:

func reparent_by_group(group):
    navNodes = get_tree().get_nodes_in_group(group)
    for i in navNodes:
        var gPos = i.get_global_transform()
        i.get_parent().remove_child(i)
        self.add_child(i)
        i.transform = gPos
       
    print(self.get_child_count())
    pass

   
*I add pass to all my functions since I sometimes write numerous functions at a time.

Let's look at path generation

get_simple_path( Vector3 start, Vector3 end, bool optimize=true )

This creates an array of Vector3s to generate a  "path". Running it too often causes lag.
The start should be the NPC's translation or transform origin (get_transform().origin)
End should be a Vector3. Using the translation or transform origin of a node is a fine idea.
Travel to each point by using the look_at( Vector3 target, Vector3 up ) function.
Make a variable to keep track of which point you are moving to.
Add to the variable when you get close to the point. Use the Vector3().distance_to( Vector3 b ) function.
Again, NPC translation or transform origin is acceptable for the first Vector3.
When you run out of points, regenerate the path. Keep this up until you are near your goal.

If you are using node positions to navigate to, there are a few things to watch for.
Any nodes in nested scenes (child,grandchild) will cause the NPCs to converge around the map center or similar area.
Using get_global_transform().origin to generate paths caused lag.
Reparenting the nodes is a 'safe', simple option. Be sure to apply any groups or modifications to the nodes before reparenting them.
You shouldn't have to rename the nodes, the engine seems to do it automatically.

That should fix the majority of the problems you'll come across.

Working with multiple navigation meshes:

It may not be feasible to model one large navimesh for everything.
Building a game from numerous smaller scenes or reusing assets can complicate things.
You can use several navimeshes, but there is one thing to remember.

The meshes should have faces that line up perfectly.





Snapping vertices to the 3D modeling grid, and using snapping in Godot, will help.
As long at two meshes have faces that are vertex-perfectly aligned a path can be made including both meshes.
Any gaps, overlaps, or misaligned vertices can cause problems or mistakes.

Just make sure things align like a puzzle and everything will work well.