We love Blizzard's popular game, Diablo. We love it so much, in fact, that we're willing to spend our precious time developing a free and open source solution for those wanting to play it on a modern computer.
Short answer, yes. We don't distribute any copyrighted game assets, which means you'll need to have a copy of Diablo to be able to play.
Hi all, Over the last month or so, I’ve been mainly focused on cleanining up the rendering code in freeablo. This doesn’t make for very exciting stuff to show off, but it’s important in the long run. The new approach works by pre-loading all of the game’s sprites at startup, which should eliminate any stutter when doing something that needs a new sprite (like changing your equipped items). Framerate is also much improved by the many optimisations taken care of along the way.
Once I was done with general cleanup + optimisations, I finally implemented zooming, which was sorely needed. Freeablo looks great in 4k, but it’s a little impractical to play a whole game that way!
Next steps for graphics are scaling the GUI, and there are still a lot more possible optimisations on the table, but for now I will probably move on to more gameplay-related changes (specifically ranged combat).
Prior to this refactoring, freeablo’s rendering was a nasty sprawl of ad-hoc opengl and SDL related code in a huge file called sdl2backend.cpp. The first step was to abstract the rendering code into something cleaner, which also lets us swap out opengl down the line as well. The system I went for is pretty simple, you have a RenderInstance class that is in charge of creating the GL context, as well as resources like buffers and textures. RenderInstance is subclassed into RenderInstanceOpenGL, but the application only uses the base interface from RenderInstance.
Down the line, there’s a decent chance that we will want to add a vulkan renderer, so there is some inspiration taken from that API here. For example, the RenderInstance is not in charge of dispatching draw calls, that is done by a CommandQueue. In vulkan you create a command queue object, and then push commands into it on whatever thread you want. Then, you hand it over to your main graphics thread to submit it for execution on the GPU. For now, the implementation of CommandQueueOpenGL just runs the corresponding GL commands immediately, but having the interface in place should help if and when we want to add a vulkan renderer.
As for optimisations, the big one was batching, thanks to @grantramsay for getting that started. For those of you who are not familiar with graphics APIs, fundamentally what you do is a: push vertex data onto GPU, and then b: issue commands to draw the vertices with a specific configuration (shader, blending, etc). Especially in older apis like opengl and Directx 11 and under, there is a large cost associated with issuing a new draw call, so if you can batch up items that use the same state configuration and issue fewer, but larger draw calls, that is a major performance win.
In the end, the system I implemented involves pre-loading all the assets in the game into a series of large atlas textures. Before, each game sprite was in a separate texture, so we had to bind the correct texture for each sprite before drawing. If you draw two textures in a row that share the same texture atlas however, since you don’t need to change the GPU state (the currently bound texture, in this case), you can batch them both into one draw. This way, you can accumulate a “batch” of draws as they come in, and only send them to the GPU for rendering when you get a new request which switches the texture.
This approach works well, but it depends on the game drawing objects from the same sprite atlas (remember, we can’t fit the whole game in one atlas texture, we have a few of them), but the ideal case would be if we could issue only one draw for each atlas texture that we used, instead of switching around as draws come in. Well, it turns out we can. If we accumulate all the draw commands for a whole frame, then sort them by texture, we can render the whole thing with N draw calls, where N is the number of separate texture atlases.
However, we run into a problem. This doesn’t preserve the order in which the draws are performed, so we can end up with situations like the ground being drawn on top of the player. All the draws within one batch will have the correct ordering relative to eachother, but the ordering between batches will be all messed up. The solution I opted for was the z-buffer.
Z buffers are a concept in graphics used for solving this exact problem, but normally with 3d meshes instead of sprites. How it works is, for each pixel in your mesh that gets rasterised, it also writes a value into the z-buffer, which is just an array of floats, with one value for each pixel. The value that it writes is normally the “depth”, or distance from the camera to the point on the surface of the mesh that is being rasterised. Then, when we draw a second object, it first checks whether its own depth is less than the value currently in the z-buffer. If it is, it draws on top of the previous result, and writes its own depth to the z-buffer. If it is greater, then we know the object is behind than the previous one, so we leave the current pixel as-is.
In freeablo, what I did was, in the shader for drawing sprites, write the original index of the draw into the z-buffer (actually, a normalised value generated from the position). This means that we can use the z-buffer to sort the sprites in their original draw order, while issuing the actual draws in whatever order we want. As the sprites are drawn as textured quads, we had to take the alpha channel into account as well when writing the z-buffer (transparent pixels are effectively infinitely distant from the camera).
In the end, this whole process resulted in a framerate bump on my machine from somewhere around 50FPS to about 700. There is still low-hanging fruit (eg, the game tiles are diamonds, but we draw them with a non-rotated square, so we’re drawing a lot of useless transparent pixels), but for now I think that will do. If you have any questions, or want to correct any mistakes I made in this post, please get in touch. I haven’t done much public technical writing before, so it would be nice to know if this was intelligible at all! You can reach me on wheybags at wheybags dot com, or PM me on the freeablo forums.
So, that’s it for now. Stay tuned for more updates :)
Version 0.4 finally released, after a looong time. The game is still not yet fully playable, but is much much closer now, with multiplayer, proper melee combat, shops, all dungeon levels, some magic and ranged combat, etc etc.
Here’s a video with some juicy footage:
Things have been quiet for a while, but freeablo has been moving forward, and I have a pretty important change in the development to share with you all. I have decided to switch to working part time on my main job, and spend 2-3 days a week working on freeablo. If you’ve been following the project for a while, you have probably noticed that things tend to go in phases, where I work on it for a month or so and then drop off. Working full time makes it hard to stay motivated to commit your limited free time to working on a large project like freeablo, which is why I decided to bite the bullet and just get the job done. For the next few months (at least 6, maybe more) I will be working an average of 2.5 days a week on freeablo, in a final push to get it finished. This should mean that things will move a lot faster than before, and I will still have free personal time on the weekend.
As for what has actually been happening on the project, the main thing is that the implementation of combat is now much advanced. Health, mana, hit recovery, armor class, to hit chance, and melee damage are all calculated accurately now, and the only things missing for melee combat (as far as I know) are proper attack speed, and unique weapon effects. The freeablo 0.4 version will be a massive one, partially because I’ve moved the goalposts for it several times. originally, I wanted it to just introduce multiplayer, but it’s since accrued a plethora of other features, and honetsly I haven’t even made a proper list for the release changelog yet, so I won’t try to list them here. What I will say however, is what I now plan to get done before releasing, and that is as follows:
Since starting with this new part time setup a couple of weeks ago, I wanted to make a push to release 0.4 soon, but I also wanted to get a bit of development done before I did, which is why I decided to get a really proper melee combat implementation in before I did.
As for what else remains to be done before I call the engine “version 1.0”, I’ve brainstormed the following rough outline (note, this doesn’t include a whole bunch of extra features I want to add later, like mods and fancier graphical effects).
In other news, I’ve been in contact with Pedro Faria / Jarulf, the author of a sacred tome known as “Jarulf’s Guide to Diablo and Hellfire”, which is a document that has been floating around on the internet since the 90s, and contains a whole load of detailed information about how Diablo performs various calculations internally. I’ve been using it as a reference during development, and it is a truly invaluable resource. I wanted to reboot and modernise it a bit, so I’ve made a version available here. It’s a bit rough, since it is largely autoconverted from the old .DOC files, with a bit of manual cleanup after. Further cleanup / additions / corrections are very welcome!
So, that’s it for now. Stay tuned for more updates :)
So, there hasn’t been much activity on this site in a while, but that doesn’t mean there hasn’t been any development!
My main focus for the next version (0.4) has been getting multiplayer working. It is now mostly working, aside from a few issues. It’s basically just these few issues that are blocking the release now, so I’m hoping to clear them up soon. If you’re interested, you can see the roadmap here: https://github.com/wheybags/freeablo/milestone/5.
As for what else is in the release, there’s a whole bunch more GUI now, thanks to predelnik, and I’ve rewritten the renderer to use opengl directly instead of the SDL renderer. This will allow some nicer graphical effects, such as fancy shadow effects, which I’m planning to add in v0.5, as well as finishing up at least melee combat. There’s also been a whole bunch of miscellaneous improvements to the codebase, and probably a bunch of features I’ve forgotten about because it’s been so long since they were added, but I’ll make sure to cover everything properly in the release video, when the time comes.
In non-dev news, I’m planning to move the server hosting this site, and while I’m at it, I’m going to switch the site from wordpress to a simple static site generated by jekyll, and also probably moving the github project page to gitlab, since github has unfortunately been acquired by Microsoft.
I’m also thinking of moving the spam-riddled phpbb forums to discourse.
So, I’ve gotten the main renderer ported to OpenGL instead of using SDL2 (still using SDL2 for input, audio, window + OpenGL context creation, so it’s by no means gone).
So different, wow
The code is still a bit of a mess, and unfortunately libRocket doesn’t work, so there’s no GUI at the moment. If you’re curious, you can see the code here: https://github.com/wheybags/freeablo/pull/250
Why would you want this? OpenGL lets us use programmable shaders, so we can do fancy lighting effects, instead of just dumping images on top of eachother.
So, what about the GUI? Well, libRocket hasn’t been working out as fantastically as I had hoped. It is a fairly dead library (there is a guy maintaining it on life support, but it needs much more work), and has problems with memory leaks that are unlikely to get solved. It also uses python as it’s scripting language (actually supports lua now too, but it would be as much work to switch to that as to just dump it), which is kind of just a bad choice for this project.
I want to allow mod developers to write script code for their mods, so preferably the scripting language would be sandboxed from doing bad things like network and disk I/O, but with python this just in’t possible. As well, the libRocket rcss and rml languages are close enough to html/css that you try to use the tricks you know from that space, but far enough that the tricks don’t work.
So, I’ve decided that as part of this port, I will just switch GUI library too. The current front-runner is MyGUI, with some custom lua script bindings. This is the gui library used in OpenMW (awesome project, check it out if you haven’t heard of it). A lot of my technical decisions so far have been based on OpenMW, so in a sense this is just following that trend.
Finally for the programmers reading this, I wanted to plug an awesome utility that I’ve found out about recently, and will definitely be using in freeablo in the future: Hunter
Hunter is a cmake library that acts as a package manager for c/c++. This is amazing because the most awkward thing about working with these languages is the immense pain involved in getting your code to build and link (especially getting it to build and link on other people’s computers). Hunter solves this problem by downloading the source of the library, building it as a static library and linking it in, all from within a few lines of CMake.
So, yeah, Hunter is great, use it :p
Thanks to konopka90 and pengyz, we now have pathfinding in freeablo!
You can now hit things until they fall over, even in multiplayer!
Also, the multiplayer code has been massively overhauled, so things are in a much better state for moving forward.
Anyway, here’s a quick video of some things being hit until they fall over:
There’s been some progress on multiplayer, I’ve been working to switch to a unit tested serialisation framework based on the gafferongames article series here.
So far most stuff is working, with the notable exception of monsters in the dungeon. Below is a short video demo:
Also, another big announcement, following this forum post, brightlord, the developer behind the Diablo 1 HD mod/Tchernobog has shared the sources for Tchernobog with me to use as a resource for the further development of freeablo. So, a big thanks to him for that, and here’s hoping it’ll come in useful in the future. I’m afraid, however, I can’t share the sources at the moment, but chunks of them will probably end up in the freeablo codebase.
Hey, so not much has been happening in the past month or so because work was pretty hectic for me and I had no free time to work on freeablo. The good news is that has changed. MP is pretty close to done, expect a proper video of that soon. Also, the forums were absolutely inundated with spam, that’s been fixed now, and hopefully won’t happen again, as I’ve enabled captchas for signup. o/
Probably the only feature half of you even care about :p Anyway, perhaps an overstatement, as what you see is just the player being synced, but I’ve started on implementing mp, so you should be hearing more about it “Soon”
As it says, v0.3 finally released.
Big features this time round are level 3 level generation, and some cool new gui stuff from konopka90 and Exairnous.
Im hoping that for v0.4 I can get a start on combat and multiplayer, so it should be a more exciting one (a lot of the stuff in this release is a bit “invisible” to end users). I’m also gonna try actually write something on here a bit more often, keep it updated with project status and the occasional general interesting gamedev bit I run into.
Anyway, (slightly less) crappy video, and changelog below:
- Bugfix - monsters spawn on level stairs #112 - Threading refactor #107 - Hotkey selection GUI #106 - level 3 dungeon generation #103 - UI chroma key transparency #96 - UI animation #95 - Bugfix - gui clicks register as movement clicks #88 - Initial version of launcher #33 - sound #26 - better celview gui #134 - Bugfix - music memory leak #111 - Bugfix - exit when DIABDAT.MPQ not found #114, #115
Hey all, I updated the website. Finally have themes for wordpress and phpbb that match :3
also, SPINNY PENTAGRAMS
Hello, all. As the title says, v0.2 is released. The big features of this release are the gui, music, and level generation for dungeon level 2. Downloads available at https://github.com/wheybags/freeablo/releases/tag/v0.2
Crappy video and changelog below:
- Bugfix - MPQ filename case sensitivity #78, #76 - Bugfix - Deadlock on caertain command line args - Bugfix - Player-npc clipping #97 - Bugfix - Reading freed memory in FAIO 6f098b1 - Config File parsing #81 - LibRocket Gui framework #82, #86 - Improved CEL rendering #85, #91 - Inventory and char menu placeholders #86 - Pause menu #90 - Main menu #94 - Keybinding configuration framework #98 - Music #99 - SDL1 support removed d4da725 - Dungeon level 2 generation #93
Another short update - I made a media section with some screenshots + a basic video: here
BTW: If any of you out there are good at web (or just ordinary) design, it would be nice to get custom wordpress + phpbb themes (that match), and/or a freeablo logo.
So, it was called to my attention that I haven’t updated this site in a good while. Since the last update, there’s been a few changes - the big ones being gui and level generation for dungeon levels 5-8 (still in a pr, https://github.com/wheybags/freeablo/pull/93)
Dungeon level 5:
Char and Inv windows (don’t actually do anything yet):
As you can probably see, the gui bits are fairly placeholder for now, missing some visual features (like trasparency for that ugly green, and animation for the spinning pentagrams and fire), but they are a good base in my humble opinion :P
Anyway, development does continue, in fact we’re probably approaching a point where we can release v0.2, if you take a look at the github milestone: https://github.com/wheybags/freeablo/milestones/v0.2, it’s mostly finished, with music being the only big feature remaining.
I have been planning to use libRocket as the gui library for freeablo. The great thing about it is that it allows you to design guis with a derivative of html and css, so this would be very user-moddable.
However, freeablo is using SDL for rendering, and libRocket has no native support for SDL. Fortunately, it does have a nice interface for plugging in rendering backends, and someone has written an sdl backend for it (http://mdqinc.com/blog/2013/01/integrating-librocket-with-sdl-2/). Unfortunately, this code was rather tied up in the game engine it was created for, and was not a drop-in solution.
It was a massive pain getting it to work, but I finally managed to do so. I have submitted a pull request to the libRocket authors, in the hopes that this will prevent this pain from happening ever again, but I’m not sure if there’s anyone actually reviewing pull requests on their end. Anyway, the code can be found here: https://github.com/wheybags/libRocket/tree/sdl2/Samples/basic/sdl2
Unfortunately, this does mean SDL 1 support will have to be dropped, but to be fair, the reasons for it existing were fairly silly :P
Someone made an irc channel on freenode, and some people actually joined, which is always good.
Anyway, #freeablo on irc.freenode.net. Here’s a webchat link if you want: http://webchat.freenode.net?channels=%23freeablo
Not sure if this will actually get used but sure here it is: http://freeablo.org/forum
Hi all, so just made this site :P
Anyway, release notes for v0.1:
subscribe via RSS