Introduction

In this document, we present the results of Tactical Triggernometry’s third annual survey.

The following analysis was done in the popular, free and open source statistical computing language called R. Readers may access the code used in our results by clicking the collapsible “code” buttons adjacent to all the tables, statistical tests, charts, and plots. The ability to peer review this work ensures the analysis presented is transparent and reproducible. I encourage readers to examine the code, find any mistakes, and run the code themselves.

The administration team hopes the annual survey provides community members with a better understanding of the server and the community as a whole.

This document is structured in the following way:

  • Glossary
  • Topline results
  • Experienced versus other players
  • External Clans
  • Squad leaders
  • Groups & Clusters
  • Responses to comments
  • Conclusion (Read this if you just want a brief summary)
  • Appendix: Regression analysis

Readers may use the table of contents on the left to scroll to each of the various sections and subsections at their leisure.

Please forward any and all questions about this survey to me (Randy Newman). Any mistakes in this document are my responsibility alone.

Load & Clean data

Let us load the required packages to analyse the survey results.

rm(list=ls()) # Clear all objects in the global environment
library(tidyverse) # For data manipulation + graphing
library(gtsummary) # Summary statistics
library(knitr) # To compile HTML document
library(kableExtra) # To create nice looking tables
library(readr) # To read and import survey data
library(ggh4x) # Advanced layout options

Now that the requisite packages have been loaded, let us load the data and recode some variables. Recoding a variable just means making variables names more readable and cleaning the data so that it can be analysed. The full and unedited dataset, minus the comments, is available here for those interested.

#Import Data
tt <- read_csv("Data/[TT] Tactical Triggernometry - Survey 3 .csv")

#Cleaning
df <- tt[, 2:42] #Creating a separate work dataframe.

#Clean var names
colnames(df) <- c('sqtime', 'regular', 'ttime', 'sl',
                  'slserver', 'clan', 'admresp', 'admprof',
                  'admfair', 'admoverall', 'twork', 'learn',
                  'balance', 'skill', 'toxic', 'maprot', 'Skorpo',
                  'Belaya', 'Fools', 'Gorodok', 'Mestia', 'Narva',
                  'Yehorivka', 'Chora', 'Kamdesh', 'Kohat', 'Kokan', 'Lashkar',
                  'Logar', 'Sumari', 'Basrah', 'Anvil', 'Fallujah', 'Mutaha',
                  'Talil', 'Manic', 'Goose Bay', 'Black Coast', 'basecamp',
                  'comms', 'asset')

#Designate certain variables as ordered factor variables

df$sqtime <- ordered(df$sqtime, levels = c("Fewer than 100 hours", 
                                            "Between 100 - 600 hours", 
                                            "Between 600 - 1000 hours", 
                                            "1000+ hours"))

#relabel
levels(df$sqtime) <- c("Fewer than 100 hours", 
                       "Between 100 - 600 hours", 
                       "Between 600 - 1,000 hours", 
                       "1,000+ hours")

df$ttime <- ordered(df$ttime, levels = c("Fewer than 6 months", 
                                         "Between 6 months - 1 year",
                                         "Between 1 - 2 years", "Over 2 years"))

df$regular <- ordered(df$regular, levels = c("Yes", "No"))
df$sl <- ordered(df$sl, levels = c("Yes", "No"))
df$clan <- ordered(df$clan, levels = c("Yes", "No"))

#Create dummy variable for over 1000 hours
df <- df %>% mutate(over1k = case_when(sqtime == "1,000+ hours" ~ "Yes",
                                       sqtime == "Fewer than 100 hours" ~ "No",
                                        sqtime == "Between 100 - 600 hours" ~ "No",
                                        sqtime == "Between 600 - 1,000 hours" ~ "No"))

df$over1k <- ordered(df$over1k, levels = c("Yes", "No"))

#Create dummy variable for having been at TT for over/under a year

df <- df %>% mutate(over1tt = case_when(ttime == "Fewer than 6 months" ~ "No",
                                        ttime == "Between 6 months - 1 year" ~ "No",
                                        ttime == "Between 1 - 2 years" ~ "Yes",
                                        ttime == "Over 2 years" ~ "Yes"))

df$over1tt <- ordered(df$over1tt, levels = c("Yes", "No"))

#Clean up map data - Recode checks to 1 and not checks to 0
df <- df %>% mutate(across(c('Skorpo':'Black Coast'), ~
                  case_when(. == "TT should play more of:" ~ 1, 
                                        is.na(.) ~ 0)))

The dataset is now clean and ready for analysis.

Glossary

Before we can delve into the analysis, a basic glossary of statistical terms may be useful in understanding this report. For ease of reference, we have highlighted these concepts as they appear in the report. Clicking the highlighted terms will lead you back to the glossary.

#Create glossary table

#list of terms to be defined
n <- "The number of observations being used in the calculation. Sometimes different across tables because of missing values (people leaving questions blank)."

fdist <- "A frequency distribution is just a count of the number of times an observation occurs in the data. In a scoring metric of 1-10, if 50 people gave us a 9/10 in a certain category, the frequency of '9' would be 50."

sd <- "Standard deviation is a common statistical measure of the amount of dispersion in the scores. A low standard deviation suggests that observations are clustered close to the mean. A high standard deviation indicates greater dispersion."

ci <- "When dealing with sample data (the survey) we, as readers, want to make inferences about the population (the full TT playerbase) from a limited sample. A confidence interval is a range of estimates for an unknown parameter computed at a confidence level (commonly 95%). The straight forward way to interpret the confidence interval is that  'we are 95% confident that the true population parameter is between the lower and the upper bounds.'"

dens <- "A common visual tool used to represent a distribution. When you imagine a normal distribution, you are likely imagining a [density plot.](https://dr282zn36sxxg.cloudfront.net/datastreams/f-d%3A77ae1b0df235e7f9baa2286c6dd7f86f3d626299c850cb9220e17422%2BIMAGE_TINY%2BIMAGE_TINY.1) A crucial thing to note is that the area under a density plot always adds up to one (i.e., 100%)."

stest <- "A test for whether the data at hand support a certain hypothesis. Each statistical test (such as a T-test), is a hypothesis test. In the case of the T-test, the hypothesis is that 'the 2 groups have identical means.' Rejecting that hypothesis means that the two groups have different means."

pval <- "The outcome of each statistical test is a number known as the 'test statistic.' Each 'test statistic' is associated with a p-value (probability value). The p-value has a straightforward interpretation. **Conventionally, if a p-value is lower than 0.05, we conclude that there is enough evidence to reject a 'null hypothesis' in a statistical test. This means that differences we are seeing between the groups are probably real (non-zero) and not due to random chance.**"

statsig <- "Statistically significant is just a **formal way of saying non-zero.** It is really that simple - something is statistically significant if it is different from zero. We calculate **p-values** after statistical tests to acsertain the probability of statistical significance. Normally, we consider something significant if the **p-value associated with it is less than 0.05.** It is important to remember that just because something is significant (non-zero) does not mean that the effect is large.

Sometimes, we also calculate q-values too which are basically adjusted p-values. Q-values are just p-values adjusted for things like [multiple comparisons](https://en.wikipedia.org/wiki/Multiple_comparisons_problem). They have the same interpretation. In this report, I consider something to be *'strongly' significant* if **both** the associated p and q values are less than 0.05 and *'weakly' significant* if only the p-value is less than 0.05."

chi2 <- " A standard statistical test commonly used for frequency counts. More information can be gleaned [from this video on youtube.](https://www.youtube.com/watch?v=GG7dFnvbMKI)"

weltest <- "A standard statistical test commonly used to test for differences in means between categories. [See here for more information.](https://www.youtube.com/watch?v=cBJjthfJ_s0)"

#Build table
gloss <- tribble(~Term, ~Definition,
                 "N", n,
                 "Frequency Distribution",  fdist,
                 "Standard deviation", sd,
                 "Confidence interval", ci,
                 "Density plot", dens,
                 "Statistical test", stest,
                 "P-value", pval,
                 "Statistical significance", statsig,
                 "Chi-squared test", chi2,
                 "Welch's T-test", weltest)

colnames(gloss) <- c(" ", " ")

#Format table
gloss <- gloss %>% kable() %>% kable_styling(bootstrap_options = c("striped", "hover", 
                                                     "condensed"), 
                                   position = 'center') %>% 
   add_header_above(c("Glossary of standard terms" = 2)) %>%  column_spec(1, bold = T)

rm(chi2, ci, dens, fdist, n, pval, sd, statsig, stest, weltest)

#Display table
gloss
Glossary of standard terms
N The number of observations being used in the calculation. Sometimes different across tables because of missing values (people leaving questions blank).
Frequency Distribution A frequency distribution is just a count of the number of times an observation occurs in the data. In a scoring metric of 1-10, if 50 people gave us a 9/10 in a certain category, the frequency of ‘9’ would be 50.
Standard deviation Standard deviation is a common statistical measure of the amount of dispersion in the scores. A low standard deviation suggests that observations are clustered close to the mean. A high standard deviation indicates greater dispersion.
Confidence interval When dealing with sample data (the survey) we, as readers, want to make inferences about the population (the full TT playerbase) from a limited sample. A confidence interval is a range of estimates for an unknown parameter computed at a confidence level (commonly 95%). The straight forward way to interpret the confidence interval is that ‘we are 95% confident that the true population parameter is between the lower and the upper bounds.’
Density plot A common visual tool used to represent a distribution. When you imagine a normal distribution, you are likely imagining a density plot. A crucial thing to note is that the area under a density plot always adds up to one (i.e., 100%).
Statistical test A test for whether the data at hand support a certain hypothesis. Each statistical test (such as a T-test), is a hypothesis test. In the case of the T-test, the hypothesis is that ‘the 2 groups have identical means.’ Rejecting that hypothesis means that the two groups have different means.
P-value The outcome of each statistical test is a number known as the ‘test statistic.’ Each ‘test statistic’ is associated with a p-value (probability value). The p-value has a straightforward interpretation. Conventionally, if a p-value is lower than 0.05, we conclude that there is enough evidence to reject a ‘null hypothesis’ in a statistical test. This means that differences we are seeing between the groups are probably real (non-zero) and not due to random chance.
Statistical significance

Statistically significant is just a formal way of saying non-zero. It is really that simple - something is statistically significant if it is different from zero. We calculate p-values after statistical tests to acsertain the probability of statistical significance. Normally, we consider something significant if the p-value associated with it is less than 0.05. It is important to remember that just because something is significant (non-zero) does not mean that the effect is large.

Sometimes, we also calculate q-values too which are basically adjusted p-values. Q-values are just p-values adjusted for things like multiple comparisons. They have the same interpretation. In this report, I consider something to be ‘strongly’ significant if both the associated p and q values are less than 0.05 and ‘weakly’ significant if only the p-value is less than 0.05.
Chi-squared test A standard statistical test commonly used for frequency counts. More information can be gleaned from this video on youtube.
Welch’s T-test A standard statistical test commonly used to test for differences in means between categories. See here for more information.

Topline results

In this section, I shall present the findings to all questions over the full sample. We shall break the data into subgroups in later sections. We received a total of 313 responses. While the vast majority of respondents answered every question, not everyone did so. This is why readers may notice slight differences in the amount of observations associated with each question in some tables.

Demographics

In the first section of the survey, we asked general questions such as “How long have you played Squad?” and “Do you SL often on the server?” Below, I present the findings of these questions. First, let us look at the breakdown of how long respondents have played Squad:

#Remove previous
rm(gloss)

#Create blank theme to use in all pie charts
blank_theme <- theme_minimal()+
  theme(
  axis.title.x = element_blank(),
  axis.title.y = element_blank(),
  panel.border = element_blank(),
  panel.grid=element_blank(),
  axis.ticks = element_blank(),
  plot.title=element_text(size=14, face="bold"))

#Chart 1
chart1 <- df %>% select(sqtime) %>% ggplot(aes(x = factor(1), fill = sqtime)) +   
  geom_bar(width = 1)+ coord_polar("y") +  blank_theme + 
  theme(axis.text.x=element_blank()) + 
  scale_fill_brewer("How long have you played Squad?", palette = "Set1") + 
  theme(axis.text.y=element_blank()) + 
  labs(title = "Chart 1: Time spent playing Squad") + 
  theme(plot.title = element_text(hjust = 0.5))

#Display
chart1

#Remove previous
rm(chart1)

#Table 1 - Sqtime

table1 <- df %>% select(sqtime) %>% tbl_summary(type = sqtime ~ "categorical",
                                                label = sqtime ~ "Hours in Squad") %>% 
  add_ci() %>%   modify_footnote(everything() ~ NA) %>%  
  modify_footnote(ci_stat_0 ~ NA, abbreviation = TRUE)

#Save inline text results
inline.t1 <- as_tibble(table1[["table_body"]][["stat_0"]])

table1 <- table1 %>% as_kable_extra() %>% 
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), 
                                 position = 'center', full_width = TRUE) %>% 
  footnote(general = c("[N](#gloss) is the observation count",
                       "CI Stands for [confidence interval](#gloss)"))  %>%  
  add_header_above(c("Table 1: Time spent playing squad - Full sample" = 3))

table1
Table 1: Time spent playing squad - Full sample
Characteristic N = 313 95% CI
Hours in Squad
Fewer than 100 hours 5 (1.6%) 0.59%, 3.9%
Between 100 - 600 hours 79 (25%) 21%, 30%
Between 600 - 1,000 hours 64 (20%) 16%, 25%
1,000+ hours 165 (53%) 47%, 58%
Note:
N is the observation count
CI Stands for confidence interval

Both the chart and the table indicate that players with over 1,000 hours are likely overrepresented both at TT and in the pool of respondents. This is somewhat expected. We can see that the majority of respondents, approximately 53%, have over 1,000 hours in game.

Table 1 reports also confidence intervals for each category. Please check the glossary table for better understanding this and other terms!

Moving on, let us do a similar exercise for the amount of time people have been at TT:

#Remove previous
rm(table1)

#Chart 2
chart2 <- df %>% select(over1tt) %>% ggplot(aes(x = factor(1), fill = over1tt)) +   
  geom_bar(width = 1)+ coord_polar("y") +  blank_theme + 
  theme(axis.text.x=element_blank()) + 
  scale_fill_brewer("1+ Year at TT?", palette = "Set1") + 
  theme(axis.text.y=element_blank()) + 
  labs(title = "Chart 2: Time spent at TT") + 
  theme(plot.title = element_text(hjust = 0.5))

#Display
chart2

#Remove previous
rm(chart2)

#Table 2 - ttime

table2 <- df %>% select(ttime) %>% tbl_summary(type = ttime ~ "categorical",
                                                label = ttime ~ "Time at TT") %>% 
  add_ci() %>%   modify_footnote(everything() ~ NA) %>%  
  modify_footnote(ci_stat_0 ~ NA, abbreviation = TRUE) %>%  
  as_kable_extra()

table2 <- table2 %>% kable_styling(bootstrap_options = c("striped", "hover", 
                                                     "condensed"), 
                                 position = 'center', full_width = TRUE) %>% 
  footnote(general = c("[N](#gloss) is the observation count",
                       "CI Stands for [confidence interval](#gloss)"))  %>%  
  add_header_above(c("Table 2: Time spent at TT - Full sample" = 3))

table2
Table 2: Time spent at TT - Full sample
Characteristic N = 313 95% CI
Time at TT
Fewer than 6 months 66 (21%) 17%, 26%
Between 6 months - 1 year 103 (33%) 28%, 38%
Between 1 - 2 years 99 (32%) 27%, 37%
Over 2 years 45 (14%) 11%, 19%
Note:
N is the observation count
CI Stands for confidence interval

From Chart 2, we can see that the playerbase is roughly evenly split between those who have been at TT for over a year versus those who have not. The table above provides a more detailed breakdown. As before, confidence intervals are presented so that the reader can make their own inferences.

Let us see whether or not respondents are (self-declared) regulars:

#Remove previous
rm(table2)

#Table 3 - Regs

table3 <- df %>% select(regular) %>% tbl_summary(type = regular ~ "categorical",
                                                label = regular ~ "Do you consider TT to be your primary server?") %>% 
  add_ci() %>%   modify_footnote(everything() ~ NA) %>%  
  modify_footnote(ci_stat_0 ~ NA, abbreviation = TRUE)
#Inline t3
inline.t3<- as_tibble(table3[["table_body"]][["stat_0"]])

table3 <- table3 %>%  as_kable_extra() %>% 
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), 
                                 position = 'center', full_width = TRUE) %>% 
  footnote(general = c("[N](#gloss) is the observation count",
                       "CI Stands for [confidence interval](#gloss)"))  %>%  
  add_header_above(c("Table 3: Yes/No question on whether people consider TT their primary server - Full sample" = 3))

table3
Table 3: Yes/No question on whether people consider TT their primary server - Full sample
Characteristic N = 313 95% CI
Do you consider TT to be your primary server?
Yes 281 (90%) 86%, 93%
No 32 (10%) 7.2%, 14%
Note:
N is the observation count
CI Stands for confidence interval

The overwhelming majority of respondents (around 90%) are regulars. Even the lower bound of the confidence interval is very high.

A wide variety of external clans and communities have made TT their home server. Let’s check what percentage of TT’s playerbase is affiliated with outside clans and/or communities:

#Remove previous
rm(table3, inline.t3)

#Chart 3 - clans
chart3 <- df %>% select(clan) %>% ggplot(aes(x = factor(1), fill = clan)) +   
  geom_bar(width = 1)+ coord_polar("y") +  blank_theme + 
  theme(axis.text.x=element_blank()) + 
  scale_fill_brewer("Are you affiliated with an outside clan?", palette = "Set1") + 
  theme(axis.text.y=element_blank()) + 
  labs(title = "Chart 3: Outside clans") + theme(plot.title = element_text(hjust = 0.5))

#Display
chart3

#Remove previous
rm(chart3)

#Table 4 - clans

table4 <- df %>% select(clan) %>% tbl_summary(type = clan ~ "categorical",
                                                label = clan ~ "Are you affiliated with an outside clan?") %>% 
  add_ci() %>%   modify_footnote(everything() ~ NA) %>%  
  modify_footnote(ci_stat_0 ~ NA, abbreviation = TRUE)

#Inline
inline.t4 <- as_tibble(table4[["table_body"]])

table4 <- table4 %>% as_kable_extra() %>% 
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), 
                                 position = 'center', full_width = TRUE) %>% 
  footnote(general = c("[N](#gloss) is the observation count",
                       "CI Stands for [confidence interval](#gloss)"))  %>%  
  add_header_above(c("Table 4: Outside clan affiliation - Full sample" = 3))

table4
Table 4: Outside clan affiliation - Full sample
Characteristic N = 313 95% CI
Are you affiliated with an outside clan?
Yes 107 (34%) 29%, 40%
No 206 (66%) 60%, 71%
Note:
N is the observation count
CI Stands for confidence interval

We can see that a substantial portion of survey respondents, and probably TT regulars as a whole, are affiliated with outside clans and communities. The point estimate is 34%, which is high.

Due to the fact that clan members are the sort of players who are more likely to respond to a survey, their views are probably overrepresented in the sample. It is my belief that the true proportion of external clan members on the server lies closer to the lower bound of the confidence interval (around 29%), though that is still quite substantial.

Let’s check the responses to the question about whether respondents squad lead often:

#Remove previous
rm(table4)

#Chart 4- Sls
chart4 <- df %>% select(sl) %>% filter(!is.na(sl)) %>%  ggplot(aes(x = factor(1), fill = sl)) +   
  geom_bar(width = 1)+ coord_polar("y") +  blank_theme + 
  theme(axis.text.x=element_blank()) + 
  scale_fill_brewer("Do you squad lead open squads often?",palette = "Set1") + 
  theme(axis.text.y=element_blank()) + 
  labs(title = "Chart 4: Squad leaders") + theme(plot.title = element_text(hjust = 0.5))

#Display
chart4

#Remove previous
rm(chart4, blank_theme)

#Table 5 - Sls

table5 <- df %>% select(sl) %>% tbl_summary(type = sl ~ "categorical",
                                                label = sl ~ "Do you squad lead open squads often?", missing_text = "Did not answer") %>% 
  add_ci() %>%   modify_footnote(everything() ~ NA) %>%  
  modify_footnote(ci_stat_0 ~ NA, abbreviation = TRUE)

#Inline t5
inline.t5 <- as_tibble(table5[["table_body"]])

table5 <- table5 %>% as_kable_extra() %>% 
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), 
                                 position = 'center', full_width = TRUE) %>% 
  footnote(general = c("[N](#gloss) is the observation count",
                       "CI Stands for [confidence interval](#gloss)"))  %>%  
  add_header_above(c("Table 5: Do you squad lead open squads often? - Full sample" = 3))

table5
Table 5: Do you squad lead open squads often? - Full sample
Characteristic N = 313 95% CI
Do you squad lead open squads often?
Yes 108 (35%) 29%, 40%
No 204 (65%) 60%, 71%
Did not answer 1
Note:
N is the observation count
CI Stands for confidence interval

Roughly 35% of the sample respondents claim that they regularly lead open squads. The confidence intervals are also reported as before. It is my belief that respondents are over-reporting their time as “squad leaders” or perhaps they have a different definition of “often” than I do. The most likely scenario is that the truth about how many respondents “often” lead open squads lies towards the lower end of the confidence interval (roughly 29%).

The question about whether TT is a good server to be an SL is addressed in the server environment subsection.

Administration

Let us check the responses to the questions about administration.

#Remove previous
rm(table5)

#Build

table6 <- df %>% select('admresp':'admoverall') %>% tbl_summary(
  type = everything() ~ "continuous",
  statistic = all_continuous() ~ "{mean} ({sd})",
  missing = "no", label = list('admresp' ~ 'Admin response time',
                               'admprof' ~ 'Admin professionalism',
                               'admfair' ~ 'Admin fairness',
                               'admoverall' ~ 'Overall quality of administration'),
  digits = everything() ~ 2) %>% add_ci() %>% 
  modify_header(stat_0 ~ "**Mean (SD)**") %>%   
  modify_footnote(everything() ~ NA) %>%  
  modify_footnote(ci_stat_0 ~ NA, abbreviation = TRUE) %>% add_n() %>%  as_kable_extra()

#Format
table6 <- table6 %>% kable_styling(bootstrap_options = c("striped", "hover", 
                                                     "condensed"), 
                                   position = 'center') %>% 
  footnote(general = c("SD stands for [Standard Deviation](#gloss)",
                      "CI Stands for [confidence interval](#gloss)")) %>% 
   add_header_above(c("Table 6: Summary statistics for administration - Full Sample" = 4))

  
#Display
table6
Table 6: Summary statistics for administration - Full Sample
Characteristic N Mean (SD) 95% CI
Admin response time 306 8.51 (1.63) 8.3, 8.7
Admin professionalism 306 7.99 (2.01) 7.8, 8.2
Admin fairness 304 8.03 (2.02) 7.8, 8.3
Overall quality of administration 305 8.31 (1.86) 8.1, 8.5
Note:
SD stands for Standard Deviation
CI Stands for confidence interval

Let us plot some of the distributions using density plots:

#Remove previous
rm(table6)

#Pivot the category scores to long
tempdf <- df %>% select(admresp, admprof, admfair, admoverall) %>% 
  tidyr::pivot_longer(cols = c("admresp", "admprof", "admfair", "admoverall"), 
                                   names_to = "Category", values_to = "Score")

tempdf$Category <- ordered(tempdf$Category, levels = c("admresp", "admprof", "admfair", "admoverall"))
levels(tempdf$Category) <- c("Admin response time", "Admin professionalism", "Admin fairness", "Overall quality of administration" )

# Create faceted density plots
chart5 <- ggplot(data = tempdf, aes(x=Score)) + geom_density(color="#99ccff", fill="#99ccff") + theme_bw() + theme(panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_line(colour = "black")) + 
  theme(legend.position = "none") + facet_wrap( ~ Category,  scales = "free_y", ncol=2) + xlab("") + ylab("Density") + 
  labs(title = "Chart 5: Density plots - Administrative questions") + 
  theme(plot.title = element_text(hjust = 0.5))


chart5

As we can see from both the density plots in Chart 5 and the summary statistics in Table 6, survey respondents rated us very well in all categories pertaining to server administration. The plots in Chart 5 show marked skews towards the upper end of the distribution while the mean score in all categories across administration is around 8/10. The reported standard deviations and the density plots above give the reader a good sense of the spread of the distribution of these ratings.

Server environment

Let us check the responses to questions about the server environment:

rm(chart5, tempdf)

#Build
table7 <- df %>% select('twork':'toxic', 'slserver') %>% tbl_summary(
    type = everything() ~ "continuous", missing = "no",
    statistic = all_continuous() ~ "{mean} ({sd})",
    label = list("twork" ~ "Teamwork",
                 "learn" ~ "Learning Environment",
                 "balance" ~ "Team Balance",
                 "skill" ~ "Gameplay level",
                 "slserver" ~ "Environment for SLs",
                 "toxic" ~ "Overall server environment"),
      digits = everything() ~ 2) %>% add_ci() %>% 
  modify_header(stat_0 ~ "**Mean (SD)**") %>%   
  modify_footnote(everything() ~ NA) %>%  
  modify_footnote(ci_stat_0 ~ NA, abbreviation = TRUE) %>% add_n() %>% as_kable()

#Format
table7 <- table7 %>% kable_styling(bootstrap_options = c("striped", "hover", 
                                                     "condensed"), 
                                   position = 'center') %>% 
  footnote(general = c("SD stands for [Standard Deviation](#gloss)",
                      "CI Stands for [confidence interval](#gloss)")) %>% 
   add_header_above(c("Table 7: Summary statistics for server environment - Full Sample" = 4)) %>% 
  row_spec(c(2,3), bold = T, color = "white", background = "#D7261E")

#Display
table7
Table 7: Summary statistics for server environment - Full Sample
Characteristic N Mean (SD) 95% CI
Teamwork 309 8.11 (1.74) 7.9, 8.3
Learning Environment 307 6.39 (2.38) 6.1, 6.7
Team Balance 307 6.74 (2.23) 6.5, 7.0
Gameplay level 306 8.42 (1.51) 8.3, 8.6
Overall server environment 309 7.47 (2.03) 7.2, 7.7
Environment for SLs 295 7.43 (1.89) 7.2, 7.6
Note:
SD stands for Standard Deviation
CI Stands for confidence interval

As before, I show density plots to illustrate the frequency distributions of the variables above:

#Remove previous
rm(table7)

#Pivot the category scores to long
tempdf <- df %>% select(twork, learn, balance, skill, toxic, slserver) %>% 
  tidyr::pivot_longer(cols = c("twork", "learn", "balance", "skill", "toxic", "slserver"), 
                                   names_to = "Category", values_to = "Score")

tempdf$Category <- ordered(tempdf$Category, levels = c("twork", "learn", "balance", "skill", "toxic", "slserver"))
levels(tempdf$Category) <- c("Teamwork", "Learning environment", "Team balance", "Gameplay level", "Overall server environment", "Environment for SLs")

# Create faceted density plots
chart6 <- ggplot(data = tempdf, aes(x=Score)) + geom_density(color="#99ccff", fill="#99ccff") + theme_bw() + theme(panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_line(colour = "black")) + 
  theme(legend.position = "none") + facet_wrap( ~ Category,  scales = "free_y", ncol=2) + xlab("") + ylab("Density") + 
  labs(title = "Chart 6: Density plots - Server enivronment questions") + theme(plot.title = element_text(hjust = 0.5))


chart6

While the picture here is more mixed than the administration category, the server scores 7 to 8.5 out of 10 in most categories. All the scores are above 6/10 and the density plots show marked skews towards the upper end of the distribution.

TT performs best when it comes to teamwork and the overall gameplay level. With regards to the overall server environment, and the environment for SLs specifically, the scores are closer to 7.5/10. There is some room for improvement here, but not by much.

The two categories of concern are the learning environment and team balance. This is somewhat unsurprising. TT is not exactly a server that caters towards newer players. A majority of players have over 1,000+ hours playing squad (see Chart 1). It is fair to say that experienced players are over represented on the server and as survey respondents. Still, the learning environment is something that we can all improve on by being kinder and accommodating to newer players. This is not an area that the administration team has full control over.

Team Balance is tricky on most servers. While it is our opinion that TT balances better than most servers, there is still room for improvement. Given that a high proportion of our playerbase comes from outside clans (see Table 4), it can be hard to balance while keeping groups together. The one thing that I want to add is that balance is something that is always being discussed by the admins in admin chat behind the scenes. Players are constantly being shuffled. This is not something that is often visible to the general public.

Maps

We also asked two questions about the map selection at TT. First, we asked respondents how satisfied they were with the map rotation overall:

#Remove previous
rm(chart6, tempdf)

#Build table
table8 <- df %>% select('maprot') %>% tbl_summary(
  type = 'maprot' ~ 'continuous',  statistic = all_continuous() ~ "{mean} ({sd})",
  missing = "no", digits = 'maprot' ~ 2, 
  label = 'maprot' ~ "Satisfaction with map rotation")  %>% 
  modify_header(stat_0 ~ "**Mean (SD)**", label = 'Table 8 - Map rotation') %>%  add_ci() %>% 
  modify_footnote(everything() ~ NA) %>%  
  modify_footnote(ci_stat_0 ~ NA, abbreviation = TRUE) %>% add_n() %>% as_kable()

#Format
table8 <- table8 %>% kable_styling(bootstrap_options = c("striped", "hover", "condensed"), 
                                   position = 'center') %>% 
  footnote(general = c("SD stands for [Standard Deviation](#gloss)",
                      "CI Stands for [confidence interval](#gloss)"))

#Display
table8
Table 8 - Map rotation N Mean (SD) 95% CI
Satisfaction with map rotation 261 6.84 (2.31) 6.6, 7.1
Note:
SD stands for Standard Deviation
CI Stands for confidence interval

The density plot for the variable above is shown in Chart 8.

The mean score on satisfaction with map rotation is approximately 7/10. This is not a bad result for a contentious question where everyone has widely different views on what maps should be played. As readers may recall, another question asked in the survey was “Which maps do you think TT should play more of?”

Let us plot the results, sorted by popularity:

#Remove previous
rm(table8)

#Create new mapsdf
mapslong <- df %>% select('Skorpo':'Black Coast') %>% gather(key = "Maps") %>%
    group_by(Maps) %>% dplyr::summarise(number = sum(value, na.rm = TRUE))
  
mapslong <- arrange(mapslong, desc(number))

#Build Chart
chart7 <-mapslong %>%  ggplot(aes(x = reorder(Maps, number), y = number)) +
    geom_col(fill="#99ccff") + theme_bw() +
   theme(panel.border = element_blank(), panel.grid.major = element_blank(),
         panel.grid.minor = element_blank(), axis.line = element_line(colour = "black")) + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + 
  ylab("Frequency count") + xlab(" ") + theme(legend.position="none") + 
  labs(title = "Chart 7: Maps TT should play 'more of' according to respondents") + theme(plot.title = element_text(hjust = 0.5)) + coord_flip()

#Display
chart7 

This is an interesting result. A substantial amount of comments were loudly complaining about map variety. However, when these same people were asked what maps we should play even more of, the results correspond to maps we already play a lot of. The top few maps are:

  • Black Coast
  • Goose Bay
  • Mutaha
  • Yehorivka
  • Narva
  • Gorodok

We already play these maps quite a bit except perhaps Goose Bay. However, Black coast, Gorodok, Yehorivka, Mutaha and Narva are server mainstays and it seems people want even more of them.

As disappointing as it may be to some, the results mostly tell us that we are about where we want to be with regards to map rotation.

Rules & enforcement

The final section of the survey concerned respondents’ satisfaction with our ruleset at TT. Here are the results:

#Remove previous
rm(chart7, mapslong)

#Build
table9 <- df %>% select('basecamp':'asset') %>% tbl_summary(
    type = everything() ~ "continuous", missing = "no",
    statistic = all_continuous() ~ "{mean} ({sd})",
    label = list("basecamp" ~ "Basecamping enforcement",
                 "comms" ~ "Comms enforcement",
                 "asset" ~ "Asset claim system"),
      digits = everything() ~ 2) %>% add_ci() %>% 
  modify_header(stat_0 ~ "**Mean (SD)**") %>%   
  modify_footnote(everything() ~ NA) %>%  
  modify_footnote(ci_stat_0 ~ NA, abbreviation = TRUE) %>% add_n() %>% as_kable()

#Format
table9 <- table9 %>% kable_styling(bootstrap_options = c("striped", "hover", 
                                                     "condensed"), 
                                   position = 'center') %>% 
  footnote(general = c("SD stands for [Standard Deviation](#gloss)",
                      "CI Stands for [confidence interval](#gloss)")) %>% 
   add_header_above(c("Table 9: Satisfaction with server rules & enforcement  - Full Sample" = 4)) 

#Display
table9
Table 9: Satisfaction with server rules & enforcement - Full Sample
Characteristic N Mean (SD) 95% CI
Basecamping enforcement 301 7.37 (2.84) 7.0, 7.7
Comms enforcement 305 7.95 (2.18) 7.7, 8.2
Asset claim system 305 8.26 (2.50) 8.0, 8.5
Note:
SD stands for Standard Deviation
CI Stands for confidence interval

I show some density plots that show the variables above (including satisfaction with map rotation from Table 8) to give readers an idea of the distributions:

#Remove previous
rm(table9)

#Pivot the category scores to long
tempdf <- df %>% select(basecamp, comms, asset, maprot) %>% 
  tidyr::pivot_longer(cols = c("basecamp", "comms", "asset", "maprot"), 
                                   names_to = "Category", values_to = "Score")

tempdf$Category <- ordered(tempdf$Category, levels = c("basecamp", "comms", "asset", "maprot"))
levels(tempdf$Category) <- c("Basecamping enforcement", "Comms enforcement", "Asset claim", "Satisfaction with map rotation")

# Create faceted density plots
chart8 <- ggplot(data = tempdf, aes(x=Score)) + geom_density(color="#99ccff", fill="#99ccff") + theme_bw() + theme(panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_line(colour = "black")) + 
  theme(legend.position = "none") + facet_wrap( ~ Category,  scales = "free_y", ncol=2) + xlab("") + ylab("Density") + 
  labs(title = "Chart 8: Density plots of server rules section + map rotation") + theme(plot.title = element_text(hjust = 0.5))


chart8

In general, people are satisfied with our rules and enforcement. Basecamping enforcement was rated the lowest, but even then, it seems people are generally satisfied. The mean scores for all categories are between 7 to 8.5 out of 10 and the density plots are again skewed towards the upper end of the distribution.

The density plot for basecamping enforcement has a clump on the lower end of the distribution indicating that a small minority is quite dissatisfied, driving down the the (still pretty good) mean score. We investigate this further in Tables 11 and 14. However, I must stress that an average score of above 7/10 on this question suggests that the server, as a whole, is largely happy with the status quo.

Lastly, the vast majority of respondents are very happy with the “first come first serve” asset claim system.

Experience

Now that the reader has a good understanding of the topline results, we can delve into the preferences of different subgroups on the server. The largest and most prominent subgroup is experienced players. We saw in Table 1 that approximately 53% of respondents have more than 1,000 hours in the game. For the purposes of our analysis, we shall call this group the “experienced players.”

Let us see if the scores they gave TT were different from players who have fewer than 1,000 hours in squad. However, since a large amount of external clan members also play at TT, we should first check what proportion of experienced players are also external clan members:

#Remove previous
rm(chart8, tempdf, inline.t1)

#Build
table10 <- df %>% select('clan', 'over1k') %>% tbl_cross(
  row = 'over1k', col = 'clan', percent = "cell",
  label = 'over1k' ~ 'Over 1,000 hours in squad?') %>%  add_p() %>%   
  modify_footnote(everything() ~ NA)

#Inline
inline.t10 <- as_tibble(table10[["table_body"]])

#Format
table10 <- table10 %>% as_kable() %>% 
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), position = 'center') %>%  
  footnote(general = c("[P-value](#gloss) calculated using Pearson's [Chi-squared test](#gloss)",
                                              "Green row indicates strong evidence for [statistical signifcance](#gloss)")) %>% 
  add_header_above(c(" " = 1, "External clan member" = 2, " " = 2)) %>% 
  add_header_above(c("Table 10: Experienced players + Clan members crosstab" = 5))  %>% 
  row_spec(c(1), bold = T, color = "white", background = "#38761d")
  
#Display
table10
Table 10: Experienced players + Clan members crosstab
External clan member
Yes No Total p-value
Over 1,000 hours in squad? <0.001
Yes 84 (27%) 81 (26%) 165 (53%)
No 23 (7.3%) 125 (40%) 148 (47%)
Total 107 (34%) 206 (66%) 313 (100%)
Note:
P-value calculated using Pearson’s Chi-squared test
Green row indicates strong evidence for statistical signifcance

Unsurprisingly, we can see that members of external clans are more likely to have over 1,000 hours in squad. 79% (84 out of 107) of external clan members have 1,000+ squad hours versus 39% (81 out of 206) of the unaffiliated players. We can also see that 84 of the 165 (approximately 51%) experienced respondents are also external clan members.

The statistical significance of this relationship is confirmed using a Chi-squared test, a commonly used statistical test. The p-value is less than 0.001 meaning that there is a less than 0.001% chance that there is no statistical relationship between experienced players and external clan members. In other words, there is a greater than 99% chance that external clan members are disproportionately experienced players.

From these results, it is fair to say that the large presence of external clans on the server contributes to the overall experience level of the playerbase.

Let us repeat a similar exercise for all the other questions to check whether experienced players hold statistically different opinions from newer players on key survey questions:

#Remove previous
rm(table10, inline.t10)

#Build
table11 <- df %>% select('admresp':'maprot','slserver','basecamp':'over1k') %>% tbl_summary(by= 'over1k',
  type = everything() ~ "continuous",
  statistic = all_continuous() ~ "{mean}",
  missing = "no", label = list('admresp' ~ 'Admin response time',
                               'admprof' ~ 'Admin professionalism',
                               'admfair' ~ 'Admin fairness',
                               'admoverall' ~ 'Overall admin quality',
                               "twork" ~ "Teamwork",
                               "learn" ~ "Learning Environment",
                               "balance" ~ "Team Balance",
                               "skill" ~ "Gameplay level",
                               "slserver" ~ "Environment for SLs",
                               "toxic" ~ "Overall server environment",
                               'maprot' ~ "Satisfaction with map rotation",
                               "basecamp" ~ "Basecamping enforcement",
                               "comms" ~ "Comms enforcement",
                               "asset" ~ "Asset claim system"),
  digits = everything() ~ 2) %>% add_difference() %>% add_q(method = "bonferroni")  %>% 
  modify_footnote(everything() ~ NA) %>%
  modify_column_hide(ci) %>% modify_footnote(everything() ~ NA) %>%  modify_header(stat_1 = "1,000+ hours", stat_2="< 1,000 hours") %>%  as_kable()

#Format
table11 <- table11 %>% kable_styling(bootstrap_options = c("striped", "hover", 
                                                     "condensed"), 
                                   position = 'center') %>% 
  footnote(general = c("[P-value](#gloss) calculated using [Welch's Two Sample t-test](#gloss)",
                       "[Q-value](#gloss) calculated using [Bonferroni's correction](https://en.wikipedia.org/wiki/Bonferroni_correction) for multiple comparisons")) %>%  row_spec(c(2, 6, 9, 10, 13), bold = T, color = "white", background = "#e06666") %>%
   row_spec(c(12), bold = T, color = "white", background = "#D7261E") %>%
  add_header_above(c(" " = 1, "Mean scores" = 2, " " = 3)) %>% 
  add_header_above(c("Table 11: Experienced vs Newer players on major questions" = 6))

#Display row_spec(c(12), bold = T, color = "white", background = "#D7261E") %>%
table11
Table 11: Experienced vs Newer players on major questions
Mean scores
Characteristic 1,000+ hours < 1,000 hours Difference p-value q-value
Admin response time 8.41 8.62 -0.21 0.3 >0.9
Admin professionalism 7.76 8.25 -0.48 0.035 0.5
Admin fairness 7.90 8.17 -0.27 0.2 >0.9
Overall admin quality 8.20 8.45 -0.25 0.2 >0.9
Teamwork 8.07 8.15 -0.08 0.7 >0.9
Learning Environment 6.10 6.70 -0.60 0.026 0.4
Team Balance 6.94 6.53 0.41 0.11 >0.9
Gameplay level 8.52 8.33 0.19 0.3 >0.9
Overall server environment 7.17 7.80 -0.62 0.006 0.090
Satisfaction with map rotation 6.51 7.22 -0.71 0.012 0.2
Environment for SLs 7.32 7.56 -0.23 0.3 >0.9
Basecamping enforcement 6.80 7.99 -1.2 <0.001 0.003
Comms enforcement 7.71 8.22 -0.51 0.041 0.6
Asset claim system 8.39 8.10 0.29 0.3 >0.9
Note:
P-value calculated using Welch’s Two Sample t-test
Q-value calculated using Bonferroni’s correction for multiple comparisons

Here’s how to read the table above

  • Red/pink rows indicate strong/weak evidence (respectively) of a statistical difference in mean scores between the two groups.

  • Rows without colour should be treated as statistically insignificant (i.e., any difference is statistically indistinguishable from zero).

  • To understand the criteria used to determine statistical significance, please refer to the glossary.

Before we get into the results, I show a density plot for basecamping enforcement as this is the only category where there is a strongly significant difference between experienced and newer players:

#Remove previous
rm(table11)

#Pivot the category scores to long
tempdf <- df %>% select(basecamp, over1k) %>% 
  tidyr::pivot_longer(cols = c("basecamp"), names_to = "Category", values_to = "Score")

tempdf$Category <- ordered(tempdf$Category, levels = c("basecamp"))
levels(tempdf$Category) <- c("Basecamping enforcement")

# Create faceted density plots
chart9 <- tempdf %>% filter(Category == "Basecamping enforcement") %>% 
  ggplot(aes(x=Score)) + geom_density(aes(fill = over1k), alpha = 0.5, colour = NA) + scale_fill_manual(values = c("#ff0000", "#0000FF")) + theme_bw() + theme(panel.border = element_blank(), panel.grid.major = element_blank(),
                                             panel.grid.minor = element_blank(), axis.line = element_line(colour = "black")) + 
  theme(legend.position = "bottom") + labs(fill = "1000+ hours") + xlab("") + ylab("Density") + 
  labs(title = "Chart 9: Experienced vs Inexperienced - Strongly significant areas") + theme(plot.title = element_text(hjust = 0.5)) +
  facet_wrap( ~ Category, scales = "free_y")

chart9

Headline results:

Strong evidence that experienced players differ from newer players on the question basecamping enforcement.

Weak evidence of differences between the two groups in the following categories:

  • Admin professionalism
  • Learning environment
  • Overall server environment
  • Satisfaction with map rotation
  • Comms enforcement

Readers can visually examine the differences enumerated in Table 11 in the chart above. There are some differences in views on basecamping enforcement. We see a much flatter curve for experienced players versus a more left-skewed (higher scores) curve for newer players suggesting that experienced players overall gave TT slightly lower ratings when it comes to basecamping enforcement.

One reason could be that experienced players are just more demanding (or perhaps jaded). Basecamping rules are designed to protect newer players at the expense of more experienced players who tend to want to punish weakness and thus, push up against the limits of the rule. This may cause them to chafe at enforcement and more loudly decry inconsistencies.

Another related reason is that these differences are driven by external clan members. We know from Table 10 that around half of experienced players are external clan members and they too differ on this matter (see Table 14).

The differences in the categories with weak evidence are more marginal. It is rather amusing to think that newer players think that the server is friendlier and has a better learning environment compared to their experienced counterparts. One would think that newer players would bear the brunt of toxicity or criticism, but this did not seem to factor into their ratings.

Overall ratings remain quite high (between 7 and 8 out of 10) from experienced players in most categories, including in the key categories of administration, teamwork, and gameplay level. This is good news.

Long-term TT players

Long-term TT players are defined as those who have been at TT for over a year. As readers may recall from Chart 2, long-term players make up approximately half of the survey respondents.

The opinions of such long-term players are particularly important to us since they have contributed immensely to the server. Let us check if long term players vary across other groups (such as clan members of experienced players):

#Remove previous
rm(tempdf, chart9)

#Build
table12a <- df %>% select('over1tt', 'over1k') %>% tbl_cross(
  row = 'over1k', col = 'over1tt', percent = "cell",
  label = list('over1k' ~ 'Over 1,000 hours in squad?',
               'over1tt' ~ 'Been at TT for more than a year?')) %>%  add_p() %>%   
  modify_footnote(everything() ~ NA) 

table12b <- df %>% select('over1tt', 'clan') %>% tbl_cross(
  row = 'clan', col = 'over1tt', percent = "cell",
  label = list('clan' ~ 'External clan member?',
               'over1tt' ~ 'Been at TT for more than a year?')) %>%  add_p() %>%   
  modify_footnote(everything() ~ NA)

#Stack
table12<- tbl_stack(list(table12a, table12b))

#Inline text
inline.t12 <- as_tibble(table12[["table_body"]])

#Format
table12 <- table12 %>% as_kable() %>%  
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), position = 'center') %>%  
  footnote(general = c("P-value calculated using Pearson's [Chi-squared test](#gloss)",
                                              "Green row indicates strong evidence for [statistical signifcance](#gloss)")) %>% 
  add_header_above(c(" " = 1, "Been at TT for more than a year?" = 2, " " = 2)) %>% 
  add_header_above(c("Table 12: Time at TT crosstab with other categories" = 5))  %>% 
  row_spec(c(1), bold = T, color = "white", background = "#38761d")
  
#Display
table12
Table 12: Time at TT crosstab with other categories
Been at TT for more than a year?
Yes No Total p-value
Over 1,000 hours in squad? <0.001
Yes 96 (31%) 69 (22%) 165 (53%)
No 48 (15%) 100 (32%) 148 (47%)
Total 144 (46%) 169 (54%) 313 (100%)
External clan member? 0.8
Yes 48 (15%) 59 (19%) 107 (34%)
No 96 (31%) 110 (35%) 206 (66%)
Total 144 (46%) 169 (54%) 313 (100%)
Note:
P-value calculated using Pearson’s Chi-squared test
Green row indicates strong evidence for statistical signifcance

Unsurprisingly, long-term players tend to be overrepresented in the ranks of the experienced. Around 58% (96 out of 165) of experienced players are long term TT players. The first p-value is strongly significant.

Long-term players are just as likely than not to be clan members. Approximately 45% (48 out of 107) of external clan members are also long-term players compared with around 47% (96 out of 206) of unaffiliated players.

The proportions are very similar, and hence, not significantly different from one another. It is still noteworthy that so many external clan members are also long-term players.

Let us check if the opinions of these long-term players vary on key questions:

#Remove previous
rm(table12a, table12b, table12, inline.t12)

#Build
table13 <- df %>% select('admresp':'maprot','slserver','basecamp':'asset', 'over1tt') %>% tbl_summary(by= 'over1tt',
  type = everything() ~ "continuous",
  statistic = all_continuous() ~ "{mean}",
  missing = "no", label = list('admresp' ~ 'Admin response time',
                               'admprof' ~ 'Admin professionalism',
                               'admfair' ~ 'Admin fairness',
                               'admoverall' ~ 'Overall admin quality',
                               "twork" ~ "Teamwork",
                               "learn" ~ "Learning Environment",
                               "balance" ~ "Team Balance",
                               "skill" ~ "Gameplay level",
                               "slserver" ~ "Environment for SLs",
                               "toxic" ~ "Overall server environment",
                               'maprot' ~ "Satisfaction with map rotation",
                               "basecamp" ~ "Basecamping enforcement",
                               "comms" ~ "Comms enforcement",
                               "asset" ~ "Asset claim system"),
  digits = everything() ~ 2) %>% add_difference() %>%  add_q(method = "bonferroni") %>% 
  modify_footnote(everything() ~ NA) %>%
  modify_column_hide(ci) %>% modify_header(stat_1 = "1+ year at TT", stat_2="< 1 year at TT") %>% modify_footnote(everything() ~ NA) %>%  as_kable()

#Format
table13 <- table13 %>% kable_styling(bootstrap_options = c("striped", "hover", 
                                                     "condensed"), 
                                   position = 'center') %>% 
  footnote(general = c("P-value calculated using [Welch's Two Sample t-test](#gloss)",
                       "Q-value calculated using [Bonferroni's correction](https://en.wikipedia.org/wiki/Bonferroni_correction) for multiple comparisons")) %>% 
  add_header_above(c(" " = 1, "Mean scores" = 2, " " = 3)) %>% 
  add_header_above(c("Table 13: Long term TT players versus newer arrivals" = 6)) %>% 
  row_spec(c(1, 8, 13, 14), bold = T, color = "white", background = "#38761d") %>%
  row_spec(c(3, 4, 5), bold = T, color = "white", background = "#6aa84f")

  
#Display
table13
Table 13: Long term TT players versus newer arrivals
Mean scores
Characteristic 1+ year at TT < 1 year at TT Difference p-value q-value
Admin response time 8.81 8.26 0.55 0.003 0.040
Admin professionalism 8.17 7.84 0.33 0.2 >0.9
Admin fairness 8.28 7.82 0.46 0.047 0.7
Overall admin quality 8.64 8.04 0.60 0.004 0.059
Teamwork 8.34 7.92 0.43 0.030 0.4
Learning Environment 6.45 6.33 0.12 0.7 >0.9
Team Balance 6.93 6.59 0.34 0.2 >0.9
Gameplay level 8.80 8.11 0.69 <0.001 <0.001
Overall server environment 7.51 7.44 0.07 0.8 >0.9
Satisfaction with map rotation 7.01 6.70 0.31 0.3 >0.9
Environment for SLs 7.62 7.26 0.36 0.10 >0.9
Basecamping enforcement 7.38 7.36 0.03 >0.9 >0.9
Comms enforcement 8.35 7.62 0.73 0.003 0.040
Asset claim system 8.82 7.78 1.0 <0.001 0.002
Note:
P-value calculated using Welch’s Two Sample t-test
Q-value calculated using Bonferroni’s correction for multiple comparisons

Here’s how to read the table above

  • Dark/light green rows indicate strong/weak evidence (respectively) of a statistical difference in mean scores between the two groups.

  • Rows without colour should be treated as statistically insignificant (i.e., any difference is statistically indistinguishable from zero).

  • To understand the criteria used to determine statistical significance, please refer to the glossary.

The density plots of the categories with strongly statistically significant differences are shown below:

#Remove previous
rm(table13)

#Pivot the category scores to long
tempdf <- df %>% select(admresp, skill, asset, comms, over1tt) %>% 
  tidyr::pivot_longer(cols = c("admresp","skill" ,"asset", "comms"), 
                                   names_to = "Category", values_to = "Score")

tempdf$Category <- ordered(tempdf$Category, levels = c("admresp","skill" ,"asset", "comms"))
levels(tempdf$Category) <- c("Admin response time",
                             "Gameplay level",
                             "Asset claim system", 
                             "Comms enforcement")

# Create faceted density plots
chart10 <- ggplot(data = tempdf, aes(x=Score)) + geom_density(aes(fill = over1tt), alpha = 0.5, colour = NA) + scale_fill_manual(values = c("#ff0000", "#0000FF")) + theme_bw() + theme(panel.border = element_blank(), panel.grid.major = element_blank(),
                                             panel.grid.minor = element_blank(), axis.line = element_line(colour = "black")) + 
  theme(legend.position = "bottom") + labs(fill = "1+ Year at TT") +  ylab("Density") + xlab(" ") +
  labs(title = "Chart 10: Long term vs not long term - Strongly significant areas") + theme(plot.title = element_text(hjust = 0.5)) +
  facet_wrap(~ Category, scales = "free_y")

chart10

Headline results:

Unsurprisingly, the people that have been around the longest and contributed the most also hold more positive views about the server in a whole host of areas.

Strong evidence of statistically different opinions between long term players and recent arrivals found in:

  • Admin response time
  • Gameplay/Skill level of the server
  • Comms enforcement
  • Happiness with asset claim system

Weak evidence of statistically different opinions found in:

  • Admin fairness
  • Overall quality of administration
  • Teamwork

It is nice to know that we have largely lived up to the expectations of our long-term regulars. In every single category - where there is a statistically significant difference between long-term players and newer arrivals - long-term players rate us higher. However, even our long-term regulars think we have more work to do in the area of learning environment.

External Clans

As readers will recall from Chart 3, approximately 34% of respondents to the survey are affiliated with outside clans or groups. Let us check if members of these groups hold opinions that are significantly different from the unaffiliated:

#Remove previous
rm(tempdf, chart10b, inline.t4, design)

#Build
table14 <- df %>% select('admresp':'maprot','slserver','basecamp':'asset', 'clan') %>% tbl_summary(by= 'clan',
  type = everything() ~ "continuous",
  statistic = all_continuous() ~ "{mean}",
  missing = "no", label = list('admresp' ~ 'Admin response time',
                               'admprof' ~ 'Admin professionalism',
                               'admfair' ~ 'Admin fairness',
                               'admoverall' ~ 'Overall admin quality',
                               "twork" ~ "Teamwork",
                               "learn" ~ "Learning Environment",
                               "balance" ~ "Team Balance",
                               "skill" ~ "Gameplay level",
                               "slserver" ~ "Environment for SLs",
                               "toxic" ~ "Overall server environment",
                               'maprot' ~ "Satisfaction with map rotation",
                               "basecamp" ~ "Basecamping enforcement",
                               "comms" ~ "Comms enforcement",
                               "asset" ~ "Asset claim system"),
  digits = everything() ~ 2) %>% add_difference() %>% add_q(method = "bonferroni") %>% 
  modify_footnote(everything() ~ NA) %>%
  modify_column_hide(ci) %>% modify_footnote(everything() ~ NA) %>%  modify_header(stat_1 = "Clan member", stat_2="Unaffiliated") %>%  as_kable()

#Format
table14 <- table14 %>% kable_styling(bootstrap_options = c("striped", "hover", 
                                                     "condensed"), 
                                   position = 'center') %>% 
  footnote(general = c("P-value calculated using [Welch's Two Sample t-test](#gloss)",
                       "Q-value calculated using [Bonferroni's correction](https://en.wikipedia.org/wiki/Bonferroni_correction) for multiple comparisons")) %>% row_spec(c(6, 10, 12), bold = T, color = "white", background = "#D7261E") %>% 
  row_spec(c(2, 3, 4, 5, 9, 11, 13, 14), bold = T, color = "white", background = "#e06666") %>% 
  add_header_above(c(" " = 1, "Mean scores" = 2, " " = 3)) %>% 
  add_header_above(c("Table 14: Clan members vs unaffiliated players on major questions" = 6))

#Display
table14
Table 14: Clan members vs unaffiliated players on major questions
Mean scores
Characteristic Clan member Unaffiliated Difference p-value q-value
Admin response time 8.44 8.54 -0.10 0.6 >0.9
Admin professionalism 7.62 8.19 -0.57 0.023 0.3
Admin fairness 7.68 8.21 -0.53 0.042 0.6
Overall admin quality 7.97 8.50 -0.53 0.031 0.4
Teamwork 7.78 8.28 -0.50 0.020 0.3
Learning Environment 5.69 6.75 -1.1 <0.001 0.002
Team Balance 6.81 6.71 0.10 0.7 >0.9
Gameplay level 8.36 8.46 -0.10 0.6 >0.9
Overall server environment 7.14 7.65 -0.50 0.042 0.6
Satisfaction with map rotation 6.20 7.19 -1.0 0.001 0.020
Environment for SLs 7.00 7.66 -0.66 0.007 0.093
Basecamping enforcement 6.53 7.81 -1.3 <0.001 0.005
Comms enforcement 7.41 8.24 -0.83 0.004 0.055
Asset claim system 7.81 8.49 -0.68 0.037 0.5
Note:
P-value calculated using Welch’s Two Sample t-test
Q-value calculated using Bonferroni’s correction for multiple comparisons

Here’s how to read the table above

  • Red/pink rows indicate strong/weak evidence (respectively) of a statistical difference in mean scores between the two groups.

  • Rows without colour should be treated as statistically insignificant (i.e., any difference is statistically indistinguishable from zero).

  • To understand the criteria used to determine statistical significance, please refer to the glossary.

As ever, before we get into the results, I show the density plots for the questions where there is strong evidence of a statistical difference between clan members and unaffiliated players:

#Remove previous
rm(table14)

#Pivot the category scores to long
tempdf <- df %>% select(learn, basecamp, maprot, clan) %>% 
  tidyr::pivot_longer(cols = c("learn", "basecamp", "maprot"), 
                                   names_to = "Category", values_to = "Score")

tempdf$Category <- ordered(tempdf$Category, levels = c("learn", "basecamp", "maprot"))
levels(tempdf$Category) <- c("Learning environment", "Basecamping enforcement", "Satisfaction with map rotation")

# Create faceted density plots
chart11 <- ggplot(data = tempdf, aes(x=Score)) + geom_density(aes(fill = clan), alpha = 0.5, colour = NA) + scale_fill_manual(values = c("#ff0000", "#0000FF")) + theme_bw() + theme(panel.border = element_blank(), panel.grid.major = element_blank(),
                                             panel.grid.minor = element_blank(), axis.line = element_line(colour = "black")) + 
  theme(legend.position = "bottom") + labs(fill = "External clan member") + ylab("Density") + xlab(" ") +
  labs(title = "Chart 11: Clan members vs unaffiliated - Strongly significant areas") + theme(plot.title = element_text(hjust = 0.5))

design <- c("BBAA
            BBCC") 

chart11 + ggh4x::facet_manual(~Category, scales = "free_y", design=design)

As we can see from both Table 14 and Chart 11, clan members hold statistically divergent and relatively more negative views on several questions.

However, as we saw from Table 12, almost half of such external clan members have been around TT for a long time. We also know from Table 13 that long term players tend to have more positive views of the server. Therefore, I calculate an “overall score” as the average score across all categories and investigate whether or not these relatively negative views of clan members are being driven by the influx of “new” clans to TT:

#Remove previous
rm(chart11, tempdf, design)

#Subset clans + exp
clansdf <- df %>% filter(clan=="Yes") %>% 
  select('clan', 'over1tt', 'admresp':'maprot', 'basecamp':'asset') %>%
  mutate(clan_long = case_when(clan == 'Yes' & over1tt=="Yes" ~ "Yes",
                               TRUE ~ "No"))

clansdf$clan_long <- ordered(clansdf$clan_long, levels = c("Yes", "No"))

#Rowmeans which handle missing values
clansdf$Overall <- rowMeans(clansdf[, 3:15], na.rm=TRUE)

#Calculate P-value
pval <- clansdf %>% select(Overall, clan_long) %>% tbl_summary(by="clan_long") %>% add_difference() %>% as_tibble()
pval <- pval[1,6]
caption <- paste("P-value calculated using Welch's Two Sample t-test", pval, sep = " = ")

#Plot chart
chart12 <- clansdf %>% ggplot(aes(x=clan_long, y=Overall)) + geom_violin(color="#99ccff", fill="#99ccff") + theme_bw() + theme(panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_line(colour = "black")) + 
  ylab('Overall average') +
  xlab("Long term external clan member?") + 
  labs(title = "Chart 12: Violin plot of mean overall scores by type of clan member", 
       caption = caption) + 
  theme(plot.title = element_text(hjust = 0.5)) + 
  theme(plot.caption = element_text(hjust = 0.5))

chart12

Readers can visually confirm that long term clan members hold more positive views by looking at Chart 12 above. The violin plot (a sort of mix between a density and a box plot) shows a bulge in the upper end of the spectrum for long term clan members. The distribution for newer clan members is markedly more negative. This difference is indeed strongly statistically significant judging by the p-value reported in the chart’s caption.

Headline results:

Strong evidence of statistically different views between external clan members and unaffiliated players found is in:

  • Learning environment
  • Basecamping enforcement
  • Satisfaction with map rotation

Weak evidence of statistically different views found in:

  • All admin categories except response time
  • Teamwork
  • Overall server environment
  • Environment for SLs
  • Comms enforcement
  • Happiness with asset claim system

Clan members have slightly lower ratings across the board, driven largely by newer clans to the server.

Rather than get into each category specifically, all I can say is that, particularly in the areas of basecamping and comms enforcement, some clans feel that the admins “play favourites.” This assertion is also supported by the fact that external clan members rate the admin team slightly worse across the board (except in response time), though the differences are only weakly statistically significant.

While I consider this view about bias to be strongly misplaced, more work needs to be done to correct this perception. I should note that TT has several admins which are drawn from the ranks of these external clans, but they also tend to be long term players at TT. I can only assure readers that the admins go to great lengths to be fair, but then again, I am biased. I mentioned earlier why experienced players and clan members may chafe at basecamping rules.

Another way to look at this question is that basecamping rules are designed to protect the average public player, who is more likely to be both unaffiliated and newer to the game, from the predations of the more experienced and/or clan members who seek to punish weakness and bad play. It is not therefore not entirely surprising that these are precisely the people chafing under the status quo. The average public player, it seems, is by and large satisfied with the current state of basecamping enforcement. This is clear in both Table 14, where unaffiliated players give a higher score on the basecamping question, and Chart 11, where the curve for unaffiliated players on the issue is markedly more skewed towards higher values. Still, I must stress that even the scores of such clan members on the basecamping question isn’t horrible; it is merely average.

However, on the whole, clan members still rated TT highly in most categories (7+/10) with the worst performing categories being the learning environment (slightly ironic since clans are the most guilty of running locked squads) and map rotation (also funny since, when asked, the vast majority of people just end up wanting more “common” maps such as Gorodok, Blackcoast and Yehorivka).

Squad leaders

Squad leaders are a crucial part of both squad and the server since these are the players that make or break the server. This is why it is important to understand where this group comes from and what motivates people to lead squads. In the table below, I examine whether squad leaders are more likely to be experienced players and/or external clan members.

#Remove previous
rm(clansdf, chart12, pval, caption)

#Build
table15a <- df %>% select('sl', 'over1k') %>% tbl_cross(
  row = 'over1k', col = 'sl', percent = "cell",
  label = list('over1k' ~ 'Over 1,000 hours in squad?',
               'sl' ~ 'Do you SL open squads often?'), missing = "no") %>%  add_p() %>%   
  modify_footnote(everything() ~ NA) 


table15b <- df %>% select('sl', 'clan') %>% tbl_cross(
  row = 'clan', col = 'sl', percent = "cell",
  label = list('clan' ~ 'External clan member?',
               'sl' ~ 'Do you SL open squads often?'), missing = "no") %>%  add_p() %>%   
  modify_footnote(everything() ~ NA)

#Stack
table15<- tbl_stack(list(table15a, table15b))

#Inline text for table 15
inline.t15 <- as_tibble(table15[["table_body"]])

#Format
table15 <- table15 %>% as_kable() %>% 
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), position = 'center') %>%  
  footnote(general = c("P-value calculated using Pearson's [Chi-squared test](#gloss)",
                                              "Green row indicates strong evidence for [statistical signifcance](#gloss)")) %>% 
  add_header_above(c(" " = 1, "Do you SL open squads often?" = 2, " " = 2)) %>% 
  add_header_above(c("Table 15: Squad leaders crosstabs with other categories" = 5))  %>% 
  row_spec(c(1,5), bold = T, color = "white", background = "#38761d")
  
#Display
table15
Table 15: Squad leaders crosstabs with other categories
Do you SL open squads often?
Yes No Total p-value
Over 1,000 hours in squad? 0.028
Yes 66 (21%) 98 (31%) 164 (53%)
No 42 (13%) 106 (34%) 148 (47%)
Total 108 (35%) 204 (65%) 312 (100%)
External clan member? 0.006
Yes 48 (15%) 59 (19%) 107 (34%)
No 60 (19%) 145 (46%) 205 (66%)
Total 108 (35%) 204 (65%) 312 (100%)
Note:
P-value calculated using Pearson’s Chi-squared test
Green row indicates strong evidence for statistical signifcance

Table 15 shows that squad leaders are indeed more likely to be experienced players and come from external clans. The tests used to calculate the statistical significances of these differences in ratios are the same as the one used in Table 10 and they are highly significant.

Approximately 40% (66 out of 164) of experienced players often lead open squads as opposed to 28% (42 out of 148) of newer players. Similarly approximately 45% (48 out of 107) of external clan members often lead open squads as opposed to 29% (60 out of 205) of unaffiliated players.

Let us check whether squad leaders hold divergent views on any of the key survey questions:

#Remove previous
rm(table15, table15a, table15b, inline.t15)

#Build
table16 <- df %>% select('admresp':'maprot','slserver','basecamp':'asset', 'sl') %>% tbl_summary(by= 'sl',
  type = everything() ~ "continuous",
  statistic = all_continuous() ~ "{mean}",
  missing = "no", label = list('admresp' ~ 'Admin response time',
                               'admprof' ~ 'Admin professionalism',
                               'admfair' ~ 'Admin fairness',
                               'admoverall' ~ 'Overall admin quality',
                               "twork" ~ "Teamwork",
                               "learn" ~ "Learning Environment",
                               "balance" ~ "Team Balance",
                               "skill" ~ "Gameplay level",
                               "slserver" ~ "Environment for SLs",
                               "toxic" ~ "Overall server environment",
                               'maprot' ~ "Satisfaction with map rotation",
                               "basecamp" ~ "Basecamping enforcement",
                               "comms" ~ "Comms enforcement",
                               "asset" ~ "Asset claim system"),
  digits = everything() ~ 2) %>% add_difference() %>%  add_q(method = "bonferroni") %>% 
  modify_footnote(everything() ~ NA) %>%
  modify_column_hide(ci) %>% modify_header(stat_1 = "SLs", stat_2="Non-SLs") %>% modify_footnote(everything() ~ NA) %>%  as_kable()

#Format
table16<- table16 %>% kable_styling(bootstrap_options = c("striped", "hover", 
                                                     "condensed"), 
                                   position = 'center') %>% 
  footnote(general = c("P-value calculated using [Welch's Two Sample t-test](#gloss)",
                       "Q-value calculated using [Bonferroni's correction](https://en.wikipedia.org/wiki/Bonferroni_correction) for multiple comparisons")) %>%
  row_spec(2, bold = T, color = "white", background = "#e06666") %>% 
  add_header_above(c(" " = 1, "Mean scores" = 2, " " = 3)) %>% 
  add_header_above(c("Table 16: SLs vs non-SLs on major questions" = 6)) 

  
#Display
table16
Table 16: SLs vs non-SLs on major questions
Mean scores
Characteristic SLs Non-SLs Difference p-value q-value
Admin response time 8.32 8.61 -0.28 0.2 >0.9
Admin professionalism 7.66 8.18 -0.52 0.049 0.7
Admin fairness 7.72 8.21 -0.48 0.055 0.8
Overall admin quality 8.13 8.42 -0.29 0.2 >0.9
Teamwork 7.94 8.20 -0.26 0.2 >0.9
Learning Environment 6.14 6.51 -0.37 0.2 >0.9
Team Balance 6.90 6.67 0.23 0.4 >0.9
Gameplay level 8.29 8.50 -0.21 0.3 >0.9
Overall server environment 7.17 7.63 -0.46 0.069 >0.9
Satisfaction with map rotation 6.73 6.92 -0.20 0.5 >0.9
Environment for SLs 7.57 7.35 0.22 0.3 >0.9
Basecamping enforcement 7.01 7.54 -0.53 0.15 >0.9
Comms enforcement 7.81 8.02 -0.21 0.5 >0.9
Asset claim system 8.01 8.38 -0.37 0.2 >0.9
Note:
P-value calculated using Welch’s Two Sample t-test
Q-value calculated using Bonferroni’s correction for multiple comparisons

Headline results:

Weak evidence of statistically different views found in the category of Admin professionalism. This difference, while not zero, is quite small. It is probably being driven by external clan members (see Table 14).

There are very few differences between SLs and non-SLs on any of the key questions. In some instances, SLs actually rate the server slightly higher, though, these differences are not statistically significant and therefore should be regarded as being zero.

For the enthusiastic reader, I do examine the question of how we can get more squad leaders on the server in the appendix.

Groups & Clusters

Let us check whether we can identify some clusters and groups in the survey scores:

#Remove previous
rm(table16)

#Create a new analysis frame

df3 <- df

#Row means which handle missing values sensibly
df3$admscore <- rowMeans(df3[, 7:10], na.rm=TRUE)
df3$envscore <- rowMeans(df3[, 11:16], na.rm=TRUE)

#Modify new analysis frame - prepare for kmeans clustering
df3 <- df3 %>% select('admscore', 'envscore') %>% filter(!is.na(admscore))

#Seed set to random number, 2, for reproducibility
set.seed(2)
#Cluster
clust <- kmeans(df3, centers = 4)
#Map cluster ID to OBS
df3$cluster <- as.character(clust$cluster)

#df3 %>% ggplot(aes(x=admscore, y=envscore, colour = cluster)) + geom_jitter(width = 0.1, height = 0.1) + theme_bw()

#Assign cluster ID sensble names
df3 <- df3 %>% mutate(Group= case_when(cluster==4 ~ "Adm high, Env avg",
                                       cluster==1 ~ "Env avg, Adm avg",
                                       cluster==3 ~ "Both High",
                                       cluster==2 ~ "They hate us"))

df3$Group<- ordered(df3$Group, levels = c("Both High", "Adm high, Env avg", "Env avg, Adm avg", "They hate us"))

#Build chart
chart13 <- ggplot() + 
  geom_jitter(data = df3, aes(x=admscore, y=envscore, colour = Group), width = 0.1, height = 0.1) +   
  geom_point(mapping = aes_string(x = clust$centers[, "admscore"], y = clust$centers[, "envscore"]),color = "magenta", size = 4) + 
  theme_bw() + 
  scale_color_manual(values = c("black", "blue", "purple", "red" )) + 
  theme(panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_line(colour = "black")) + 
  xlab('Average score for admin categories') + ylab('Average score for environment categories') + 
  labs(title = "Chart 13: Why play at TT?") + theme(legend.position = "bottom") + theme(plot.title = element_text(hjust = 0.5))

#Display
chart13

The average scores of participants for administration categories is shown along the X-axis and the average score for the server environment categories is shown on the Y-axis. I assume that people play at TT because they either like the way it is run (administration) or because they like the environment. I do not think people play at TT because of our asset claim system or because they really like how we enforce basecamping so the questions about rules were not considered when producing this chart.

Participants are assigned to groups using a clustering algorithm. Chart 13 above shows roughly four groups:

table17 <- df3 %>% select(admscore, envscore, Group) %>% 
  group_by(Group) %>%  
  summarise(Count = n(), "Group Mean (Admin)" = round(mean(admscore), 2), " Group Mean (Environment)" = round(mean(envscore), 2))

table17 <- table17 %>% kable() %>% 
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), 
                position = 'center', full_width = TRUE) %>% 
   add_header_above(c("Table 17: Counts per cluster" = 4))

table17  
Table 17: Counts per cluster
Group Count Group Mean (Admin) Group Mean (Environment)
Both High 119 9.26 8.65
Adm high, Env avg 102 8.80 6.78
Env avg, Adm avg 71 6.60 6.74
They hate us 17 3.99 4.26

Headline results:

  • The largest group is comprised of people who rate TT highly across both administrative and environmental questions.

  • The second largest group rate us highly on administrative questions, and slightly above average on environmental ones.

  • The third largest group rates both sets of questions as about or slightly above average.

  • The smallest group is comprised of a tiny minority who seem to not like us very much.

The results suggest that more needs to be done in the server environment category on questions such as learning environment and team balance since these are the categories driving down the environment score.

Responses to comments

We did receive many comments. A big thanks to Affinity for responding to a selection of these. If we didn’t answer your comment, please feel free to reach out on our Discord! We hope you enjoyed our responses to your comments as much as we enjoyed reading them.

Comment 1

Comment 1

Dear Affinity,

Some of the admins have a severe problem with a “holier than thou” attitude. They get sarcastic and snarky REAL quick and it’s not cool. It just pisses off the person who’s trying to make their case. Helps nobody. It’s not your job to be a keyboard warrior hardass, it’s your job to administrate. That means keeping YOURself in check at ALL times, even when the player is not.

-Loveable Snark Man

Response 1

Dear Loveable Snark Man,

We try our very best as professional video game administrators. It is a strange, but necessary career path in our society. The benefit of not being paid work is acceptable, the low status of the gig provides job security, but it is often a thankless, stressful job. Day-to-day there are anomalies in the background operations that may color your perception of our performance.

Some quick insights to follow: my colleagues now only communicate through internet “copypastas” from the 2000’s. Mentioning “Navy SEALs” might be interpreted as restarting the server or changing the map. As you might deduce, this is very confusing. The office can only be described as a hostile, potentially hazardous work environment. Since my first day here the number of hamsters in cages strewn about the office has increased tenfold. As to their purpose, a man – so intoxicated I worry he may hurt himself – shows up once a month solely to assure us they are integral to our operation.

I hope this sheds some light on any perceived shortcomings. May it give you confidence to overcome the snark in your life.

Yours sincerely,

Affinity

Comment 2

Comment 2 (Added formatting to make diatribe more readable)

Dear Affinity,

Y’all need to calm down when people are very obviously having a civil, legitimate conversation about sensitive topics (IE current events). I admit that civil conversations about this stuff don’t happen often, but when they do, it should be encouraged, NOT immediately stopped.

Allow people to discuss their opinions. Whether YOU like it or not, online chat rooms/programs like Discord ARE the modern public square, the site of public discourse. You MUST treat it as such. It does not matter whether or not it is “your” server; the FACT is that people talk about their views and such mostly online now. Encourage it as long as it is civil.

Do NOT shut it all down as soon as it starts. That helps nothing. Don’t be afraid of people getting their feelings hurt a bit. That’s life. Allow them to experience it. Obviously if a conversation turns sour and offensive, then yes, it should be stopped. But allow it to happen in the first place. You do not know where it will go. It could be civil all the way through. And if not? No harm done. It’s an online chat room. There aren’t really any real-world effects

-Just Asking Questions

Response 2

Dear Just Asking Questions,

I do not believe we are obligated to run a general discussion forum, but I can understand your frustration. Limiting free discussion of current events, politics, and the controversial views of your Uncle Garrett is a tragedy. We aren’t allowed to bite our teeth into the real meat of life in this community for Squad. I feel your pain, this is not a ball and chain you or I asked for.

Prior to becoming an administrator, I was sure myself and DaddyMyPussyHurt were a knife’s edge away from solving world hunger in a game of Narva AAS. I had a meaningful conversation about collective consciousness with BitchPuncher in the backseat of an MRAP before somebody kicked us. DrJugsMcBuldge and I were on the cusp of uncovering evidence that would prove the Illuminati controlled passageway through the Ice Wall at the edge of our flat Earth. All before the powers that be shut us down.

These are important topics which should be discussed. Thankfully, there are many places to discuss anything you want to on this large internet. I hope you find that special place.

Yours sincerely,

Affinity

Comment 3

Comment 3

Dear Affinity,

Locked squads are a problem… I’d suggest a bi-weekly/monthly event night where newbies are encouraged to join to get a taste of the TT experience, with regulars leading open squads….

-Holy Second Medic

Response 3

Dear Holy Second Medic,

I agree that locked squads can be a problem for newer players across the community. I am not opposed to such an event, but to increase SL participation we need to be creative with incentives.

Like you, I think the best prescription is cultural; personal initiative, encouragement from peers, and a rewarding experience. We notice and appreciate those who try to provide visiting players a more genuine, organized Squad experience. I recommend everyone learns the role and pitches in when they can. The SL service need not be unending. We would have fewer stray cats if players would add 1-2 blueberries to their group of friends or commit to leading one open squad per game session. Similarly, if more players made an effort to decrease their SL’s virtual burden we would have more SLs. Chicken meets egg and all that jazz.

I would encourage any new player who wants to learn and feels left out to chat with us in Discord. Give us a shout, tell us you’re new, ask us any questions, and offer your services as a Holy Second Medic.

Yours sincerely,

Affinity

Comment 4

Comment 4 (Truncated)

Dear Affinity,

…I dislike SLing, I find it boring, and feeling like I can do support roles better than my squadmates, so I rarely find myself SLing, and I don’t enjoy it… I think a rule of no locked squads smaller than 6 would work out. I think that’s a decent compromise…

-Bored Blueberry Revolutionary

Response 4

Dear Bored Blueberry Revolutionary,

You are not alone. Have you considered squad leading more? In psychology there exists a theory called the Mere Exposure Effect. This theory posits the more familiar something becomes the more an individual learns to enjoy it. This means you can trick your brain into thinking squad leading is a good time.

I do wish we had more squad leaders in the game, but I do not believe your request is fair. You are asking the administration to move the burden of the “locked squad problem” from yourself, a person who does not want to lead squads, to other people who also do not wish to lead open squads. This demand for SL redistribution is a dangerous call to action that can only end in violence. Additionally, I consider it an affront to my God given right of freedom, liberty, and the pursuit of kicking marksmen.

Yours sincerely,

Affinity

Comment 5

Comment 5 (Typos from original comment included)

Dear Affinity,

Although good for learning, there is a culture of shirt on SLs who are learning and it can be intimidating knowing you are going to get called out consistently.

-Command Net Muting Commando

Response 5

Dear Command Net Muting Commando,

Possibly the most important thing we like to see in our community is a player, especially a leader, with a desire to learn and improve. Criticism in this win-lose game can be harsh. Still, a significant part of learning is failure followed up by feedback. As a general rule, constructive criticism will provide you with more information than noise.

As an infantry SL, you will meet our greater expectations if you: coordinate over the command net, vocalize your plans, respond to changing needs of the team, learn from mistakes, and ask for guidance when necessary. Try to pick up the good titbits of advice; however, leave the salty nerd sweat in the previous match. If you ever feel especially hard done by, do not hesitate to let us know.

Yours sincerely,

Affinity

Comment 6

Comment 6

Dear Affinity,

There’s often a large server queue. If possible, maybe consider opening a second server?

-Please, have mercy

Response 6

Dear Please, have mercy,

We do not have plans for running a second vanilla server. It takes a somewhat ridiculous amount of collective effort to manage a single video game server. Our server is far from perfect; even with the help of our sizable team of volunteers. We do offer low cost whitelist spots through Patreon donations which allow you to skip the queue.

Yours sincerely,

Affinity

Comment 7

Comment 7

Dear Affinity,

i was pretty sad when i saw learning friendly appear in the name. i joined this server to play with experienced players.

-Keen Eyed Kook

Response 7

Dear Keen Eyed Kook,

I don’t know what you’re talking about. This is starting to sound like a conspiracy. No politics allowed in chat. No more questions about [REDACTED] server names, please.

Clear all chat!

Yours sincerely,

Affinity

Conclusion

I hope that you have found this survey helpful in understanding what the community thinks about how the server is run and administered. Overall, in many key categories such as teamwork, gameplay, and administration, TT does very well scoring approximately 8/10 in these areas. We score approximately 7/10s in the for the questions on map rotation, overall environment for SLs, basecamping enforcement, and overall server environment.

Our lowest score is in the area of learning environment (Table 7). While this is disappointing, it is somewhat unsurprising as TT has earned a reputation for catering to experienced players. Still, as I said before, this is not an area entirely within the control of the admins and we can all, as a community, do better on this front. However, on the bright side, it is the newer players who rate the learning environment more highly than experienced players and clan members.

The other area of concern is team balance. Again, as mentioned earlier, balancing is something that is always at the forefront of in-game admin discussions. We are constantly shuffling players around. Perhaps we should be more open in communicating this to the general public.

We are glad that our long term regulars think highly of us. This group comprises approximately half of the respondents, and these are the players who form the backbone of TT. We received many comments regarding variety in map rotation. From Table 8 we can see that, on average, TT scored approximately 7/10. Chart 7 also suggests that the maps that people want more of are maps that, by and large, we already play! This suggests to us that the map rotation is about where it needs to be given the preferences of the server.

Clan members, who make up roughly a third of our playerbase, seem to be a bit more dissatisfied than unaffiliated players especially in the areas of learning environment and basecamping enforcement (see Table 14). As I mentioned earlier, this may be due to perceived unfairness. External clan members also rate several other areas more negatively than their unaffiliated counterparts, though these differences are small and are only weakly statistically significant. Table 10 shows that clan members contribute to the high proportion of experienced players on the server and Table 12 shows that approximately half of all clan members are also long-term players (1+ year at TT). The relatively more negative views of clan members in Table 14 are largely driven by those who are newer to TT.

Chart 13 shows that the largest cluster is made up of players who like both our administration and our server environment with only a tiny minority (fewer than 20 respondents) who utterly despises us. The enthusiastic reader is also encouraged to read the appendix where we investigate how we can get more people to squad lead on the server. The results in the appendix show that though much of what motivates someone wanting to squad lead is outside the remit of the admin team, admins and server regulars can still play a useful role by improving upon things such as the environment for Sls, which in turn is linked to things such as teamwork and the overall server environment (i.e. friendliness).

Overall, the scores are high enough across the board in key areas (see Tables 6, 7, 8, and 9) to say that respondents (even within the subgroups!) largely give us a clean bill of health.

Thank you for reading. We hope to see you on the server.

Appendix: Regression Analysis

Frankly, if you are crazy enough to have read the report this far, chances are that you might just be crazy enough to go a little further. I must warn people that this section is meant for enthusiasts, though a great deal of effort has gone into making it tractable for a lay audience. I apologise to you, dear reader, in advance for subjecting you to this.

Everything that has been presented up to this point has been summary statistics of raw data and some rudimentary statistical testing to check for differences among groups. Now, we can turn our attention to modelling relationships between these variables to answer one key question: How we can get more squad leaders on the server?

In our opinion, it is squad leaders that make or break the server and it is partly because of great squad leaders that people keep coming back to TT. We wanted to understand what drives the decision to become a squad leader. Recall from Table 5 that roughly 35% of respondents claim to “lead open squads often.” While self-reported measures can be unreliable, it is a good place to start to try and understand what characteristics of the server, if any, drive the decision to lead a squad.

Defining the models

To try and understand this question, I start by estimating following equation as a logistic regression.:

\[ \begin{align*} Y_{i} = \beta _{0} + \beta _{1}x_{1} + \beta _{2}x_{2} +...\beta _{15}x_{15} + \varepsilon \end{align*} \] Where: \(Y_{i}\) is the response of an individual, \(i\), to the question about whether or not they lead squads on the server frequently. This is a variable that can only take on two values, “Yes” and “No.”

\(x_{1}...x_n\) is a vector of explanatory variables from the survey, \(\beta_{1}...\beta_{n}\) are the estimated coefficients, and \(\varepsilon\) is the standard residual term. The explanatory variables used are:

\[ \begin{bmatrix} x_{1}\\ x_{2}\\ x_{3}\\ x_{4}\\ x_{5}\\ x_{6}\\ x_{7}\\ x_{8} \end{bmatrix} = \begin{bmatrix} 1,000+\;Hours\;(Yes/No)\\ 1+ \;Year\;at\;TT\;(Yes/No)\\ External\;Clan\;Member\;(Yes/No)\\ Admin\;Response\;Time\\ Admin\;Fairness\\ Admin\;Professionalism\\ Teamwork\\ Learning\;Environment\\ \end{bmatrix} \;\;and\;\; \begin{bmatrix} x_{9}\\ x_{10}\\ x_{11}\\ x_{12}\\ x_{13}\\ x_{14}\\ x_{15} \end{bmatrix} = \begin{bmatrix} Balance\\ Gameplay\;level\\ Overall\;server\;environment\\ Environment\;for\;SLs\\ Basecamping\;enforcement\\ Comms\;enforcement\\ Asset\;claim\;system\\ \end{bmatrix} \]

Logistic regressions are preferred over standard OLS regressions when the outcome variable (in this case, the binary question of “Do you lead open squads often?”) is a dichotomous (Yes/No) variable.

I omitted the question for “Overall quality of administration” because tests showed that it was too highly correlated with the other 3 admin categories - response time, fairness and professionalism. This high degree of correlation leads to a problem called multicollinearity which, if left unchecked, would have made the estimation less precise - more formally, it would widen standard errors in the other coefficients. Satisfaction with map rotation was also left out as a covariate because a lot of people left that question unanswered (see N count in Table 8) which would mean that we would have lost a lot of observations during estimation.

Based on the results of the model above, I also estimated a second model. This second model is essentially identical to the first except that the outcome variable, \(Y_{i}\), has been changed from the previous “Yes/No” SL question to \(x_{12} = Envrionment\;for\;Sls\). Consequently, \(x_{12} = Envrionment\;for\;Sls\) has been removed as a predictor variable in the second model since it is now the outcome variable. The second model has been estimated as a standard multiple regression model because the outcome variable is no longer dichotomous.

Estimation & Results

The next lines of code prepare the data and perform the estimation:

#Load libraries for regression modelling

library(margins) # To extract/plot marginal effects from logit models
library(DescTools) # Tools for GLM models
library(huxtable) # Nice looking tables

#Generate regression dataframe (RDF) from main DF

rdf <- df %>% select(sl, clan, over1k, over1tt, admresp, admfair, admprof, admoverall,
                     twork, learn, balance, skill, toxic, slserver, basecamp,
                     comms, asset) %>% drop_na()

#Relevel
rdf$sl <- factor(rdf$sl, levels = c("No", "Yes"),ordered = FALSE)
rdf$clan <- factor(rdf$clan, c("No", "Yes"),ordered = FALSE)
rdf$over1k <- factor(rdf$over1k,c("No", "Yes"), ordered = FALSE)
rdf$over1tt <- factor(rdf$over1tt, c("No", "Yes"), ordered = FALSE)

#Estimate
logit <- glm(sl ~ over1k + over1tt + clan + admresp + admfair + admprof  +
            twork + learn + balance + skill + toxic + slserver  + basecamp + 
              comms + asset, data = rdf, family = binomial(link = "logit"))

linear <- lm(slserver ~ over1k + over1tt + clan + admresp + admprof + admfair +
            twork + learn + balance + skill + toxic + basecamp + comms + 
            asset, data = rdf)

############Logit without environment for SLs#################################
# #Estimate
# logit2 <- glm(sl ~ over1k + over1tt + clan + admresp + admfair + admprof   +
#             twork + learn + balance + skill + toxic + basecamp + 
#               comms + asset, data = rdf, family = binomial(link = "logit"))
# 
# Check results:
# tbl_regression(logit2, exponentiate = TRUE,
#                          show_single_row = c("over1k", "over1tt", "clan"),
#                          intercept= TRUE) 
############Logit without environment for SLs#################################

#Extract logit coefficients & Standard errors
logit.OR <- exp(coef(logit))
se.coef <- function(logit){sqrt(diag(vcov(logit)))}
logit.ORSE <- logit.OR * se.coef(logit)
logit.r2<-round(as.numeric(DescTools::PseudoR2(logit, which = "McKelveyZavoina")), 3)

lin.r2 <- summary(linear)
lin.r2 <- round(lin.r2[["adj.r.squared"]], 3)

######################################################
#The reader can run this themselves to verify that the linear model passes the test, but they are commented out here.
#Homeskedasticity test for linear model
#Homoskedasticity is irrelevant for logit models

#library(lmtest)
#lmtest::bptest(lm2)

#Chi2 test for logit - Readers can run it themselves.
#library(jtools)
#summ(logit)
######################################################

# #Create regression tables
tbl.logit <- tbl_regression(logit, exponentiate = TRUE,
                         show_single_row = c("over1k", "over1tt", "clan"),
                         intercept= TRUE,
                         label = list("over1k" ~ "1,000+ hours? (Yes/No)",
                                      "over1tt" ~ "1+ year at TT? (Yes/No)",
                                      "clan" ~ "External clan member? (Yes/No)",
                                      'admresp' ~ 'Admin response time',
                                      'admprof' ~ 'Admin professionalism',
                                      'admfair' ~ 'Admin fairness',
                                      "twork" ~ "Teamwork",
                                      "learn" ~ "Learning Environment",
                                      "balance" ~ "Team Balance",
                                      "skill" ~ "Gameplay level",
                                      "slserver" ~ "Environment for SLs",
                                      "toxic" ~ "Overall server environment",
                                      "basecamp" ~ "Basecamping enforcement",
                                      "comms" ~ "Comms enforcement",
                                      "asset" ~ "Asset claim system")) %>% modify_column_hide(ci)

tbl.linear <- tbl_regression(linear, exponentiate = FALSE,
                         show_single_row = c("over1k", "over1tt", "clan"),
                         intercept= TRUE,
                         label = list("over1k" ~ "1,000+ hours? (Yes/No)",
                                      "over1tt" ~ "1+ year at TT? (Yes/No)",
                                      "clan" ~ "External clan member? (Yes/No)",
                                      'admresp' ~ 'Admin response time',
                                      'admprof' ~ 'Admin professionalism',
                                      'admfair' ~ 'Admin fairness',
                                      "twork" ~ "Teamwork",
                                      "learn" ~ "Learning Environment",
                                      "balance" ~ "Team Balance",
                                      "skill" ~ "Gameplay level",
                                      "toxic" ~ "Overall server environment",
                                      "basecamp" ~ "Basecamping enforcement",
                                      "comms" ~ "Comms enforcement",
                                      "asset" ~ "Asset claim system")) %>% modify_column_hide(ci)

#Merge and covert to tibble
table18 <- tbl_merge(tbls = list(tbl.logit, tbl.linear)) %>% as_tibble()
colnames(table18) <- c("", "Odds Ratio", "p-value", "Beta", "p-value")
table18[13,4] <- "-"
table18[13,5] <- "-"

#Build Custom Table
reghux <- as_huxtable(table18, groups_to_headers = TRUE) %>%
  set_background_color(evens, everywhere, "grey95") %>% 
  insert_row("Table 18: Regression Results", "", "", "", "", after = 0) %>% 
  set_bold(1, everywhere) %>% 
  set_align(1, everywhere, "center") %>% 
  insert_row("", "Do you SL? (Yes/No)", "", "Environment for SLs", "", after = 1) %>% 
  merge_cells(2, 2:3) %>% merge_cells(2, 4:5) %>% set_bold(2:3, everywhere) %>%
  set_align(2:3, 2:5, "center") %>% 
  set_align(everywhere, 2:5, 'center') %>% set_width(1) %>%
  rbind(c("Type of model", "Logistic", "","Linear (OLS)", "" )) %>% 
  rbind(c("Type of R-squared", "McKelvey-Zavoina", "","OLS Adjusted R-squared", "" )) %>% 
  rbind(c("R-squared", logit.r2 , "",lin.r2, "" )) %>% 
  rbind(c("Observations", nrow(rdf) , "",nrow(rdf), "" )) %>% 
  merge_cells(20, 2:3) %>% merge_cells(20, 4:5) %>% 
  merge_cells(21, 2:3) %>% merge_cells(21, 4:5) %>%
  merge_cells(22, 2:3) %>% merge_cells(22, 4:5) %>% 
  merge_cells(23, 2:3) %>% merge_cells(23, 4:5) %>% 
  set_align(20:23, 2:5, "center") %>% 
  set_bold(20:23, 1, TRUE)

#Formatting for significance
reghux <- reghux %>%   set_background_color(7, 2:3, "#6aa84f") %>% 
  set_background_color(c(13,16), 2:3, "#38761d") %>%
  set_background_color(c(9, 11, 12 , 15), 4:5, "#38761d")
  
#Text formatting for significance
reghux <- reghux %>%   set_text_color(7, 2:3, "white") %>% 
  set_text_color(c(13,16), 2:3, "white") %>%
  set_text_color(c(9, 11, 12 , 15), 4:5, "white") %>% 
  set_bold(7, 2:3, TRUE) %>% set_bold(c(13,16), 2:3, TRUE) %>% 
  set_bold(c(9, 11, 12 , 15), 4:5, TRUE)

#Add model row before borders
reghux <- reghux %>% insert_row("Variable", "Model 1", "Model 1", 
                                "Model 2", "Model 2", after = 3)
#Add Blank column before borders
reghux <- reghux %>% insert_column(after = 3, fill = "", rowspan = 1, copy_cell_props = TRUE ) %>% 
  merge_cells(1, 1:6)

#Borders
bottom_border(reghux)[1, ] <- brdr(1, "solid", "grey")
bottom_border(reghux)[2, 2:3] <- brdr(1, "solid", "grey")
bottom_border(reghux)[2, 5:6] <- brdr(1, "solid", "grey")
bottom_border(reghux)[4, ] <- brdr(1, "solid", "grey")
bottom_border(reghux)[20, ] <- brdr(1, "solid", "grey")
bottom_border(reghux)[24, ] <- brdr(1, "solid", "grey")

reghux
Table 18: Regression Results
Do you SL? (Yes/No)Environment for SLs
Odds Ratiop-valueBetap-value
VariableModel 1Model 1Model 2Model 2
(Intercept)1.940.50.530.4
1,000+ hours? (Yes/No)1.200.60.160.5
1+ year at TT? (Yes/No)0.740.30.030.9
External clan member? (Yes/No)1.730.080-0.170.4
Admin response time0.970.8-0.020.8
Admin fairness0.830.120.240.002
Admin professionalism0.940.60.01>0.9
Teamwork0.950.70.27<0.001
Learning Environment0.920.30.110.028
Team Balance1.190.023-0.040.4
Gameplay level0.850.20.120.11
Overall server environment0.860.100.180.003
Environment for SLs1.390.001--
Basecamping enforcement0.990.9-0.020.7
Comms enforcement1.110.20.010.9
Asset claim system0.970.60.00>0.9
Type of modelLogisticLinear (OLS)
Type of R-squaredMcKelvey-ZavoinaOLS Adjusted R-squared
R-squared0.1590.39
Observations278278
#Bin plots (exploratory)
#library(binsreg)
# form <- slserver ~ over1k + over1tt + clan + admresp + admprof + admfair +
#             twork + learn + balance + skill + toxic + basecamp + comms + 
#             asset
# 
# class(form)
# 
# rdf <- as.data.frame(rdf)
# bin.skill <- binsreg::binsreg(y = slserver, x = skill, w = form, data = rdf, at = "mean")
# bin.skill <- as.tibble(bin.skill[["data.plot"]])
# bin.skill <- as.tibble(bin.skill[[1]][[1]])

Here’s how to read the table above

  • Dark/light green rows indicate strong/weak evidence (respectively) of a statistical difference in mean scores between the two groups.

  • Rows without colour should be treated as statistically insignificant (i.e., any difference is statistically indistinguishable from zero).

  • We are using slightly different significance criteria here. We consider P<0.10 as weakly significant and P<0.05 as strongly significant. To understand more about statistical significance, please refer to the glossary.

  • Odds ratios from logistic regressions are a measure of probability. If an odds ratio is greater than 1, the event (in this case, leading a squad) is more likely to occur as the variable increases in value. For example, an external clan member is 1.74 times more likely to choose to squad lead when compared to an unaffiliated player after controlling for all the other variables in the model (the presence of experienced/clan players, rule enforcement, admin behaviour, etc.). I refer the reader to this simple guide for a more comprehensive explanation.

  • Betas from linear regressions are marginal effects. For example, every 1 point increase in teamwork is associated with a 0.27 point increase in the “Environment for SLs” after controlling for all the other variables in the model.

  • R-Squared is a number from 0 to 1 and can be read as the proportion of the outcome variable that the model explains. A model with a higher R-squared explains more of the outcome variable and vice versa. For logistic models, we cannot directly calculate an R-squared so we calculate something called a pseudo R-squared (there are many types, I picked one) which can be interpreted in a similar way.

I understand that “Odds ratios” and “Betas” are abstract and confusing to many. I tend to find that graphs help in making sense of abstract ideas. There are two sets of plots, one from the logistic model and the other from the linear model, which show the effects in a more tangible way:

Logistic - Environment for SLs

##########THIS WAS GENERATED IN A HIDDEN CODE CHUNK AND SHOWS HOW THE PLOTS ARE CALCULATED#########
# #Generate data for plots
# logit.balplot <- margins::cplot(logit, "balance")
# logit.envplot <- margins::cplot(logit, "slserver")
# lin.fairplot <- margins::cplot(linear, "admfair")
# lin.tworkplot <- margins::cplot(linear, "twork")
# lin.learnplot <- margins::cplot(linear, "learn")
# lin.toxicplot <- margins::cplot(linear, "toxic")
##########THIS WAS GENERATED IN A HIDDEN CODE CHUNK AND SHOWS HOW THE PLOTS ARE CALCULATED#########

#Build
logit.env <- logit.envplot %>% ggplot(aes(x = xvals)) + 
  geom_line(aes(y = yvals*100), colour = "blue") + 
  geom_line(aes(y = lower*100), colour = "red", linetype = "dotted") + 
  geom_line(aes(y = upper*100), colour = "red", linetype = "dotted") + theme_classic() +
  labs(title = "Impact of improving environment for SLs on probability to SL", subtitle ="Dotted lines are 95% Confidence intervals", 
       caption =  "Controlling for the other variables in the model") + 
  theme(plot.title = element_text(hjust = 0.5)) +
  theme(plot.subtitle = element_text(hjust = 0.5))  +
  theme(plot.caption = element_text(hjust = 0.5))  + 
  ylab("Chances of avg. person becoming SL (%)") + 
  scale_x_discrete(name ="Environment for SLs", limits=c(1:10))

#Display
logit.env

Logistic - Team Balance

#Remove previous
rm(logit.envplot, logit.env)

#Build
logit.bal <- logit.balplot %>% ggplot(aes(x = xvals)) + 
  geom_line(aes(y = yvals*100), colour = "blue") + 
  geom_line(aes(y = lower*100), colour = "red", linetype = "dotted") + 
  geom_line(aes(y = upper*100), colour = "red", linetype = "dotted") + theme_classic() +
  labs(title = "Impact of improving Team balance for SLs on probability to SL", subtitle = "Dotted lines are 95% Confidence intervals",
       caption =  "Controlling for the other variables in the model") + 
  theme(plot.title = element_text(hjust = 0.5)) +
  theme(plot.subtitle = element_text(hjust = 0.5))  + 
  theme(plot.caption = element_text(hjust = 0.5)) +
  ylab("Chances of avg. person becoming SL (%)") + 
  scale_x_discrete(name ="Team Balance", limits=c(1:10))

#Display
logit.bal

Linear - Admin fairness

#Remove previous
rm(logit.balplot, logit.bal)

#Build
lin.fair <- lin.fairplot %>% ggplot(aes(x = xvals)) + 
  geom_line(aes(y = yvals), colour = "blue") + 
  geom_line(aes(y = lower), colour = "red", linetype = "dotted") + 
  geom_line(aes(y = upper), colour = "red", linetype = "dotted") + theme_classic() +
  labs(title = "Impact of improving Admin fairness on Environment for SLs", subtitle = "Dotted lines are 95% Confidence intervals",
       caption =  "Controlling for the other variables in the model") + 
  theme(plot.title = element_text(hjust = 0.5)) +
  theme(plot.subtitle = element_text(hjust = 0.5))  +
  theme(plot.caption = element_text(hjust = 0.5)) +
  ylab("Environment for SLs") + 
  scale_x_discrete(name ="Admin Fairness", limits=c(1:10))

#Display
lin.fair

Linear - Teamwork

#Remove previous
rm(lin.fairplot, lin.fair)

#Build
lin.twork <- lin.tworkplot %>% ggplot(aes(x = xvals)) + 
  geom_line(aes(y = yvals), colour = "blue") + 
  geom_line(aes(y = lower), colour = "red", linetype = "dotted") + 
  geom_line(aes(y = upper), colour = "red", linetype = "dotted") + theme_classic() +
  labs(title = "Impact of improving Teamwork on Environment for SLs", subtitle = "Dotted lines are 95% Confidence intervals",
       caption =  "Controlling for the other variables in the model") + 
  theme(plot.title = element_text(hjust = 0.5)) +
  theme(plot.subtitle = element_text(hjust = 0.5))  +
  theme(plot.caption = element_text(hjust = 0.5)) +
  ylab("Environment for SLs") + 
  scale_x_discrete(name ="Teamwork", limits=c(1:10))

#Display
lin.twork

Linear - Learning environment

#Remove previous
rm(lin.tworkplot, lin.twork)

#Build
lin.learn <- lin.learnplot %>% ggplot(aes(x = xvals)) + 
  geom_line(aes(y = yvals), colour = "blue") + 
  geom_line(aes(y = lower), colour = "red", linetype = "dotted") + 
  geom_line(aes(y = upper), colour = "red", linetype = "dotted") + theme_classic() +
  labs(title = "Impact of improving Learning environment on Environment for SLs", subtitle = "Dotted lines are 95% Confidence intervals",
       caption =  "Controlling for the other variables in the model") + 
  theme(plot.title = element_text(hjust = 0.5)) +
  theme(plot.subtitle = element_text(hjust = 0.5))  +
  theme(plot.caption = element_text(hjust = 0.5)) +
  ylab("Environment for SLs") + 
  scale_x_discrete(name ="Learning environment", limits=c(1:10))

#Display
lin.learn

Linear - Overall server environment

#Remove previous
rm(lin.learnplot, lin.learn)

#Build
lin.toxic <- lin.toxicplot %>% ggplot(aes(x = xvals)) + 
  geom_line(aes(y = yvals), colour = "blue") + 
  geom_line(aes(y = lower), colour = "red", linetype = "dotted") + 
  geom_line(aes(y = upper), colour = "red", linetype = "dotted") + theme_classic() +
  labs(title = "Impact of improving Overall server environment on Environment for SLs", subtitle = "Dotted lines are 95% Confidence intervals",
       caption =  "Controlling for the other variables in the model") + 
  theme(plot.title = element_text(hjust = 0.5)) +
  theme(plot.subtitle = element_text(hjust = 0.5))  +
  theme(plot.caption = element_text(hjust = 0.5)) +
  ylab("Environment for SLs") + 
  scale_x_discrete(name ="Overall server environment", limits=c(1:10))

#Display
lin.toxic

Discussion

The plots above and Table 18 present some interesting findings. The logistic regression (see Model 1 in Table 18) only captures around 15% (the R-squared) of what drives a person’s choice to become a squad leader. This means that roughly 85% of what goes into the decision to SL is based on things outside the model. This finding makes intuitive sense as a person’s decision to SL is probably driven by their personality traits rather than a server’s environment or administration team.

However, there are still certain things that the server can do better to attract more squad leaders. External clan members are around 1.7 times more likely than unaffiliated players to squad lead, even controlling for experience and all the other variables. Though this finding is only weakly significant, it seems a safe bet that attracting more external clan members will result in more squad leaders. Unsurprisingly, the kinds of people who join clans are just more likely to squad lead.

Admin performance or rule enforcement have no impact on a person’s decision to SL after controlling for the other variables. This is somewhat unsurprising, at least anecdotally. What does have an impact on a person’s decision to SL is team balance and the environment for SLs. We can see from the plots above that improving the environment for SLs from roughly 7 to 9 would result in going from roughly a third of people willing to SL to about half of the respondents willing to take up the burden (see the plot titled “Logistic - Environment for SLs”). There is a similar, albeit weaker, effect in the case of team balance. Improving upon both of these variables will result in more people willing to squad lead. I should note that even if we were perfect in these categories, a majority of players still would not want to squad lead often.

Since improving the environment for SLs has a large impact (second to attracting more external clan members), I estimated a standard OLS model (Model 2 in Table 18) which tries to capture the factors that may explain this variable. We do find statistically significant effects (which are shown in the plots above under the tabs titled “Linear”) from admin fairness, teamwork, learning environment, and overall server environment as they relate to the the environment for SLs.

The effects are small. For example, even if we were rated perfectly in the teamwork category, holding all else constant (i.e. controlling for the other variables in the model), the environment for SLs would only improve marginally to approximately 8/10. Recall from Table 7 that the average score for the environment for SLs variable is already around 7.5/10. The results suggest that we can only make marginal improvements to the environment for SLs.

A keen eyed statistician will notice that there is a possibility that the environment for SLs is highly correlated with factors such as teamwork, learning environment, etc. and ask whether removing this variable from the logistic model might show that it is in fact those other variables that are driving someone’s decision to become a squad leader and not the environment for SLs per se. I did account for this by estimating Model 1 in Table 18 without \(x_{12} = Envrionment\;for\;Sls\) (results not shown - but the code is present for readers who would like to run it themselves). The goal was to check whether removing \(x_{12} = Envrionment\;for\;Sls\) from Model 1 would make the factors that may be related to the it significant predictors of a person’s likelihood to lead a squad. The answer was no and therefore it is fair to say that admin fairness, teamwork, learning environment, and overall server environment increase a person’s person’s likelihood to lead a squad indirectly through their effect on improving the environment for Sls.

Although we may not have a lot further to rise, we can still fall quite far. For example, if the score on the environment for SLs variable falls to 5/10, less than 20% of the player base would be willing to squad lead (see the plot titled “Logistic - Environment for SLs”)! The results show that we must be vigilant in maintaining the standards of the server in order to keep and possibly improve upon the numbers of our current pool of squad leaders.

The second model only captures around 40% of what drives the environment for SLs (see the R-squared for the linear model in Table 18). This suggests that the majority of what influences the SL environment lies beyond the direct control of the admin team. However, even if we cannot control everything, both the admin team and server regulars have a role to play in keeping the server a good place to play and lead squads on.

This is the real end of this report. I do not know or quite understand why anyone would have read this far. However, to those that did, thank you. You are what make the server what it is and for that, you have our gratitude.