Game Development Community

Back to Basics: SimGroup vs SimSet

by Dreamer · in Torque Game Engine · 11/05/2005 (1:55 am) · 28 replies

I'm going to start a series of threads on stuff I should know but can't remember anymore, called back to basics, this way folks can have a quickly searchable series of topics, for instances, when they have forgotten more about a topic then they remember, like I seem to be running into more and more these days.

My first topic (and yes I'm inviting full comments and opinions), is SimGroup vs SimSet.

Recently I purchased RTS and while going through the code I noticed something that at first I thought was quite odd.

// Create simset to track selection
   %this.selection = new SimSet();
   
// Create simset to track buildings
   %this.buildings = new SimGroup();

This seemed to me especially peculiar, since first of all, my instincts would have been to use an array for both types and secondly, shouldn't they both be the same?

Turns out after a bit of digging the answer is a resounding NO!

A SimGroup is a much more restrictive form of SimSet, in that you can only have a single object type in a group, for instance buildings belong in the buildings group. So in this case at least, since any number and type of objects can be selected at anyone time, we want to place all of our selected objects into a Simset.

This updated information is from Stephen Zepp an employee of GarageGames.
Quote:
There is no other reason to select a SimGroup over a SimSet, and in fact arbitrarily using a SimGroup over a SimSet is probably a bad idea until you understand the complexities. There is are no memory/performance improvements in a SimGroup over a SimSet (it's the same underlying code, just that SimGroup implements the restraint that a SimObject can be a member of one and only one SimGroup.


That would mean that since buildings all belong to one group at a time, we want to place them into a SimGroup. However Stephen further goes on to say, that when he made his mod to RTS the buildings in a SimGroup, were the first thing to go, replaced instead with a SimSet.

Eitherway, once created SimSets and SimGroups are handy ways around the inherent limitations of Array handling in Torque. Array limitations are the subject of my next back to basics discussion topic.

Feel free to leave input.
Page «Previous 1 2
#1
11/05/2005 (9:47 am)
Another difference I learned between simsets and simgroups is that an object(handle) can only belong to one simgroup at a time, whereas the same object can occupy multiple simsets. if an object in a simgroup is assigned to another simgroup, it gets removed from the first.
#2
11/05/2005 (11:07 am)
Also, SimGroups and SimSets are much better than arrays when you need to search through their contents. The engine deals with this, you don't have to do costly iterations in script.
SimGroups also destroy their subobjects when the group gets deleted, SimSets don't.

--
Hans
#3
11/05/2005 (11:52 pm)
@Sean this is interesting to know for instance in an inventory situation, you could have 2 simsets one for a backpack and one for items that are equipped. Then moving items from backpack to equipped is as simple as adding the object to the equipped simgroup, thereby negating the need to delete the object from one array and copy it to another. There are other uses I could think of for this as well, but thats the first that comes to mind.
#4
11/06/2005 (1:07 am)
Hmm i'm currently using a simgroup for all my inventory. it's good information to know the differences between the group and the set.
#5
11/09/2005 (10:49 am)
Just to clarify: There is no logical reason to use a SimGroup over a SimSet unless you require the property that a particular object can never be in both your SimGroup and another SimGroup.

There is no other reason to select a SimGroup over a SimSet, and in fact arbitrarily using a SimGroup over a SimSet is probably a bad idea until you understand the complexities. There is are no memory/performance improvements in a SimGroup over a SimSet (it's the same underlying code, just that SimGroup implements the restraint that a SimObject can be a member of one and only one SimGroup.

And to note on the buildings: quite honestly, the use of a SimGroup there was an implementator's poor choice IMO. It was one of the first things my personal project changed ;)
#6
11/09/2005 (10:57 pm)
@Stephen thanks for the clarification, I will update this as soon as I have a few moments.
#7
11/16/2005 (1:01 am)
@all thanks!
#8
11/16/2005 (4:13 am)
You know this type of info would be good on tdn.garagegames.com :)
#9
11/16/2005 (4:26 am)
It'll get there eventually, I'm just allowing time for corrects, additions and comments as to thier utility. Also I can't seem to log in to tdn reliably without being kicked out every second or third page view.
Furthermore, it doesn't seem to recognize me as a valid RTS or T2D license holder half the time.
So until then, comment and correct away!
#10
11/16/2005 (4:29 am)
Just noticed for your comments...

// Create simset to track selection
%this.selection = new SimSet();

// Create simset to track buildings
%this.buildings = new SimGroup();


says create simset for both. is that a typo?
#11
11/16/2005 (5:04 am)
Well it's copied and pasted from the source code so it's not my typo, if thats what you mean, but good catch.
#12
11/18/2005 (9:56 am)
As I mentioned in my post above, it was either a typo, or a possibly poor implementation decision. I would suggest simply making both of them SimSets.
#13
12/23/2005 (7:58 am)
Good info. I believe SimGroups are perfect for inventory. When you add items through the mission editor, you should place them in a Items SimGroup. Then when the player picks up an item, you just do an Inventory.add(%obj) and it's automatically removed from the world and added into your inventory.

To drop an item, you just do the opposite.

This assumes you have an Inventory SimGroup in place:
new SimGroup (Inventory);

Now the question is, how do you attach a SimGroup to a Player's or NPC's object?

Ideally, this is what I'm trying to do but of course doesn't work:
// Create the player object
   %player = new Player() {
      dataBlock = PlayerBody;
      client = %this;
    [b]playerInv = new SimGroup ();[/b]
   };

Any ideas?

Nick
#14
12/23/2005 (8:54 am)
I think what youre trying to do would work except for the fact that you're trying to do a new() inside of another new(). i don't think you can nest new statements. instead of attaching the simgroup to the player during creation, just do it at some other point.

%player = new Player(){
    dataBlock=PlayerBody;
    client=%this;
};

%player.playerInv = new SimGroup();
#15
12/23/2005 (8:57 am)
This is what I'm trying to do, but a couple of things:

- I would use a SimSet, not a SimGroup. As above, there's never much reason to pick a SimGroup over a SimSet.
- My understanding is that when you add an object to a SimSet (or SimGroup), it doesn't remove the object from the world. In fact, this is exactly why I'm trying this method - when the player picks up an object in my game, I don't want the object deleted, just "stored". So I add the object to the SimSet, and then set the object's visibility to false. It disappears from the world, but it still exists.

In your above example, instead of using

playerInv = new SimGroup();

I would instead use

new SimSet(playerInv);

and then when you want to add an object to the inventory, you just use the playerInv.add(%obj) statement.

Edit: as Sean said, you don't need to put this inside the creation of the player object.
#16
12/24/2005 (6:58 am)
Sean, you're right I forgot that. Thanks!

Rubes thanks for your input. Though I think that when you add a world object to another SimGroup, it does get removed from the world's MissionGroup. However, it still shows in the mission so all you need to do is:

%obj.setHidden(true);

Basically, an object that is added to another SimGroup does not get deleted, it just moves from the MissionGroup to the new SimGroup and that's the advantage I see for using SimGroups for an inventory.

When the player throws the object, all you need to do is
MissionGroup.add(%obj);
%obj.setHidden(false);

and the object is removed from the Player's inventory array. I may be missing something though.

Nick
#17
12/24/2005 (8:01 am)
No, I don't think you're missing anything; that's essentially what I meant. I had thought when you said "removed from the world" you meant deleted. But we basically said the same things with regard to making the objects invisible once picked up.

I'm not sure about adding the object back to the MissionGroup once dropped, though. That's a good point, I'll have to look into it more.
#18
12/25/2005 (4:02 am)
And if you want to let's say save the game, you also need to save a copy of the mission.mis file along with the save data right?
#19
11/16/2006 (2:18 pm)
I'd just like to say that this was an excellent idea (to have Basic Topics in the forum) and an excellent thread. I've been coming across a lot of issues that aren't in the manual (because it's basically a code list), and aren't in the examples (because they're specific to one situation). Having a reference that explains how the item actually works, and doesn't just list off the syntax, is invaluable.

I've been using SimGroups to handle item creation. I have multiple types of treasure and I wanted to "reuse" them. For instance, create more than one piece of Amethyst. The problem was, without a container to store the originals in, any changes made to the first item, were also made to the second. By using a SimGroup, I was able to store the originals (for instance, all items of type "GemObj") and then copy them whenever I needed to create a new gem. In that way, the created object had all the attributes of the "base model", but each individual gem could be altered as the player interacted with it.

This didn't help me when it came time to have an enemy pick up the treasure and store it, however, since the enemy might pick up a GemObj, a HouseholdObj and a JewelryObj. I couldn't figure out why he'd hold 3 gems and then as soon as a household item came up, the SimGroup would either list just the household item, or TGB would crash entirely. Nuances like this are good to know and are never addressed in the docs!

Please, someone, pick this idea back up with other topics! You just saved me pulling my hair out!

-Net
#20
11/16/2006 (2:26 pm)
Okay, just as an addendum, my problem *isn't* solved. TGB just crashed again. I have changed the SimGroup into a SimSet. I'm running listObjects() to follow what's in the set at a given time, and here's what happened:

First iteration, thief picks up a piece of Jewelry. List shows id #.
Second iteration, thief picks up a Gem. List shows id# of piece of jewelry, and TGB crashes as it begins to list the gem id.

Jewelry items are of superclass JewelryObj and gems are of superclass GemObj. They both have their own SimGroup for the originals, and then copies are made and dropped into the scenegraph. Do I have to change their "containers" to SimSets too, now?
Page «Previous 1 2