LearnersGuild / game-prototype

Lightweight, minimal implementation of game mechanics for rapid experimentation and prototyping.
0 stars 0 forks source link

Players have a Support stat #17

Closed jeffreywescott closed 7 years ago

jeffreywescott commented 8 years ago

@tannerwelsh commented on Tue Jun 21 2016

The Support stat is a measurement of player altruism and contribution to the collective.

It is represented as a percentage, up to 2 decimal places.

The support stat is the mean of three sub-stats:

Culture Contribution

  1. Find CULTURE_CONTRIB scores for each project
    • Weight by hours worked on project (more hours = greater weight)
    • Weight by recency of project (more recent = greater weight)
  2. Aggregate all scores into mean, then convert to % (/ by 7)

Learning Support

  1. Find LEARNING_SUPPORT scores for each project
    • Weight by hours worked on project (more hours = greater weight)
    • Weight by recency of project (more recent = greater weight)
  2. Aggregate all scores into mean, then convert to % (/ by 7)

Review Stat

  1. Find REVIEW_RATIO
  2. Find MAX_REVIEW_RATIO
  3. Compare REVIEW_RATIO to MAX_REVIEW_RATIO, convert to %
  4. This is the Review Stat

To make the full Support stat, find the mean of the above three stats.

On weighting

The Learning Support and Culture Contribution stats should be weighted to ensure that these stats are balanced by the amt. of time the player spent on a project (so that scores in a 4-hour and a 100-hour contribution are not considered equal) as well as the recency of the project (so that recent changes are reflected boldly to the player, and early scores don't overly influence the aggregate).

I'm no statistician, so I'd love suggestions/feedback on how to do this best. My initial idea for weighting is:

Example:

const projectStatsForPlayer = [
  {
    avgCulture: 5.47,
    avgLearning: 4.75,
    hours: 35,
    cycleNo: 1
  },
  {
    avgCulture: 5.23,
    avgLearning: 6.32,
    hours: 20,
    cycleNo: 2
  },
  {
    avgCulture: 6.66,
    avgLearning: 4.52,
    hours: 30,
    cycleNo: 3
  },
]

function calculateWeightedStats(stats) {
  let hoursTotal = 0
  let cycleTotal = 0

  let augmentedStats = stats.map((stat) => {
    stat.weightedCulture = stat.avgCulture * (stat.hours + stat.cycleNo)
    stat.weightedLearning = stat.avgLearning * (stat.hours + stat.cycleNo)
    hoursTotal += stat.hours
    cycleTotal += stat.cycleNo

    return stat
  }).reduce((total, stat) => {
    total.culture += stat.weightedCulture
    total.learning += stat.weightedLearning

    return total
  }, { culture: 0, learning: 0 })

  let weighingTotal = hoursTotal + cycleTotal

  return { culture: augmentedStats.culture / weighingTotal,
           learning: augmentedStats.learning / weighingTotal }
}

console.log(calculateWeightedStats(projectStatsForPlayer))
// => { culture: 5.843516483516483, learning: 5.046153846153847 }

original: https://github.com/LearnersGuild/learning-os-software/issues/85


@tannerwelsh commented on Fri Jul 29 2016

IGNORE: NO LONGER VALID (just keeping for historical reference)

Example implementation of calculation:

const likertMax = 7

// === SINGLE CYCLE STAT

const playerCycleStats = {
  cultureContributions: [5, 2, 3, 7]  // answers to "X contributed positively to our team culture"
, helpfulnessRatings: [4, 5, 5, 4]    // answers to "X supported me in learning my craft"
, noProjReviews: 4                    // no. of project reviews submitted this cycle
}

const chapterCycleStats = {
  maxProjReviewsSubmitted: 6
}

function cycleSupportStat(playerCycleStats, chapterCycleStats) {
  const cultureStat = mean(playerCycleStats.cultureContributions) / likertMax
  const helpfulStat = mean(playerCycleStats.helpfulnessRatings) / likertMax
  const reviewStat = playerCycleStats.noProjReviews / chapterCycleStats.maxProjReviewsSubmitted

  return mean([cultureStat, helpfulStat, reviewStat])
}

function mean(nums) {
  return nums.reduce((pre, cur) => { return pre + cur }) / nums.length
}

const currCycleSupportStat = cycleSupportStat(playerCycleStats, chapterCycleStats)

console.log(currCycleSupportStat) // => 0.6388888888888888

// === OVERALL (MULTI-CYCLE) STAT

const cycleSupportStats = [0.5722, 0.823, 0.292, currCycleSupportStat]

function aggregateSupportStat(cycleSupportStats) {
  let weightedCycleSupportStats = cycleSupportStats.map((stat, i) => {
    return Array(i + 1).fill(stat)
  })

  weightedCycleSupportStats = [].concat(...weightedCycleSupportStats) // flatten

  return mean(weightedCycleSupportStats)
}

const supportStat = aggregateSupportStat(cycleSupportStats)

console.log(supportStat) // => 0.5649755555555556

@tannerwelsh commented on Fri Jul 08 2016

@shereefb I took a first stab at the calculation of Support Stat. What do you think?


@shereefb commented on Wed Jul 27 2016

Don't we also need to weigh this by the number of total dev hours for the project?


@tannerwelsh commented on Tue Jul 19 2016

@shereefb yup, that should go into this as well. Shouldn't be too hard to adjust the above to match, I just need to consider it a bit longer.


@jeffreywescott commented on Wed Jul 27 2016

@tannerwelsh, I'm going to remove this from #111 and this can be part of the next round of stats that we work on. Unless you think it's ready, in which case, please add it back to #111 and then move it into the To-Do lane with the rest of the stats stuff.


@tannerwelsh commented on Thu Jul 28 2016

Thanks @jeffreywescott - I need to figure out how to incorporate an hourly weight into this number, and then I'll bump it back up.


@tannerwelsh commented on Fri Jul 29 2016

@shereefb what do you think of the changes to the support calculation (now includes hours)? If you like it, please move to Backlog.


@shereefb commented on Wed Aug 03 2016

@prattsj I moved this back to Design/Spec. Still needs some work (from me) before it's ready for todo. Were you planning on working on it today?


@prattsj commented on Wed Aug 03 2016

@shereefb: ok. Need an answer on whether you want to hold player stats DMs until it's worked out or release without them.


@shereefb commented on Tue Aug 09 2016

tannerwelsh commented 8 years ago

waiting on #6

tannerwelsh commented 7 years ago

Moved to Clubhouse.