Tidy Up
After finishing the
game-jam there were a few things I needed (wanted) to do before uploading it
for anyone to play.
- Rendering stutter - performance on lower spec machines was terrible.
- Collision and physics - so you could walk around the maze, confined to the rooms.
- Additional detail - the walls were a bit plain and were supposed to be brickwork.
- Difficulty tweaks - The maze size should have been linked to difficulty and I wasn't sure if it was fair.
I didn't think it
was unreasonable to try and polish off these issues as they were either a bit
of a show-stopper or had already been started during the jam.
Render Performance
It seemed that
slower machines and particularly ones with only a couple of CPU cores suffered
badly from low frame-rate and bad stalls whilst moving around the maze. I had a few ideas where this could be, but
really needed to gather more intel.
There were several avenues of investigation I could use:
- I started with the Remotery integration already in Apparance, to get some ideas what was going on.
- Running the GPU and CPU profiling tools in Visual Studio.
- Adding hard coded timing and logging to suspect areas of the engine.
I wasn't having much
luck and after a few red-herrings I wondered what else I had changed or added
in the past that could be causing such issues.
It was a tricky issue to diagnose as there are various systems between
the camera movement and the rendering that could be at fault. Performance on my main dev machine (many
cores) was fine so I suspected something to do with the threaded-rendering or
main message loop could be to blame. To
resolve this I tried a few things out of desperation:
- Boost the priority on render thread.
- Boost the priority on the main thread.
- Run the renderer on the main thread (single-threading model).
- Switch message look to non-blocking (needed for 3).
I made these
command-line switchable so I could try different combinations on a couple of
machines.
The priority boosts
made no noticeable difference, but running the renderer on the main thread did
help on machines with only a couple of cores.
My investigations
eventually lead to two things that seemed to explain my woes.
- My slightly hacky camera smoothing system was completely broken.
- I was logging synth errors to debug output.
The first one was
only showing up on slower machines so I just disabled it (something to revisit
later). The second should have only
affected development and debug builds of the engine or when running under the
debugger, however I disabled it anyway.
Once all these had
been fixed and tweaked, performance was much better and so I moved on to
collision.
Collision and Physics
Aware that
implementing a physics engine is no light-weight task, I tried to keep it
focused and simple. I have implemented
this sort of collision successfully before for an experimental Quake clone
built in .Net and set in a cube based world.
The collision requirements there were sufficiently constrained that it
wasn't too difficult to do. Based on
this previous experience I decided I could get it done quickly.
After an initial
late-night foray into hacking together a solution during the jam itself I
decided to try and finish this implementation.
My proposed design
went like this:
- Meshes can be tagged with a special material that signifies collision properties.
- The material will normally be hard wired not to render anything, but can be enabled to visualise the collision surfaces.
- The engine will gather together any meshes tagged in this way that are within a certain bounds around the camera.
- A custom camera controller (similar to the free-cam one) will handle FPS style player movement.
- This controller will hook into the engine to request collision information.
- Based on this information, collision tests and simulation will be performed to give the impression of solid walls and floors.
- A Sphere-Triangle Swept collision test would be used to implement this.
I had most of this
working during the game-jam, but didn't get the actual motion sim and collision
working well enough. This is what I
spent most of the follow-up time on. I
got quite close, with floor and wall collision generally holding up smoothly,
but the wall collision was still jittery and there were plenty of failure cases
where you could fall though the geometry. I also found it was going to need the collision geometry to be handled quite a bit differently with regard to detail levels than regular geometry. This would be a lot of work.
In the end I decided that I was flogging a dead horse and should leave
it out. I didn't want to spend the
additional time at this stage.
Additional Detail
The walls I had used
to build the maze rooms were using a brick wall procedure written ages ago, and
did include additional brickwork detail, even down to modelled bricks and
mortar between them. However, they were implemented
before the current detail management system was in place and I was still
working out how detail was controlled.
The wall procedure had a manual detail level control that you had to
drive at the top-level. Unfortunately
this didn't integrate well with the block based detail control and couldn't be
used. I would have had to re-do the
brick wall procedures from scratch and I just didn't have the time.
Difficulty Tweaks
This was one thing I
did manage to have a go at, and the maze size now increases with difficulty
setting.
Release
I had already set up
the release build generation process so it was simple to package up a build for
upload. The final zip file was almost
exactly 1 MB which was a nice size to show the compression at play with procedural
generation.
The game is
available to play via:
I also submitted it
to The Procedural Generation Jam that
was going on at the time:
It even got included
in a Let's Play of all the entries by Jupiter
Hadley.
https://www.youtube.com/watch?v=-NtPCzF2mZI
(it's the first one at 00:54)
Download it and have
a play!
(Oh, but don't
forget to pretend the walls are solid :O)
No comments:
Post a Comment