Sign in to follow this  

The "action" systems that 2D game frameworks all now have...

This topic is 1110 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am also curious what others have to say about this.

 

I like the idea of doing things in batches so you can sort stuff and only do slow context switches once.  Passing time-delayed messages to everyone can be hard to debug and cause infinite loops.

 

Having said that, if the framework you are using expects to use Actions for everything, then it will certainly be harder to try and do things differently. 

 

Maybe old gamers like us are rare, but I still like to have an init, while loop, shutdown game loop.

Edited by Glass_Knife

Share this post


Link to post
Share on other sites

I used it in cocos (long ago) because I didnt find any other means to control the stuff (like animations) tightly.

I hated it, it requires a bunch of loading code to prepare the actions, and when you need to interrupt it, cancel in the middle or something, it gets even more ugly. ( I dont remember very well thou)

 

In my engine, I have chainable tasks, the purpose of those (from my POV of course) is to use it when you need to execute some code that would be a rare if case in the game loop. Basically, having a loop full of IFs that almost never execute is ugly/poor code, so the tasks works perfectly for stuff like this, since in the game loop is just a tasker.update(delta); call. So I use it as a temporary code executer.

 

One of my tasks is a "delegate task", that basically executes a delegate till it returns false, making it very easy to create new tasks without having to derive a new class (just create a new method and plug on the delegate).

 

Chaining tasks is not as cute as I though it would be when I implemented it. Reusing tasks by reordering the chain is not so obvious and generally I end up with a few small tasks that are almost the same. 

 

The fact that I prohibit myself from allocate memory at run time also requires pre initializing all tasks, with is also a pain in the ass. The task machine works with shared pointers so I basically initialize a bunch shared pointers with noop deleters.

Share this post


Link to post
Share on other sites

I used it in cocos (long ago) because I didnt find any other means to control the stuff (like animations) tightly.
I hated it, it requires a bunch of loading code to prepare the actions, and when you need to interrupt it, cancel in the middle or something, it gets even more ugly. ( I dont remember very well thou)

 

Yeah the trouble with the actions thing that I see is the following:

  1. You often need something to happen that is "an action" in a general sense but that doesn't map cleanly to a particular sprite. It needs to happen to a bunch of sprites. It needs some state to be preserved across modifications to the sprites but not across iterations of the game loop. It is something that just naturally wants to be applied to some sprites in a loop rather than to be called by each sprite.
  2. You need to perform an action on a sprite that will take a long time (in game programming terms) to complete and probably will be cancelled, interrupted, or otherwise transformed before it completes.

Now obviously both 1. and 2. can be done with actions but would you choose to do either this way, all things be equal, if a framework wasn't demanding that you have to? And further, I would say that most "actions" in the games that I write are like 1. or 2. The exceptions would be very simple cosmetic things such as this guy is taking damage so make him glow red or whatever, but very simple cosmetic things are the exception not the rule...

 

In cocos2d-x I was able to get out of the whole action thing by just scheduling an update event on the layer and then treating that like the update in a game loop. I wrote an entire game to cocos2d-x and didn't use actions at all. Basically I used cocos2d-x for the node tree, input, and sound and that was the extent to which I used the framework. I believe it will be possible to do the same thing with Sprite Kit ... I am just posting here to see if I am being stupid. I don't want to be some dude who insists on doing everything the way I have always done it, but it just looks like to me that using the actions system is going to make my code worse.

Edited by jwezorek

Share this post


Link to post
Share on other sites

scene->update(dt);
scene->render()


I'm not sure what you're specifically referring to, but it might be related to that code sample there. That's an inefficient and inflexible way to handle game updates. Even back in the simpler days, that kind of update loop only took you so far before you started needing piles of hacks to get all the different things to update in the right order.

On mobile devices (and the Web) you're also barred from actually having a main loop. They're not allowed. Those OSes do not allow an application to "run forever" but instead require that they only run in an idle or timer callback driven by the low-level OS/library itself. e.g., you can't have a `main` function, but you can have a `onAnimationFrame` (borrowing some HTML5 terminology there) that will be called at some point by the OS/platform when it feels like it (usually at a steady 60 FPS if the application is active, and never at all if it's not active). This is due to the vastly different multitasking models of mobile platforms and the Web compared to desktop applications.

Sensible PC game engines are still heavily event-driven and the main loop serves mostly to pump out events and poll hardware at a steady rate. Since other platforms do this automatically, it makes sense for game frameworks to abstract this detail so that things will work on mobile and the Web while also working on PC.

Share this post


Link to post
Share on other sites

That's an inefficient and inflexible way to handle game updates. Even back in the simpler days, that kind of update loop only took you so far before you started needing piles of hacks to get all the different things to update in the right order.

 

I don't know anything about fancy 3D engines but 2D games indeed commonly have a method that gets called with a time delta on some game stage object or whatever that then updates the state of in-play sprites and what-nots with the time delta and then draws them. Are you seriously saying that that is not common? 

 

Don't know if mobile frameworks are not calling the update method in a simple loop in their implementations but whatever they are doing amounts to a loop.

Edited by jwezorek

Share this post


Link to post
Share on other sites

Are you seriously saying that that is not common? 

That's how I like to do it. However, Qt, being a desktop application GUI toolkit, wants to control the main messaging loop for me, so I have to write my code to react in response to callbacks. Not too much of a hassle, since I still have React(), Update(), Draw(). Having dozens of different callbacks that I'd need to react to would be annoying, depending on how high-level the API is.

Share this post


Link to post
Share on other sites

I'm not sure what your issue is exactly.  Spritekit already has methods for:
update      <---- This would be your game loop
evaluateActions
simulatePhysics
finishUpdate

These are called every frame.  You don't need to use actions to control Sprites you can actually set the properties manually in the update method of your scene:

mySprite.scale = 1.2
 

Apple actually mentions in some of the documentation that this is the recomended way of doing things and that Actions should only be used for one time canned effects or UI animation

 

Cocos2D has similar methods too.  However all the tutorials out there people just tend to use the Actions because they are simple to set up.   If you are doing anything more complex than a match3 or word puzzle game then just drop actions and stick to updating your objects manually.

Share this post


Link to post
Share on other sites

It is interesting to see that most frameworks will force you to use a pattern that you should clearly avoid. We all have learned that

having something like GameObjects and call an update method in every object is bad due to cache misses and so on. This is the gap

that actually ECS tries to eliminate. So in general it is bad practice to do it like Cocos2d.

On the other hand how would you do it when you are such a framework designer? This is the only currently somehow accepted solution.

Since there still is no common vision how a ECS should be designed and there are many different solutions out there it is safe to

fall back to such an approach. But still it is bad design.

Share this post


Link to post
Share on other sites


It is interesting to see that most frameworks will force you to use a pattern that you should clearly avoid. We all have learned that

having something like GameObjects and call an update method in every object is bad due to cache misses and so on. This is the gap

that actually ECS tries to eliminate. So in general it is bad practice to do it like Cocos2d.

On the other hand how would you do it when you are such a framework designer? This is the only currently somehow accepted solution.

Since there still is no common vision how a ECS should be designed and there are many different solutions out there it is safe to

fall back to such an approach. But still it is bad design.

 

Neither cocos2D or SpriteKit "force" you to use any pattern.  There is a simple game loop that you can use to perform your custom game logic however you see fit.  If you want an Entity Component System then write one.  Neither cocos2d or SpriteKit even have "GameObjects"  they have Sprite Nodes in a scene graph.  You should be writing your own GameObjects and which have some kind of access to the Sprite (If you are have written your own ECS then this would probably be your RenderableComponant?).

Share this post


Link to post
Share on other sites

Apple actually mentions in some of the documentation that this is the recomended way of doing things and that Actions should only be used for one time canned effects or UI animation

 

This answers my question. 

 

I know that it must be possible to not use actions to drive a game codebase's architecture in Sprite Kit because, as I said upthread, I have done exactly this in cocos2d-x and Sprite Kit seems to borrow a lot from cocos2d. Actually that is an understaement: Sprite Kit seems to be basically a version of cocos2d, Apple's version.

 

My question was, do other people who have written nontrivial games to Sprite Kit or cocos2d-iPhone or cocos2d-x and have them in the App Store etc. do this too? Or do people use actions extensively? -- unlike the way that I do it.

 

If Apple really mentions in the documentation that you should use a scene object's update method for most game logic then that answers my question. Do you have a link to this?

Edited by jwezorek

Share this post


Link to post
Share on other sites

Our inhouse engine uses GOAP system (goal oriented action planning) and this works better than other in lot's of cases, especially for HOPA games. If anybody is interested in a convenient 2d game engine - feel free to contact me. We're providing it to anybody interested without any advance fee (you pay for engine license only at beta/pre-release stage when you're definitely sure you're going to release the game) and we charge for providing consulting on how to use it, but as it usually takes no more than a few days - it's quite cheap too. 

 

Answering possible questions (I don't read forums at all) - it's possible to make any 2d games basing on it, in particular we're currently working on a Tycoon/city-builder kind and on another "Road to Rome" like one. 

 

Platforms: PC/Mac/iOS/Android.

Share this post


Link to post
Share on other sites

Things get mixed here i think. Actions like in cocos2d are not related to tasks like Update or Render or the like. Actions are just used to ease the change of parameters of an object over time and to chain such. Actions actually have their own Update() method wich is invoked during the usual/root Update(). So it is not a rivaling concept.

Share this post


Link to post
Share on other sites

This topic is 1110 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this