• Welcome to Smashboards, the world's largest Super Smash Brothers community! Over 250,000 Smash Bros. fans from around the world have come to discuss these great games in over 19 million posts!

    You are currently viewing our boards as a visitor. Click here to sign up right now and start on your path in the Smash community!

SkillKeeper - TrueSkill™ Rankings Bookkeeper

Zankoku

Never Knows Best
Administrator
BRoomer
Joined
Nov 8, 2006
Messages
22,906
Location
Milpitas, CA
NNID
SSBM_PLAYER
I've been using Glickoman for PM PR's that I help with. I like a few things about SkillKeeper a little more so I wanted to switch over. I just have two problems. One is that when PM 3.5 hit we wanted to start with a fresh slate. But we wanted to raise the player skill level in Glickoman for the players that were already PR'd, so an upset in the early season would give the points deserved. Transferring from Glicko to SkillKeeper does not keep the changed player skills that were put in Glicko. I'm not sure why that is and I'm not sure if there's a way to change that. So let me ask this. In SkillKeeper, for players that are already known to be top-10 worthy, should their Sigma, MU, or score be changed? Which one and how much?

Also, when transferring from Glicko to SkillKeeper, it treats it as one big tournament. I can't figure out a way to change specific match dates meaning monthly decay doesn't work unless I manually enter in every match again like I've done with Glicko (which I'll probably end up doing). Is there any way that can be changed?
Regarding changing initial skill levels, I'd decided not to implement such a thing for fairness' sake, since arbitrarily editing an initial value has potentially strange consequences. Over the course of time skills should balance out to where they belong anyway, and introducing "new" players to the field doesn't damage existing players' scores that much since a "new" player will have a maxed out Sigma value, which causes his score to shift significantly but lessens his own match results' effects on opponents' scores.

Regarding importing a GlickoMan file, unfortunately in the old program I didn't really program in any way to track dates. You *can* move entire tournaments (which SkillKeeper distinguishes by different descriptions) to different dates, but there's not much else around it.

Can we get an option to omit certain columns from the CSV
I wasn't really sure of what this would be used for, so I didn't write the feature in at the time. Could I be given a reason for putting it in?
 

Citricide

JuneauSmashBros Tournament Organizer
Joined
Jan 11, 2014
Messages
176
Location
Juneau, Alaska
Regarding changing initial skill levels, I'd decided not to implement such a thing for fairness' sake, since arbitrarily editing an initial value has potentially strange consequences. Over the course of time skills should balance out to where they belong anyway, and introducing "new" players to the field doesn't damage existing players' scores that much since a "new" player will have a maxed out Sigma value, which causes his score to shift significantly but lessens his own match results' effects on opponents' scores.

Regarding importing a GlickoMan file, unfortunately in the old program I didn't really program in any way to track dates. You *can* move entire tournaments (which SkillKeeper distinguishes by different descriptions) to different dates, but there's not much else around it.


I wasn't really sure of what this would be used for, so I didn't write the feature in at the time. Could I be given a reason for putting it in?
I feel like having the option to choose what columns to display would be nice. Seeing as columns like Teams or Characters might be left blank. Maybe someone might only want to display Names and Score rather than all the extra information and such.
 
Last edited:

lazymp

Smash Apprentice
Joined
Apr 14, 2013
Messages
114
Location
Raleigh, NC
NNID
mpittman17
I feel like having the option to choose what columns to display would be nice. Seeing as columns like Teams or Characters might be left blank. Maybe someone might only want to display Names and Score rather than all the extra information and such.
I also usually leave Teams and Characters blank, and we never have Draws either, so in my use case I also have to remove those columns from my csv after exporting. It's not too hard with a regex find/replace but it would be nice to be able to choose the columns when exporting if that's not a significant amount of work to implement.

I also liked the grades that Glicko generated based on player score ranges/clusterings. Those are fairly easy to make myself too but I did like having them in built into the program.

An option for setting decay to custom amounts (specifically bi-monthly is what I'd like) would be good too. For me anyways, monthly is too fast but yearly is too long.

Just offering my feedback and try to show you how I'm using it. It's a great tool, thanks for your work on it, Tony. May check out the code myself and see what's going on under the hood.
 
Last edited:

Zankoku

Never Knows Best
Administrator
BRoomer
Joined
Nov 8, 2006
Messages
22,906
Location
Milpitas, CA
NNID
SSBM_PLAYER
I eliminated grades because it was just arbitrary assigning of letters to pre-programmed ranges. It also didn't particularly accurately portray statistically large gaps in scores.

I'll see what I can do on column selection on leaderboard.

Custom decay is a possibility... I might have an idea on what I want to implement as far as that goes.

With all that in mind, I released a new version yesterday, so go ahead and check it out.
 

shairn

Your favorite anime is bad.
Joined
Nov 16, 2013
Messages
2,596
Location
Laval, QC
3DS FC
4742-6323-2961
I'm running v1.0.1.0, and I get this error every time I try to authenticate with my challonge API key.


I don't use a subdomain.

EDIT:
************** Exception Text **************
Fizzi.Libraries.ChallongeApiWrapper.ChallongeApiException: Exception of type 'Fizzi.Libraries.ChallongeApiWrapper.ChallongeApiException' was thrown.
at Fizzi.Libraries.ChallongeApiWrapper.ChallongePortal.throwOnError(IRestResponse response)
at Fizzi.Libraries.ChallongeApiWrapper.ChallongePortal.GetTournaments()
at SkillKeeper.SKChallongeImporter.importChallonge(String apiKey, String subDomain, List`1 playerList)
at SkillKeeper.SkillKeeper.fileImportChallongeButton_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
 
Last edited:

Fizzi

Smash Ace
Joined
Feb 14, 2008
Messages
802
Location
Brooklyn, NY
Slippi.gg
FIZZI#36
I'm running v1.0.1.0, and I get this error every time I try to authenticate with my challonge API key.


I don't use a subdomain.

EDIT:
************** Exception Text **************
Fizzi.Libraries.ChallongeApiWrapper.ChallongeApiException: Exception of type 'Fizzi.Libraries.ChallongeApiWrapper.ChallongeApiException' was thrown.
at Fizzi.Libraries.ChallongeApiWrapper.ChallongePortal.throwOnError(IRestResponse response)
at Fizzi.Libraries.ChallongeApiWrapper.ChallongePortal.GetTournaments()
at SkillKeeper.SKChallongeImporter.importChallonge(String apiKey, String subDomain, List`1 playerList)
at SkillKeeper.SkillKeeper.fileImportChallongeButton_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
If you PM me your API key I can try to reproduce the issue. Works fine with my API key. You can regenerate it after I finish using it. I promise I won't touch your tournaments :p

Otherwise try this version and show me the error message (it should be more descriptive). http://www.mediafire.com/download/1gh1ccna8cg8ldg/SkillKeeperTemp_2.7z
 
Last edited:

shairn

Your favorite anime is bad.
Joined
Nov 16, 2013
Messages
2,596
Location
Laval, QC
3DS FC
4742-6323-2961
If you PM me your API key I can try to reproduce the issue. Works fine with my API key. You can regenerate it after I finish using it. I promise I won't touch your tournaments :p

Otherwise try this version and show me the error message (it should be more descriptive). http://www.mediafire.com/download/1gh1ccna8cg8ldg/SkillKeeperTemp_2.7z
It actually works with that version. Still doesn't work with the version provided in the OP.
I guess I can send you the API if you want to try it out.
 

Fizzi

Smash Ace
Joined
Feb 14, 2008
Messages
802
Location
Brooklyn, NY
Slippi.gg
FIZZI#36
It actually works with that version. Still doesn't work with the version provided in the OP.
I guess I can send you the API if you want to try it out.
That's odd. But if it works, I don't need to test it myself. Feel free to change your API key.
 

Zankoku

Never Knows Best
Administrator
BRoomer
Joined
Nov 8, 2006
Messages
22,906
Location
Milpitas, CA
NNID
SSBM_PLAYER
I've pulled in the changes and re-released... I think.

v1.0.1.1 (1/8/2015)
- Fixed issue where program would prompt to save even if no changes were made.
- Fixed bug that caused player merge to crash under certain conditions.
- Fixed issue where tournaments with the same name could not properly be accessed individually. (Fizzi)
- Added improved error message when attempting to load Challonge tournaments. (Fizzi)
 

Sharkz

Smash Ace
Joined
Nov 11, 2007
Messages
529
Location
NC State, NC
NNID
Sharkz1
Quick question. Could you explain how decay works? I was entering in a recent tournament, and I was keeping an eye on the score of a certain player that I was curious about (who wasn't at that tournament). When I entered in the matches, that player's number drop thanks to monthly decay. But he had just been to a tournament under a week ago. He did take a month break before though. Do you know why they randomly drop like that?
 

Syde7

The Sultan of Smut
Joined
Dec 7, 2004
Messages
1,923
Location
Winston-Salem, NC
NNID
syde_7
Quick question, and it may be one that is easy to answer w/in the application and I totally glossed over it. When I enter manual results (am just running tests and such to get comfortable with it) the score reports as 1-0. Does that count as a game win (as in, one game of a 2/3, or 3/5 set), or 1 match win?

Am curious, as I feel that a player winning a set 2-0 should increase their score more than if they win 2-1 (and vice versa as it applies to losing).

If the former is the case (1 game win as opposed to a match win), is there a way to keep track of total matches won, regardless of the scores of those matches??

Thanks in advance, and again I apologize if this is somewhere in the application its documentation, Ive been looking for a few hours on and off and can't find anything.
 

Zankoku

Never Knows Best
Administrator
BRoomer
Joined
Nov 8, 2006
Messages
22,906
Location
Milpitas, CA
NNID
SSBM_PLAYER
Currently there is no differentiation as I haven't found a very effective way the incorporate game wins into the formula and tio/challonge only record scores rather than order of game wins (technically, you can just enter game wins in rather than set wins, but it's difficult to keep track of ordering of wins in order to do so).
 

Syde7

The Sultan of Smut
Joined
Dec 7, 2004
Messages
1,923
Location
Winston-Salem, NC
NNID
syde_7
Thanks for the very prompt response. Much appreciated.

So, just to clarify, the 1-0 (as you've designed it) is to communicate set wins. IE, Player A beats Player B.. enter it as "Player A defeats player B; score of 1-0"; with 2"-0/1" being used in the event of a grand finals bracket reset or something along those lines.


Thanks again.
 

Zankoku

Never Knows Best
Administrator
BRoomer
Joined
Nov 8, 2006
Messages
22,906
Location
Milpitas, CA
NNID
SSBM_PLAYER
That's correct.
Quick question. Could you explain how decay works? I was entering in a recent tournament, and I was keeping an eye on the score of a certain player that I was curious about (who wasn't at that tournament). When I entered in the matches, that player's number drop thanks to monthly decay. But he had just been to a tournament under a week ago. He did take a month break before though. Do you know why they randomly drop like that?
Decay occurs for all players for each decay period, universally. I might think of changing this later, not sure.
 

lazymp

Smash Apprentice
Joined
Apr 14, 2013
Messages
114
Location
Raleigh, NC
NNID
mpittman17
So it doesn't matter how many tournaments you compete in then?
Correct me if I'm wrong, Zankoku.
No, the number of tournaments you compete in doesn't directly affect decay, just the recency of the tournaments. If the decay is set to every 2 months, then results from tournaments that occurred prior to the previous 2 months count less.
 

BirdLordMasterBeak

Smash Apprentice
Joined
Dec 7, 2014
Messages
80
Location
Charlotte, NC
I wrote a small java program for this. It takes an exported csv file and a list of tags (typed up like challonges bulk add feature), compares the 2 lists and puts the names in properly seeded order into a text document . The only problem it has is that it's case sensitive. Anyone interested in it?
 
Last edited:

Citricide

JuneauSmashBros Tournament Organizer
Joined
Jan 11, 2014
Messages
176
Location
Juneau, Alaska
I wrote a small java program for this. It takes an exported csv file and a list of tags (typed up like challonges bulk add feature), compares the 2 lists and puts the names in properly seeded order into a text document . The only problem it has is that it's case sensitive. Anyone interested in it?
yes
 

BirdLordMasterBeak

Smash Apprentice
Joined
Dec 7, 2014
Messages
80
Location
Charlotte, NC
Alright if I am not allowed to link files, someone let me know and I will delete this link.
https://www.mediafire.com/?9ibyc563wt33qtj (URL updated)
To use it, you need to name the csv seeding.csv and make a txt document called participants.txt with the list of players in the same format that you would type them into challonge's bulk add. Place those 2 files in the same folder as the .jar file and then run the jar file. A text document called PerfectSeed.txt will be created. What it does is it will look at 1st seed and see if that person entered, then it will look at 2nd seed, etcetc and then it adds people that arent on the list at the bottom (and you can just do those manually) --Problem I was initially having was fixed due to @ Zankoku Zankoku 's mastery of the java API :)
 
Last edited:

Zankoku

Never Knows Best
Administrator
BRoomer
Joined
Nov 8, 2006
Messages
22,906
Location
Milpitas, CA
NNID
SSBM_PLAYER
Just do a check like
if(playerName.equalsIgnoreCase(otherName))
 

BirdLordMasterBeak

Smash Apprentice
Joined
Dec 7, 2014
Messages
80
Location
Charlotte, NC
Just do a check like
if(playerName.equalsIgnoreCase(otherName))
I am not very familiar with java api. That is so much simpler than the 30 lines of code I typed to fail at doing the same exact thing lol.
Here is the new url: https://www.mediafire.com/?9ibyc563wt33qtj
Let me know if there are any problems (whoever uses it) :)

Source in case you want to use it for anything:
It can probably be made more efficient but I was just trying to make something that worked lol

Code:
package seedingjava;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

public class Csvsplit
{
  public static void main(String[] args)
    throws UnsupportedEncodingException
  {
    Csvsplit obj = new Csvsplit();
    obj.run();
    obj.run2();
  }
 
  String[] participants = new String[1000];
  String[] goodParticipants;
  String[] seeding = new String[1000];
  String[] goodSeeding;
 
  public void run()
    throws UnsupportedEncodingException
  {
    String csvFile = "./seeding.csv";
    BufferedReader br = null;
    String line = "";
    String cvsSplitBy = "\",\"";
   

    int i = 0;
    try
    {
      br = new BufferedReader(new FileReader(csvFile));
      while ((line = br.readLine()) != null)
      {
        String[] seedingTemp = line.split(cvsSplitBy);
        this.seeding[i] = seedingTemp[1];
        i++;
      }
    }
    catch (FileNotFoundException e)
    {
      e.printStackTrace();
      if (br != null) {
        try
        {
          br.close();
        }
        catch (IOException e1)
        {
          e1.printStackTrace();
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
      if (br != null) {
        try
        {
          br.close();
        }
        catch (IOException e1)
        {
          e1.printStackTrace();
        }
      }
    }
    finally
    {
      if (br != null) {
        try
        {
          br.close();
        }
        catch (IOException e)
        {
          e.printStackTrace();
        }
      }
    }
    this.goodSeeding = new String[i];
    for (int j = 0; j < i; j++) {
      this.goodSeeding[j] = this.seeding[j];
    }
  }
 
  public void run2()
    throws UnsupportedEncodingException
  {
    String csvFile = "./participants.txt";
    BufferedReader br = null;
    String line = "";
    String cvsSplitBy = "\n";
   
    int i = 0;
    try
    {
      br = new BufferedReader(new FileReader(csvFile));
      while ((line = br.readLine()) != null)
      {
        String[] partparse = line.split(cvsSplitBy);
        this.participants[i] = partparse[0];
        i++;
      }
    }
    catch (FileNotFoundException e)
    {
      e.printStackTrace();
      if (br != null) {
        try
        {
          br.close();
        }
        catch (IOException e1)
        {
          e1.printStackTrace();
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
      if (br != null) {
        try
        {
          br.close();
        }
        catch (IOException e1)
        {
          e1.printStackTrace();
        }
      }
    }
    finally
    {
      if (br != null) {
        try
        {
          br.close();
        }
        catch (IOException e)
        {
          e.printStackTrace();
        }
      }
    }
    this.goodParticipants = new String[i];
    for (int j = 0; j < i; j++) {
      this.goodParticipants[j] = this.participants[j];
    }
    compare();
  }
 
  public void compare()
  {
    int seedCount = 0;
    String[] perfectSeed = new String[this.goodParticipants.length];
    for (int i = 0; i < this.goodSeeding.length; i++) {
      for (int j = 0; j < this.goodParticipants.length; j++) {
        if (this.goodSeeding[i].equalsIgnoreCase(this.goodParticipants[j]))
        {
          perfectSeed[seedCount] = this.goodParticipants[j];
          this.goodParticipants[j] = "";
          seedCount++;
        }
      }
    }
    for (int i = 0; i < this.goodParticipants.length; i++) {
      if (this.goodParticipants[i] != "")
      {
        perfectSeed[seedCount] = this.goodParticipants[i];
        seedCount++;
      }
    }
    try
    {
      FileWriter fw = new FileWriter(new File("./PerfectSeed.txt"));
      for (int i = 0; i < perfectSeed.length; i++)
      {
        fw.write(perfectSeed[i]);
        fw.write(System.lineSeparator());
      }
      fw.close();
    }
    catch (IOException ex)
    {
      ex.printStackTrace();
    }
  }
}
 
Last edited:

ooglefart

Smash Rookie
Joined
Oct 6, 2014
Messages
22
Hi, I like this thing very much. I found maybe a bug. When there's an X at the start or end of a name and you have a player named "X" it will automatically assign that player to "X". Not really a super important bug since it can be manually changed very easily. Just thought I would point it out. Also weird characters change up the order, I have a guy with weird lambda sign in his name or something that appears above the << Create New Player >> option. It doesn't overwrite it though so, once again, not a super important bug.
 

Zankoku

Never Knows Best
Administrator
BRoomer
Joined
Nov 8, 2006
Messages
22,906
Location
Milpitas, CA
NNID
SSBM_PLAYER
Oops lol. My bad.

v1.0.1.4 (2/11/2015)
- Fixed issue with unfinished tournament import in Challonge (now uses create date if completion date does not exist).
- Adjusted player import selection detection.

v1.0.1.3 (2/3/2015)
- Added draw detection capability to account for Challonge imports.
- Added ability to import unfinished tournaments from Challonge (experimental).
 

LiteralGrill

Smokin' Hot~
Joined
Dec 9, 2012
Messages
5,976
Location
Wisconsin
I hate to be a pain, but I've been trying to enter in this bracket: http://challonge.com/SSSSONE and been having issues.

It keeps telling me An item with the same key has already been added.

I'm not sure if it's the nature of it being pools to DE or something else, but I can't seem to find a way around it. Even when I click continue nothing will load. Does anyone have any idea what might be causing this?
 

Fizzi

Smash Ace
Joined
Feb 14, 2008
Messages
802
Location
Brooklyn, NY
Slippi.gg
FIZZI#36
It sounds to me like you're trying to add someone as a new player that already exists in your pool of players.

If it's the same player, make sure you specify you're merging with the existing entry with that name.

If it's a different player, change the name manually before trying to import. Maybe add a "(2)" or something at the end of the name.

That said maybe that's not the case cause I haven't tested uploading a two-stage tournament. So maybe tomorrow you can give me your API key and I can try to debug it... I'm about to go to bed now lol.
 
Last edited:

LiteralGrill

Smokin' Hot~
Joined
Dec 9, 2012
Messages
5,976
Location
Wisconsin
I tried what I could @ Fizzi Fizzi

This is the first tournament I put into the program so I'm not sure if the players overlapping is the issue. I have a feeling the big problem probably is the two-stage tournament. I really want to keep doing pools if possible and use the program. I PMd you my API if you want you bug test stuff.
 

Floppeh

Smash Cadet
Joined
Dec 22, 2014
Messages
61
Location
California
NNID
FloppehFeesh
This is a super useful tool and I will definitely be using this a lot. I am curious, how exactly is the score calculated for each player? I believe it is accurate, I am just curious.
 

Zankoku

Never Knows Best
Administrator
BRoomer
Joined
Nov 8, 2006
Messages
22,906
Location
Milpitas, CA
NNID
SSBM_PLAYER
score = (mu - 3 * sigma) * multiplier <defined in settings>
At a multiplier of 1 and no score decay (which raises sigma over each time period), the score ranges from 0 to 50.
 

BirdLordMasterBeak

Smash Apprentice
Joined
Dec 7, 2014
Messages
80
Location
Charlotte, NC
Would it be possible to add a feature to omit certain matches from the data? I have had a couple DQs recently and some of them actually have a big impact on the leaderboards. It would be a cool feature to look into adding in the future!
 

Fizzi

Smash Ace
Joined
Feb 14, 2008
Messages
802
Location
Brooklyn, NY
Slippi.gg
FIZZI#36
Would it be possible to add a feature to omit certain matches from the data? I have had a couple DQs recently and some of them actually have a big impact on the leaderboards. It would be a cool feature to look into adding in the future!
This has happened in our scene to. You can go into the history and delete them.
 

Fizzi

Smash Ace
Joined
Feb 14, 2008
Messages
802
Location
Brooklyn, NY
Slippi.gg
FIZZI#36
can you not import tournaments that you did not create?
I'm assuming you mean for challonge. The answer is no if they are on somebody else's account directly. If they are in an organization I believe you can view them. Just put the URL name of the organization in the subdomain field.

If they are on somebody else's account directly, I think they have to give you access for it to show up on your account. Either that or you need their API key.
 

the wizard howl

Smash Apprentice
Joined
Sep 24, 2013
Messages
123
Location
WI
(; _ ; )
I'm assuming you mean for challonge. The answer is no if they are on somebody else's account directly. If they are in an organization I believe you can view them. Just put the URL name of the organization in the subdomain field.

If they are on somebody else's account directly, I think they have to give you access for it to show up on your account. Either that or you need their API key.
(; _ ; ) am using it for statewide seeding.
but thank you for the information.
 

fraggle

Smash Cadet
Joined
May 2, 2014
Messages
26
So for some reason I keep getting a message that says Invalid API Key. Then I tried it on a version that you posted a while back and it gave me the same error message that says unhandled exception has occurred...if you select continue you will continue if you select quite the program will close.
 
Top Bottom