Skip to content
This repository has been archived by the owner on Oct 2, 2021. It is now read-only.

Performance tweaks #260

Closed
kmatheussen opened this issue May 30, 2016 · 84 comments
Closed

Performance tweaks #260

kmatheussen opened this issue May 30, 2016 · 84 comments

Comments

@kmatheussen
Copy link
Contributor

kmatheussen commented May 30, 2016

Maybe I'm wrong, but I think these tweaks make the bot run a bit better. A/S value should be set to around 20. Average score is around 3-4000, but that's because it often dies very early. When it gets above 3-4000, it often gets above 10000 as well. My record is 25489.

(removed wrong diff)

full file: http://users.notam02.no/~kjetism/bot.user.js

@kmatheussen
Copy link
Contributor Author

Sorry, that was a diff against a preliminary version. Here:

--- bot.user.js 2016-05-30 16:20:37.738144318 +0200
+++ ../bot.user.js  2016-05-30 14:58:20.486463824 +0200
@@ -318,13 +318,13 @@
         currentFood: {},
         opt: {
             // target fps
-            targetFps: 30,
+            targetFps: 25,
             // size of arc for collisionAngles
             arcSize: Math.PI / 8,
             // radius multiple for circle intersects
-            radiusMult: 10,
+            radiusMult: 20,
             // food cluster size to trigger acceleration
-            foodAccelSz: 60,
+            foodAccelSz: 20,
             // maximum angle of food to trigger acceleration
             foodAccelDa:  Math.PI / 3,
             // how many frames per food check
@@ -348,6 +348,17 @@
         MID_Y: 0,
         MAP_R: 0,

+        scale: function(x,x1,x2,y1,y2){
+            return y1 + ( ((x-x1)*(y2-y1))
+                          /
+                          (x2-x1)
+                        );
+        },
+
+        getSnakeLength: function() {
+            return (Math.floor(150 * (window.fpsls[window.snake.sct] + window.snake.fam / window.fmlts[window.snake.sct] - 1) - 50) / 10);
+        },
+
         getSnakeWidth: function (sc) {
             if (sc === undefined) sc = window.snake.sc;
             return Math.round(sc * 29.0);
@@ -622,7 +633,7 @@
         checkCollision: function () {
             var headCircle = canvas.circle(
                 window.snake.xx, window.snake.yy,
-                bot.speedMult * bot.opt.radiusMult / 2 * bot.snakeRadius
+                bot.speedMult * bot.opt.radiusMult / 3 * bot.snakeRadius
             );

             var fullHeadCircle = canvas.circle(
@@ -660,7 +671,6 @@
                         bot.collisionPoints[i].radius
                     );

-
                     if (canvas.circleIntersect(fullHeadCircle, eHeadCircle)) {
                         if (window.snakes[bot.collisionPoints[i].snake].sp > 10) {
                             window.setAcceleration(1);
@@ -686,8 +696,11 @@
         // Round angle difference up to nearest foodRoundA degrees.
         // Round food up to nearest foodRoundsz, square for distance^2
         scoreFood: function (f) {
+            f.score = (160 * f.sz) / Math.sqrt(Math.sqrt(Math.sqrt(f.distance)));
+/*
             f.score = Math.pow(Math.ceil(f.sz / bot.opt.foodRoundSz) * bot.opt.foodRoundSz, 2) /
-                f.distance / (Math.ceil(f.da / bot.opt.foodRoundA) * bot.opt.foodRoundA);
+               (Math.ceil(f.da / bot.opt.foodRoundA) * bot.opt.foodRoundA);
+*/
         },

         computeFoodGoal: function () {
@@ -696,21 +709,23 @@
             var fi = 0;
             var sw = bot.snakeWidth;

-            for (var i = 0; i < window.foods.length && window.foods[i] !== null; i++) {
+            for (var i = 0; i < window.foods.length; i++) {
                 var a;
                 var da;
                 var distance;
                 var sang = window.snake.ehang;
                 var f = window.foods[i];

-                if (!f.eaten &&
+                if (f !== null && !f.eaten &&
                     !(
                         canvas.circleIntersect(
                             canvas.circle(f.xx, f.yy, 2),
                             bot.sidecircle_l) ||
                         canvas.circleIntersect(
                             canvas.circle(f.xx, f.yy, 2),
-                           bot.sidecircle_r))) {
+                                bot.sidecircle_r)
+                    )
+                   ) {

                     var cx = Math.round(Math.round(f.xx / sw) * sw);
                     var cy = Math.round(Math.round(f.yy / sw) * sw);
@@ -736,18 +751,25 @@
             foodClusters.forEach(bot.scoreFood);
             foodClusters.sort(bot.sortScore);

+            if (foodClusters.length > 0) {
+                bot.currentFood = foodClusters[0];
+                return;
+            }
+/*
             for (i = 0; i < foodClusters.length; i++) {
                 var aIndex = bot.getAngleIndex(foodClusters[i].a);
                 if (bot.collisionAngles[aIndex] === undefined ||
-                    (Math.sqrt(bot.collisionAngles[aIndex].distance) -
-                        bot.snakeRadius * bot.opt.radiusMult / 2 >
-                        Math.sqrt(foodClusters[i].distance) &&
-                        foodClusters[i].sz > bot.opt.foodSmallSz)
+                    foodClusters[i].score > 0 //|| 
+//                    (Math.sqrt(bot.collisionAngles[aIndex].distance) -
+  //                      bot.snakeRadius * bot.opt.radiusMult / 2 >
+    //                    Math.sqrt(foodClusters[i].distance) &&
+      //                  foodClusters[i].sz > bot.opt.foodSmallSz)
                 ) {
                     bot.currentFood = foodClusters[i];
                     return;
                 }
             }
+*/
             bot.currentFood = { x: bot.MID_X, y: bot.MID_Y };
         },

@@ -760,7 +782,8 @@
                 if (
                     bot.collisionAngles[aIndex] && bot.collisionAngles[aIndex].distance >
                     bot.currentFood.distance + bot.snakeWidth * bot.opt.radiusMult
-                    && bot.currentFood.da < bot.opt.foodAccelDa) {
+                    &&
+                        bot.currentFood.da < bot.opt.foodAccelDa) {
                     return 1;
                 }

@@ -788,7 +811,7 @@
             bot.sin = Math.sin(window.snake.ang);

             bot.speedMult = window.snake.sp / 5.78;
-            bot.snakeRadius = bot.getSnakeWidth() / 2;
+            bot.snakeRadius = bot.scale(bot.getSnakeLength(), 0, 16000,  400, 800) / 20;
             bot.snakeWidth = bot.getSnakeWidth();

             bot.sidecircle_r = canvas.circle(
@@ -818,17 +841,28 @@

             if (bot.checkCollision()) {
                 bot.lookForFood = false;
+                /*
                 if (bot.foodTimeout) {
                     window.clearTimeout(bot.foodTimeout);
                     bot.foodTimeout = window.setTimeout(
                         bot.foodTimer, 1000 / bot.opt.targetFps * bot.opt.foodFrames);
                 }
+                */
             } else {
                 bot.lookForFood = true;
+                if (window.playing && bot.lookForFood &&
+                    window.snake !== null && window.snake.alive_amt === 1) {
+                    bot.computeFoodGoal();
+                    window.goalCoordinates = bot.currentFood;
+                    canvas.setMouseCoordinates(canvas.mapToMouse(window.goalCoordinates));
+                }
+
+                /*
                 if (bot.foodTimeout === undefined) {
                     bot.foodTimeout = window.setTimeout(
                         bot.foodTimer, 1000 / bot.opt.targetFps * bot.opt.foodFrames);
                 }
+                */
                 window.setAcceleration(bot.foodAccel());
             }
         },

@Defimatt
Copy link
Collaborator

Can you please submit this as a PR, or post the full file? It makes it easier to test it out, thanks.

@Drflash55
Copy link
Collaborator

If you want add this to the bot, make a pull request from your forked project, and the collaborators here will test it out.

I'm one of the testers, so once you get the PR from your forked project, I will test it out soon.

@kmatheussen
Copy link
Contributor Author

Can you please submit this as a PR, or post the full file? It makes it easier to test it out, thanks.

Hi, just paste the contents into a new file called diff.diff and execute
patch < diff.diff
in your tree.

If you want add this to the bot, make a pull request from your forked project, and the collaborators here will test it out.

No, it's not meant to be a pull request. I would have made a pull request if I wanted to make a pull request. It's just (ugly) tweaks, some may make sense, some may not. It's for people to look at and discuss and try, if you want.

@Defimatt
Copy link
Collaborator

@kmatheussen Apologies for my ignorance with GitHub, but how do you execute 'patch' on GitHub.com? Is there a special URL to visit?

@kmatheussen
Copy link
Contributor Author

Hi,

"patch" is a pogram you execute in the terminal:
https://en.wikipedia.org/wiki/Patch_%28Unix%29

On Mon, May 30, 2016 at 9:13 PM, Matt Duffin notifications@github.com
wrote:

@kmatheussen https://github.com/kmatheussen Apologies for my ignorance
with GitHub, but how do you execute 'patch' on GitHub.com? Is there a
special URL to visit?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#260 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/ABF9pyeV01p3Uy1MZxlyXPA91ksA0PhTks5qGzbigaJpZM4Ip1aN
.

@Defimatt
Copy link
Collaborator

@kmatheussen Thanks, I'll look for a Windows equivalent.

@kmatheussen
Copy link
Contributor Author

Sorry for making it so inconvenient. Here is the full file:
http://users.notam02.no/~kjetism/bot.user.js

@Defimatt
Copy link
Collaborator

@kmatheussen I'm sure it's not inconvenient, I'm just not used to this workflow, but enjoying learning as I go! 👍

@ermiyaeskandary
Copy link
Owner

@MattDuffin @kmatheussen Yeah - a file is better. You don't just dump diff logs into a issue - just saying 👍

@clemens-tolboom
Copy link
Collaborator

clemens-tolboom commented May 31, 2016

This is hard to read so an abstract

The first set (issue summary) contains 2 formatting changes (ignored). This is what I extracted

Change foodAccelSize from 40 to 20

Change food score calculation

   f.score = Math.pow(Math.ceil(f.sz / bot.opt.foodRoundSz) * bot.opt.foodRoundSz, 2) /
    (Math.ceil(f.da / bot.opt.foodRoundA) * bot.opt.foodRoundA);

into

  f.score = (160 * f.sz) / Math.sqrt(Math.sqrt(Math.sqrt(f.distance)));

Fix distance calculations

From

distance = 1;//Math.round(
  //canvas.getDistance2(cx, cy, window.snake.xx, window.snake.yy));

into

distance = Math.round(
  canvas.getDistance2(cx, cy, window.snake.xx, window.snake.yy));

Remove long food selection calculation

for (i = 0; i < foodClusters.length; i++) {
  var aIndex = bot.getAngleIndex(foodClusters[i].a);
  if (bot.collisionAngles[aIndex] === undefined ||
... some fuzzy changes
  ) {
    bot.currentFood = foodClusters[i];
    return;
  }
}

into

if (foodClusters.length > 0) {
  bot.currentFood = foodClusters[0];
  return;
}

I will proceed with #260 (comment) later on.

@ermiyaeskandary
Copy link
Owner

@kmatheussen

This is hard to read

@kmatheussen
Copy link
Contributor Author

kmatheussen commented May 31, 2016

This is hard to read

Seriously? You compain that diffs are hard to read? Sorry, but I don't want to spend time on this. I thought it was better to post this than not. Do what you want with it. Feel free to ask specific questions.

@ermiyaeskandary
Copy link
Owner

ermiyaeskandary commented May 31, 2016

@kmatheussen We are able to work with this - it isn't impossible but it isn't the most ideal way.
What I would have done was make a fork, change it and then put a link to the diff between master and your fork - visually appealing and easier to work with...

I thought it was better to post this than not

Of course it is better but help us in the run up 👍

You think diffs are hard to read?

You can work with them - but yes - I believe diffs are hard to read 👎 and I think they do as well :

post the full file? It makes it easier to test it out, thanks.

If you want add this to the bot, make a pull request from your forked project, and the collaborators here will test it out.

This is hard to read so an abstract

You don't just dump diff logs into a issue - just saying 👍

@Drflash55
Copy link
Collaborator

Drflash55 commented May 31, 2016

@kmatheussen It's usually easier when Github.com is able to compare differences via two files that are the same instead of trying to find them yourself.

Which is the reason why I asked to make a PR from your forked project. Differences are much easier to see this way, than trying to find what has changed manually.

@Defimatt
Copy link
Collaborator

@kmatheussen Could you please explain how a targetFps of 25 is beneficial? In my own experiments, I've set targetFps to 50 on a pretty beefy machine, which results in quicker decisions being made. (Anything above 65-70ish tends to cause jerkiness.) I can't see how 25 would be better than 30, so please explain...

@kmatheussen
Copy link
Contributor Author

@MattDuffin Just a mistake. I tried setting fps 60 but found out it didn't help, and set it back to the original value. Or at least I thought I set it back. :-)

@Defimatt
Copy link
Collaborator

@kmatheussen Ah ok, thanks. I found the same when setting a high FPS value - anything above 65-70ish tends to cause jerkiness; I assume this is because you're then sending updates faster than the slither.io API can accept, and you then get sent corrections from the server that contradict the client state (not that I've tested this).

50 tends to be a good compromise, I've found.

@kmatheussen
Copy link
Contributor Author

I originally tried to remove all the timing stuff, but gave up for some reason. Why is there a timer? Is it to avoid using too much CPU when looking for food? In case that is the reason, it might be better to randomly select food to look for until we have spent more than approx 10ms or so. The important thing is to find clusters as soon as possible, and those will be found if we just look randomly for food.

@kmatheussen
Copy link
Contributor Author

A better algorithm might be something like this:

for(int startpos = 0 ; startpos < 5 ; startpos++){
  for(pos = startpos ; pos < foods.length ; food+= 5){
   var food = foods[pos];
    ...
  }
  if (spent_too_much_time)
    break;
}

@Defimatt
Copy link
Collaborator

I'm enjoying this discussion. @kmatheussen, I'm sorry if I made you feel uncomfortable with my ignorance of diffs, that wasn't my intention.

@j-c-m
Copy link
Collaborator

j-c-m commented May 31, 2016

👎

@ermiyaeskandary
Copy link
Owner

@j-c-m Why? What's your reason?

@kmatheussen
Copy link
Contributor Author

No problem, I didn't perceive you as ignorant, you just wanted to try the file. I should have posted a link to the file in the first post, which was a bit arrogant since it doesn't take much time to do that.

@j-c-m
Copy link
Collaborator

j-c-m commented May 31, 2016

These changes resulted in -1800 average score.

@kmatheussen
Copy link
Contributor Author

@j-c-m Can you share more number? Maximum and average score for these changes, and master? And how many times have you played?

@j-c-m
Copy link
Collaborator

j-c-m commented May 31, 2016

~10 hours worth of games ~70 games each, -1800 average score.

Do you understand what logic you removed?

@kmatheussen
Copy link
Contributor Author

What where the top 5 scores for the sessions?

Do you understand what logic you removed?

I removed code that caused the snake not to hunt clusters if it was behind it,
and I adjusted the radius multiplier to be based on the snake length instead of the snake width
since I observed that you manually had to increase the radius multiplier the longer
the snake became.

@ChadSki
Copy link
Collaborator

ChadSki commented May 31, 2016

FYI we're discussing standardizing how we test the effectiveness of the bot over here: #265

@Defimatt
Copy link
Collaborator

Defimatt commented Jun 1, 2016

@kmatheussen Thanks for doing these tests, but I don't think we can read too much into them since the j-c-m, master and master-old bots have only played 12, 10 and 14 games respectively.

@kmatheussen
Copy link
Contributor Author

I'm just contributing. The tests would have been more relevant if I had monitored it and filtered out the results that was caused by someone circling you. That's just bad luck I guess. Also, outliers such as numbers below 300 should be removed, and numbers above 15000 could probably be rounded down to 15000, since this happens so seldom that we don't know that well what causes death above 150000.

@Defimatt
Copy link
Collaborator

Defimatt commented Jun 1, 2016

I wasn't moaning, just sounding a note of caution. Personally I'm tempted to accept it due to our bot's highest average score, but that wouldn't be very scientific of me 👅 ...

@ermiyaeskandary
Copy link
Owner

I personally said 10 tests, just to have as a backup @MattDuffin - 👍

for 10 games played by each

@kmatheussen Thanks alot - it confirms my results. I also got a better average with the current bot but a higher max score on the old and @j-c-m .
IMO a higher average score is better than a higher max score as it evens out throughout time and the highest scores and normally anomalies in the data.
Thanks again :)

@j-c-m
Copy link
Collaborator

j-c-m commented Jun 1, 2016

Updated test numbers, they will continue to run. 3,5-10 games is not enough.

l->r : main bot, j-c-m, @kmatheussen, j-c-m with 1.5x big enemy head circle (similar to bigger circle in @kmatheussen)

image

@j-c-m
Copy link
Collaborator

j-c-m commented Jun 1, 2016

Results of long test:

main / j-c-m / km

image

@clemens-tolboom
Copy link
Collaborator

The statistics should contain

  • position reached
  • #players
  • preferably the score of all other players but we probably only could add top 10.
  • server IP
    as in "It's harder to reach a highscore in a crowdy slow server with big snakes"

This morning I entered (as human) an arena with ~300 players with #1 having ~900 (nine hundred) point. It took me not long to become #1.

@phrokton
Copy link

phrokton commented Jun 3, 2016

@kmatheussen @j-c-m

  1. The snake movement freezes now and then, causing it to crash into things

Would it help to provide both the average of three ping results from SpeedTest.net and respective average jitter results from PingTest.net ?

@clemens-tolboom
Copy link
Collaborator

Ive created PR #286 in preparation of #260 (comment)

@ermiyaeskandary
Copy link
Owner

Performance now has improved and has been confirmed by the tests we have been doing.

@ermiyaeskandary
Copy link
Owner

@kmatheussen @Salvationdk is currently testing different radiuses...

Me and others have tested your changes and they cause a degrade in the bot's efficiency. :(

@kmatheussen
Copy link
Contributor Author

Good. But compared to master 1.2.1 I am pretty sure this version improves performance significantly on some computers, at least it stabilizes the performance. For instance, both @j-c-m and my tests have shown large differences in performance in 1.2.1 (and by "1.2.1" I also include the j-c-m branch which was tested here, which should behave the same).

I think it has something to do with the timers since I changed how that is done. It seemed like collision avoidance was not checked regularly on the master branch.

I hope this has been fixed in master now, and I'm looking forward to test it.

@ermiyaeskandary
Copy link
Owner

@kmatheussen the newest commits have fixed the performance issue. Be sure to test and post results if you can! 👍

@ChadSki
Copy link
Collaborator

ChadSki commented Jun 6, 2016

I wonder if your changes rebased onto master perform any better? Two performance fixes are better than one!

@ChadSki ChadSki modified the milestone: Better Performance Jun 6, 2016
@ermiyaeskandary
Copy link
Owner

@ChadSki From my tests, and @j-c-m 's these tests don't improve it. But I tested before the new master. Maybe @kmatheussen or someone else can share results - master vs @kmatheussen 's changes ?

@ChadSki
Copy link
Collaborator

ChadSki commented Jun 6, 2016

AFAIK, nobody rebased kmatheussen's changes on top of our current master, so you didn't test what I mean.

@ermiyaeskandary
Copy link
Owner

Yeah @ChadSki

But I tested before the new master.

@ChadSki
Copy link
Collaborator

ChadSki commented Jun 7, 2016

I think we can close this bug as performance problems have been resolved, but I'm still interested in @kmatheussen 's changes if they'll help improve the bot further.

@ChadSki ChadSki closed this as completed Jun 7, 2016
@clemens-tolboom
Copy link
Collaborator

In #286 I've added game duration to the scores.

I still think more data could be useful but then we should be able to post all our test results into ie a Google sheet.

@kmatheussen
Copy link
Contributor Author

I've tested master against this version for a while now, and there's little doubt that master performs much worse. I guess it's because master takes more chances, and my computer performs badly (for some reason) and doesn't update as often as it should and therefore the snake is killed much sooner in master.

Here's an idea: How about measuring how long time it is since last time we got data from the server, and then increase/decrease the radius based on this measurement?

@ChadSki
Copy link
Collaborator

ChadSki commented Jun 7, 2016

Which commits are you testing?

master (b969a83) and what's your commit?

I can run tests of my own, and I also want to look at your diff.

@kmatheussen
Copy link
Contributor Author

Still this one: http://users.notam02.no/~kjetism/bot.user.js
This is the master commit I just used: 0e3a1b4

@ChadSki
Copy link
Collaborator

ChadSki commented Jun 7, 2016

Oh, that's not master, that's develop. @ermiyaeskandary made develop the default branch you see when visiting the git repo.

That's fine though; I'll run a test versus your changes and see what's up.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants