Tuesday, 30 September 2008

Maze Doors and Textures

Slowly progressing towards a more complex and better looking maze. It's already easy to get lost - though you can always find a way out, as generation code is sooo lighthearted on the player. :) But heading the right direction. Little coding to include the doors into generation. tidbit's door models and texture and Zphr's new wall texture addition rounds up a real classy classic atmosphere. Thanks go out to them again! :)

Thursday, 25 September 2008

More of tidbit's contributions + Work on Dungeon/Labyrinth

tidbit's continuously contributing miscellaneous models/textures that the project is in need of. Great job! Nice new textures for the misc objects, a new cyclops model, new pavilion for the storage area, fence, trunk-bench etc. I'll try to integrate them all as time passes. You can check the shot of the already integrated part.

Currently the main focus of my dev time is to create the randomly generated dungeon/labyrinth parts that will be scattered around the world of the game. Planned to be infested with monsters and loaded with ancient treasure. First the abstract generation part has to be perfected. Currently it's just starting to shape up but it's graphics is quite ugly. For this a new art concept is under work as well.

Thursday, 18 September 2008

mediawiki downtime - only direct download

Due to SF.net migrations the project's mediawiki is down. Till it will be back please use this link if you want to download. I hope they'll get over with it soon... will update this post if so.
EDIT: good news, wiki seems to be working again!

Wednesday, 17 September 2008

Publicity Sawteeth

We have had some booms of publicity around this month. Two major web nodes had published some lines and links on jClassicRPG.

The first in this short line was the popular RPG site rpgwatch with a longer article based on my submission. Our thanks go to Dhruin and the staff for giving some spotlight for us! Besides the nice number of webhits and the more fame -- unfortunately it has not attracted new contributors till now.

The second was again due to my submission on the famous blendernation. jClassicRPG was already mentioned on the site another time before, somehow they found us when the project was just a few months starting out. :) Thanks! This time it brought lotsa hits again and luckily one new contributor too! tidbit has already added nice miscellaneous handcraft objects (boxes, barrels, signpost and more) and a new cave entrance at the forum which is very cool as towns and cave entrances' look should have bigger diversity. Big thanks go out for tidbit!

Thursday, 11 September 2008

Migrating jME version from 1.0 to 2.0

A long pending aspiration of mine has come to fulfillment! JClassicRPG's full sourcecode and dependency have been converted / changed to JMonkeyEngine 2.0 by me. :) JME 2.0 is called alpha but it is as stable as it should be by the overall experiment of the community. It also uses the new major version of lwjgl (2.0), which is also containing major improvements.

The conversion is mostly about using Enumerations instead of static int constants, removing multiplicity of the buffers of TriMeshes, removing the now non-existent TriangleBatch class usage, convert AlphaState to BlendState, use some new classes like Texture2D instead of the now abstract Texture class.

It wasn't too hard to migrate because in the end it turned out to be not such a hard thing to migrate the opensource md5reader2 library as well. It's a separate library which jcrpg depends on created by other nice jme people at jme forums, but who seems to be a bit away, so me had to do the conversion of it. You can grab the modified jme 2.0 version of it at the forums here.

You can get the whole new jcrpg with jme 2.0 compatible source code from SVN.

Tuesday, 9 September 2008

Background thread for area loading, optimizations, bugfixes

Finally after two previous attempt to realize a working and fast parallel load of map I have succeeded. Now a separate thread is starting to load the area when you reach the middle of the previous render distance, so while you keep walking around it will load the things and with high chance you won't reach the limit of loaded area before the load of the newly needed area finishes in the background thread. It generally doesn't happen yet the rendering is prepared for that, if you reach the limit the background thread is stopped and a new foreground loading starts halting you walk. But this case happens really rarely if you selected the right level of detail for your PC's performance. Thus you will be able to walk freely without pauses with a dynamic background loading - in the next release that will come. Or if you check out the latest SVN you can test it right now.

Bugs...Long lurking culling problem of tree foliage now I could eliminate - GeometryBatchMesh spatial instance needed a buildMatrices to have the correct world rotation before being locked. Also I could fix some other annoying bugs - foliage of bushes rendered at high above the trunk sometimes and texturestate vegetations were wrongly repositioned while you walked around (both problems were related to reuse and wrong modification of position vectors).

A new RenderedArea implementation was born to fasten the loading of area - and it was a successful rewrite! Now it's 3 or 4 times or even 8 times faster than before in some cases. It includes a smarter calculation of areas to newly load and to remove. It calculates the newly needed and removable areas based on the disposition to the last rendered location vector. The other big thing was to define and implement a new getFilledZonesOfY for the Place superclass. Every Place extension (Geographies, Economics, Waters, etc.) now tells what Y height intervals are parts of them at a given X/Z location of the World. The information is collected and combed together and is used to determine what Y intervals to include in RenderedArea's rendering. This way about 4 or 5 times less World.getCube call is needed - only the really filled cubes are being requested by the loading process, empty positions are skipped. Naturally this leads to a much better loading time because of the nature how a world's surface is only consisting of a few cubes height even considering economic upon them.

Cool! :) Listing the things done since starting the optimization session: much more stable memory use (less overall memory needed), continuous appending of 3D scenario, background process for loading areas with no pauses, important bugfixes, better 3D performance/loading times.

Friday, 5 September 2008

Improving Performance/Memory/Rendering

I've added a new kind of scene graph appending mechanism parallel to the normal screen update/render cycle! This needed hell of a lot changes, bug hunting, refactoring. Now it is done in little time slices between the draw of the frames to add a smooth walking experience. While you move in the world the new parts are added/updated/removed. This clears out the small pauses between each step that was present in the game before.

The whole thing is done in class J3DStandingEngine which is mostly reorganized to support iterative calls to different parts like organizing the addition/removal to batches, the actual update part where batch buffers are rebuilt, cleared, and finally locked. The J3DCore class (extension of jME's BaseSimpleGame) in its simpleUpdate function (which is run upon each update before drawing a frame) checks what iterative function must be still called in J3DStandingEngine. Thus gradually the whole appending/updating of the scene graph is being done.

Also a series of changes were made to the GeometryBatchMesh to optimize it further for my needs. Memory consumption is lessen by some of these changes. I've removed its unneeded tmpVertexBuffer, now it is commiting the batch instances vertex buffers directly (saving a lot of temp buffer allocation). Also removed its special AABB bounding box updater, and use the standard bounding volume update mechanism of jME. Yet I'm still hunting for optimizations and bugfixes. :)

All the progress and optimization made possible smooth rendering of much bigger view distances than before, although it can consume much more memory when extreme distances are set.

Monday, 1 September 2008

Direct memory buffer pool and DDS

Well, it's been a long time since I had checked some really important aspects of the 3d core of jClassicRPG, and looking at that part I was a bit scared. :) Now it's not a secret, it's the memory consumption ratio of the game. But don't fear -- ways to improve are at hand.

With the long ago addition of an extended version of GeometryBatchMesh (created by Snylt @ jme) a new factor was secretly creeping into the memory usage of jCRPG: the direct memory buffers are heavily allocated especially because of the dynamic nature we use the batches, adding new batch instances every step walking around in the 3D world. In Java 5 and 6 there's this thing called direct memory buffers which is handled out of the heap of jvm for quick direct access e.g. by video cards. This speeds up things a lot with jME, so it's a handy thing. But there's a small problem with that (just like with the normal garbage collection), and it is that it's freeing is out of control of the programmer. This is not necessarily bad but in a game you would aim at controlling it - and allocate as little as possible because it takes time, fragments memory etc. jCRPG could end up with a big size of memory allocated to it rather quickly while walking around in the game.

Now my solution to circumvent the inability to free the buffers is the same as always: pool them! :) And it's mostly done committed to SVN repository. I've tuned GeometryBatchMesh to get and release its buffers from/to my BufferPool object. The handled buffer's size are always multiples of bigger numbers (say 500) and are limited down to the needed size (this helps the reusability of the buffers for different capacities). Thus the consumption is more or less stable and adds less stress on to the jvm's decision mechanism (how to allocate/free/reallocate). It's a good thing! :) I've even written a speedy QuickOrderedList to store the buffers in order of capacity with quick lookup/put/remove functions.

The other thing to lessen the consumption is the good old ace of using DDS files (which possibility I was not aware of till some days ago). DDS files are by default compressed (in sys and video memory too) and with pre generated mipmaps, quickening the load of them. I've started the process to migrate the textures to .DDS format with the help of GIMP and the GIMP DDS plugin. For use with jME I had to tweak the plugin's source ( mipmap.c's get_num_mipmaps() ) to add more mipmaps (jME DDS loader is picky about it, and accepts only an exact number of mipmaps for a given image size).

So the bugfixing, optimization phase is still going on... ;) (PS.: added two screenshot of my improved Depth Of Field render pass with 'bleeding' prevention.)