Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / DBP Coding Tips - Modules

Author
Message
Sasuke
20
Years of Service
User Offline
Joined: 2nd Dec 2005
Location: Milton Keynes UK
Posted: 18th Feb 2010 20:38 Edited at: 18th Feb 2010 20:41
I came up with this method while designing my particle engine (and many others) and thought I'd like to share the idea cause I believe it could be very useful to others (or to tell me I wasted my time cause theres a better way). Modules are just bits of functionality created from a system, basically they just break the system into smaller pieces but also optimize it at the same time by cutting down on un-used variables and adding more functionality. I'll use my particle engine to explain this:

Let's look at a basic particle emitter type (not mine):



The emitter sets up how it's particles will be emitted but is pretty baisc. If you wanted to add more functionality you'd just add more params to the type right. But when your emitter becomes as complex as mines is (known as a super emitter) you'd find that you don't use half of the params for each emitter. All these params are just sitting there wasting memory. Here's where modules come in.

Now with modules it would look like this:



I define modules as anything specific to the emitted particle, this is why life is a module cause the emitter doesn't use life, only it's particles. So let's look at a module:



This module defines the life of the emitted particles, it's pretty basic but can be improved which I'll show you later. So lets assign a module to an emitter:



Particle Emitter Module's just reference the module arrays. So _ParticleEmitter(1).Module.Life would be the index reference for _PEMod_Life() array. When a particle emitter is created all the module refs are set to -1, this tells the engine that a module hasn't been assigned to it, so skip this module on updating. So when the emitter is emitting a particle is would check if a module has been assigned and set the particle by the reference array. Example:



So whats the advantage of this, well if you created 1000 particle emitters, it would have 1000 life float variables attached to it which would then be assigned to the particle or the particle references the emitter. Now if all of the 1000 lifes = 1.0, with modules you could assign 1000 lifes to a single float variable, so they all use a single array index. This mean's we've cut away 999 float variables and free'd up a bunch of memory, or another way to put it, we use 1000 integers for the references and 1 float, which is still less than 1000 floats variables. Take into account that there will be a ton more modules full of variables and then you'd saved a ton of memory. Even if you wanted modules only specific to the emitter you still save memory since you not using all of them. There are many others advantages, you could have a group of emitters that share modules, or you could swap in and out modules on the fly by changing a single value, the references. Cool huh.

Once the system is in place, we can then start adding more complex modules and improving on other for instance are life one like mine:



Quick explaintion of this. The DistributionType defines how the life float variable will be distribution. The types are: Float, FloatCurve, UniformFloat and UniformFloatCurve. There's also vector types but there not needed for this. Float is just a constant float value, FloatCurve is a float based on a keyframe curve, UniformFloat are two floats - MIN and Max and will pick a random value between them and UniformFloatCurve is just like UniformFloat, but based between Min and Max keyframe curves. All this does is add a ton of functionality to my life module. The idea being once the the base system is in place, you only have to improve on the modules and not edit a ton of code.

Heres some of my other modules I use in my particle engine:



And what my particle system looks like if you made it in the IDE:



So now we could add more to the system, interaction between present assigned modules and un-assigned modules, module lists instead fixed modules which work perfectly for semi-script systems. I use modules or what I call cell layers on grid systems, so if I had a world based off a grid system and I wanted a paticullar cell to have something like... strong gravity, I could add a gravity layer to it to alter the gravity of that cell. These layers are parts of module lists. So I've added a cell module to the world grid that allows me to add layers to a define cell instead of every single cell on a grid having un-used layer lists. Basically modules within modules.

Just incase this Module stuff confused the hell out of you, I'll show you an example:



I wouldn't use it in this way, but this is just an example of how it works. You would mostly use it for referencing, for instances my particle emitters are just references for my particle emitter actors, which just use the emitter ref ID and emit particle based on the ref emitter and the modules attached to it. Anyway, hope this helps some, and as always, have fun programming. (Let the flames of terror begin)

A dream is a fantasy, if you achieve that fantasy it was never a dream to begin with.
tiresius
23
Years of Service
User Offline
Joined: 13th Nov 2002
Location: MA USA
Posted: 19th Feb 2010 19:54
That is interesting. I find the use of dots in your type declarations to be confusing, but maybe that is just me. I'll definitely take a closer look at this as I am keenly interested in whatever ways are available to contain/augment BASIC language coding practices.

I wonder if there really is a need for all these references. Could you stick them in a single type to avoid the use of so many arrays (and the housekeeping that involves) ?



If you want the x position of an object it is simply _Object().Module.Position.x instead of digging through arrays with get/set functions. And no need for the ugly global g_CurrentObject which messes with your nice modular design.


A 3D marble platformer using Newton physics.
Sasuke
20
Years of Service
User Offline
Joined: 2nd Dec 2005
Location: Milton Keynes UK
Posted: 19th Feb 2010 21:45 Edited at: 19th Feb 2010 21:47
Quote: "That is interesting. I find the use of dots in your type declarations to be confusing, but maybe that is just me."


Saying that, I didn't really notice since it works fine. Don't why I do it, just do.

Quote: "I wonder if there really is a need for all these references. Could you stick them in a single type to avoid the use of so many arrays (and the housekeeping that involves) ?"


Well that's what I did, but I noticed that tons of variables where just sitting there, doing nothing but taking up memory. So I came up with this to get rid of them. It also does seem to do the job aswell, plus there's many things you can do with this method, like dumping un-used modules to save even more memory, there's more. I'll come up with some examples and post them when I'm not busy.

Quote: "If you want the x position of an object it is simply _Object().Module.Position.x instead of digging through arrays with get/set functions. And no need for the ugly global g_CurrentObject which messes with your nice modular design."


As I said, you wouldn't use modules in this way. Module are really anything over the base model or things that the object doesn't require to exist, so for objects, ID, Position, Rotation would be the base. But things that affect the base model could be a module. And your right, I don't know why I added that g_CurrentObject, which I don't need.

A dream is a fantasy, if you achieve that fantasy it was never a dream to begin with.
Sasuke
20
Years of Service
User Offline
Joined: 2nd Dec 2005
Location: Milton Keynes UK
Posted: 3rd Jun 2010 21:17
Just a quick question, does this method actually conserve memory?

A dream is a fantasy, if you achieve that fantasy it was never a dream to begin with.

Login to post a reply

Server time is: 2026-07-25 16:18:53
Your offset time is: 2026-07-25 16:18:53