March 2007 - Posts
The Jad Engine blog has moved here to Kartones.net :) Thanks a lot to Kartones for his kind offer of space here. Keep your eyes open the next days, we have something important to say ;)
The 13 September 2006 I posted in this blog:
"Nothing more I think, probably the next post will be about the new virtual file system of Jade."
And
then the nexts posts were not about the VFS :p They were more reports
about how the project is going. I'll do a quickly one and move on: 1.1
is really close, most features are there (collada is there, animation
is there, new input is there, scripting is there, VFS is there,...).
But polishing takes a lot of time :( But you can download the latest
check-ins and play with all the new things ;)
And now about the VFS. Back to when I started thinking about this subject (severals months ago), I asked in
Stratos
if someone had already done it (just to avoid common mistakes and to
get some guidelines). I got several very useful answers, and a link to
a very good article in old Flipcode (
here). I also got several good answers from Jade forums.
Most of my objectives for the VFS were pretty similar to those of the article:
- it should be able to handle archives (a big file with lots of files inside, like a .zip file)
- it should allow plugins to read or write in archives (encryption, compression,...)
- accessing normal files and archives should be transparent to the user
- it should allow several file paths
The
idea was to write the new VFS and replace the old class of the engine
that managed that (JPath). I had a more or less idea of what JPath was
doing and I though switching from one thing to the other wouldn't be
very hard (BIG mistake, more on this later) .
So, with that in
mind, I started to code. I took the decision to leave the plugins for
the end (not a great idea, but not too bad either) because I wanted to
have first a bare minimum functionality. The main code was written
pretty fast (it was quite easy), and were I spent most time was writing
the tool to create the "archives" (a small winforms application). I was
lucky that Fernando (delahermosa) was not too busy during that time and
he helped me a lot in several parts of the tool.
The structure for the VFS at the start was like this:
-
there was a JVFS class that represented the file system. The engine or
the user would ask for files to this class. This class would hold
internally a dictionary of FileSources (places where you can find
files) and pass the request to them. One of the features from JPath
that the engine used a lot was that you could ask for a file without
knowing where it is exactly and then JPath would search for it.
-
I wrote to FileSources implementations: HardDiskSources and
StorageSources. HardDiskSources is normal IO, and StorageSources are
the so called archives. A StorageSource holds virtual directories and
files inside it.
- The engine used to read files the .NET
methods called FromFile(string path,...), but now it would have to use
the FromStream(Stream stream,...), because there´s not a real file when
reading from an archive file. To allow this a new type of stream class
is created: a VirtualStream. A virtual stream works over a file stream
(the stream for the archive file) and controls that the reading is done
the right way (you read the file you want to, and not more or less than
you should). This way, the archive is only open once really and close
at the end (so you avoid lot of costly IO operations).
And that was it more or less. It sounded great, but when I started merging the VFS with the engine, things weren't so great ;)
First,
I decided to do the plugins support. And well, it was hell to write
that. Plugins are small classes that modify how a file is written or
read, and you can apply several of them to a file. This is their final
interface:
Stream ApplyForRead(Stream input);
Stream ApplyForWrite(Stream input);
In
theory it is pretty easy: most times filters will be streams wrapping
streams. In practice it was quite complicated. Why? Things go more or
less like this: we are writing our new archive (remember, lots of files
together like a .zip), so we have one stream open and a binary writer
writing on it. But now, when writing files with filters applied, we
have to modify the stream the writer uses to write (filters modify the
stream). So:
- we cache the position where we are in the stream
- we close our stream
- we reopen it and apply the filters to write
- we write the file
-
we get the new position in the stream. Now, we can calculate the number
of bytes we wrote :) We can't use the Length property of a file stream
to know the number of bytes we wrote because we can be reading a
compressed file or writing a compressed file, and compressed streams
don't support the Length property (System.IO.Compression).
- we close the stream
- we reopen it again to continue doing work with it (file header, and other things)
Sure
you loved it :p But then things get better. After finishing that part
(I can tell you it took me a while to write those 40 lines of code),
now I needed to give support for the filters in the visual tool. It
involved writting a custom attribute so filters can tell the type that
edits them in a visual environment (like VS visual designers) and a lot
of strange errors with reflection and assembly loading.
And the
last headache I got was when testing the encryption filters, because
for some strange reason, when using AES, DES or TDES symmetric cyphers
with PaddingMode.ISO10126 the output ended truncated. It took me a
while to realize it was the algorithm padding, so well, I set it to
PaddingMode.Zeros and at last, filters were working :)
And things got worse :p
Now
I started replacing JPath for JVFS. I deprecated all the JPath code and
started searching the warnings around to replace it. I had to change
also some configuration stuff, but nothing too serious.
After
looking how JPath was working I found the harsh reality: my JVFS
interface wasn't prepared to manage it. JPath allowed the user to get
all files from a directory, write a file (I didn't allow to write
files! You can't save your game, you have to finish it at once :p), set
special directories (like for example, Shaders directories where all
shaders would be), ignore extensions,... Well, a lot of stuff I haven't
thought. So I had to stop the merge and rework the VFS.
This
rework involved mostly the FileSources interface. Before this change,
the VFS had methods to ask for a file to a specific FileSource (all of
them have an unique name) or to all of them at the same time. But now,
the VFS class was reworked to be also a FileSource. So, I took out the
methods to ask for a specific file or to a generic file. Now the method
was something like this:
public abstract Stream GetFile(string path, string fileName, bool recurse, System.IO.FileAccess access);
So,
if you do VFS.GetFile, the VFS implementation would search in all its
FileSources, but if you do VFS["FileSourceName"].GetFile, it will be
use whatever that specific FileSource implementation is. Everything is
much clearer like that. FileSources also got some new methods (all
files from one directory and minor things needed).
Next step was to allow for defined directories. The old way of putting directories for Jade was something like this:
X:\Whatever\InHouse
X:\Whatever\Base
InHouse
is for internal engine files. Base is for your game files. But the
engine assumes some directories always exist. For example, it loads all
shaders in the Shaders defined directory, that is that the engine
searches for InHouse\Shaders and Base\Shaders. So I had to allow a way
to get all files from a specific path from all the FileSources. And the
defined directories where born.
A defined directory is a pair of
key (name, for example Shaders) and value (path, for example
MyWork\Shaders). What the engine does when it finds a request to a
defined directory is to ask every FileSource if the defined directory
key exists, and if it does exist, it performs a normal search using the
path associated to that key. So every user can put the Shaders wherever
he likes the most as long as the key is Shaders.
All of this is defined in the configuration file, like this:
[VFS]
[FilesSource Type="HardDisk" Name="Base" Path="../../../../Base"]
[DefinedPath Name="Materials" Path="Materials"/]
[DefinedPath Name="Models" Path="Models"/]
[DefinedPath Name="Particles" Path="Particles "/]
[DefinedPath Name="Scenes" Path="Scenes"/]
[DefinedPath Name="Textures" Path="Textures"/]
[/FilesSource]
[FilesSource Type="HardDisk" Name="InHouse" Path="../../../../InHouse"]
[DefinedPath Name="Effects" Path="Effects"/]
[DefinedPath Name="PostProcess" Path="Effects/PostProcess"/]
[DefinedPath Name="Shaders" Path="Shaders"/]
[DefinedPath Name="Geometry" Path="Shaders/Geometry"/]
[DefinedPath Name="Internal" Path="Shaders/Internal"/]
[DefinedPath Name="Lighting" Path="Shaders/Lighting"/]
[DefinedPath Name="Materials" Path="Materials"/]
[DefinedPath Name="Textures" Path="Textures"/]
[DefinedPath Name="Gizmos" Path="Textures/Gizmos"/]
[/FilesSource]
[/VFS]
(Note: it's a normal XML File, I just replaced it with brackets [] to avoid some formatting problems here in the blog)
Quite
easy: you define a FilesSource, with its type (HardDisk is normal
files, Storage is an archive), its name and its path (relative to the
configuration.xml file or absolute, as you wish). And then inside it
you can add defined paths with their name and their real path.
With
everything done, I went back to replace JPath for the VFS again: now
things were fitting much better as there weren't strange things around
that I hadn't thought. But, when I finished, the engine didn't work at
all :( It would load and start, but it would not render correctly,
probably related to a shaders loading problem, but I was unable to find
it, so in the end I had to go back and undo all the changes in the
engine (I backed up everything first). See changesets 14554, 14572 and
14574 comments to see what I mean (I broke the build compilation on the
first check-in).
And so, there I'm at the moment, trying (for
the 3rd time) to replace JPath for JVFS, but this time, instead of
changing all at the same time, I'm going to have both systems living
together and then I'll remove JPath little by little.
Let's hope this time it works ;)
Edit:
I forgot to say (and I shouldn't have) that all of this work was
possible thanks to the support, advice and comments from Jader, Reed,
Quimbo and delahermosa. They helped me a lot to catch bugs, write some
parts of the code, test, ideas,... Thks team! ;)
Long time since last post, and lots of things happened along the way :)
Jade 1.1 it´s coming out nicely, and it´s going to package more features than expected. At the moment the Jade binary format is completed and Jader has moved to tweak with the engine internals: his changes now allow to support multiple render views and scenes. Also, he did some changes in the engine shaders.
The collade import is advancing at a very good rate, with most of the import now finished (meeshoo is now giving it finishing touches and testing). Animation should closely come after he finishes with this.
The new filesystem is finished, except for the filters and total integration, but it´s working and the packager tool performs it work too.
The only point we haven´t being able to touch yet is the buffered input, that part will come probably after all the other features are finished. But on the other hand we are getting a very nice new mathematic library from Reed, who has finished several classes for interpolation and geometry operations. He also cleaned most warnings from the development code, so it´s much more neat now :)
But one of the most exciting things that have being happening to Jade in these last days are related to the Jad Engine Editor, codenamed JadEd (we are so clever with word jokes :p). After several people expressed their interest in JadEd, we have decided to create a new project in codeplex:
http://www.codeplex.com/Wiki/View.aspx?ProjectName=jadedThis project will be exclusively for JadEd, and it´s mainly managed by gonzo, Quimbo, Reed and matias. There´s some code now available to download, and I must admit that the level of architectural design they are giving to it will make it a very good piece of software. If you don´t believe me, you can join them at the new JadEd forum:
http://forums.jadengine.de/forumdisplay.php?fid=16Also, if you have read the latest news in the boards, you will probably know that we have now some IRC channels where you´ll be able to chat with us and see how the development goes. You can grab the info at the JadEngine webpage (
www.jadengine.com).
Hope to see you on IRC!
| We are getting
closer and closer to 1.1. Jader is hunting bugs in the engine to help
Gonzo with a new planet tutorial. It will be quite a complete tutorial
that will show you step by step how to use Jade to render a full
planet. This is an early screenshot:
I´m aware it looks more like a hedgedog right now ;) But it will get prettier with some effects and shaders that are coming.
Meeshoo
continues with his Collada work, and he has being able to import
information to the engine from Collada, and now is working in the
animation part (importing the Collada data and then playing the
animations correctly).
The JadEd team has finished most of the
core services of JadEd (plugin services, messaging services, undo/redo
services,...). They are now going to start wrapping the engine so JadEd
can talk to Jade and preparing the UI to work with Jade. They have
being a little out during this last days, but they are back to work.
And
myself I have finished the VFS once for all and uploaded to the main
code. The VFS and the Storage Packager tool are now functional and
working. The next step is to replace the JPath class for the VFS class
to handle file requests. This change will be a little more heavy than
expected in the end because I plan to change another thing also.
Usually, when people get to try Jade for the first time, the "strange"
directory structure we use gives them some problems to setup the engine
and start using it.
So, as I have to change the JPath class (the
one that was in charge of this feature also), I'm going to change how
the engine starts up: you'll be able to define paths for files in the
configuration.xml file, so it will be way easier to start playing with
the engine and change resource locations (no need to compile anymore).
After
this is ended, I´ll write two different tutorials, once about how the
VFS internals (more oriented to understand how it works, how to extend
it,...) and another about using the VFS.
And not much more,
there are some interesting threads in the boards that maybe you should
read if you haven´t done it: Jade GUI, DX10 vx XNA,... Check them,
because they are the ones that will decide where Jade will be headed in
the future.
Have a nice x-mas! |
Today the Jade Team announced the new features that will come with Jade 1.1. The new features are:
-
Jade binary format: it will be able to load and save a full scene
(scenegraph, meshobjects, meshes, materials, physics & animation).
-
Collada converter: it will be able to convert collada exported scenes
into Jade binary format with all the information needed to build a Jade
scene. It will be a tool for the engine.
- Animation system: it will support morphing and skeletal animation.
-
Virtual file system: it will be able to load files from real paths and
virtual paths (storage files). It will come with a tool to create
storage files.
- Input: buffered input and action based input (through scripting or another solution, not clear yet).
I
must admit I´m very happy with the new features that are coming to the
engine, as most people seems to want animation and importing/exporting
facilities (and with a good reason, the engine is much less usable
without them). Also, a lot of minor improvements are coming for all
parts of the engine: refactoring, comenting, editing,... To be truth,
with 1.1 I really hope more people will start considering Jade for
their own game development needs using .NET.
We love to optmize code, all programmers do. We find joy and pleasure
in writing more optimal and faster algorithms and routines. The problem
is that most times, we just do it and think that the new code will be
better, without taking measures or doing some tests to confirm that the
new code is in fact faster than the old one.
Since the last
update, I´ve spent most of my time profiling Jade. While I´m not able
to make architectural changes to improve performance, I can find some
functions that are not well written and improve them. I´ve had a lot of
fun fighting with the Hashtable and Dictionary classes.
When I did my first profiles, I found two dark points:
- JEffectBuilder
- Building shadow volumes in the light pass
Both
parts were using a lot of time calling several methods of the Hashtable
class (Contains, [], Add,...). I started looking first at the
JEffectBuilder class. There the Hashtable was declared as:
Hashtable effects = new Hashtable;
I
browsed the code to search what it was using as keys and values: it was
using JUniqueEffectID (struct) for the keys and JEffect (a class) for
the values.
My first move was to change it to the Dictionary
class. I like a lot generics and generic collections (they save casts),
so a Dictionary should work better than a Hashtable. I also changed the
keys from JUniqueEffectID to int because that struct has a field called
Global that is like a hash value. It wasn´t going to save me from the
call to GetHashCode, but well, I felt it was more natural to put it
that way.
I profiled again the code and well, I was amazed: the
time used by the JEffectBuilder diminished a lot. I was very happy with
this, but I couldn´t believe that changing from Hashtable to Dictionary
would yield such a great speed improvement. I rushed to do the same
change in the shadow volumes, because they were well... slow as hell to
say the least.
I re-ran the profiler again, and I was shocked by
the results: the shadow volumes were as slow as usual. I started to
think what had happened, because I was really surprised that I had
changed the Hashtable of the shadow volumes to a Dictionary and the
speed was the same... And then I realized: the problem was in the
GetHashCode method. I don´t know the implementation, but I´m pretty
sure that calculating the hash code of a struct is a lot slower than
calculating the code of an int. That´s why changing to int keys from
structs gave me such a big improvement in speed in the JEffectBuilder
while in the shadow volumes, as the keys were already int values, I
didn´t notice the boost.
I then had another strange result:
Dictionaries have a method called TryGetValue. In the .NET 2.0
framework there are a lot of methods like that (like TryParse in float,
int, double,...) that help to make code faster and easier to read. In
Jade, the TryGetValue would save me from calling first Contains to see
if a key existed in the dictionary, and then using the indexer to get
the value. I was reducing the number of calls in half :)
I did
some test projects, and they confirmed my idea: using TryGetValue was
nearly 2 times faster than using Contains and the Indexer. But then the
strange thing happened: when implemented in Jade, it was slower :(
I
will continue studying this result, because it doesn´t make any sense
at all (or I haven´t found it yet). I must admit it can be also that I
haven´t run enough tests: my laptop heats quite fast when running Jade
and then the performance of my ATI card drops a lot. I´ll investigate
this one further.
Appart from my rambling in profiling and optimization, this last check in has several other aditions:
- documentation and translation fixes (seems they aren´t going to end any time soon).
-
a third person camera class written by gonzo. Very nice addition for
the default camera classes of Jade (and much more useful later in his
editor JadEd).
- fixed some error messages in the code: the engine
wasn´t reporting some errors as it should. Sweenie and timbann wrote
some code that fixes that.
- fixed the dammed resize bug: Haddd
found it at the end, after fighting with it since nearly the start of
the engine coding. This will help a lot in the work of the editor.
-
the old Haddd editor ported to Jade. Haddd and I ported it to the new
code so people can use it as a testbench for their own experiments.
Nothing
more I think, probably the next post will be about the new virtual file
system of Jade. Or maybe about a surprise, but I don´t know where it´ll
be ready (I´m not writting it ;)
One of the best ideas when thinking about Haddd future was converting
it into an Open Source project. In very little time some people have
submitted code in the form of new features or bug fixes that are very
valuable for the engine future.
The first updates that have being merged in the engine code are:
- XBox360 controller and XInput wrapper by plonkman
- Jostick support by ThunderMusic
- JApplication with integrated states by meeshoo
- Reporting delegate on .haddd files loading by Ronnie Barnard
- Bug in input classes from MindGames
They are small features, but nice ones to be truth. And much more important things are on the works:
- Networking by ThunderMusic
- Collada support by meeshoo
- Viewer/Editor by gonzo
This
projects when finished will allow Jade to be a much more rounded engine
for game development and more useful for the community in general. So,
that´s why I feel very happy having opened the code of Haddd, because
if not, that code would have never appeared in Jade and no matter how
small or big it is, it´s useful :)
Well, I said I was going to
return to steering behaviors after this, but I´m going to move to
profile the engine, I´ve seen very strange things in the performance,
and I´m confident that some small changes can be done to improve it.
The ideas is to rework some inner workings of the engine that will
allow it to gain 10% speed more or less without breaking any interface
or anything (so no method name or signature will change).
Let´s see what happens in the end, I´ll post some points that will be changed when I´m more sure that I´m right ;)
When starting with AI programming, a lot of people fight with a problem
called "pathfinding": the search of the path to move from one point to
another. Pathfinding has a lot of resources around the web, mostly
related to Dijkstra algorithm or A*. While efective pathfinding
(dynamic environments, multiple agents,...) is much more than A*, A* is
a great point to start solving this problem.
But other problems
people find when they have implemented A* are: how do I move from A to
B? How do I avoid another unit that is moving while moving myself? One
way of moving the entities is using "steering behaviors": they are easy
to understand, easy to implement and fast to calculate.
The original paper about steering behaviors comes from Craig Reynolds and can be found here:
http://www.red3d.com/cwr/steer/I
like specially the Java Applets, as seing things visually helps a lot
to understand them. His paper is also not to hard on the technical
side, so it´s quite easy to follow. Some other links in his web are
also useful, as the OpenSteer project: their sourcecode can help to
understand some problems and concepts in the implementation.
To
implement steering behaviors in Jade, I first used the material
presented in "Programming Game AI by Example", from Mat Buckland
(excellent book, don´t miss it if you like AI programming). After some
tests, while most behaviors were working pretty nicely, I had several
problems, so I moved to look at Reynolds paper and other sources to
find the mistakes I was doing.
After some hard work last week,
while not all the behaviors are yet implemented, I think I have ended
with a very easy to use architecture to move entities using steering
behaviors. Also, I started to try another feature I wanted to develop,
but I never found time to: visual AI debuggers.
Debugging AI is
pretty hard, you just can´t follow code or print things on a file most
times, but watching visually what´s happening makes things very easy to
understand and fix. I added a new namespace (JadEngine.AI.Utilities)
that allows to draw easily some "2D" figures (circles, crosses,...) to
give visual clues of what is happening: it´s like Jade copy of those
nice Java Applets from Reynolds. I´m pretty happy with the results so
far, although I have to find a good way to put 3D text yet (I asked
Haddd about this subject and it seems I have missed some methods and
classes used for this, I´ll look better next time).
All the new
source code is up and checked in Codeplex. Now I´ll move on to 2
different things: adding the tutorials to the TSS (including a new
tutorial for steering behaviors) and adding the community contributions
to Jade source code.
And after that, who knows, probably more steering behaviors, but not sure yet ;)
One of the things the engine lacked since the start of the project was
a good documentation: inside the code and an outside reference.
The
first problem was because the code was a heavy mix of english and
spanish, and a lot of things were unexplained. While the engine has
being fully translated to english, some things remain undocumented
(with a nice TODO tag to remember myself that I have to fix that
someday). That problem will be fixed as the engine moves on.
The
second problem was an outside reference for the engine. Usually, .NET
projects use NDoc to build their help, but due to several reasons
(mostly lack of support from the .NET community), the NDoc project
died. The engine uses generics and it has some references to unmanaged
assemblies, 2 things NDoc dislikes a lot, so it wasn´t possible to
build our documentation with it.
Other tools on the web are professional documenters that cost at least 400-500 dollars, and well, I´m not going to pay that.
But
this kind of documentation is quite needed for the community (it is one
of the things people asked about first). gonzo helped building a
documentation file with an alpha version of NDoc 2.0 and taking out the
references to Vorbisdotnet.dll. I continued searching for something (a
lot of people have this same problem, so there must be a solution). So
after browsing a lot, I discovered project "Sandcastle":
Microsoft Sandcastle BlogThis
project are the tools Microsoft uses to build its own documentation. I
was quite happy when I found this: "now I can build the doc for Jade!"
I though. But another problem arised: using Sandcastle CTP was far from
"intuitive" or "easy". But by chance (reading the CodeProject
Newsletter), I found this jewel from Ashley van Gerven:
Sandcastle CHM-compile BAT script & configuration utilityThis
project builds a .bat script that calls Sandcastle and HTML Workshop to
build a nice .chm file with the documentation of your assembly. After
some tries, I managed to create 2 .chm, one for Jade and one for
Jade.AI, and the results are impressive in my opinion. The files are
now uploaded in the 1.0.0.0 Release (Jad 1.0 Documentation), so have a
look at them, you won´t be disappointed.
After a long fight, it seems Jade has got a nice documentation (at last!).
At last! I´ve finished the update of the EvolutionaryComputing namespace. I´ve being thinking about this update for a long time, but because all the work involved in moving from Haddd to Jade I didn´t have time to commit to it until this last week.
This objective with this namespace was to get an easy to use yet powerful solution for genetic algorithms and evolutionary strategies. The evolutionary strategies thing was halted because I lacked a gaussian random number generator, but now I´ve got it, so I´ll do some work on it in the upcoming weeks.
The genetic algorithms on the other side, was more or less finished, and even though not many people have use it, the comments from all of them have being pretty good. I myself like the library a lot (well, it´s mine after all ;)).
But even with that, some "dark" points where lurking there: some things I didn´t end to like, some comments from the people that used it, some bugs and some mistakes I realized later after using it.
Some points:
The IChromosome and IPopulation interfaces are pretty useless. After thinking and arguing about this one, I think I was wrong and it´s true that this interfaces are useless, as their implementation is trivial (you can´t hardly implement a List property without using a List as the field, and so on). I think this problem came from the "over-designing and pattern overloading" I´ve experienced in my work for some time (and my lack of real experience). In the end, I´ve decided to eliminate them, if someone wants more capabilities for those classes, just inherit from them.
The Clone method of Chromosome and Population. This one was harder to realize. I´m used to write the Clone method like this:
public object Clone()
{
MemoryStream memory;
BinaryFormatter formater;
object clone;
using (memory = new MemoryStream())
{
//Serialize ourself
formater = new BinaryFormatter();
formater.Serialize(memory, this);
//Move the memory buffer to the start
memory.Seek(0, SeekOrigin.Begin);
//Undo the serialization in the new clone object
clone = formater.Deserialize(memory);
return clone;
}
}
This aproach has several good properties: it´s very easy and it works very well if everything is Serializable. But it has a big drawback: it´s slow as hell. The Serialize call is very slow (browse a little and you´ll see lots of arguments about this subject).
Most times, the Chromosomes are using value types as their type paremeter T. Value types can just be copied, there´s no need to clone them and waste so much time.
//Best scenario, T is a ValueType
if (typeof(T).IsValueType)
{
newChrom = (Chromosome) MemberwiseClone();
newChrom.Genotype.Clear();
for (int i = 0; i < genotype.Count; i++)
newChrom.Genotype.Add(genotype
); return newChrom;
} Other times the type parameter will be a Cloneable class, so we can call it´s clone method. And in the worst case, we just can use the old method (well, the worst case is that the item is not ValueType, Cloneable or Serializable so the method crashes, but I won´t count that one :p).
Calling Activator.CreateInstance(type). I needed to call this method in some places of the code to create new instances of items and make the code generic. This method is very slow and it does too much for my needs, so I decided to use a MemberwiseClone type of method (I have to test this one more, but it seems things go better).
Selection, Scaling, Crossover. This one has several parts. First, in the selection methods that used the scaling operator (RouletteWheelSelection and SUSSelection), the operator was being called in every selection to create the ScalingMapping. Well, that was overkill, you could just call it the first time and use the result for all the selections. That "bug" has being fixed.
But there´s a strange relation in those three operators: all of them are used in the creation of the offsprings population (you scale the parents if needed, select some parents, cross them to create a children, select, cross, select, cross,...). I changed some code from EvolutionaryAlgorithm class and moved it to the SelectionAlgorithm, so now creating the offsprings it´s only a call like:
//Create the offsprings population
offsprings = selection(parents, numberOffsprings);
A cosmetic change that will make that part a little easier (and more in line with the others operators of the namespace).
Well, that´s all. I have to finish the evolutionary strategies crossover and mutation operators, but I think I´ll rest from evolutionary computing a little and move to other things like a tutorial on how to setup Jade for your own projects (it´s not a very intuitive thing), fixing some error messages and adding some contributions from the community to the source code.
| Well, a little
update. I´ve uploaded another Release called "Demo and Examples" where
well, demos and examples will go ;) At the moment there´s only one demo
game, a side scroller platformer made by SlykDrako. I only changed some
code to make it compatible with Jade and some cosmetic changes (casing,
translating, formatting,...).
The game is pretty nice to play
and the code is very interesting to read to gain more knowledge of
Jade. I have another demo in the road to upload (about pathfinding,
steering behaviors and goals) but it has a nasty memory bug somewhere
I´m unable to find :(
Also, expect a massive update in the EvolutionaryComputing namespace soon (1 or 2 days). |
From now on, this blog will be the official site for news about Jad
Engine (Jade), an open source Managed DirectX written in C#.
The project is hosted in:
www.jadengine.com