Sometimes I wonder why I even bother. It all started because there was a bug in the NTL compiler apparently not recognizing handler tokens. I could have sat down and probably fixed it in a bunch of hours. But no. I had to put the whole NTL language idea aside (as I said to Zak, it was mainly a "programming masturbation", but a cool one ;( ) and fall back to XML.
Well, I think it's eventually a good choice since XML is widespread, can be read by almost anything, espresso machines included, and is an accepted standard.
Luckily I didn't have to rewrite all the code that actually creates CLR assemblies out of the entity system definitions you spam in, or it would have been serious pain. Much pain.
Anyway. While I was at it, I also removed a feature which I didn't like. When the entities were processed and turned to IL, they were added a field named Prototype, which contained an EntityPrototype object basically describing the objects referenced by the entity; this means components, handlers and handled messages. All of this just to speed up entity creation at runtime.
However, I had forgotten once again about Attributes, and why they're in the CLR. So, armed with loads of patience but handicapped by lack of proper sleep, I set to remove this prototype stuff and go on with attributes. Now I'm in the middle of realizing what's the next step.
The most annoying part is that I am storing Types via their TypeHandles (actually their RuntimeTypeHandle.Values ToInt32()ed); this basically means creating a type storage via indices; this so reminds me of the database stuff I have going on at work - though, when I started to ramble about entity systems, I kind of expected it.
I had a nice demo going on but it's no more. Raaargh. Here's hoping it won't be long until I have something actually doing its job again.
I'm out.
07 Sept. Edit: Well, it wasn't as bad as I initially thought. I managed to get things up and running again, now including some things like proper component installation and uninstallation. Since my programming life is full of happy gummybears again, I can commit some time to the actual entity system editor. I'll keep you posted.
Saturday, September 6, 2008
Tuesday, September 2, 2008
Entity System and Lua
Lately the Entity System code has been getting more and more complex, to the point that I had to read what I was writing very carefully (and sometimes reading aloud too... go figure).
I have some news about it... about time!
The good news is that it is almost complete! It's a joyful day for me. Object pooling, message dispatching... stuff that works! I still have to finish adding and removing components dynamically (right now we just get the components we defined per entity in an NTL file).
The bad news is that Lua hates me, and it's giving me all kind of exceptions. I think I know what's going on and the relative fix, but if said fix did not work, I'd be in serious troubles. Basically, Lua needs to know what types you're working with, otherwise it would just sit and cry pitifully, making you feel guilty for such carelessness. And it makes sense, of course. LuaInterface is a mysterious world, I still have to figure out thoroughly how the .NET bridging works - luckily the source code is freely available.
At some point of yesterday evening, while bashing my head on the desk for the umpteenth exception, I even felt like writing a Lua compiler / interpreter from scratch in order to get rid of problems when interfacing with the CLR. Sadly, it's a task beyond my available time and most likely experience as well. It would be a great challenge, though.
I still haven't performed any performance tests, but I know in advance I will have to make sure a) the object pool isn't raping the heap b) entity creation is quick and painless, and so is its disposal.
I know it's all a bit vague, but I'll be sure to release the NTL environment as soon as I have something worth attention.
Have a good and productive .NET day! (...rolololflol.)
I have some news about it... about time!
The good news is that it is almost complete! It's a joyful day for me. Object pooling, message dispatching... stuff that works! I still have to finish adding and removing components dynamically (right now we just get the components we defined per entity in an NTL file).
The bad news is that Lua hates me, and it's giving me all kind of exceptions. I think I know what's going on and the relative fix, but if said fix did not work, I'd be in serious troubles. Basically, Lua needs to know what types you're working with, otherwise it would just sit and cry pitifully, making you feel guilty for such carelessness. And it makes sense, of course. LuaInterface is a mysterious world, I still have to figure out thoroughly how the .NET bridging works - luckily the source code is freely available.
At some point of yesterday evening, while bashing my head on the desk for the umpteenth exception, I even felt like writing a Lua compiler / interpreter from scratch in order to get rid of problems when interfacing with the CLR. Sadly, it's a task beyond my available time and most likely experience as well. It would be a great challenge, though.
I still haven't performed any performance tests, but I know in advance I will have to make sure a) the object pool isn't raping the heap b) entity creation is quick and painless, and so is its disposal.
I know it's all a bit vague, but I'll be sure to release the NTL environment as soon as I have something worth attention.
Have a good and productive .NET day! (...rolololflol.)
Saturday, August 23, 2008
Shameless plug here
Aloha to everyone reading this blog (hi granma!), I'm now back from holidays and ready for a quick recap about my latest endeavours (whoa).
As if the Entity System weren't enough to keep me entertained and make my fellow team mates doubt about my commitment, I've restarted the long-forgotten UI project. This time it's been redesigned the good way. The good thing of the stuff I'm writing lately is that is it 3d engine-independant, I'm just providing managed Truevision3D implementations since this is what we're using at the moment.
The UI includes / will include the following features:
I decided to restart the interface project since it's the best environment where to test my libraries (engine, input, scripting, console, data structures etc...).
Stay tuned-zorz.
As if the Entity System weren't enough to keep me entertained and make my fellow team mates doubt about my commitment, I've restarted the long-forgotten UI project. This time it's been redesigned the good way. The good thing of the stuff I'm writing lately is that is it 3d engine-independant, I'm just providing managed Truevision3D implementations since this is what we're using at the moment.
The UI includes / will include the following features:
- Full scripting support
- Multiple views (UI on meshes and on screen, for instance)
- Markup compiler (a la WoW interface)
- Event driven design (in combo with the Input Manager contained in the Rainweaver.Core library)
- Layout Customization, allowing your artists to do their job and snap pieces together
I decided to restart the interface project since it's the best environment where to test my libraries (engine, input, scripting, console, data structures etc...).
Stay tuned-zorz.
Thursday, August 14, 2008
Away Notice
To everybody who sent me an email in these last days: I'm on holiday, I'll be sure to reply as soon as I come back.
Wien (Vienna) and Budapest are awesome :)
PS: If you plan on going abroad with your trusty laptop, be sure to bring a power adapter.
PPS: I'm away for another week and I won't have an internet connection... take good care everyone and see you soon!
Wien (Vienna) and Budapest are awesome :)
PS: If you plan on going abroad with your trusty laptop, be sure to bring a power adapter.
PPS: I'm away for another week and I won't have an internet connection... take good care everyone and see you soon!
Wednesday, August 6, 2008
Getting back on track...
Well, these have been very busy days. I managed to rewrite a good part of the Entity System, which now supports object pooling.
I have to brush up my Lua knowledge before implementing message handlers properly.
Here's hoping it won't be too long before I post again with more substantial news.
I have to brush up my Lua knowledge before implementing message handlers properly.
Here's hoping it won't be too long before I post again with more substantial news.
Wednesday, July 30, 2008
Of Disappointment
I came to the conclusion that I really wanted to implement object pooling for the Entity System, but I think I've hit two or three (or many more) snags along the way.
The more I try to add this feature to the ES, the more I realize I have to rewrite a good part of the compiler too (make it 80%). I have based the design of the ES upon different assumptions, and now stitching new stuff is proving to be very difficult.
Moreover, I'm not sure all of this will be eventually worth the effort.
So, as much as I'd love to release an ES with an object pool, I don't seem able to pull it off with the current design. It'll have to wait for a new ES version, when perhaps I'll have the time to rewrite it from scratch. This will also mean I'll break the compatibility with assemblies produced with the old compiler.
Bah.
Edit: hell, since I love to rewrite code, I think I'm going to redo the compiler from scratch, this time taking in account everything. I haven't been analysing the problem at hand enough, and that's the result! Don't follow my example! ç_ç/
The more I try to add this feature to the ES, the more I realize I have to rewrite a good part of the compiler too (make it 80%). I have based the design of the ES upon different assumptions, and now stitching new stuff is proving to be very difficult.
Moreover, I'm not sure all of this will be eventually worth the effort.
So, as much as I'd love to release an ES with an object pool, I don't seem able to pull it off with the current design. It'll have to wait for a new ES version, when perhaps I'll have the time to rewrite it from scratch. This will also mean I'll break the compatibility with assemblies produced with the old compiler.
Bah.
Edit: hell, since I love to rewrite code, I think I'm going to redo the compiler from scratch, this time taking in account everything. I haven't been analysing the problem at hand enough, and that's the result! Don't follow my example! ç_ç/
Tuesday, July 29, 2008
Entity System (Part 4)
As I said in part 2, the core of this entity system is how messages are dispatched to entities (technically, to their message handlers). Since handlers have a state and a priority flag, it'd make sense to create an ordered list of handlers, and shoot the message down this list. Of course, upon component installation, the order must be kept and it depends on the above flags.
At this point, I don't care if the "message pipe" must be a list, a tree, an array, whatever; I'm worried about the performance of the system, to be precise about allocations.
In a game, especially such as ours, it is common to have many similar enemies which share the same type of components (to keep the es terminology) - we know that all of them, at least, have a Health component. Since I mentioned allocations, the attentive reader might have already understood that I'm about to talk about object pooling.
Why pooling? I find it logical to reuse some objects over and over, since I'm not sure how long they'll live. They might be short-termed (entity insta-kill), or long-lived, or anything in between. We know that GCs kick in post allocations, and that short-lived objects are fast to collect. We also know that caches need a policy, or they're just disguised memory leaks (and if Rico Mariani says so...).
However, in our case scenario, I cannot predict the life of the objects composing an entity (plus the entity itself). Should I just allocate whatever I want and focus my attention on, say, a funny youtube video? Or should I consider creating a pool of reusable objects, instead of allocating without a specific order? Still, allocations are very fast in the CLR.
And the story isn't over, yet. A message pipe contains many references to handlers. And there will be x message pipes equal to the number of entities times the number of system messages, each of which will contain y references to y different handlers. It's a lot of references to be tracked by the garbage collection, and I'm scared to just think what'd happen if these references kept some objects alive instead of letting the GC collect them.
My solution (and it's far from being the right one, I suppose) would be to pool stuff, even if I have just advised against it in a recent gamedev.net post. With pooling, I have collections of objects ready to be used or already used, and I can access them via an integer "handle" (namely an index). All my message pipes would contain is a list of these integers - thus no actual pointers but indices. Would my garbage collector be happy? Am I wasting my time? I tend to think the latter, since I haven't managed to make up my mind about this matter yet.
I gotta say I find many .net perf advices a bit obscure.
There's also something else which has kept my mind a bit busy between a general ledger entry table and a C/AL codeunit this morning (brrrrr!). Should I suggest the GC to perform a collection when, say, the user reloads the level or changes map? I'd say so, but it isn't necessarily right. I must remember to test this as well at some point...
Premature optimization, anyone?
At this point, I don't care if the "message pipe" must be a list, a tree, an array, whatever; I'm worried about the performance of the system, to be precise about allocations.
In a game, especially such as ours, it is common to have many similar enemies which share the same type of components (to keep the es terminology) - we know that all of them, at least, have a Health component. Since I mentioned allocations, the attentive reader might have already understood that I'm about to talk about object pooling.
Why pooling? I find it logical to reuse some objects over and over, since I'm not sure how long they'll live. They might be short-termed (entity insta-kill), or long-lived, or anything in between. We know that GCs kick in post allocations, and that short-lived objects are fast to collect. We also know that caches need a policy, or they're just disguised memory leaks (and if Rico Mariani says so...).
However, in our case scenario, I cannot predict the life of the objects composing an entity (plus the entity itself). Should I just allocate whatever I want and focus my attention on, say, a funny youtube video? Or should I consider creating a pool of reusable objects, instead of allocating without a specific order? Still, allocations are very fast in the CLR.
And the story isn't over, yet. A message pipe contains many references to handlers. And there will be x message pipes equal to the number of entities times the number of system messages, each of which will contain y references to y different handlers. It's a lot of references to be tracked by the garbage collection, and I'm scared to just think what'd happen if these references kept some objects alive instead of letting the GC collect them.
My solution (and it's far from being the right one, I suppose) would be to pool stuff, even if I have just advised against it in a recent gamedev.net post. With pooling, I have collections of objects ready to be used or already used, and I can access them via an integer "handle" (namely an index). All my message pipes would contain is a list of these integers - thus no actual pointers but indices. Would my garbage collector be happy? Am I wasting my time? I tend to think the latter, since I haven't managed to make up my mind about this matter yet.
I gotta say I find many .net perf advices a bit obscure.
There's also something else which has kept my mind a bit busy between a general ledger entry table and a C/AL codeunit this morning (brrrrr!). Should I suggest the GC to perform a collection when, say, the user reloads the level or changes map? I'd say so, but it isn't necessarily right. I must remember to test this as well at some point...
Premature optimization, anyone?
Subscribe to:
Posts (Atom)