I am getting in the habit of sticking to my own beliefs, without considering what others are doing.
What are you doing to improve your number of code lines Vs function Vs features. I am reaching the 15,000 line mark and could do with some pointers.
Ids
One of the first things I've tried which has proven pretty useful is the Matrix1 Freelists. Basically, these provide Ids for any item group you specify by number. You can reserve Ids and make them available per group.
Instead of writing functions like this for each and every UDT based array:
Function HealthPackExists( id )
i = Array Count( HealthPack() )
For i = 1 to iCount
If HealthPack(i).Active
ExitFunction 1
EndIf
Next i
EndFunction 0
Just use the following:
If Available In Freelist( HealthPackList, id ) = 0 )
Or with an alias (sort of) function:
Function Exists( resourceList, id )
bResult = Available In Freelist( HealthPackList, id ) = 0
EndFunction
There are other ways to handle this, but this is what sprung to my mind at the time. This principle applies to adding and removing ids; I also call a delegate function using
which can do some management on newly added items with their ids; they are effectily Events that occur when an item is added, deleted or updated; if I want the event.
How are you handling ids?
Types in types in types..
No more writing x#, y#, z#, width#, height#, name$ etc in each and every UDT for every object. If you are making a game about a ball that rolls in 4 directions on the screen then this is double-over-over-overkill. But if you got more types than folders on your hardrive, then having to rewrite such vague terms is a whole bunch of unjustified finger strain.
In my project, i am dealing with Positions, Sizes and Info types. At first glance you can see it saves me re-writting lots and lots of stuff in types; the compiler (virtually) writes it for me each time I declare a type in a type.
This also makes functions that can work on any type which contains a type. So if all doors and windows have positions, why shouldn't my MoveToPosition function be able to work on doors and windows? Why make a function for each UDT? Just pass in the type in the type like so:
Function MoveToPosition( pos as PosType ) :
` Random egg sandwich!!
EndFunction
Types are also effective at remedying typomania syndrome. (You cannot compile code that contains mistyped type members).
Ultimately, I send these types inside memblocks through the network to be used as function parameters; without any of this rubbish:
mn Add Float Packet, x#
mn Add Float Packet, y#
mn Add Float Packet, z#
mn Add Float Packet, angleX#
` etc etc
Just send my type arrays via memblock through the ethernet cable instead.
Loading and saving resources
I am currently going array to memblock crazy on this one. Nothing is being saved that is not a memblock which contains some header information and a series of arrays. This means I do not need to create much of an object parser. I have not used the simple file commands at all so far; but may use the file blocks for images and media later on.
I am giving the future hackers a tour on how to hack open my games, but I go in expecting the worst anyway.
I am sticking to UDT arrays and memblocks because these are easy to transmit over the network:
Make Memblock From Array 1, MyArray()
mn Add Memblock Packet, Get Memblock Ptr(1), 0, 1
mn Send TCP ` etc
This sends all the array elements, which are usually macros, objects and positions.
What else could be done to make saving, loading and sharing easier? Any tactics anyone?
Functions
Once you put together an if branch or select statement, the only way to reuse your work is to copy and paste it. Your program is not being educated to redo things and you lengthing the code and your compile delay.
I have found heavy function use pretty useful so far. Although there is a tiny little delay during function calls, so far the FPS is doing good. Everytime I write something new, the program can do it again with another variable, because I put it in a function.
Array Pointers
Array pointers are a life saver; I used to only use them for passing specific arrays into functions. But they can also be used for running generic queries; and I find that generic functions are the most used.
Stuff like loading all images in any given text array, or applying all images to each subsequent stage of an object's texture has been cool. Stuff like loading all images in any compatible array, not just one. Some images are for textures and others are for GUI, so you can store them seperately then link to them:
Dim ImageFile$()
Dim ImageList()
Dim IteratorIndex()
Dim String$()
Function LoadImages( list )
Link Array ImageFile$(), list
ForEachString( Get Arrayptr( ImageFile$() ), "LoadImage", Get Arrayptr( ImageList() ) )
Unlink Array ImageFile$()
EndFunction
Function ForEachString( stringArray, function$, iteratorArray )
Link Array String$(), stringArray
Link Array IteratorIndex(), iteratorArray
For i = 1 to Array Count( String$() )
IteratorIndex() = Call Function Name( Function$, String$(i) )
Next i
Unlink Array String$()
Unlink Array IteratorIndex()
EndFunction
Function LoadImage( file$ )
i = Reserve Free Image()
Load Image file$, i
EndFunction i
Just call LoadImages( list ) and it does the work for me.
Call Function Ptr, Call Function Name$ functions are good for storing delagates. Basically, these are allowing me to store function calls for later, or obtaining functions from the user or script files.
These Matrix1 gems save me from having to do things like:
Select Func$
Case "LoadFile"
LoadFile()
EndCase
Case "SaveFile"
SaveFile()
EndCase
Case "DeleteFile"
SaveFile()
EndCase
EndSelect
Instead I just use:
You can also return values and use parameters. These parameters can be defaulted in scripts, INI files or UDT members. So if a script file, INI or UDT hasn't got a parameter specified, the function is called with a default.
I have not fully grasped CoRoutines and Arglists yet, my brain is not having it. CoRoutines seem like a good toolset to use for certain low priorty game object update tasks later.
There is more I am doing, but the point is what you are doing, and how I could save more time and compile attempts.