Best practices, using table search, table values with timers?
Hello, I have been working on a project which uses an inventory system that search through table values, and add then adds values to that table once the row has been found. I'm also using this in conjunction with pause, which I am using as a menu.
Every time I pick up an item, it will search the table then if the row is not found it will add a new row. If it is found then it will add values to that row in multiple columns. I am using the same logic for transferring from the players inventory to a storage. Every time I search a table, then add many values etc.
Now this works, but when I stress test it I encounter issues. Like rows not adding or adding to wrong row, or worst of all after moving items around a bit. I will open the inventory menu, and it will just freeze.
I wanted to use this approach, as I wanted it to be fairly dynamic. But it seems the engine struggles??
Have people encountered similar issues when constantly searching through tables, and updating table values constantly? Also if you keep pausing and unpausing does this cause errors?
Perhaps I'm using the tables too much, searching too much, too much going on? Do I need to use it combined with Game Attributes? Any help or advice would be appreciated..
Comments
I have eliminated the timers in the rules, it may be working better now.
This prompts the question, is it not good practice to use timers when changing table values? I have used timers to stagger the actions/events in certain scenarios in the past.
I assumed that when doing many changes of table values or any attributes, you should stagger these actions to make sure that they execute properly. Using table search for example, should you allow some search time to take place before executing the next action? When the table size gets larger, it will take longer for the table search to process?
Does the next action occur only when the previous action has been completed? I assume so, but if some complicated actions take 0.1 seconds longer, this the next action account for this?
This may have been brought up before, but I would just like to clarify these things.
I believe you should use the loop behavior and not timers. I believe that in a loop all actions will complete before starting the next.
www.rossmanbrosgames.com
Good questions. More complex behaviors/functions such as loops or table searches will not happen instantaneously. And no, other rules and behaviors will not wait for those to finish unless you manually force them to. So a timer is one way to make sure that those following actions don't fire early. Other ways depend on what you're doing. If you were searching for a known value, you could have other rules/behaviors fire only when the search has been completed, for example. Or if you were running a loop, you could wait until the loop index is maxed out before firing other actions.
New to GameSalad? (FAQs) | Tutorials | Templates | Greenleaf Games | Educator & Certified GameSalad User
@hrsmedia,
No, tables are the right way to go, crucial to complex games. If used with care, given the event driven code of GS, quite reliable.
Here my pointers to your questions:
Are you using the new tableSearch function? If so, good.
This is generally not a good idea in GS, as GS actually creates a new copy of the table (with the new row included), then removing the original table. This can cause lag spikes if the table is biggish.
Rather define a table with the maximum rows, then maintain an index of the last row used. Increasing this index as the table fills with values.
Not easy to answer. Times can be a lifesaver, but just as well the cause of problems.
e.g. if you have a long set of instructions that need to be processed inside a rule, it "can" happen that some of the instructions get skipped if the rule turns false during execution. The solution to this is to place the instructions into a timer (after 0 seconds/run to completion). At the same time, this causes the instructions no longer to be processed strictly in sequence with the rest of the behaviours during that draw cycle.
Using delay timers, to give other code time to finish is very unreliable. There is such a difference in execution speed between device types, meaning you would have to slow down your code execution to the lowest common denominator.
A better practice is to set flags when a set of code has completed. This flag would trigger the next rule containing the subsequent set of behaviours. So, implement a very flat rule structure - avoid nesting rules as much as possible.
This makes it easier to debug and avoids weird behaviour.
MESSAGING, X-PLATFORM LEADERBOARDS, OFFLINE-TIMER, ANALYTICS and BACK-END CONTROL for your GameSalad projects
www.APPFORMATIVE.com
Thank you all for the advice. I will have to implement the suggestions that you all have made. I have not really used the loop behavior before, I cannot believe I have overlooked some of these things. Thanks again.
@Hopscotch I am using the tableSearch function.
Could you explain more about where you mention:
"Rather define a table with the maximum rows, then maintain an index of the last row used. Increasing this index as the table fills with values"
Lets assume that your game contains 100 collectable items. Then create a blank table with 100 rows and an index attribute (tbl_Index) set to 0.
As a player picks up items, you then add these to the next available row (tbl_Index+1).
Alternatively use the tableSearch function to get the first blank row, then add the values to this row. The benefit is that if a player drops an item, you only have to blank out the appropriate row, instead of deleting it (which would again case the creation of a copy of the table).
Then, adding a new item, would again reuse the first available blank row, found by the tableSearch function.
One thing I forgot to mention previously ... make sure that your code never tries to access rows or columns which don't exist. e.g. make sure that your code never refers to row 0. This can cause the app to crash or hang.
MESSAGING, X-PLATFORM LEADERBOARDS, OFFLINE-TIMER, ANALYTICS and BACK-END CONTROL for your GameSalad projects
www.APPFORMATIVE.com
To find a blank row do I search for key " " or do I search for 0? Something like that?
To blank out a row do I have to set all the values in that row to 0? Also, to blank out a text value you have to set it to " " ?
I would also have to do 2 table searches in this case. First for the item, if item is not located in the table then search again for a blank row?
@hrsmedia, yes, search for "" or 0 in a column you choose, depending if it is a text field or integer.
To set the row to blank, just set the appropriate column to "" or 0.
Yes, but the tableSearch function runs at native speed, whereas a self constructed loop, even the GS loop behaviour, only cycles once per draw call (ca. 0.02s each cycle), quite slow.
MESSAGING, X-PLATFORM LEADERBOARDS, OFFLINE-TIMER, ANALYTICS and BACK-END CONTROL for your GameSalad projects
www.APPFORMATIVE.com
So you don't recommend running a loop when doing a tableSearch? Or did I misunderstand you?
I'm not sure I understand how the loop works anyway, I mean how do I know when it has finished searching the table to activate the next event?
tatiang mentioned something about checking when the loop index is maxed out before firing other actions. I see Loop over table which has a store index in attribute. Not sure how to use this. Sorry for the continued questions..
@hrsmedia, I avoid the loop and loop over table behaviours if at all possible, they are just too slow.
I will make you a small project to explain ...
MESSAGING, X-PLATFORM LEADERBOARDS, OFFLINE-TIMER, ANALYTICS and BACK-END CONTROL for your GameSalad projects
www.APPFORMATIVE.com
I think I'm starting to understand the loop over table. It will just count the number of rows between the cells you select. You have to store that index value and when the last row number is stored as the index, you can put a rule to listen for this to activate the next action.
But If you do not use the loop behaviours, how can you know that the tableSearch has finished searching the table?
@hrsmedia, here is a sample.
Searching, adding, removing, etc, without any loops.
The tableSearch function returns the row in which it found the condition. It it returns 0 then no occurrence was found.
MESSAGING, X-PLATFORM LEADERBOARDS, OFFLINE-TIMER, ANALYTICS and BACK-END CONTROL for your GameSalad projects
www.APPFORMATIVE.com
@Hopscotch -- thats a nice little inventory system! Instant steal!
Thanks @RThurman, even comes with free @Socks
MESSAGING, X-PLATFORM LEADERBOARDS, OFFLINE-TIMER, ANALYTICS and BACK-END CONTROL for your GameSalad projects
www.APPFORMATIVE.com
@Hopscotch
I'll check the file out when I get back from work.
Thank you very much for your help, I really appreciate it.
I had a look at the file. It seems I was on the right lines in terms of tableSearch, but now I'm using your idea of changing the existing table instead of adding and removing rows.
Though I see that there's nothing to signify the tableSearch is done though before moving on to the next. Is this reliable then if the table is large?