Skip to content

Commit 616c3c7

Browse files
authored
Enhance README with installation and usage instructions
1 parent 337476e commit 616c3c7

1 file changed

Lines changed: 147 additions & 1 deletion

File tree

README.md

Lines changed: 147 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,147 @@
1-
[Tutorial & Documentation](https://bstummer.github.io/openskill.lua)
1+
# openskill.lua
2+
3+
openskill.lua is an implementation of the [Weng-Lin Bayesian ranking](https://www.csie.ntu.edu.tw/~cjlin/papers/online_ranking/online_journal.pdf), a better, license-free alternative to the [TrueSkill](https://www.microsoft.com/en-us/research/project/trueskill-ranking-system) ranking system.
4+
5+
It is a Luau port of the amazing [openskill.js](https://github.com/philihp/openskill.js) module, designed specifically for Roblox game development.
6+
7+
## Installation
8+
9+
Get the module [here](https://www.roblox.com/library/8134663273) and insert it into your game (preferably in ServerStorage).
10+
11+
Alternatively, you can paste this directly into your Roblox Studio command bar:
12+
13+
```lua
14+
game:GetObjects("rbxassetid://8134663273")[1].Parent=game.ServerStorage
15+
```
16+
17+
## Quick Start
18+
19+
### 1. Require the Module
20+
21+
Create a script and require the module:
22+
23+
```lua
24+
local OpenSkill = require(game.ServerStorage.OpenSkill)
25+
```
26+
27+
### 2. Create Ratings
28+
29+
You can create a rating for every player to describe their skill. Ratings are represented as a Gaussian curve with two properties:
30+
31+
- mu: The average skill of the player.
32+
- sigma: The degree of uncertainty in the player's skill.
33+
34+
Maintaining an uncertainty (sigma) allows the system to make large changes to skill estimates early on, but smaller, more stable changes after a series of consistent games.
35+
36+
```lua
37+
local a1 = OpenSkill.Rating() --> {mu = 25, sigma = 8.333}
38+
local a2 = OpenSkill.Rating(32.444) --> {mu = 32.444, sigma = 10.814}
39+
local b1 = OpenSkill.Rating(nil, 2.421) --> {mu = 25, sigma = 2.421}
40+
local b2 = OpenSkill.Rating(25.188, 6.211) --> {mu = 25.188, sigma = 6.211}
41+
```
42+
43+
### 3. Rate a Match
44+
45+
If `a1` and `a2` form a team and win against a team of `b1` and `b2`, you can update their skill ratings:
46+
47+
```lua
48+
OpenSkill.Rate({{a1, a2}, {b1, b2}})
49+
```
50+
51+
### 4. Displaying Ratings
52+
53+
When displaying a rating or sorting a leaderboard, use `Ordinal`. By default, this returns `mu - 3 * sigma`, showing a rating for which there is a 99.7% likelihood the player's true rating is higher. In early games, a player's ordinal rating will usually go up, even if they lose!
54+
```lua
55+
OpenSkill.Ordinal(a1) --> 0 (before rating)
56+
OpenSkill.Ordinal(a1) --> 2.3245624871094 (after winning)
57+
```
58+
59+
## Advanced Match Results
60+
61+
### Custom Ranks
62+
63+
If your teams are listed in one order but your ranking is in a different order, you can specify a `rank` option. Lower ranks are considered better.
64+
65+
```lua
66+
local a = OpenSkill.Rating()
67+
local b = OpenSkill.Rating()
68+
local c = OpenSkill.Rating()
69+
local d = OpenSkill.Rating()
70+
71+
OpenSkill.Rate({{a}, {b}, {c}, {d}}, { --4 teams consisting of 1 player
72+
rank = {4, 1, 3, 2}
73+
})
74+
```
75+
*In this example, team b placed 1st, d placed 2nd, c placed 3rd, and a placed 4th.*
76+
77+
### Custom Scores
78+
79+
You can also provide a score instead, where higher is better. These can just be raw scores from the game.
80+
81+
```lua
82+
OpenSkill.Rate({{a}, {b}, {c}, {d}}, {
83+
score = {37, 19, 37, 42}
84+
})
85+
```
86+
*Note: Ties should have either an equivalent rank or score.*
87+
88+
## Rating Models
89+
90+
openskill.lua provides two rating models: `PlackettLuce` and `ThurstoneMosteller`.
91+
- Plackett-Luce (Default): A generalized Bradley-Terry model for k ≥ 3 teams which scales best. It follows a logistic distribution over a player's skill, similar to Glicko.
92+
- Thurstone-Mosteller: Follows a Gaussian distribution, similar to TrueSkill. Accuracy is usually slightly lower than Plackett-Luce, but can be tuned with an alternative gamma function.
93+
94+
*Note: openskill.lua uses full pairing which yields highly accurate ratings. However, in games with an extremely high number of teams (100+), calculations become computationally expensive due to joint probability integration.*
95+
96+
You can change the global default model or pass it per-match:
97+
98+
```lua
99+
-- Global
100+
OpenSkill.Settings.DefaultModel = "ThurstoneMosteller"
101+
102+
-- Per-match
103+
OpenSkill.Rate({{a}, {b}, {c}, {d}}, {
104+
model = "ThurstoneMosteller"
105+
})
106+
```
107+
108+
109+
## API Reference
110+
111+
```lua
112+
OpenSkill.DefaultModel : string
113+
```
114+
Determines the model which is used by default.
115+
116+
```lua
117+
OpenSkill.Rating(mu : number?, sigma : number?, options : any?): rating
118+
```
119+
Creates a rating object, which describes a player's skill. Ratings are kept as an object which represent a gaussian curve, with properties where `mu` represents the mean, and `sigma` represents the spread or standard deviation. `mu` is the average skill of the player and `sigma` is the degree of uncertainty in the player's skill. Maintaining an uncertainty allows the system to make big changes to the skill estimates early on but small changes after a series of consistent games has been played. If omitted, `mu` defaults to 25 and `sigma` defaults to 25 / 3.
120+
121+
122+
```lua
123+
OpenSkill.Ordinal(rating : rating, options : any?): number
124+
```
125+
Represents a player's skill estimate as a single number. By default, this returns `mu - 3 * sigma`, showing a rating for which there's a [99.7%](https://en.wikipedia.org/wiki/68–95–99.7_rule) likelihood the player's true rating is higher. So in early games, a player's ordinal rating will usually go up and could go up even if that player loses.
126+
127+
128+
```lua
129+
OpenSkill.Rate(teams : {{rating}}, options : any?): {{{number}}}
130+
```
131+
Takes an array of teams (which are arrays of ratings) and updates their values based on the outcome of the match. Returns the new rating values in identically structured arrays.
132+
133+
134+
```lua
135+
OpenSkill.WinProbability(teams : {{rating}}, options : any?): {number}
136+
```
137+
Calculates the probability of each team winning the match.
138+
139+
140+
```lua
141+
OpenSkill.DrawProbability(teams : {{rating}}, options : any?): number
142+
```
143+
Calculates the probability of a draw between the teams. This is extremely useful for determining fair team compositions in matchmaking.
144+
145+
## Contributing
146+
147+
Contributions, issues, and feature requests are greatly appreciated!

0 commit comments

Comments
 (0)