Saturday, September 26, 2015

A handful of tweaks

The updates for this weekend (so far) have been a few smaller changes, none of which individually merit a post of their own. Here's what's been happening:

Lag spikes
Moving around in the world caused noticeably jumpy behavior. After spending weeks adding timers and looking at inscrutable performance graphs, I finally decided to go with my gut. At least one category of lag spikes was pretty obviously happening when the player crossed block boundaries (the terrain in Playform is divided into blocks of 8m x 8m x 8m), so I experimented with effectively disabling different parts of the code that were sensitive to block transitions. It didn't take long to find out that the major offender was the code that updates the render state. Playform has a separate thread to deal with OS I/O (specifically, to deal with all SDL-specific things, since a single thread to deal with SDL and OpenGL is not-uncommonly a system requirement), which includes things like mouse movement, window focus, and rendering.

Because of the single thread (and the message-passing style used to communicate with it), the "move the camera to where the player is" messages weren't being treated differently from the "now start displaying this piece of terrain" messages. Basically, crossing the boundary of a terrain block caused some LOD (Level-Of-Detail) switching to happen, which slowed down the processing of camera movement events (and other events, which were less noticeable, like sun position updates). The solution was to split the updates into two separate queues, and to give terrain changes their own, lower-priority queue. The code is really hacky right now (I mostly just copy-pasted code and added "0" and "1" suffixes to things). I also capped the amount of time (1ms) that a thread can spend on a given task before it "leaves work for next time". The code is starting to look a little repetitive, and I'm considering creating some abstraction for the general idea of "prioritized budgeted processing". where you have several code blocks that have some total budget, and that run in some (prioritized) specified order.

Loading Surroundings
When you start up Playform, your player hovers in the air for quite a time while the terrain loads. I'd like to say I fixed this, but the fix adds some incredible (and unacceptable) lag. I still think the basic idea is sound, though, which is that the server prioritizes "give me this block" requests from the client based on how far the block is from the player. Ideally, the load priority would also favor more recent requests within a given "priority tranche".

Biomes, Mountains
I've added a preliminary stone material for the preliminary mountain biome. This is the kind of thing that feels very productive, even though the code changes are minuscule (I'll pat myself on the back here for making some solid abstractions).



I also accidentally placed a tree.



Internal
Other than those changes, I've made some internal changes: I've created a "voxel" crate, which separates out the generic voxel-y parts of the code; and a "terrain" crate, which separates out the terrain data structures and terrain gen code. I'm creating the crates based on a loose idea of abstraction boundaries of "I want code to exist that I don't actually use, for completionist purposes". For instance, the different biome code, or the different voxel materials. Playform is built with a specific biome in mind, but I still want to have the code for other biomes lying around in the terrain crate.

No comments:

Post a Comment