When is it appropriate to use Types?

Blitz3D Forums/Blitz3D Programming/When is it appropriate to use Types?

Cubed Inc.(Posted 2012) [#1]
I've been getting into this habit of creating types for EVERY entity in my game. This created some much confusion and inconvenience that I decided to rewrite the game's code altogether.
Before I begin the process again, when, in your opinions, is it appropriate to use types when working on a game?


Yasha(Posted 2012) [#2]
Any data structure that isn't a number or a string should ideally have its own type to represent it.

There are a few weaknesses in B3D (to do with the fact that it didn't originally support custom types) that makes this less sensible in practice, but in general, it is as follows: "Here?" "Yes." Use them pretty much everywhere, for everything practical, and you will not regret it.

(If you found that using them was causing confusion, it's a sign that you need to go back to basics and do some more reading, or ask the rest of us some more questions: types are to data as functions are to process: they always simplify the program's expression and should be preferred where possible.)


Cubed Inc.(Posted 2012) [#3]
Actually I do have a question.
How do you parent two object together when they are from 2 different types?


Bobysait(Posted 2012) [#4]
"When" should we use type or not :
- when the size of datas is not fixed : all you can't achieve with Dynamic array without generating a biiiiig array, you 'd better do it with types
For the rest, it's up to the spec of your project to deal with the best way to store datas.
types are for confort, you can store as many as you want (from of to the range of your memory), but it's not that easy to access a specific instance of a type without an other support (because Blitz3D types uses internal linked-list), where a simple array could have been more usefull (or not)

as your citation says :
"It's not about the engine, it's about the person, and how he uses it."
;)


Then, your question "How do you parent two object together when they are from 2 different types?"

You have to think about the structur of your datas before any coding
If you have instances from differents types, maybe you should use a "main" type for your objects, and have sub-types to deal with different kind of objects (and you'll probably have to deal with Handle/Object functions)




the second method is (imho) unoptimized
You create a type with all fields that any sub-type should have required. and a "class" field to specify which kind of type you have created
- advantage : no use of handle/function (smarter code)
- disadvantage : more memory used per instance
more difficult to access specific types



third method :
Use your own Linked-List for types.
(It is generally the way I use types in blitz)
- Advantage : less memory
you can create lists of types that does not contain "all" the instances of the specified type, so you can have an octree based system for entity partitioning, that contain lists of entities

- disadvantage : You'll have to program your own linked-list support and it is not always very fast (depend on the way you do it)

Last edited 2012


Rroff(Posted 2012) [#5]
Theres almost no time you wouldn't want to use types imo tho you need to be a little creative with some useage of them.

You don't need to program your own linked-lists for parent/child grouped types either they are extremely powerful when you start to think outside the box.

The trick is to use dummy type instances as demarcation points between groups of the same type - then you insert a new one after the demarcation type instance for the group it is in and can walk the group until you come to another demarcation indicating the end of the group (or reach the end of the list of types).

Last edited 2012


Yasha(Posted 2012) [#6]
My advice is to try to keep separate in your mind the idea of Types as data structures and by-reference objects, and Types as lists of those data structures. The two are 1:1 in B3D - every time you define a data structure, the engine will automatically create a linked-list of every instance of that type that you create - but that's solely a design decision by Mark, and on a theoretical or logical level, the two aspects of Type-in-B3D have nothing to do with each other. It's only there for your convenience, and there are plenty of other ways to store and access collections of objects, or to get list functionality.

So if you're still not too familiar with individual objects being created on the heap and passed around by reference, you should start by completely ignoring anything to do with the For/Each command (and its friends First/Last/Before/After/Insert): this is really something else entirely, and will not help you understand what the data structures/by-ref semantics are.


H&K(Posted 2012) [#7]
I've been getting into this habit of creating types for EVERY entity in my game
I hope you dont mean that every entity is a seperate type.
(For everyone else ; Is he saying every entity is a instance of a singleton?)


Rroff(Posted 2012) [#8]
While your correct in that commands like first/last/before, etc. will quickly get someone new to it in over their heads I think its important to get your head around these as at a more advanced level they open up capabilities in B3D that a lot of people don't seem to realise exist.

I will try and get some decent fully featured examples up over the next little while as I feel they add a lot to B3D when the scope is realised. (Plus I need to get my head around the most efficent way to implement it).

Last edited 2012


Bobysait(Posted 2012) [#9]
@Rroff:

You don't need to program your own linked-lists for parent/child grouped types either they are extremely powerful when you start to think outside the box.

The trick is to use dummy type instances as demarcation points between groups of the same type - then you insert a new one after the demarcation type instance for the group it is in and can walk the group until you come to another demarcation indicating the end of the group (or reach the end of the list of types).


Yep, but, keeping Head/Tail instances to contain lists of types between them still remains a way to build our "own system of linked-list".

Anyway, at the moment, it's probably premature, but as he wanted to know, here it is.


@Yasha :
For someone new with the blitz3d types, I think the best way to explore them is to test the whole thing about types (internal linked-list too) checking a bunch of exemples to read and try
And understanding "what a type really is", generally comes later
All programmers not coming from an Object Oriented language probably always start this way, and maybe it is the best way to understand them.
(The famous "try and understand by yourself" method)
Then, when the practice is good enough, it becomes more theorical and we can accept concepts of why/where/what/when do we choose a kind of data structur

For a non-beginner programmer, it is different, we have notions about class, data structures, lists, maps, vectors etc ... We probably don't have to deal with thinking about things we already know :)


@H&K :
(quote]I hope you dont mean that every entity is a seperate type.[/quote]
It's probably a mispelled thing
In the french blitz3d community, we use to say a "type" for "instance" or "instance of type", (Yep, it's a bad "habit" ;) ) maybe he does the same here ... maybe
I Hope so ....


So, maybe the first "legitimate" matter is :
TaGames, Have you already done simthing involving blitz3d-Types ? and what do you want to do exactly ?

Last edited 2012


D4NM4N(Posted 2012) [#10]
I would say always!

Even for global variables eg:
Type T_Globals
     var1 = 123
     var2 = 123
     var3 = 123
     etc....
end type

Global Globals.T_Globals = new T_Globals


then you can access everything with globals\var1 etc..
why?
..well, the reason for this is that it is the only "strict" var referencing in b3d, and will not permit you to make variable spelling mistakes (something that is a HUGE debug pain in non-strict languages).



One thing about using types in B3D though (and javascript actually), if you have a function that has a lot of -really- heavy repeated processing of type variables, it is faster to "unpack" them into simple local variables . It also makes it nicer to read. (dont forget to write them back where needed when finished :)

eg:
function doSomething(player.t_player)
    h% = player\handle
    x% = player\x
    y% = player\y

    ....do a million things with h, x and y........

    player\x = x
    player\y = y
end function

note we only write back values we need to be written back, the handle is unnessecary because it is just a pointer to the sprite or whatever and has not changed.

I found this was significantly faster when there are 100s of type access calls. Of course if you just have a few access calls, don't bother.

Last edited 2012


Bobysait(Posted 2012) [#11]
the reason for this is that it is the only "strict" var referencing in b3d


That's not totally true, you can send a local array as function parameter

function Do(Arr%[0])
 Arr[0]=2
end function

local a%[0]
Do(a)
print a[0]
waitkey
end


But you're right, it's a good method for debuging

Other point :
I would say always!

I would say it too, but I also use blitz3d to program some fast templates to test a gameplay or else, and in many case, dealing with types will probably be slower than not using them (see: in programmation time)
So, it really depends on the purpose of the program you're ... programming.
A matter of comparision between :
- time to code/timeline
- required performance
- complexity of datas involved


Rroff(Posted 2012) [#12]
Actually thats a very good idea D4NM4N suprised I didn't think about that, very nice way to both organise and enforce strict useage of globals.

I generally do the 2nd method when handling a lot of data from types out of habit but never really thought about the performance implications - another thing to keep in mind for future reference.


D4NM4N(Posted 2012) [#13]
That's not totally true, you can send a local array as function parameter

Yes sorry, arrays are strict too and faster, but nowhere near as versatile. :D


RemiD(Posted 2012) [#14]
I use arrays (dim) to store most of my pointers and variables, i like how i can access an entity or a variable with its index without having to go through a For next loop. And i often use multi dimensional arrays to define parents/childs.

I use Types only to create/store/delete particles or others things that have a variable list size.

It is a matter of preferences, if the program behaves as expected that's all that matters...

Last edited 2012


dynaman(Posted 2012) [#15]
I used types for EVERYTHING possible. It helped to even make a single instance type for variables - since the compiler will crash on a non-declared type variable but would happily use a non-declared variable, mis-typed variable names are the bane of existance.

Blitz3D types are fast and easy to use as well, so unless speed of exectution became an issue (and I don't recall it every happening) I used types exclusively.


_PJ_(Posted 2012) [#16]
I use Types a great deal too.
I rarely use dim, but when I know there's a specific, fixed-size of data members, I find BlitzArrays also help.
More typically, I combine the two, having a BlitzArray within a Type Field.

Types are nice, since they can be randomly accessed with the Object/Handle commands, and also, you don't need to know how many instances there are or a maximum.


Charrua(Posted 2012) [#17]
There are more pros than cons in using types.
normally the worst thing i found (and as i saw, many others) is to scan a list of typed vars with a for each loop.
This was true until i found the (undocumented lamentably) Object/Handle

normally we has a MyEntity, returned by a blitz function (say PickedEntity or EntityCollided) and we need to find a MyTyped var wich has other properties we mantain associated to it (MyEntity)

if we Name each entity with the Handle to the instance of the Typed var, then we evade the scan with a for each loop.



an example:



@ pj: i post almost over you!

Juan

Last edited 2012


Rroff(Posted 2012) [#18]
Very quick and dirty example of grouping objects of the same type without having to iterate through each one to check what its parent is.

In this example we are using an instance of player objects each with their own inventory group of items.



There is so much more you can do with this tho.

Last edited 2012


RemiD(Posted 2012) [#19]

if we Name each entity with the Handle to the instance of the Typed var, then we evade the scan with a for each loop.



The same thing is possible with arrays (dim) without having to use the "handle".
You can retrieve the index of a mesh stored in a dim by using EntityName(Mesh) after a collision or a linepick or a camerapick and by reading the name of its list and its index number if you have properly named it before.
Also, if you use several Types you have to use more than the Handle in the NameEntity in order to be able to find the correct list.
For example, i use a name for each list like "CHA"+Handle and "ITE"+Handle for lists with types, and "CHA"+Index or "ITE"+Index for lists with dim.

But you can achieve the same result.

The difference is that you can read/write directly a variable or an entity with its index in a list with dim, but i haven't found a way to do this in a list with types. But maybe there is a way.

It is a matter of preferences...


Charrua(Posted 2012) [#20]
yes, it's a matter of preferences, planning and/or needs, as always.

there are other things to take into account like speed/memmory usage

typed vars: dynamic memory allocation (handled by blitz)
arrays: static memory allocation (yes use redim!: manually handled)

or the type check (strict) made by blitz wich isn't an isue if you use IDEAL or a similar editor.

so as you said and i agree 100%, "its a matter of preferences"

it's better to use a tool we felt comfortably, probably because we know better their issues.

Juan

Last edited 2012