File conversions

Planning and Development, World Editor

I have now converted all of the art assets for Penrith Forest into glTF files.  Before I had a mix of .json, .fbx, and .gltf/.glb files.  While I was doing this I created collider meshes for all the assets that needed them.  I also added in the ability to load double sided meshes.  By default meshes created by THREE are one-sided.  This is an optimization that prevents WebGL from drawing triangles that are facing away from the viewer on the assumption that these triangles will probably get drawn over anyway.  This works fine for most things but for very small, simple objects like grass and flower petals I need the material to be visible from any angle.  This is accomplished by simple putting the word “(Double)” anywhere in the material name in Blender.  This name gets exported and the object loading code looks at the name of each material getting loaded, and if it contains “(Double)” it sets that material to double sided.  This only has to be done once, when the asset is loaded, so it shouldn’t have any real effect on performance and will allow me to make all kinds of foliage as simple planes.

The next thing I need to do is clean up and confirm/re-implement the terrain editing and painting code.  I had this working at one point, but I’ve changed quite a bit over the last several week so I’m guessing it’s at least partially broken.  Once this is fully working again, I’ll put some time into the design and layout of Penrith Forest.

Frustrations and perseverance

Planning and Development, World Editor

I was plugging along converting my tree models to glTF by exporting them out of Blender as .glb files and replacing the references to the old .fbx files in the map when I found a piece of weird behavior.  The glTF files I was loading into the world editor moved strangely.  It seemed like each individual asset would move differently when selected and moved.  This made absolutely no sense because the code to move any object is the same for all objects, but I could see it happening.  I’ve now spent a few days investigating this and I finally figured out it was a bug in what I was selecting.  My assets are structured like this (for now):

  • Scene (Scene)
    • Collider (Mesh)
    • Asset (Group)
      • Asset Mesh_0 (Mesh)
      • Asset Mesh_1 (Mesh)
      • etc.

OR

  • Scene (Scene)
    • Collider (Mesh)
    • Asset (Mesh)

When an object only has one material applied to it (which will likely never happen with a production asset) the exported file contains a Scene object named “Scene” with two child objects that are Meshes, an object named “Collider” and an object named “Asset.”  If an object has more than one material it follows the same patter except that the object named “Asset” is now a Group and contains children, one for each part of the Mesh to which a particular material is applied.  So if the asset has three materials, there will be three child Meshes name Asset Mesh_0, Asset Mesh_1, and Asset Mesh_2.

Updating my selection code to handle both possibilities was not terribly difficult, but it took me a while to actually figure out this structure of the exported files.  I’m sure it’s documented somewhere, but I’ve never actually seen it.

The problem I was seeing was caused by selecting the wrong object.  If I select the Asset Mesh or Group then move it around, its transform is still ultimately affected by its parent Scene object.  So if I move a selected Group like this strictly along the x-axis, but the parent Scene object is rotated along the y-axis, the resulting movement will be unexpected and it will move off of the global x-axis.  Since each Scene object is rotated when it gets loaded I was seeing different translation behavior for each object and it was very confusing and frustrating.  Now that I understand the structure of the loaded files a little better I can select the root Scene object and move it, and everything works the way I want it to.

One of the primary lessons I’ve learned through this whole project is that I have to just keep looking at it.  When frustrations come up, and many have, if I just keep working on it a little at a time I will eventually get past the problem.  Just last night I was seriously considering scrapping the whole thing and starting over with a 2d game engine like Phaser.  Now I’m glad I didn’t because I didn’t even have to change much to make this work, just invest some time and effort into understanding what is actually happening inside THREE.

 

Deciding what to do next

Planning and Development

I’m actually struggling a bit with deciding how to move forward.  There are still many, many things to do before I have something that could be considered a working game, but figuring out where to focus next has been a bit of a struggle.  I’m honestly still a little shocked that my implementation of the collision detection system actually works.  I need to rewrite that whole thing, but I’m hesitant to mess with it because I don’t want to break it and waste time.  I know I talked about broad phase collision detection and spatial partitioning, but I just really don’t feel like diving into either of those right now even though the broad phase thing should actually be quite easy.

I’ve committed to using the glTF format so I’ve been recreating the assets I have now as glTF files.  I also created a pretty nice looking fishing shack that I’ll stick into the world once I figure out how I want to handle water.  I guess for now I’ll continue converting/improving my art assets and working on the world editor.  The editor still works but it really needs to be cleaned up and have some more convenience functions added.  I don’t particularly like working on the editor because it doesn’t always result directly in a new feature in the game, but it’s a necessary tool and requires time, so I guess I’ll just keep plugging away at it.

Gravity

Planning and Development

A basic, working system for gravity is now in place.  Eventually I would like for gravity to work a little more realistically because right now you fall at a rate of 9.81 m/s, not 9.81 m/s².  This isn’t a huge deal, but eventually I want to make it so that falling off a cliff means the character’s falling speed increases until he hits the ground, then use that impact speed to determine how much, if any, damage the character should take in the fall.  Still, I’m really excited a player can now stand on top of a box, or a fence, or whatever.  There is still plenty of adjusting to do.  For instance, I’m not sure what would happen if a player stood on a sloped roof.  My desire is that a character would slide down a steep slope but not on a shallow slope, but that will likely come later.  Now that the major pieces of my collision system are in place, I absolutely have to spend the time to refactor that part of the code to be more usable.  That will take at least a few days, but I’m happy to be moving forward again.

More collision detection

Planning and Development

I have incorporated the collision detection system in its current state into the game engine.  This took some time because I was fighting with the Blender-to-THREE workflow again.  Here’s a little sidebar on that.

The recommended file format for working with 3D assets in THREE is glTF.  This format is maintained by Khronos Group and includes important features like materials and animations.  Unfortunately, it’s also been a huge pain to work with so far.  Creating assets in Blender then exporting them to glTF seems to work fine, but working with the imported assets in THREE is just quirky sometimes.  When you import a file it is added as a Scene that you then have to add to an existing Scene.  The geometries are all BufferGeometry objects (which is actually a good thing for performance, but difficult to work with) and you just have to really work at getting things to line up just right.

I wanted to be able to model an asset in Blender, model a collision object separately but in the same file, then import the file with THREE and tell my collision detection system to use the hidden collision object.  This way I can make the asset somewhat complex but still keep a simple collision cage for performance reasons.  I don’t think this should be complicated but I struggled with it.  Partially I still have trouble with asynchronous aspects of Javascript programming and so I was just confused.  Partially it’s just somewhat difficult to do what I want to do with THREE.

After quite a bit of tinkering my system is now working.  I have a weirdly shaped concave object with a separately modeled (also concave) collision cage that I put into a map file.  My engine loads the asset, recognizes the collision cage, and the collision system responds correctly when you walk around it.

This is a big step in the right direction.  Next I still need to do pretty much everything from my last post, but I have a working system already integrated into the rest of the engine.  Hopefully this will keep me motivated to finish the code rewrite, implement gravity, blah blah blah.

Collision Detection

Planning and Development

I’ve been rewriting the collision detection system for the last few weeks.  I have looked at several different collision detection algorithms over the years but the one that I keep coming back to is in a paper by Kasper Fauerby at peroxide.dk called “Improved Collision detection and Response.”  The primary reason I kept going back to that one is that it included information on the response step, not just how to detect collisions.  Unfortunately, it’s a little tough to follow in places and his code listings are in C++, so taking those and converting them to Javascript has been tricky.  After several attempts with varying degrees of success, I think I finally have it working.  I have a test scene with a sphere that just moves around the x-z plane.  I placed a few primitives (boxes and spheres) and a more complicated object modeled in Blender into the scene.  Without gravity it appears to be working perfectly right now.  The algorithm handles multiple objects close together and non-convex objects as well.  I only have a few objects in the scene but I don’t see a significant impact on performance so far.

This is very, very exciting as is but there are several things I need to implement or improve:

  • Code refactoring
    • Up to this point I’ve been trying to transcribe the paper’s C++ straight into Javascript just to keep things simple.  There are some C++ conventions that just don’t make sense in Javascript (like reference variables) so I would like to rewrite the whole thing.
  • Gravity
    • The Fauerby paper actually includes some information on how to implement this, so hopefully it will be easy.
  • Broad phase collision detection
    • The current implementation runs the rather expensive collision detection algorithm on every object in the scene on every frame.  This is fine for a very limited number of objects but I need to implement a broad phase that can quickly eliminate objects that are far away and thus cannot collide with the player.  THREE automatically generates an axis aligned bounding box (AABB) for every object in a scene, so checking against those is likely the way to go.
  • Spatial partitioning
    • In addition to a broad phase, I would like to use something like an octree to further optimize the collision detection system.  There are lots of good articles on this concept, but I probably won’t implement this immediately.

There are other things to do but these are the big ones.  I’ll probably spend the next several days rewriting the code, then stick in a broad phase check, then put the code into the game.  After that I’ll work on gravity, and save octrees for another day.

Overall I’m very excited because a reliable collision detection and response system will allow me to make a basic world that feels interactive.  I can then build off that by adding more “game” type features.

More animation problems

Planning and Development

Undoubtedly the biggest frustration I’ve had working with THREE.js is loading and animating objects modeled in Blender.  The tools just aren’t very polished yet and it drives me crazy that so many things work so well but that process is basically broken.  I’ve noticed on my older development machine that the created SkinnedMesh objects work differently than on my (somewhat) more powerful machine.  Specifically, I get this weird jittering action on loaded gLTF objects whenever the object is any distance at all from the origin.  This is a known issue in THREE.js and has to do with matrix transformations being performed in world space instead of local space, but I’ve looked at the code and I get lost immediately.  I just don’t understand the animation system as a whole well enough to contribute anything of value.  It doesn’t happen on every machine, which makes it all the more frustrating to troubleshoot and makes me wonder what else behaves differently on different platforms.  One of the primary advantages of using a browser and WebGL is (I thought) consistency across platforms.  It’s still open as a bug in THREE.js, so I’m hopeful that it will get fixed one day, but for now I will just see weird jittery animations sometimes because it isn’t worth the time to try and find a workaround right now.

My next step is to do a little painting of the Penrith terrain, just so it looks a little nicer.  Then I’m going to tackle collision detection again.  That’s always been a big hangup for me but if this project is ever going to get off the ground I absolutely must have a reliable way for players to collide with and react to objects in the world.

Status update

Planning and Development

My new machine isn’t here yet.  I’m expecting it Saturday.  Still, I’ve been diving back into the codebase the last few days and continuing the reorganization project.  I’m now back to basic “walk around the map” functionality.  No collision detection, other than not falling through the terrain, but you can zoom the camera in and out.  I’ve also been working on some of the substance of the game since I really need to know what I’m building at this point, so that’s been helpful.  Penrith will still be the game’s starting area, but I have the first region semi-mapped out and a general scale for the whole game.  Lyridia is going to be a big place.  Or, at least it can be a big place.  The island is about 10,000 km².  That’s roughly the size of Jamaica.  Of course none of it will actually exist until I make it, but that’s the plan for now.

New development machine

Planning and Development

I’ve ordered the components for a new computer to use for game development.  I have been working on an old machine that was generally good enough, but I was just getting tired of it.  I ordered everything around a week ago and I’m still waiting on a few things to show up.  Once everything is here and the new machine is built I’ll dive back into development on the game.  I’ve been a little lazy/distracted the last few weeks but I’m definitely planning to pick back up soon.

That was quick

Planning and Development

I was able to implement the ability to save heightmaps and colormaps in the new world editor pretty quickly.  This is just a quick draw in the editor, so it’s definitely not a finished product and it doesn’t even look exactly like the game because it’s rendered by the editor, but check it out:

You can see here that I was able to draw some green for grass, put in a very basic path, and then put some snow on those little mountains in the background to the left.  You can also see the weird orange color I used as a base and didn’t draw over in the background to the right.  I’m really excited about this because I can now easily make terrains that are interesting and colorful, and that should allow me to really start fleshing out the world a little better.  Without a tool to mock things up, it’s sometimes hard to even imagine how the world will work, but now I can make assets for the world then just place them in an area and tweak both the asset and the world around it.  Super exciting.