I’ve continued off and on development on GMDP this past week between a couple of other projects, some of which I’ll share shortly. I’ve been learning a lot about the Doom WAD format these past couple of weeks, and have been making huge strides in GMDP. Much of what I’ve done with it is actually invisible, such as loading various information in regards to the different vertexes, linedefs, sidedefs, sectors, subsectors, nodes, glverts, glsegs, glssects and a considerable amount more. There is enough information being loaded right now to create an untextured version of any level in the game. This is a huge step.
I’ve now got all THINGS in a level loading up, including their positions, and any flags or settings that are defined for each. I’ve now got them displaying as small green dots on the map that I’ve loaded earlier.
In addition to that, I’ve finally accomplished something today that I’ve not seen done in GM before, Patch loading! The one thing that wasn’t accomplished in the project that inspired me to work on this is finally a reality. Textures, sprites, backgrounds, all of them are readable from a wad file. I’m super excited about this. It’s currently a little slower than I’d like but that’s what optimizations down the road are for.
Now for a little evidence!
Yep, there’s the TITLEPIC loaded dynamically from a wad straight into GM: Studio. You can also see THINGS drawn on the map overlayed onto the background.
Progress, it’s a joyous feeling :)
I’ve done a good deal of talking with some of the more adept Game Maker programmers the past couple of days, in fact much of what made my current iteration of GMD+ actually work was thanks to a signing swap code provided by Yourself, from the Yoyo Games forum. As I’ve talked to Yourself, as well as Xot, another moderator from the forums, It’s been suggested, briefly, by both of them, that I should look into the new buffer functions built into GameMaker Studio. Before I go too far into what exactly a buffer is, I’m going to talk a bit about what it takes to currently read variously sized integers from a binary file as is.
Firstly, the data that’s being loaded from a wad file at the current progress is as follows: the Header, which consists of a 4 byte string, followed by two unsigned integers, 4 bytes each; the Directory, which consists of two unsigned integers 4 bytes each and an 8 byte string multiplied by a couple thousand times for the number of lumps in the wad; and much more, too much at the moment for me to feel like typing it all out. What this basically means is that there are literally thousands of bytes of information being loaded into GMS even at this incomplete iteration. Currently E1M1 loads incomplete in 0.12 seconds, and E1M3 in 0.2 seconds. This may not seem like much time, but when combined with loading texture data, reconstructing the textures in game, constructing sounds, building the levels, and constructing the 3d models that make up the gl_sectors, loading time increases exponentially which is why its very important to shorten up the loading time at the beginning, before you even start assembling the textures, sounds, and meshes.
How can I speed up data reading? Let’s take a look at how you’d read the various data formats inside a binary file using the file_bin_read_byte() functions in GM. Let’s say you need to read an unsigned 16 bit integer, also known as a short. A short is made up of two bytes. As you can guess, you will have to call file_bin_read_byte() twice, once for each byte, then on top of that you have to convert both of those bits of information into the final product. This becomes even more tasking when you have to read 32 bit integers because you have now to read twice the number of bytes and perform even more calculations to convert the data into a usable format. Doing these once or twice won’t impact performance very much, but when you start reading hundreds and thousands of them it can really hinder development. What is the alternative?
Buffers are a new addition to the GameMaker core, and much of what the manuals mention in reference to buffers are creating file saves for games quickly, creating temporary checkpoints in games, and saving created data in game. One of the things mentioned in the manual is that you can load “the buffer data that was previously saved using the buffer_save functions” from a binary file. What the manual fails to mention is that the file you’re loading from doesn’t need to be created by using the buffer_save functions, but ANY binary file can be loaded into a buffer, including a classic Doom WAD. What makes a buffer so much quicker than all of the bytes loading and converting that I was doing prior is that buffers have built in functions for reading specific types of data, from unsigned 8bit integers to signed 64bit integers, it’s all hard coded and all I have to do is write buffer_read(buffer,data_type).
The downside? There’s only one problem that I’ve come across while exploring buffers and that is how you read strings stored in the buffer. GameMaker assumes that your strings are null terminated, meaning that the byte immediately following your string is 0. This does not work when loading a Doom WAD because strings are not null terminated, rather they are length dependent. Using buffer_read(buffer,buffer_string) to read a 4 byte string would possibly return something that consists of several more bytes, and completely offsetting the position in the buffer and will result in erroneous values loaded afterwards. To remedy this a custom script was created that essentially reads a byte at a time from the buffer dependent upon a length argument, and returns the resulting string. This is not ideal as I’m manually seeking through bytes as I was before, however, this happens much less often now.
I’ve just begun converting to buffers, but already data is loading properly from the buffer. After swapping out all of the binary file reading with buffer reading I will post the differences it makes in loading times.
Feel free to comment with any questions you may have and keep your eyes glued here for more progress!
Heya guys, now that my latest game Combat Cats is released on the Windows store, I’ve had a little time to think about what I feel passionate about. My life as a gamer began decades ago when I first laid my eyes on Doom: Knee Deep in the Dead. Ever since then I’ve been head over heels for Doom, and everything else that came out of id Software’s offices.
It is this love that fuels my latest side project: GMDoom Plus. Partly inspired by an open source game maker file from 2006, GMD+ is a planned semi source port of Vanilla Doom for Game Maker Studio. What this means, essentially, is that I’ll be creating a way to read information from a wad file and load it into game maker in a usable format, with a bare bones fps control scheme. Using this system you’ll be able to load up a wad file, get the graphics, load up a level, and run through it from start to finish, collecting keys, ammo, health packs, guns, unlocking doors, flipping switches, opening doors, triggering whatever. What it won’t do is have ai routines, proper player weapon handling events, menus, huds, health, armor, player damage and probably more. What does this accomplish? Well I think that it makes the engine much more versatile. You’re no longer bound to creating a “mod” by replacing maps and graphics, but the user will have infinite control over what they can do with the engine. From third person games, to racing, from exploration adventure, to fast paced action fps.
You do with it what you like. Which brings me to my next point. GMD+ will be open source, when it’s done that is. I will likely release milestone demos during development so keep your eyes glued here.
Here’s a look at the progress so far, and this is just after one days worth of work:
What you are looking at there is the E1M1, Doom’s famous first level, linedefs and vertexes fully loaded from a wad file and displayed in realtime on a 2d plane. What this signifies is that the information needed to build a complete level from a wad file is easily loaded into GameMaker Studio without much hassle, directly from a wad with no middle man, no dll’s, no extensions. All of the work is done with the functions that are built into Studio. It honestly surprises me that nobody has done this yet, and it is a great honor to be the first to get this tech into Game Maker natively.
Any day now… between the 20th of March, and the 20th of April. If you know what this is, you know the implications ;)
Hey guys, while my portfolio is in development I’ve decided to host many of the images that will be in my portfolio in this post to make it easier for my potential application reviewers to see my samples outside of a real portolio environment!