If you’re a casual gamer, then now’s the time for me to tell you this: “Turn back!” This article go into the science of Neko Atsume, and doesn’t stop until it comes out the other side with kittens clinging to us.

Data Driven Kittens

“Now I’m all out of Frisky bitz !” - Punctual

The Bear went and posted a link to Data Atsume nominating it for a prestigious award in our small circle of (mostly) friends from college who like fart jokes and the occassional dick pick. He’d talked about cookie clicker. Beknownst to him or not I looked into it a bit. It already had some app that told you everything to buy next to make Grandma’s treats come out faster and faster. I saw the allure, but didn’t get into it.

But this time when we had an award for a site I felt I needed to check out the game in more detail. Data Atsume had a lot of stuff talking about all the super special combos you can do to get the rarest cats, and patterns for optimizing how many unique cats you’ll see.

Maybe I can sit down and take pictures of rare cats all afternoon and it’ll be a days work?

They give me some silver and gold fish and tell me to buy kitten toys. Sure. No problem. Lemme just look at Atsume’s list…

Everything he’s talking about is so expensive. And he’s talking about putting out 2 types of cat food at once? Wait…

Yeah, this has ABSOLUTE ZERO on what to do for your new cat collector, sallying forth into the back yard la première fois. Nothing to tell our newly made photographers on how they might weigh their almighty choice? “WHAT DO I BUY FIRST?!”

Go Fish–

I shot a surprised email back to the Bear.

‘They’re telling you what cats want to come, but they’re doing nothing to tell you your roi as a player who hasn’t yet made it rich. Other useful features that are missing include adjusted fish income when talking about “getting the most fish”. This should definitely be an option as the store tells you you can trade 250 silver fish for 10 gold fish.’

I also had done some poking around to see if anyone had a real data driven guide about how to start make some quick silver and gold fish. Data Atsume posts a link to the data set on which jewelloree’s analysis is based. The data set does some exploratory analysis, but I felt it fell flat at giving players what would be useful to the most players.

I decided I needed a guide to help me determine the answer to this question:

“Which toys (or combinations of toys) would maximize daily (meaning real time) fish income?”"

I hit on a this Quora guide. Here was someone using the same data. Unfortunately William Chen, although he plays Neko Atsume daily, doesn’t expound on his analysis methods, just throws out some numbers and some recommendations. There’s no way I’m going to trust his data analysis over my own.

It’s about this time, I realize I’m gonna need to run the numbers myself.

I make a local copy of the Neko Atsume Database: “Raw Data” and “Toy Information” and start my journey.


Neko Atsume– A Primer

The beginning the end.

As beginners to Neko Atsume, here’s where we’re starting from, and what we want as an end result.

  1. Buy toys
  2. ???
  3. Have all options available

After all options become available to us, what we do with collecting kittens becomes more complex, and is beyond the scope of this primer. I suggest looking at Data Atsume’s Guide for more ideas. In the meantime, we’re going to work though the many substeps of step 2:

  • Place toys/food for cats to play with
  • Wait for cats to finish1
  • Collect magnificent fish gifts from our thankful cats
  • Use fish to buy toys that will make cats even more thankful
  • Repeat all of step 2.
  1. Note that if we don’t wait for cats to finish playing with a toy or eating a food, then they will be less thankful, and return fewer fish.

The hardest part about step 2 is determining what toys to buy to make the cats the most thankful. We explore this question in great detail for the rest of the primer.

Toys for Kitteh

There was an undertaking track the effects of placing out certain toys. This momentus data collection program was undertaken by several users on reddit. We hope to use their efforts to determine which displayed toys result in the highest return on investment.

With the current data set I don’t think we can accurately predict an hourly fish income rate. Thus, the objective of this primer is to get readers to buy toys that, in so far as we can tell, yield a lot of fish per usage.

“What’s the difference between high fish yield and hourly income?”

We don’t have any data on how long each cat spends so overjoyed with a toy that it can’t pull itself away. Nor does our data set yield any information about how many times per hour a cat actually plays with a toy.

Accordingly, we focus on fish yield.

Determining the best fish yields

Here I begin digging around in the actual data. I’m doing everything in R, and using the dplyr package.

require(dplyr)

I began by loading the data I’ve downloaded into R. Unfortunately the “Toy Information” spreadsheet tells the price of the item, but uses the color of the cell to denote the type of fish required to purchase the toy. I copied the data to my own spreadsheet and split the one cell into two, indicating both the number of fish and the type of fish required to make a purchase. Below is the result.

items <- read.csv("Copy of Neko Atsume Database - Toy Information.csv") %>% as.tbl
items 
## Source: local data frame [126 x 7]
## 
##                    Name Category   Size Cat.Capacity Price   Type
##                  (fctr)   (fctr) (fctr)       (fctr) (int) (fctr)
## 1              Baseball    Balls  Small            1    90 Silver
## 2     Rubber ball (red)    Balls  Small            1    60 Silver
## 3  Rubber ball (yellow)    Balls  Small            1    60 Silver
## 4    Rubber ball (blue)    Balls  Small            1    60 Silver
## 5       Watermelon ball    Balls  Small            1    80 Silver
## 6        Ping pong ball    Balls  Small            1    50 Silver
## 7           Soccer ball    Balls  Small            1    10   Gold
## 8           Temari ball    Balls  Small            1    25   Gold
## 9       Stress reliever    Balls  Small            1    80 Silver
## 10         Ball of yarn    Balls  Small            1   120 Silver
## ..                  ...      ...    ...          ...   ...    ...
## Variables not shown: Description (fctr)

Next up was the raw data. We want to get an idea of the data frame, so we run a quick summary on the entire thing. It turns out that we have so many variables we can’t even see everything properly.

raw <- read.csv("Neko Atsume Database - Raw Data.csv") %>% as.tbl
raw
## Source: local data frame [12,528 x 10]
## 
##                          Name               Toy  Fish   Type
##                        (fctr)            (fctr) (int) (fctr)
## 1    Snowball / Shironeko-san      Ball of yarn     3 Silver
## 2       Smokey / Kuroneko-san  Scratching board     5 Silver
## 3       Smokey / Kuroneko-san Rubber ball (red)     1 Silver
## 4         Shadow / Haiiro-san Rubber ball (red)     7 Silver
## 5        Sunny / Tobimike-san      Mister mouse     2 Silver
## 6  Pumpkin / Shirochatora-san    Cat metropolis     2   Gold
## 7       Bandit / Sabigara-san    Cat metropolis     3   Gold
## 8  Pumpkin / Shirochatora-san          Baseball    11 Silver
## 9      Socks / Kutsushita-san    Cat metropolis     3   Gold
## 10          Callie / Mike-san      Ball of yarn     1 Silver
## ..                        ...               ...   ...    ...
## Variables not shown: Silver.Equivalent (int), Gold.Equivalent (dbl),
##   Food.condition (fctr), Date (fctr), Theme (fctr), Toy.Size (fctr)

Next we look at the outputs

raw %>% colnames()
##  [1] "Name"              "Toy"               "Fish"             
##  [4] "Type"              "Silver.Equivalent" "Gold.Equivalent"  
##  [7] "Food.condition"    "Date"              "Theme"            
## [10] "Toy.Size"

The initial data frame has way more variables than we’re interested in handling in this primer, so we’ll pare things down considerably. We’re most interested in the following columns:

data <- select(raw, c(Toy:Silver.Equivalent,Food.condition,Toy.Size)) %>% as.tbl
data
## Source: local data frame [12,528 x 6]
## 
##                  Toy  Fish   Type Silver.Equivalent Food.condition
##               (fctr) (int) (fctr)             (int)         (fctr)
## 1       Ball of yarn     3 Silver                 3    Frisky bitz
## 2   Scratching board     5 Silver                 5    Frisky bitz
## 3  Rubber ball (red)     1 Silver                 1    Frisky bitz
## 4  Rubber ball (red)     7 Silver                 7    Frisky bitz
## 5       Mister mouse     2 Silver                 2    Frisky bitz
## 6     Cat metropolis     2   Gold               100    Frisky bitz
## 7     Cat metropolis     3   Gold               150    Frisky bitz
## 8           Baseball    11 Silver                11    Frisky bitz
## 9     Cat metropolis     3   Gold               150    Frisky bitz
## 10      Ball of yarn     1 Silver                 1    Frisky bitz
## ..               ...   ...    ...               ...            ...
## Variables not shown: Toy.Size (fctr)

Aside about Cat Food

You’ll notice above that the food above is referred to as Food.condition. This is because many cats will only make appearances with specific foods out. From the outset, setting out food is already going to influence our yield.

The first thing that we’ll do here is only select the food Frisky bitz. It is by far the most affordable of the cat foods you have to pay for, and independent sources all agree that it brings a high average fish yield. An exploratory analysis has lead me to agree for now.

Fdata <- filter(data, Food.condition == "Frisky bitz")

Along with this, we’ll make sure we remove all foods from the list of toys, since we have set these up as two distinct realms. With this complete, we no longer care about the category of toy or the toy’s description. So we ditch those two variables.

items <- filter(items, Category != "Food") %>% 
    select(-c(Category, Description))

A further note on cat food. Not all foods last the same amount of time (if uneaten). All of the ‘premium’ foods (ones that cost gold fish) seemingly last three hours, while Frisky bitz lasts 6 hours, and Thrifty bitz lasts 12 hours.


Aside about Toys

Toys come in two sizes: Small and Large. Small toys can be placed anywhere and hold a maximum of 1 cat. Large toys have to be placed in a central position, and take up the same amount of space as two small toys. Many times a large toy can hold more than 1 cat.

With the current data set it is hard to know whether having space for more cats on a toy makes it more likely that high numbers of cats will visit said toy. For the present we will assume that each space on a large toy has the same chance of being visited by any 1 small toy.

We create a new variable called efficiency factor that takes into account the number of locations used and the number of cats the structure is able to hold. We then generate the efficiency factor for each toy.

effCalc <- function(Size,Capacity) {
    
    Capacity <- as.integer(Capacity)
    
    if(Size=="Small") return(Capacity)
    else if(Size == "Large") return(Capacity/2)
    
    }

Eff.Factor <- apply(select(items, c(Size,Cat.Capacity)), 1, function(x) effCalc(x[1],x[2]))
items<- cbind(items,Eff.Factor) 

Now we can dispense with the variables Cat.Capacity, since it is a part of efficiency.

items <- items %>% select(-Cat.Capacity) %>% as.tbl
items
## Source: local data frame [120 x 5]
## 
##                    Name   Size Price   Type Eff.Factor
##                  (fctr) (fctr) (int) (fctr)      (dbl)
## 1              Baseball  Small    90 Silver          1
## 2     Rubber ball (red)  Small    60 Silver          1
## 3  Rubber ball (yellow)  Small    60 Silver          1
## 4    Rubber ball (blue)  Small    60 Silver          1
## 5       Watermelon ball  Small    80 Silver          1
## 6        Ping pong ball  Small    50 Silver          1
## 7           Soccer ball  Small    10   Gold          1
## 8           Temari ball  Small    25   Gold          1
## 9       Stress reliever  Small    80 Silver          1
## 10         Ball of yarn  Small   120 Silver          1
## ..                  ...    ...   ...    ...        ...

Getting Back to Fish Yields

Next we’ll summarize toy yields in terms of silver fish equivalents. To do this we first comb through the data looking for all toys of the same name. We take these groups of toys and calculate the mean, standard deviation, and number of visits for each.

sfeSummary <- Fdata %>%             # group the data into which type of toy it comes from
    group_by(Toy) %>%               # make calculations on the sfe and find the number of visits
    summarize(meanYield = mean(Silver.Equivalent), sdYield = sd(Silver.Equivalent), Visits = n())

sfeSummary %>% arrange(desc(meanYield)) %>% as.tbl # print sorted table
## Source: local data frame [121 x 4]
## 
##                   Toy meanYield   sdYield Visits
##                (fctr)     (dbl)     (dbl)  (int)
## 1           Warm sock 153.50000 174.02203      4
## 2  Rubber ball (blue) 102.28571 130.27754      7
## 3         Frisky bitz  66.67089  73.23701     79
## 4      Cushion (pink)  58.75000 111.94731     16
## 5      Beach umbrella  53.10714 105.66100     28
## 6         Twisty rail  48.40000 112.95688     15
## 7      Scratching log  45.73077 106.42915     26
## 8           Snow sled  42.91176  99.32358     34
## 9      Burger cushion  42.76923 100.64058     13
## 10        Cat pancake  42.05882 106.93893     17
## ..                ...       ...       ...    ...

A glance here shows that the two highest yields have only a few visits, and that the standard deviation is insanely large. This is a strong sign that there is not enough data to be confident that these visits to be representative of the true mean.

In the next part of our analysis, we merge the sfeSummary and items data sets.

sfe <- merge(sfeSummary,items, by.x = "Toy", by.y = "Name") 

We create a new variable that will replace mean yield and Eff.Factor, called adjusted yield.

sfe <- sfe %>% mutate(adjYield = meanYield*Eff.Factor)              # make new variable
sfe <- sfe %>% select(-c(meanYield,Eff.Factor)) %>% select(1,7,2:6) # delete old variables and rearrange
sfe %>% arrange(desc(adjYield)) %>% head(20)                        # print sorted table
##                   Toy  adjYield   sdYield Visits  Size Price   Type
## 1           Warm sock 153.50000 174.02203      4 Small    11   Gold
## 2  Rubber ball (blue) 102.28571 130.27754      7 Small    60 Silver
## 3      Beach umbrella  79.66071 105.66100     28 Large   340 Silver
## 4      Cushion (pink)  58.75000 111.94731     16 Small   100 Silver
## 5      Paper umbrella  56.07692  79.34738     26 Large    50   Gold
## 6      Cat metropolis  52.91429  58.24166    315 Large    50   Gold
## 7   Tunnel (3D piece)  49.80392  68.58137    255 Large    20   Gold
## 8      Scratching log  45.73077 106.42915     26 Small    30   Gold
## 9       Giant cushion  45.32143  68.08211     56 Small   210 Silver
## 10          Snow sled  42.91176  99.32358     34 Large   140 Silver
## 11     Burger cushion  42.76923 100.64058     13 Small    15   Gold
## 12        Cat pancake  42.05882 106.93893     17 Small    24   Gold
## 13    Cushion (brown)  41.00000  92.22256      7 Small   100 Silver
## 14        Basket case  40.92857  90.76891     14 Small   320 Silver
## 15       Fruit basket  39.27586  84.89680     58 Small    80 Silver
## 16       Bucket (red)  39.12500 105.41949      8 Small    60 Silver
## 17   Black head space  37.76000  89.11943     25 Small   380 Silver
## 18    Butterfly swarm  37.14286  84.86900     14 Small    12   Gold
## 19    Bureau with pot  35.50000  53.52107    100 Large   950 Silver
## 20       Ball of yarn  35.05357  83.44414     56 Small   120 Silver

With this, I’m done for now. Good luck photographing cats and collecting fish!