Greetings.
I decided to make this thread because I have noticed a few posts lately by people asking how to speed up their game, or how to squeeze those few extra Frames a second out of their game so they can run it more smoothly, and the answers seem to be kinda spread all about the place.
Ok, down to business.
Firstly, I must say, in general, there is no *Specific* way to speed up your particular game, as each game has different methods for doing different things. But, I'll tell you some no-no's and some must-do's to get you on your way to uncovering those last few Frames a Second.
DBC
The Matrix.
In theory, this is a great idea, and an easy way to make a level. But, in practice, it tends to kill of your FPS infront of a fireing squad.
Why?
Simply, there are too many polygons being drawn per loop.
A matrix consists of tiles. Each tile consists of two triangles. Each of these triangles are double-sided. Each of these triangles are being drawn *every* loop, and there's nothing you can do to stop it. Imagine a 10x10 tile Matrix. That's 100 tiles all-up, each with 4 polygons ( two double-sided triangles ), so, that's a total of 400 polygons in just a 10x10 Matrix!
What can I do?
Well, first off, don't use a Matrix.
Unless you're really unsure, I suggest using a .x terrain that you can create in one of many, many free programs ( some even written in DarkBASIC itself ), and divide that up into sections. That way, you can hide the sections that aren't on-screen, thus meaning less polygons to be drawn. And since when you make a terrain, it will most likely be single sided, you have then halved the number of polygons straight away.
Textures.
When you're using Textures for terrain, and sometimes even objects, it seems that your program slows down somewhat unexpectantly.
Why?
Most of the time, this is because the textures are *too large*. If you have a 512x512 texture that you are using to paste onto a tile that is much smaller than that, and you load that texture, it is going to take up lots of memory in the Video Card ( the textures are turned into Bitmaps when loaded into VRAM [ Video Memory ], so they take up alot of space ).
If you're using this texture on multiple area's on a terrain or object, the program is having to draw that large picture each loop. Thus you lose Frame Rate.
What can I do?
Firstly, reduce the size of the image.
[
Updated 4th July '04]
Secondly, when you load the image in, you can optionally set it to not be Mip Mapped ( Mip Mapping involves creating multiple instances of the texture, at different resolutions, for LOD [Level Of Detail] purposes. This increases the amount of VRAM used by each texture. ).
[/Update]
Primitives.
DBC and DBP's built in primitive objects ( Sphere and Cone in particular ) are very high in poly count. And drawing lots of these means too many polygons on screen, thus, lower Frame rates.
Why?
Well, that's just the way it is.
What can I do?
Simply use your own model. Just make a simple cone or Sphere in an external application such as JTEdit or GMax etc, and load that in. You will be able to get a much, much lower polygon count without any significant visual quality loss.
Colour Object.
This command can slow down your program significantly if used in excess on many different objects and with many varynig colours.
Why?
The Way DBC and DBP "Colour" the objects is simple. It makes a texture of the colour specified, doesn't mip map it, then loads it directly into VRAM ( Video Memory ). The textures are often too big, and are quite unecessary.
What can I do?
Simply make your own, single coloured texure and load that in with the model. There should be a slight increase in the speed then.
Sprites
As most of you probably already know, DBC's 2D commands are quite slow, in particular, the drawing commands and the Sprite commands.
Using these commands in high quantities can result in slowed Frame rates.
Why?
The drawing engine was never fully optimised to be it's best quality. But I'm sure there are some other factors along with that too that I am unaware of.
What can I do?
Try to limit your 2D operations.
One way around this problem, is to create Plains and texture them with the images, and use them like sprites. This will give you alot more speed and help to keep your program running smoothly.
Unecessary Caculations
You may be using un-needed loops. Doing too many checks when they're all not needed. Recaculating distances all the time instead of defining it at the start. Whatever the reason, you may be executing redundant caculations, thus putting extra work on the processor when it's simply not needed.
Why?
Think about it. The more calculations you have to carry out per loop, the more work the processor has to do.
What can I do?
Have a look through your code.
Use a method called "Steping Through" where you read the code line by line, and have imaginary numbers written down on a piece of paper. And you pass these numbers throughout your code as if the computer was executing the commands. ( This isn't the best method for programs with large amounts of code, but shouldn't be a problem if you're modulated the code )
Check to see if you've got two For...Next loops in the one loop that are both using the same number ranges, and are both being executed each loop, but you've put it in twice simply because you needed to do two different things. These should be merged.
Put in checks to see when a condition has become true so you can break out of a loop when it is no longer needed. For example, lets say in a For...Next loop with values from 1 to 200, you were trying to check a random condition. Now lets say that the condition became true on the second loop. Normally, the program would execute another 198 loops before it continued, but if you put in a simple If...Then statement, you could break from that loop and continue your normal execution of code.
Also, if there is a constant that you do not need to calculate each loop. Such as the radius of an unchanging circle, compute it before entering the main loop, and store it for access later.
Similarily, if you have a large equation that keeps using calls to Object Position, or some such property retreiving command, get the value and store it, then just use that variable instead of the whole command. It is much faster to reference a variable than it is to call Object Position 40 times a loop.
[EDIT]
Added 8th June '04
Object Drawing
When objects are drawn in DarkBASIC ( or any other 3D program for that matter ), All polygons that are on the screen get "drawn" even if they are facing in the wrong direction ( ie, away from the camera ). This can result in masses of away-facing polygons being calculated and drawn unecessaraly.
Why?
Well, in lot's of programs ( including DBC/P ), the away facing polygons can still be "seen" by shading the back-side of them a different colour to forward facing polygons. This is usually for modeling purposes or for seeing how a model is constructed, but in some cases, as is most likely the case in DB, the model might not be closed ( you can see "into" the model in area's ) so the away facing polygons are drawn so that parts of the model don't apear to disapear... By default, all polygons in a model that is visible get drawn to the screen.
What can I do?
Use the
Set Object command to turn culling on ( set the "cull" flag to 1 ).
Culling is the name given to the process of calculating ( usually using vertex or face normals ) which way a polygon is facing, and deciding whether ot not to draw it depending on if it is facing the view port.
You should only use this command if your models are "closed", otherwise, it will seem like parts of the model just disapear.
Artificial Intelligence ( AI )
larger scal AI routines usually involve larger scale calculations. Things like Mass PathFinding, Mass AI item controll, and Mass AI bullet code tend to tie up the processor quite a bit.
Why?
Well, if you look at almost all AI scripts that are quite involved, and contain alot of code, then you'll see why straight away.
What can I do?
Limit AI routine execution to one routine per each 5 game loops, or for less intense calculations, per 3 game loops.
In this manner, you free up the processor to do other tasks while the AI is not being run.
Also, you can then divide up your execution, so that you have a sinlge routine per loop.
For example, PathFinding every first loop, Item control every second loop, and Bullet Control ever third loop, then back to PathFinding.
Usage of Memblocks
MemBlocks are just that, blocks of Memory. These blocks are area's of protected memory created in RAM by DBC/P that you have full write and read access to. You can use these area's of memory to directly access certain information and also to store certain data for much quicker acess than by conventional methods.
Why?
Well, when accessing a MemBlock, you are directly accessing area's of RAM ( don't worry, as I said, it's protected, so you can't crash your computer... Unless you really try to, anyway ), thus, you are not having to use commands ( which take time to execute ) to access data that is in RAM, ie, you're going directly to the memory rather than taking the round-about way ( in some cases ) by using DB's commands.
What can I do?
Firstly, you have to have the Expansion Pack ( comes free with DarkMATTER, or you can get a 30 day trial by upgrading to patch 1.13 ). This allows you to use the MemBlock commands ( and the DLL commands ).
MemBlocks can be used in many different routines.
As arkheii stated, they can be used to store ( using one of the many conversion to MemBlock commands ) certain data items such as images and/or object mesh data.
Once you have stored these items in a memblock, you can directly access and modify them without having to go via DBC/P's inbuilt commands.
As an example ( again, that arkheii suggested ), you can modify images on the pixel level via a MemBlock ( of course, only after you have converted the data to a MemBlock first ), which is faster than modifying them on an off-screen bitmap.
Another use is for Mesh Deformation ( refer to the code Base for this. Tip: Search for "Mesh To MemBlock" ).
Usage of Dynamic Link Libraries ( DLL's )
Due to the way that DBC creates its exe files, it is faster to make ( or get ) a pre-compiled DLL which has certain functions in it that you might require, and access them that way rather than use the in-built commands. For example, collision routines ( the major example here is Nuclear Glory's DLL ).
Why?
DBC is an interpreted language. This means that when you "compile" your code, it is turned into a little .exe file which has with it an interpreter. Think of it as an English to French interpreter. The English is your code, and the French is what get's calculated and displayed on the screen.
The Interpreter reads the english, line-by-line and repeats it exactly in french to a frenchman.
Even when the Interpreter get's back to the first line after it has read it once ( or even a thousand times ), it still has to translate it into French. As you can imagine, this is much slower than if all the English had just been converted to French, then that read by the Frenchman directly... Well, that's exactly what happens to a DLL ( and DBP source code too ). Thus, the English ( now French ) is read much, much faster.
In this way, the DLL will run faster than the exact same code in DBC ( within reason of course ).
What can I do?
Firstly, you have to have the Expansion Pack ( comes free with DarkMATTER, or you can get a 30 day trial by upgrading to patch 1.13 ). This allows you to use the DLL commands ( and the MemBlock commands ).
You need to also get ( or make, using C or C++ or Delphi, or other, depending on your language choice ) some DLL's.
Once you have these DLL's, you can simply use
Load DLL in your code, then
Call DLL to execute the functions that are held within the DLL's structure.
[EDIT]
9th June '04
Set Sprite
As a continuation to the General comment made about sprites in DBC, here is some aditional information.
BackSave and Transparency on sprites slow down your Frame rate somwhat.
Why?
Using BackSave, DBC is then responsible to copy and store the area of the screen behind the sprite, then restore it once the sprite moves, or is removed.
The Transparency on sprites is worked out by determining all the pixels that are black on this sprite and making them transparent. This is obviously slow.
What can I do?
You can use the Set Sprite command to turn off the backsave and transparency options, however you will then be responsible for restoring the screen ( usually using
Cls )
Also if you don't need black on a sprite to be transparent turn off transparency and you will also gain a performance boost, especially in DBC.
[Addition added 21st June '04]
Ok, it has been brought to my attention that using the BackDrop instead of Cls to clear the screen is *not* a speed increase, but a hinderance.
Here is a demo.
[/Addition]
[EDIT]
14th June '04
Hiding Objects
In DBC's internal engine, when it draws objects, it still draws all those that aren't on the visible screen. As you can imagine this is somewhat of a speed hogger at times.
Why?
That's just the way it is I'm afraid.
What can I do?
Every so-often ( once every 5 or 6 loops say ) Do a check to see if the objects are on the screen. If they are, and they're visible, Hide them. This will stop them from being drawn unnecessaraly.
The code for this would be:
If Object In Screen(x) = 0 And Object Visible(x) = 0 Then Hide Object(x)
This should give you a marked speed increase if you are using alot of objects at any one time.
Note:
The Object In Screen(x) command has been reported to not always report the correct information.
[EDIT]
15th June '04
Set Camera Range
The Camera Range determins the distance in world units away from the camera that polygons are drawn. Any polygons that are further away than this distance will not be drawn.
Why?
Well, imagine if you had an infinite draw distance. This means that EVERY polygon in the entire world would be drawn EVERY loop, weather or not it was so far away as to be un noticable, or is behind the camera.
What can I do?
Use the Set Camera Range command to set the minimum and maximum draw distances.
The Minimum Draw Distance is the value that as a polygon approaches the camera, if it get's too close, it is not drawn.
The Maximum Draw distance is the value that as a polygon goes away from the camera, if it goes past this distance, it is not drawn.
As you can see, this can allow you to speed up your game quite alot, espectially for those games that have a high camera angle that cannot see too far ahead. For this you would set the Maximum draw distance to relatively low.
A fair amount of experimenting is required.
[EDIT]
24th July '04
Side Note;
Bibz1st and Robin ( Author of MagicWorld ) came up with a solution to slow running 1.13 exe's;
"Having recently had speed problems regarding an exe made in DBC ver 1.13 enhanced, the rather excellent Robin King (author of MagicWorld) suggested that it might be that later versions of DBC have more modules in them so that resulting exe's have more work to do when running therefore slowing the program down,so I uninstalled my all singing/all dancing version of DBC and reinstalled the bogstandard ver 1.08 off my CD, the new exe I made ran like a dream.
So maybe this tip will work for you if you run into speed problems,it's worth a try."
There's a few points for you to start with. I hope this helps any and all
If anyone wants to add anything, just say so and I'll fix it up. Also if something I mentioned is incorrect, I can fix that up too
Happy codeing,
Jess.
Team EOD :: Programmer/Logical Engineer/All-Round Nice Guy