Well, it’s hard to believe it’s already been over a month since I last posted. The good news is PV development is still going strong! I’ve been neglecting to write a new post for a while, mainly due to the fact that I keep forgetting to write one, and the fact that what I’ve been working on is mostly behind-the-scenes stuff and bug fixes.
For now, I’ve stopped working on the VBL Editor. As it stands, it has enough features and is stable enough for me to start basic development of Project Voxel itself. There are definitely more features to be added in the future, but I’m not going to worry about those right now since I want to create an actual game prototype first.
So at this point, you might think I’ve started development of PV, right? Not quite. I’ve actually started another (PV-related) project that I have had planned in my mind for a little while! It’s currently in its early stages, but is shaping up quite well and should take far less time than the level editor.
I’m not quite ready to talk about the new editor yet (mainly because it’s kind of underwhelming in its current state), but I will definitely give more information about it once it’s developed a bit more. That shouldn’t take too long (I hope).
So that’s essentially what I’ve been working on for the last month or so. After I finish the new editor, I plan to finally start work on Project Voxel itself! Both the level editor and the new editor are pretty critical to the core of PV, so they both need to exist before I start work on it. The concept of PV has also undergone quite a few changes over the last couple months, which is something I’ll talk about more as I start development on it.
P.S., I realize I haven’t really offered any way to ask questions about PV or anything else I’m working on. So if you have a question you’d like to ask me, use Tumblr’s nifty ask questions form, which is now linked to at the top of the blog, or simply email firstname.lastname@example.org. :)
Well, probably not. But it’s definitely almost complete enough for me to start PV.
Lots of new features! By far the biggest feature I’ve added is chunk loading/unloading. Chunks can now be loaded/unloaded from disk storage. Chunks that are further than the view distance from the camera are unloaded. The load/unload times are still a bit slower than I’d like them to be, so hopefully I can optimize those a little more. (And, I haven’t tested it yet, but infinite maps should be possible without any problems now.)
Props are also now mostly finished. There isn’t much to say about them, except that they’re basically grid-aligned entities.
And finally, I added a ranged placer fill in the level editor. It takes a begin grid position, spacing, and either and end range position or a placer repeat count, and then fills that area with the active placer.
Oh yeah, and after doing quite a bit of bug fixing and code refactoring, RAM usage is down 10-50% in most scenarios.
Right now, I’m in bug-fixing mode with the editor. Once I finish up a few more smaller features and make sure nothing is too broken, it’ll be time for me to move on to PV itself (or will it?). It’s a pretty exciting time. :)
I’ve actually had resource loading done for a while now but I’ve neglected to make a post on it until now. For now, resources can be loaded via C++ DLLs. The way it works is that it looks for a method in the DLL called “GetVBLFactory”, which returns a pointer to the se::ReflectionFactory of the DLL for VBL-based objects (ReflectionFactory is a class that emulates the behavior of true reflection in other languages. You pass in a class name as a string, and it returns a new instance of that class type).
Beyond that, most of what I’ve been working on lately has been in SEFW, my framework that Project Voxel and the level editor use. There were a few things I’ve been meaning to redo for a while, as well as some features I’ve been wanting to add, so I’ve been working on those the last couple weeks.
Perhaps one of the most simple changes I’ve made in SEFW has resulted in the greatest performance increase for rendering, and it’s thanks to me looking at the DirectX debug runtimes and reading a bit of the Direct3D documentation on MSDN. I was changing some things around in SharedVertexBuffer, SEFW’s vertex buffer manager backbone, when I decided to look at the method where all the vertex data is committed to the Direct3D vertex buffers.
Anyone who’s worked with Direct3D before will be familiar with the concept of locking and unlocking vertex buffers. When you lock a vertex buffer, there are a number of lock flags you can specify, and a lot of them can greatly increase performance. However, many of these flags are very context-specific. For example, you can only specify D3DLOCK_DISCARD if the vertex buffer you’re locking is dynamic. Earlier, when I was debugging something using the D3D9 debug runtimes, I received a performance warning saying that there were subsequent locks without D3DLOCK_DISCARD or D3DLOCK_NOOVERWRTE. Curious, I decided to read the reference page on buffer locks and check out D3DLOCK_NOOVERWRITE since I had never used it before. This is what it does, according to MSDN:
Indicates that memory that was referred to in a drawing call since the last lock without this flag will not be modified during the lock. This can enable optimizations when the application is appending data to a resource. Specifying this flag enables the driver to return immediately if the resource is in use, otherwise, the driver must finish using the resource before returning from locking.
So basically, provided the buffer is dynamic, you can use this flag so long as you don’t plan to overwrite existing data in the vertex buffer contained in the part you’re locking during the current frame or data that was referenced in the last draw call. SVB commits data to the buffers once per frame sequentially, so I figured I’d give it a shot to see if I got any performance gains from it.
And holy shit, my average FPS in world_1-1.vbl shot up from about 400 FPS to about 900 FPS! Just from specifying that lock flag! So for anyone who feels like reading the documentation isn’t worth it, you’re potentially missing out on some very significant optimizations. And besides that, it’s always good to know the tools you’re working with well.
Some of the other additional major changes I’ve made:
- se::VertexList (and subsequently, se::Shape) no longer take primitives per instance and vertices per primitive as template parameters, and are now passed via a constructor. The fact that these are no longer compile-time values allows for dynamic shape creation (SVB-based meshes eventually?).
- Added the ability to purge window message handler events from se::AppWindow tied to a class instance object. This gets rid of the dangling message handler issue I had.
- Fixed crashes when resetting Direct3D devices and resources.
- Message handler functions are now passed the HWND source of the message, as well as the relevant WPARAM and LPARAM.
- Added proper window resizing to the VBL Editor. Both the GUI and the rendering window resize correctly now.
What is this, an editor for ants?!
I’m pretty much done working on SEFW for a while, so I’ll probably start working on implementing props in the editor next. The editor is starting to near completion now (at least, complete enough to start working on real game content), so I’m pretty excited!
Well this last week has been one of my most productive weeks in a while, since I’ve had a surprisingly small amount of homework/studying to do this week. It’s good to finally be back to programming games, and not doing systems programming on Unix in C (no offense, systems programmers!). Anyway, here’s some of the newest features:
- Added the ability to add entities to placers. Entities can be placed with voxels simultaneously (along with props in the future). Like voxels, entities are moved along the grid (but aren’t grid-aligned).
- Took VoxelSelection class and made a generic Selection class. VoxelSelection now inherits Selection.
- Created EntitySelection class. Contains selected entities.
- Added entity highlighting. Entities are now highlighted when moused over.
- Added entity selecting. Entity selecting is intertwined with voxel selecting, so there’s virtually no difference between selecting voxels and selecting entities.
- Entities can be moved finely with arrows keys and page up/down keys.
- Entities can be moved along the grid if selected and left clicked.
- Placers are hidden if selecting objects.
- Changed placer icon generation algorithm so icons look better. Now generates icons for entities (…sometimes).
- Fixed bug where newly created placers aren’t automatically selected in the GUI.
There’s still a few minor features I need to add, like collision-based entity removing when removing data from the level with a placer, and there’s still plenty of minor bugs I need to fix, but entity placing at this point is pretty much done. I think I’m going to start working on loading level resources (i.e. classes) from DLLs so I can start working on content importing in the editor.
I added very basic entity placement functionality to the Placer class. Entities aren’t grid-aligned, so I still need to make it so you can adjust the position of them more finely. There also isn’t any Entity selection/deletion functionality yet so I still need to do that.
Once all of that’s done, though, I should be able to start working on content loading from DLLs/Scripts, which should make modding/new content pretty easy in the future.
Recently, I’ve mostly been working on bug fixing leading up to the entity placement. The overhaul I did of the grid system seems to have given everything a bit of a speed boost, so it was worth it in the end. And because Fraps didn’t record the actual editor GUI, here’s a screenshot of everything:
- Got rid of GridSector/GridCluster/GridSpace classes and made a more simple and elegant Ortree class (Ortree meaning an orthant tree—Similar to an octree but not strictly 8 children per node). Functionally, it’s equivalent to the previous version, but uses less code and is much more friendly to use and traverse.
- Added SetGrid() method to GridObject class. GridObjects are now by default expected to add themselves to a grid through the SetGrid() method, rather than calling SetObject() on a Grid.
- GridObjects now hold their position relative to their parent container, rather than a somewhat arbitrary “global” position.
- Redid Placer class. Now, instead of Placer being an abstract parent to different types of placers, the Placer class can place voxels, entities, and props simultaneously. Currently, only voxel placing is implemented.
Wall of Bugs
Terminal node lookup method fails at second level of the tree/gives inaccurate results Second half of level is loaded on top of first half
- Voxel click detection is broken
- Adding and removing voxels sometimes causes crashes
- All placers are always drawn at (0,0,0)
- No depth ordering amongst translucent blocks
- Clicking is slow and seems limited (probably Qt)
- Voxel select doesn’t use scroll bar and just compresses icons
- Placer icons are buggy
- Creating a new world when one is already loaded crashes the editor
Most of the things I’ve added and changed are under the hood stuff, so there really isn’t much of a visible difference from the previous build. Right now I’m in the middle of fixing some bugs that are the result of me rewriting the tree structure of the voxel grid. Once those are fixed, I can fix a few minor bugs in the new Placer class, and then focus on adding entity placing.
After entity placing works, I may either take a break on the editor and start some rudimentary gameplay mechanics, or work on prop placing (and defining what a prop is exactly). Lots to do!
As anyone who reads this blog has noticed, I haven’t posted anything in over 2 weeks. Sorry! Project Voxel is still alive and well, though, so don’t worry! I’ve been extremely busy with college lately, and my Skyrim addiction may or may not have been rekindled as well, so you can see why there’s been a lack of updates.
I’ve been redoing some core components in the PV engine, mostly redoing how octrees work, and I’ve also been redoing the Placer code in the editor in order to get entity and prop placing functional. This has been a somewhat major overhaul, so there’s quite a few bugs I’ve been trying to iron out.
My spring break starts next week (whoo!), so I very much hope to have at least one update up at some point next week.
After finishing the new parser for the VBLProj format, I decided to make a little test level:
- Fixed bug in MasterGrid expanding code where it deleted valid sectors. This one stumped me for a while. It turns out it was because I removed some code where objects would add themselves to the grid unannounced. This was compensated for in the grid expanding code, so I forgot to remove that code as well, which had the effect of deleting valid chunks.
- Grid class is now non-abstract and can be instantiated.
- Added grid expanding and removing code to Grid class.
- Added block removing with right click.
- Blocks can now be selected. Ctrl clicking a block selects/deselects it and adds/removes it from the selection list.
- Selected blocks can be removed (batch removing) and combined into larger placers (aka brushes).
- Newly created placers are added to the “Placers” tab and have an icon generated for them.
- Temporary placers that aren’t added to the placer list can be made by using Ctrl + C (see KeyCommands.txt below for more info).
- Placers remove a block radius of their own size (for example, a 3x4 placer will remove a 3x4 chunk of blocks from the level).
- Added basic block property editing. Alt clicking a block “property highlights” it and displays its editable properties to a table in the GUI (currently only displays its ID).
++=============+=========================+============================++ || Key | Context | Action || ++=============+=========================+============================++ || Space | FPS viewmode (editing) | Toggles GUI mode || ++=============+=========================+============================++ || Left Click | FPS viewmode (GUI) | Toggles edit mode || ++=============+=========================+============================++ || CTRL + | Editing | Selects highlighted voxel || || Left Click | | || ++=============+=========================+============================++ || CTRL + | Editing | Clears currently selected || || Shift + | | voxels and selects || || Left Click | | highlighted voxel || ++=============+=========================+============================++ || Right Click | Editing | Removes highlighted voxel || ++=============+=========================+============================++ || CTRL + | Editing | Removes all currently || || Right Click | | selected voxels || ++=============+=========================+============================++ || CTRL + C | Editing | Adds selected voxels to a || || | | temporary placer || ++=============+=========================+============================++ || CTRL + | Editing | Creates new placer from || || Shift + C | | selected voxels || ++=============+=========================+============================++ || ALT + | Editing | Highlights voxel for || || Left Click | | property editing || ++=============+=========================+============================++
Well, I was happy to get custom placers pretty much completely working this past week (for voxels, anyway). It was nice also being able to start property editing. I guess the next few things I’m going to be working on are saving to the new VBLProj format which will be able to save placers. I’m also thinking about adding basic camera placing support very soon so I can throw together a decent test level and start working on the beginning parts of the actual game. But who knows.