Multiple sprites in one factory?

#1

Hello all, I am finally back with another game dev venture. My first question to you is asking if it is at all possible to have multiple sprites coming out of one factory. My idea is similar to a candy crush concept with rows of factories dropping random sprites at a constant rate. If factories are not the way to go for this can anyone provide some ideas?
Thank you very much for your time, it is greatly appreciated. If you need more details to help better answer the question please let me know!
Thanks!
V

0 Likes

#2

If I understood correctly, one factory is enough. You can change it is sprite on runtime by changing sprite.play_flipbook .
You can check out Emthree as an example

2 Likes

#3

Ah, thank you very much! I will thoroughly look into this method! Thank you again!
V

1 Like

#4

Hey @Vgreen ,

I didn’t look through Emthree to see what’s happening there, but the way i do this is just with a property on the factory.create.

On the GO’s script put a property “sprite” = 1

Have a table of the animation names of your atlas/tilesheet:

Self.anims = { “red”, “blue”, “whatever” }

And on init() you have sprite.play_flipbook(self.anims[self.sprite])

Something like that, anyway.

1 Like

#5

Ah thank you very much. I see that sprite.play_flipbook is the main part of this. What would the self.anims end up being?
Thanks again!
V

0 Likes

#6

The way i like to do it, described above self.anims is a table of all the possible “animations,” or in your case possibly just single sprites, that a particular GO can have (named inside the tilesheet or atlas). When you create a GO with a factory you pass it a property value (a simple integer) that looks up that position in the self.anims table and uses that particular sprite or animation when creating the object. (So in the above example “1” is the red tile, “2” the blue tile, etc).

The above is “pseudo-code” to an extent. I believe animation/sprite names maybe need a hash() in front?.. I’m not at my computer at thr moment…

This method might be overkill, a more experienced defolder could chime in as to that, but it’s the way i like to organize things, and for me makes iteration easier if/when you want to change sprites/animations and only need to rename in one place (the GO’s self.anims table)

1 Like

#7

Ah, thank you very much for the in depth response, I very much appreciate it!
Have a good one!
V

2 Likes

#8

Just to stick my nose in (I do like me some solution architecture); its worth noting that if you make the attributes of a ‘candy’ dependencies of their creation then it likely that you will have to do it for all of them. IE you need to set the color of a candy before you can create it, you will then also have to set the points that candy will be worth, what animation it plays when it is destroyed, the sound it makes when touched, etc.

This is a valid approach (Data Driven Design, wooooo!) and has several advantages but is something that should be done with intention (mostly so you can take advantage of aforementioned advantages). As far as disadvantages go, the game object that takes in the settable attributes needs to be capable of dealing with every possible permutation of every candy and power up in your game. This can increase the time and cost of debugging and testing (automated or otherwise).

As an alternative approach is to create a factory for each type of candy and power-up and then set the column that they are to spawn in instead. This means that the functionality of the each ‘thing’ is isolated (modules aside) into its own game object and if something goes wrong with the blue candy or the rocket power-up then it should be isolated to their own unique object.

I also feel that this is more in line with the intended use of the Defolds game object factories, rather than trying to make them data driven, and may avoid a pit fall or two caused by unexpected use.

In saying all of this, I am a neophyte to both Defold and Lua so take the above as food for thought rather than wizened advice. :slight_smile:

2 Likes

#9

Excellent points!

Generally I use a combination of these 2 approaches, having a separate GO and factory for each “type” of object, but using properties like the sprite/animation mentioned above for variations of each.

Example, in a platformer-style game there would be a single factory/GO for “breakable objects” per level. There might be 10 different varied looks, each having maybe slightly different rewards for being broken open. The behaviors of the object would be consistent for each look, and all you need is a couple tables to differentiate them.

[main_sprite] 1 = “brick”, 2 = “stone”, 3 = “pot”…
[destroy_anim] 1 = “destroy_brick”, 2 = “destroy_stone”, 3 = “destroy_pot”…
[reward] 1 = “10”, 2 = “20”, 3 = “30”…

Then you just reference each table with table[self.type] throughout the object’s life.

I do think you’re probably right with regards to OP’s use-case, though. If each object has unique behaviors in addition to unique looks, then it would likely be best to have a separate GO and factory for each one.

That beinf said, I’m stubborn, and I like looking at these comforting little data tables as I’m coding, so I would likely still do it my way even with unique behaviors :joy:

2 Likes

#10

These are some great points listed. I like the concept of using different game objects. This would allow for any overlap bugs to be greatly minimized. This method would probably work best for a visual person like me seeing that I would be able to individually set locations of each specific candy. This method would also make it easy to introduce new aspects later in game. An example would be adding in new candies or power-ups.
Thank you very much for taking your time with this response!
V

1 Like

#11

These are great points as well. Using a combination of both methods would most likely provide the best outcome. I will tinker in both and see what I can make of them! Being a relatively new Defolder, it might take some time, but once the result is finished, I will be sure to let you guys know how it went! Thanks again for all the time you put into assisting me!
V

2 Likes

#12

I personally prefer the data driven approach where you have a single game object type with script properties that get set upon creation.

The other solution with multiple game object types and factories does also work and I guess it’s in many ways a matter of taste and preference. The multiple game object type approach is probably easier to grasp for someone coming from an OOP background.

3 Likes

#13

The multiple game object type approach is probably easier to grasp for someone coming from an OOP background.

This guy. (Which is to say I come from a OO background). :smiley:

At the risk of going off on a tangent; is there a definitive intent in Defolds game object factories for which one of these it is intended to support? Both? Data Driven seems somewhat blocked by not being able to set ‘public attributes’ to strings (So can’t use them for a dialog system or such ((you can work around this but it starts being counter productive fairly quickly).

Also; does the data driven approach hold true for collection factories as well, and if so, doesn’t trying to having a boat load of game objects in one collection then trying to turn them all off and on get really hard really quickly?

I don’t mind either way incidentally, I am quite happy to use either approach (or most likely a little of column A and a little of column B) but am interested to know if the Defold team had an intended usage pattern in mind when they wrote them.

1 Like

#14

I 100% back doing it the way you like doing it.

My point was more to outline out the advantages and disadvantages, in my opinion, of the approach.

If it works, its good code. :wink:

1 Like

#15

You can use ”hash” as a property type, and can then input a string, e.g ”DLG_GREETING_0” which is a very common way to index dialogue data (e.g when switching between localized languages)

2 Likes

#16

Sure, which is certainly a valid approach.

But if you get your dialogue exclusively from a json file, then I would imagine you would need to load the file into memory, hash the name of all the ‘elements’ so that the hashed attributes have something to look up.

If you could pass in a string, then you don’t have to do that, the function just goes and grabs the name of the attribute straight from the file. Which is likely a lot slower than above approach but that’s unlikely to make an actual difference in most use cases.

Amusingly the second approach can handle the json file being altered on the fly (mostly) while the first cannot. You can make the first approach ‘hot reload’ the file under certain circumstances but then the performance issue flips; the second approach being more efficient than the first.

In saying that, until I actually end up having to implement any of this, it doesn’t really matter. I just enjoy the theorizing. :smiley:

Feel free to close this off, I have derailed it enough.

0 Likes

#17

I would argue that you should get your dialogue and other text from a Lua file (which may have been autogenerated from json).

0 Likes