Want AI, Gestures, 3D, Inventory, or Menus???

  try{ getFittingBoard(new Topic()); }
catch (Exception e) { postHere() };

Want AI, Gestures, 3D, Inventory, or Menus???

Postby IFL » Mon Oct 31, 2011 9:48 pm

(Looking at the description of the other boards, none could facilitate this topic. Please ignore/excuse any pointless-narrative or side-topics that might come up.)

I like sharing what I know and some people need coding/design guidance. I'll list what I've done in regard to AndEngine and, if anyone is interested in specific topics, I'll let you know how I did it. I might share code (or pseudo-code at my discretion) so just ask if you have an interest. If requested, I can also provide my design references for everything here.

Here's what I've done:

Complete AI system... I'm proud of this project :D . It has animations, emotions, beliefs, desires, intentions, and a nifty little node-editor... (screenshot is of a character deciding if he should chase the player)
AI_NodeEditor.jpg
AI_NodeEditor.jpg (70.78 KiB) Viewed 2725 times

Gesture-based touch-input... Allows lasso-selecting any number of items and calling functions based on how the user draws with multiple fingers.

Orthographic 3d rendering system with physics... It's like isometric, but without the stupid cardinal-direction-locking camera. You can actually view an entire 3d scene from any heading. This is the largest project that I've done with AndEngine. It was my main focus for several months :oops: .

Inventory... Loads from a database file. Can create/edit/delete items from the database file at run-time. The run-time inventories based on the global database take up minimal ram and allow sorting items by type, base-value, weight, or custom characteristics. Tied into the AI system.

Menus... Created from the AI system. Easy to animate. Has a scene manager that can retrieve multiple scenes by their names.



I could share my knowledge up-front without prompt, but I'm sure that no one needs to know all of it. Plus, that would take a lot of time. This way I get to explain/discuss it in small portions. I'll also give my opinion on how to do stuff not listed here. I love discussing game design. I'll be deleting this thread if it doesn't catch on after a couple of days. Cheers.
User avatar
IFL
 
Posts: 177
Joined: Fri Mar 04, 2011 6:28 am

Re: Want AI, Gestures, 3D, Inventory, or Menus???

Postby Mathew » Tue Nov 01, 2011 11:16 pm

Very interesting, but could you please post this image with higher resolution? Because I can hardly see anything even with big enlargement, thanks.

I'll also give my opinion on how to do stuff not listed here. I love discussing game design


I would be really thankful to hear from you how would you do following game "feature"

As you already know, I'm making mario style game, but much more advanced. But unfortunately there is limitation of course, because of performance issues. I'm trying to implement "monsters" into my game, nothing really advanced at beginning - simple 'monsters' which may move in right/left direction or fly or something, depends on monster type. First solution which comes on minds, is simple DynamicBody -> it would meet mostly every needed condition for this monster, such as physic handling, contact listening and so on. But dynamic body is so expensive for our devices, and obviously I need couple of monsters per every scene, so game becames quite laggy (while there is like 58FPS without those test monsters)

I have been asking about this already, and I received help from different member of this forum, but I would like to hear from different people as well - like you, maybe you will know better solution.

I had many ideas about how to do it so far, for example limit every level to have only one monster of each type and simply moving those monsters to next positions (and disabling player to go back [left direction])

Thanks for any ideas!
User avatar
Mathew
 
Posts: 1073
Joined: Sun Jul 31, 2011 2:49 pm
Location: Tarnów, Poland

Re: Want AI, Gestures, 3D, Inventory, or Menus???

Postby IFL » Thu Nov 03, 2011 5:38 pm

Mathew wrote:Very interesting, but could you please post this image with higher resolution? Because I can hardly see anything even with big enlargement, thanks.

I scaled the image to hide an important part of my generic agent routine :oops: . Is this quick example of a sub-routine good enough?
AI_NodeEditor_Large.jpg
AI_NodeEditor_Large.jpg (272.4 KiB) Viewed 2701 times
This example isn't very practical, but I think it gets the point across. It starts at "Is Player near?".

Mathew wrote:I had many ideas about how to do it so far, for example limit every level to have only one monster of each type and simply moving those monsters to next positions (and disabling player to go back [left direction])

I think you're on the right track... It really depends on how much time and work you're willing to put into it. I'd suggest using a dynamic level unloader/loader that utilizes object pools. Objects that are far off-screen can be recycled for use in the about-to-be-shown parts of the level. As for physics, the level loader can do something similar. This approach would allow the player to go backward through the level without having too much of a performance loss. I'm unsure about how much processor would be encountered by attaching/detaching several objects each frame, but I'm betting that it would be negligible.

On top of the level loader, and even if you don't use a level loader, make sure to cull off-screen objects. It's as simple as running a for-loop to check every sprite in the scene, but it makes gigantic levels possible. I had an unreleased project called SpyTower that experienced a lot of lag when it came to large levels. The previous game engines that I've used culled automatically so I didn't even think about it being a problem. The fps maxed out after I implemented simple culling.

Don't limit the monsters. If you use a pool, then it should really only matter during initial level loading, but I think the benefit of having multiple monsters in a level makes even an initial load-time worth it.

Take my advice lightly - it's far from perfect and I often overlook obvious solutions. Having said that, here's how I'd set up your game...
Have a sprite manager that creates pools of textures. The textures should be assigned an ID number.
Have filler-entities that just hold the position of where you want sprites. They would be nothing more than 4 floats (x,y,rotation,scale) and an integer (texture ID number). You can always add more variables if needed for some reason.
Use an extended-scene class that contains an update thread to handle the placement/visibility of sprites to the filler-entities.
Do something for the physics similar to the sprites. You can even use the placement/visibility portion of the scene to apply the physics bodies.

I'm sure that I missed something, but I hope you get the idea that I'm trying to convey. There's no sense in limiting the number of on-screen physics objects if that's what you need. I guess my solution is just about making the graphics perform well to make up for the physics.

If I confused you, let me know. I think I confused myself. :lol:
User avatar
IFL
 
Posts: 177
Joined: Fri Mar 04, 2011 6:28 am

Re: Want AI, Gestures, 3D, Inventory, or Menus???

Postby Mathew » Thu Nov 03, 2011 8:56 pm

Thank you, I guess I got your point.

About culling, thats right, I wasn't really sure at beginning about what this method does, but in fact without this method used for my sprites, there was LARGE FPS lost, so thanks to this method ; ) Couple days ago I realised it prevent from rendering while object is not visible in the camera.

I will try to realise your idea, its even quite similar to my previous idea which I had in my mind, so it means it may work :D

Thanks

Also I think about this "replacement" of the objects (their position, reusing them instead of creating plenty of them) I guess I will try to reuse only those "advanced" objects such as those using physic, coins with animation and so on.

Because even with REALLY LARGE amount of the static bodies, I can hardly see any FPS loss (~58) Problem begins while adding dynamic bodies, even kinematic are not really harmful for performance (even while I have couple of them for on my scene, used for crushing box, collapsing boxes, moving platform and so on)
User avatar
Mathew
 
Posts: 1073
Joined: Sun Jul 31, 2011 2:49 pm
Location: Tarnów, Poland

Re: Want AI, Gestures, 3D, Inventory, or Menus???

Postby IFL » Fri Nov 04, 2011 6:00 pm

Mathew wrote:Because even with REALLY LARGE amount of the static bodies, I can hardly see any FPS loss (~58) Problem begins while adding dynamic bodies, even kinematic are not really harmful for performance (even while I have couple of them for on my scene, used for crushing box, collapsing boxes, moving platform and so on)

I haven't had much of a problem with dynamic bodies. I did a stress test combining my AI system with over a hundred dynamic-bodied agents, and the FPS was always over 40.
User avatar
IFL
 
Posts: 177
Joined: Fri Mar 04, 2011 6:28 am

Re: Want AI, Gestures, 3D, Inventory, or Menus???

Postby IFL » Sat Nov 05, 2011 7:18 pm

Here's some code that might help someone. It's a really small version of my AI system that goes with the images above.

First, here's how to use it:
Turn every decision into a Conditional Action. Turn every action into a regular Action.

The code for setting up a Conditional Action:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. [Agenda].tempAction = new Action([String Conditional Action Name], [Boolean Action Active],
  2. [String[] Actions to turn on if true],
  3. [String[] Actions to turn off if true],
  4. [String[] Actions to turn on if false],
  5. [String[] Actions to turn off if false]) {
  6.         @Override
  7.         public boolean setActionConditional()
  8.         {
  9.                 [Some code to run in order to aid the conditional statement]
  10.                 return [condition];
  11.         }
  12. };
  13. [Agenda].addTempActionToActionSet();
Parsed in 0.031 seconds, using GeSHi 1.0.8.4


The code for setting up a regular Action:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. [Agenda].tempAction = new Action([String Action Name], [Boolean Action Active]) {
  2.         @Override
  3.         public void setAction()
  4.         {
  5.                 [Some code to run]
  6.         }
  7. };
  8. [Agenda].addTempActionToActionSet();
Parsed in 0.031 seconds, using GeSHi 1.0.8.4


To run the Agenda (what makes everything work) run the following in an update thread:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. [Agenda].runAgendaMainLoop();
Parsed in 0.034 seconds, using GeSHi 1.0.8.4


And here are the classes:
The "Action" class...
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package ifl.games.runtime.ai.Agent;
  2.  
  3. import org.anddev.andengine.entity.Entity;
  4.  
  5. /**@author Brian Broyles - IFL*/
  6. public class Action
  7. {
  8.         public boolean actionActive = false;
  9.         final boolean actionConditional;
  10.         public String Name=new String();
  11.         public Entity ParentCharacter;
  12.         public String[] CTOn = new String[50];
  13.         public String[] CTOff = new String[50];
  14.         public String[] CFOn = new String[50];
  15.         public String[] CFOff = new String[50];
  16.        
  17.         /** Actual Action. Override setAction() to set the code. This just runs code until it is turned off.
  18.          * @param pName - The name of the Action. This allows it to be easily called from Conditional Actions.
  19.          * @param pActive - Should this action be enabled by default (active=true), or should it wait to be enabled by a Conditional Action (active=false)?
  20.          */
  21.         public Action(String pName, boolean pActive){Name=pName;actionConditional=false;actionActive=pActive;}
  22.        
  23.         /** Conditional Action. Override setActionConditional() to set the code. This can run code as well as return a true/false conditional statement. It turns on or off other actions.
  24.          * @param pName - The name of the Action. This allows it to be easily called from Conditional Actions.
  25.          * @param pActive - Should this action be enabled by default (active=true), or should it wait to be enabled by a Conditional Action (active=false)?
  26.          * @param pCTOn - If the condition is true, which actions do you want turned on?
  27.          * @param pCTOff - If the condition is true, which actions do you want turned off?
  28.          * @param pCFOn - If the condition is false, which actions do you want turned on?
  29.          * @param pCFOff - If the condition is false, which actions do you want turned off?
  30.          */
  31.         public Action(String pName, boolean pActive, String[] pCTOn, String[] pCTOff, String[] pCFOn, String[] pCFOff){Name=pName;actionConditional=true;actionActive=pActive;CTOn=pCTOn;CTOff=pCTOff;CFOn=pCFOn;CFOff=pCFOff;}
  32.        
  33.         public void runActionIfActive(){if(actionActive){setAction();}}
  34.         public void setAction(){}
  35.         public boolean setActionConditional(){return false;}
  36. }
Parsed in 0.040 seconds, using GeSHi 1.0.8.4


The "Agenda" class...
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package ifl.games.runtime.ai.Agent;
  2.  
  3. import android.util.Log;
  4.  
  5. /**@author Brian Broyles - IFL
  6.  */
  7. public class Agenda implements Cloneable
  8. {
  9.         private Action[] ActionSet=new Action[2000];
  10.         private int currentIndex = 0;
  11.         public Action tempAction;
  12.         public boolean debugging = false;
  13.  
  14.         public void addActionToActionSet(Action pAction)
  15.         {ActionSet[currentIndex]=pAction;currentIndex++;}
  16.  
  17.         public void addTempActionToActionSet()
  18.         {ActionSet[currentIndex]=tempAction;currentIndex++;tempAction=null;}
  19.  
  20.         public void runAllActionsWithSharedNameOnce(String pName)
  21.         {
  22.                 for(int i=0; i<ActionSet.length; i++)
  23.                 {
  24.                         if(ActionSet[i]!=null)
  25.                         {
  26.                                 if(ActionSet[i].Name.equalsIgnoreCase(pName))
  27.                                 {
  28.                                         ActionSet[i].setAction();
  29.                                 }
  30.                         }
  31.                 }
  32.         }
  33.  
  34.         public void runFirstActionWithSharedNameOnce(String pName)
  35.         {
  36.                 for(int i=0; i<ActionSet.length; i++)
  37.                 {
  38.                         if(ActionSet[i]!=null)
  39.                         {
  40.                                 if(ActionSet[i].Name.equalsIgnoreCase(pName))
  41.                                 {
  42.                                         ActionSet[i].setAction();
  43.                                         return;
  44.                                 }
  45.                         }
  46.                 }
  47.         }
  48.  
  49.         public void runAgendaMainLoop()
  50.         {
  51.                 // This runs through each action in the agenda; Order really doesn't matter, but each activated node above
  52.                 //    the current node in the agenda list will wait until the next loop to run.
  53.                 // This way might seem like a loss of necessary control, but it is the most efficient and safe way to run
  54.                 //    the agenda without making it too complex or unstable.
  55.                 for(int i=0; i<ActionSet.length; i++)
  56.                 {
  57.                         // if the current action exists...
  58.                         if(ActionSet[i]!=null)
  59.                         {
  60.                                 // and if it's a conditional statement..
  61.                                 if(ActionSet[i].actionConditional)
  62.                                 {
  63.                                         // and if the Action is active...
  64.                                         if(ActionSet[i].actionActive)
  65.                                         {
  66.                                                 // and if the conditional statement is true...
  67.                                                 if(ActionSet[i].setActionConditional())
  68.                                                 {
  69.                                                                 // Condition true Turn On
  70.                                                                 if(ActionSet[i].CTOn!=null){for(int o=0; o<ActionSet[i].CTOn.length; o++){if(ActionSet[i].CTOn[o]!=null||ActionSet[i].CTOn[o].isEmpty()==false)
  71.                                                                 {for(int p=0; p<ActionSet.length; p++){if(ActionSet[p]!=null){if(ActionSet[p].Name.equalsIgnoreCase(ActionSet[i].CTOn[o])){if(debugging)
  72.                                                                 {Log.i("IFL AI Agenda","Action \"" + ActionSet[i].CTOn[o] + "\" has been turned on by Advanced \"" + ActionSet[i].Name + "\" being true.");}ActionSet[p].actionActive=true;}}}}}}
  73.                                                                
  74.                                                                 // Condition true Turn Off
  75.                                                                 if(ActionSet[i].CTOff!=null){for(int o=0; o<ActionSet[i].CTOff.length; o++){if(ActionSet[i].CTOff[o]!=null||ActionSet[i].CTOff[o].isEmpty()==false)
  76.                                                                 {for(int p=0; p<ActionSet.length; p++){if(ActionSet[p]!=null){if(ActionSet[p].Name.equalsIgnoreCase(ActionSet[i].CTOff[o])){if(debugging)
  77.                                                                 {Log.i("IFL AI Agenda","Action \"" + ActionSet[i].CTOff[o] + "\" has been turned off by Advanced \"" + ActionSet[i].Name + "\" being true.");}ActionSet[p].actionActive=false;}}}}}}
  78.                                                                 }
  79.                                                 else
  80.                                                 {
  81.                                                         // Condition false Turn On
  82.                                                         if(ActionSet[i].CFOn!=null){for(int o=0; o<ActionSet[i].CFOn.length; o++){if(ActionSet[i].CFOn[o]!=null||ActionSet[i].CFOn[o].isEmpty()==false)
  83.                                                         {for(int p=0; p<ActionSet.length; p++){if(ActionSet[p]!=null){if(ActionSet[p].Name.equalsIgnoreCase(ActionSet[i].CFOn[o])){if(debugging)
  84.                                                         {Log.i("IFL AI Agenda","Action \"" + ActionSet[i].CFOn[o] + "\" has been turned on by Advanced \"" + ActionSet[i].Name + "\" being false.");}ActionSet[p].actionActive=true;}}}}}}
  85.                                                        
  86.                                                         // Condition false Turn Off
  87.                                                         if(ActionSet[i].CFOff!=null){for(int o=0; o<ActionSet[i].CFOff.length; o++){if(ActionSet[i].CFOff[o]!=null||ActionSet[i].CFOff[o].isEmpty()==false)
  88.                                                         {for(int p=0; p<ActionSet.length; p++){if(ActionSet[p]!=null){if(ActionSet[p].Name.equalsIgnoreCase(ActionSet[i].CFOff[o])){if(debugging)
  89.                                                         {Log.i("IFL AI Agenda","Action \"" + ActionSet[i].CFOff[o] + "\" has been turned off by Advanced \"" + ActionSet[i].Name + "\" being false.");}ActionSet[p].actionActive=false;}}}}}}
  90.                                                 }
  91.                                         }
  92.                                        
  93.                                 // if the action is not a Conditional...
  94.                                 } else {
  95.                                         // perform the action.
  96.                                         ActionSet[i].runActionIfActive();
  97.                                 }
  98.                         }
  99.                 }
  100.         }
  101. }
Parsed in 0.055 seconds, using GeSHi 1.0.8.4


If you get it to work, you'll see that it's pretty easy to use. If you need help, just ask. I'll add an example if anyone needs it. I'll be gone for a couple of days, but I doubt there will be much traffic to this thread...
User avatar
IFL
 
Posts: 177
Joined: Fri Mar 04, 2011 6:28 am

Re: Want AI, Gestures, 3D, Inventory, or Menus???

Postby Mathew » Mon Nov 07, 2011 6:10 pm

with over a hundred dynamic-bodied


:O Thats interesting, I will investigate my code, maybe I fucked up something - hopefully :D
User avatar
Mathew
 
Posts: 1073
Joined: Sun Jul 31, 2011 2:49 pm
Location: Tarnów, Poland

Re: Want AI, Gestures, 3D, Inventory, or Menus???

Postby Mathew » Tue Nov 08, 2011 12:03 pm

Hmm, I'm really happy now!

- I cleaned up my code (still should be re factored a bit)
- used Sprite Batches for static tiles
- used setCullingEnabled(true) for every sprite expect HUD, controller and background

And now, even with really big amount of static bodies for tiles, kinematic bodies for collapsing boxes, moving platforms, crushing boxes and so on I have like 50-57 FPS. And whats most important, even while there are couple of dynamic bodies (tested with 19 dynamic bodies, which is really enough to make monsters per one level, and even to much, because for flying monster I will use kinematic bodies) And FPS is like 45-50 while I can see them on the "camera" and 50+ while there are not currently visible in the camera.

I'm optimistic now, I even thought I will have to give up because those performance issues, but... hurray!
User avatar
Mathew
 
Posts: 1073
Joined: Sun Jul 31, 2011 2:49 pm
Location: Tarnów, Poland

Re: Want AI, Gestures, 3D, Inventory, or Menus???

Postby IFL » Tue Nov 08, 2011 2:00 pm

Mathew wrote:Hmm, I'm really happy now! ... I'm optimistic now, I even thought I will have to give up because those performance issues, but... hurray!
I'm glad that you got it working better.

I didn't think to mention this before, but all of my test devices are dual-core. That kind of skews my performance stats - sorry about that.
User avatar
IFL
 
Posts: 177
Joined: Fri Mar 04, 2011 6:28 am

Re: Want AI, Gestures, 3D, Inventory, or Menus???

Postby Mathew » Tue Nov 08, 2011 4:03 pm

Thats why I'm happy that my Device is quite low end (Htc Wildfire S) which has as I remember ~500Mhz CPU.

Why its good to own low end device? Because if your game works well on such device, you may be sure that it will work mostly everywhere (at least its just my point of view hehe) Its good that nowadays those smart phones are getting better and better (so better for everyone, for users and.. developers - less care about performance)

:D
User avatar
Mathew
 
Posts: 1073
Joined: Sun Jul 31, 2011 2:49 pm
Location: Tarnów, Poland

Next

Return to OFF-Topic

Who is online

Users browsing this forum: No registered users and 2 guests