Page 9 of 9

Posted: Tue Apr 27, 2010 11:05 pm
by Montyphy
Ace Rimmer wrote:When I say 'not in that order', I mean I was doing both things (getting 'new' unit data and placing in tables, and searching those tables in the same tick).
...
I assumed the startlongtask/yieldlongtask would allow both functions (getnewdata/searchvisibleunits) at the same time without issues.


Yeah, doing that could potentially cause a whole load of problems. The only time it's safe to simultaneously operate multiple tasks on the same set of data (i.e. a table) is if the tasks are only reading values, otherwise you could end up deleting a value in one task while the other is about to try read from it.

For example (borrowing some syntax from Handel-C):

Code: Select all

//update
function task1(data) {
   print("deleting value");
   data["a"] = null;   //delete element
}

//read
function task2(data) {
   for (key in data) {
      print("this is...");
      print(key);
   }
}


//main
function tick() {
   data = ["a":6, "b":5, "c":4, "d":3, "e":2, "f":1];
   
   //execute task functions in parallel
   par {
      task1(data);
      task2(data);
   }
}

If you imagine each statement takes the same amount of time to execute (1 clock cycle) then things will look like this:

clock 0: Enter tick() function.
clock 1: data is defined.
clock 2: Enter task1() and task2() functions simultaneously.
clock 3: task1() prints message. task2() enters for loop with key referring to data["a"].
clock 4: task1() deletes data["a"]. task2() prints message.
clock 5: task2() references data["a"] which is null/deleted.

This is assuming data is passed-by-reference. I haven't checked but arguments in Lua are most likely passed-by-value so this shouldn't be the exact kind of thing to worry about as each task would be working on it's own copy of data. However, if you're using global variables then you would very easily hit this problem, which is why you should avoid using them. For example don't do:

Code: Select all

//global
data = ["a":6, "b":5, "c":4, "d":3, "e":2, "f":1];

//update
function task1(data) {
   print("deleting value");
   data["a"] = null;   //delete element
}

//read
function task2(data) {
   for (key in data) {
      print("this is...");
      print(key);
   }
}

//main
function tick() {
   //execute in parrallel
   par {
      task1();
      task2();
   }
}


clock 0: data is defined.
clock 1: Enter tick() function.
clock 2: Enter task1() and task2() functions simultaneously.
clock 3: task1() prints message. task2() enters for loop with key referring to data["a"].
clock 4: task1() deletes data["a"]. task2() prints message.
clock 5: task2() references data["a"] which is null/deleted.

Two possible solutions. First, make sure your update and read tasks are executed sequentially (nice and easy). Second, implement channels which would allow parallel tasks to pass information between each other (tricky and could lead to blocking as a task would have to wait for communication from the channel).

While not entirely relevant it may help to read about ACID to highlight some of the issues, in particular, the bit about isolation.

Posted: Thu May 06, 2010 4:42 pm
by Ace Rimmer
Ok, you two have been really helpful and using tables is much, much faster. I still can't get beyond it hanging though, which I believe is due to "invalid" units (units that drop off of radar), and destroyed units. I will be attempting to correct my tables to be units as suggested. I still have a large deficit of knowledge in the table area.

Also, when I tried to run Joshua, it hangs right away. :?:

Posted: Thu May 06, 2010 4:44 pm
by martin
That's odd, maybe I committed a broken version, it's been a while since I fiddled with it. I'll go take a look

edit: All I can say is "Works on my machine" ;)

Make sure you have the latest version off the svn :/

Posted: Thu May 06, 2010 4:55 pm
by Ace Rimmer
Version 17

Also, it does work, but only if I put in all six players. Is that a status bar on the whiteboard? :shock:

Posted: Thu May 06, 2010 5:16 pm
by martin
That's a scan of my territory, it draws a box around my territory and then scans every single point in the territory, that get's me several thousand points which I then add to a heap and select a few of the points to put silos and airbases on.

Version 17 is the latest version. It's odd that it only runs with 6 players, do you have a really fast computer?

Posted: Thu May 06, 2010 5:19 pm
by Ace Rimmer
i7 860
4 gb RAM
Gigabyte GTX260
150 WD Velociraptor Raid 0
7 x64 Professional

Posted: Thu May 06, 2010 6:26 pm
by martin
Can you try running the game with vsync on, if that fails run it in low performance mode. I suspect there's something about Joshua which doesn't like being run fast.

Then again, I could be barking up the wrong tree.

Posted: Thu May 06, 2010 7:00 pm
by Ace Rimmer
With vsync on, it works as 1v1, no hangin.

Posted: Thu May 06, 2010 7:18 pm
by martin
well that's very odd. Still, at least it's fixed.

Posted: Mon May 17, 2010 12:15 am
by Gogopex
edit:***

Posted: Mon May 17, 2010 11:09 am
by martin
Hey, Joshua is on a bit of a backburner during the exam period so I'm not really looking for other programmers at the moment. However, feel free to checkout the code and make your own bot based on Joshua :)

Posted: Fri Jul 02, 2010 2:19 am
by martin
I just checked Joshua out from the old google code home, and checked it into a new github home, you can find it here:

http://wiki.github.com/martindevans/Joshua-Bot/

I believe you can interact with github using an svn client, so if anyone wants to pull my code all they have to do is use a new address.

Posted: Sat Jul 03, 2010 8:38 pm
by martin
*sigh*

It's just one thing after another. Now my defcon key has been revoked for some reason :evil:

edit: that's been sorted now, back to work!

Posted: Sun Jan 16, 2011 4:46 am
by martin
Dammit! It's all poptart911's fault! He sent me a message about Joshua, and now I'm back to work on it. As before, I'm spending less time actually building Joshua and more time building useful Lua libraries, I just completed the basic version of a query system (inspired by LINQ from C#, for those who know what that's all about).

You can do stuff like:

Code: Select all

for item in Enumeration.CreateFromTable(SomeTable).Where(SomeCondition).Select(FunctionTurningAIntoB) do ...


Hopefully you can see how that can be pretty useful for rapidly building complex queries of the big datasets these bots often have :)