1
\$\begingroup\$

I have a FurGeneration() script in my game; when run, it randomly generates individual oFur objects in specified areas in the game's single Room. Each has a random depth and one of three sprites, and the script produces the impression of dense, layered fur. I've attached a screenshot.

enter image description here

At the moment, the script is working well, as I am using it on relatively small areas. However, my next challenge is to apply this across the single, 20,000 x 20,000 room of my game to produce a consistent field of fur.

My first attempt at this was to create a background sprite, a simple 1000x1000 grey square with its image_alpha set to 0. These would be generated in rows across the entire space of the room, and then each one would have the FurGeneration() script run on it to generate individual squares of fur flush with each other. I've applied this to one 'row' of my games' Room, and the game really slows down; it doesn't crash, but evidently there are just t0o many calculations going on at once.

My question is: is there a way to multi-thread in Gamemaker? Or does it already multi-thread, meaning that this plan is a foolish one? It would be interesting to hear your thoughts.

\$\endgroup\$
  • \$\begingroup\$ Can you not make it tileable? \$\endgroup\$ – MichaelHouse Jun 15 '16 at 15:48
  • \$\begingroup\$ As in create the grey block once, run the FurGeneration() on that one instance, and then duplicate it across the Room when it's done? \$\endgroup\$ – Bonfire Dog Jun 15 '16 at 15:52
  • \$\begingroup\$ Yep, like your example image, make the edges overflow with transparency, then tile them with a slight overlap. \$\endgroup\$ – MichaelHouse Jun 15 '16 at 15:54
1
\$\begingroup\$

Yes, GM:S already does multi-threading programming on its own. Being a development framework, it would be a pain in the neck if it didn't so.

Instead of creating several objects with different sprite_indexes to create a seamless field of fur, you may want to draw them on a Surface first, and then draw it into your room.

What are Surfaces?
Surfaces are a special type of canvas on which you can draw whatever you want, at any moment, with any object, and in any way, and when you're done you can draw such surface in your room (or GUI as well) and see the results.

There are many possible applications of Surfaces, such as fake lighting effects, particles, several blending modes at once, and so on.

So, instead of generating oFur objects randomly, since they are to be drawn on the screen, you can create a Surface and draw random fur sprites on it at random position (using the same position algorithm to create your oFurs); when you're done, simply draw the Surface.

There ARE performance advantages. Assuming your early oFurs weren't supposed to be moving, you can draw on your Surface once only in a particular Event, and then draw your Surface into the room in the Draw Event. This is better than having n oFur instances, which must draw their sprite_index at their x and y position, each step. You draw the single sprites on the Surface once only, and finally draw the Surface at position (0, 0) so that it is able to fit your room.

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ I haven't tried surfaces yet. Can Surfaces be drawn at a depth in the room, in this case to have other features on top of the fur? The fur will need to move, but not necessarily constantly, only on certain events (being touched, wind moving over it, etc.) Are Surfaces still the best option in this case? \$\endgroup\$ – Bonfire Dog Jun 16 '16 at 14:04
  • \$\begingroup\$ Also, taken from the link you posted, "you should note that surfaces require large quantities of texture memory to be used, and so you should attempt to keep them as small as possible. Normally you would try and keep them no larger than the size of the view or display window. This would be an problem for performance, no? \$\endgroup\$ – Bonfire Dog Jun 16 '16 at 14:08
  • \$\begingroup\$ If you need the furs to be interactive, try this: keep you oFurs as individual instances, but have them draw onto a Surface as big as your view, and tell them to draw on such Surface only if they are actually visible by the user, otherwise you don't need to draw them and that will save time (Draw actions are more expensive than others). You can rely on the built-in Application Surface, which is a Surface that will be automatically drawn on the screen by GM itself. \$\endgroup\$ – liggiorgio Jun 16 '16 at 14:40
  • \$\begingroup\$ Important thing is, don't draw everything, but only those objects which are actually going to be seen in the current view. GM doesn't always optimize this aspect for you. \$\endgroup\$ – liggiorgio Jun 16 '16 at 15:18
  • \$\begingroup\$ Thanks. I think that I will keep the Furs as individual instances, create a single oFurBlock unit of them, duplicate that block across the Room, and then perhaps implement this Surface solution to improve performance when panning around the Room by drawing them selectively based on view. \$\endgroup\$ – Bonfire Dog Jun 20 '16 at 13:58
2
\$\begingroup\$

In Game Maker, every object has a lot of built-in variables. Creating an object for every piece of fur may be a waste of resources.

You could create a single object, that would store the basic variables for every piece of fur (sprite_index, position, etc.) and then in it's draw event draw them all at once.

EDIT : as you want to interact with the fur bits, this method may be unsatisfactory. My advice, if you still want to use objects for every fur bit, would be to put as few code as possible in the fur object. For example, create a cursor object, with a slightly wide hitbox, and check for the coordinates of the fur bits inside this box. This way, the calculations will be faster.

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ So this oFurBase object, let's call it, would draw the fur sprites at random, rather than create fur objects? What about if the fur needs to be available for a place_meeting at times? Am I assuming right that this approach would no longer work? \$\endgroup\$ – Bonfire Dog Jun 16 '16 at 14:06
  • \$\begingroup\$ You are partly right. This method focuses on drawing and not on interaction with the fur. But you could still make a place_meeting with the oFurBase object and access the fur bits positions through it. What kind of interaction with the fur are you thinking about ? \$\endgroup\$ – An intern has no name Jun 16 '16 at 14:20
  • \$\begingroup\$ At the moment the potential interactions are a work-in-progress, but at the very least I would need to be able to move and rotate individual fur 'bits' when touched by the cursor or another, specific object. Therefore if doing a place_meeting with the oFurBase object, I would need to know which specific fur sprites were being touched by the cursor. \$\endgroup\$ – Bonfire Dog Jun 16 '16 at 14:24
  • \$\begingroup\$ Maybe you could use some 2 dimension array to store the every characteristic of every sprite, Then if the cursor is above the object, you look the "array tile" in which it is located and change some values in this compartment. The issue with this idea is that you fur bits seems to be randomly placed. Really, if you want interaction, my method is clearly not the best one. \$\endgroup\$ – An intern has no name Jun 16 '16 at 14:59
  • \$\begingroup\$ Thanks anyway. The interaction is a big part of the fur's usage, so it seems that just using Draw won't work. \$\endgroup\$ – Bonfire Dog Jun 20 '16 at 13:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.