Skip to content

2025.11.3 - Release

Highlights

New MapEvent-Reward Probability Matrix

The MapEvent-Reward Probability Matrix explains how likely it is that a player gets a specific reward. Rewards can be combined, the probability is calculated based on the level and the difficulty of the map and per reward.

Show Formula

The probability is calculated by the following formula:

max_levels=16max_length=9level_weight=0.6(60%)length_weight=0.4(40%)matrix[length][level]retrieved from the table\text{max\_levels} = 16 \\ \text{max\_length} = 9 \\ \text{level\_weight} = 0.6 \, (60\%) \\ \text{length\_weight} = 0.4 \, (40\%) \\ \text{matrix}[\text{length}][\text{level}] \, \text{retrieved from the table}

Probability Formula:

probability=((levelmax_levelslevel_weight)+(lengthmax_length)length_weight)×(matrix[length][level]10)item_matrix[item_level]\text{probability} = \left( \left( \frac{\text{level}}{\text{max\_levels}} \cdot \text{level\_weight} \right) + \left( \frac{\text{length}}{\text{max\_length}} \right) \cdot \text{length\_weight} \right) \times \left( \text{matrix}[\text{length}][\text{level}] \cdot 10 \right) \cdot \text{item\_matrix[\text{item\_level}]}
Map Event Reward Probability Matrix

To calculate the item_level you have to divide the percentage by 100 to get the used decimal value. Example 50 / 100 = 0.5

RewardChance
Season Points50%
Power25%

New MapEvent Probability Matrix

The MapEvent Probability Matrix explains how likely it is that a player finish will trigger a Custom Random Map Event. Every finish counts as a roll, the probability is calculated based on the level of the map and the difficulty of the event. It is possible that multiple MapEvents are on a map.

Show Formula

The probability is calculated by the following formula:

max_levels=16max_length=9level_weight=0.6(60%)length_weight=0.4(40%)matrix[length][level]retrieved from the table\text{max\_levels} = 16 \\ \text{max\_length} = 9 \\ \text{level\_weight} = 0.6 \, (60\%) \\ \text{length\_weight} = 0.4 \, (40\%) \\ \text{matrix}[\text{length}][\text{level}] \, \text{retrieved from the table}

Probability Formula:

probability=((levelmax_levelslevel_weight)+(lengthmax_length)length_weight)×matrix[length][level]\text{probability} = \left( \left( \frac{\text{level}}{\text{max\_levels}} \cdot \text{level\_weight} \right) + \left( \frac{\text{length}}{\text{max\_length}} \right) \cdot \text{length\_weight} \right) \times \text{matrix}[\text{length}][\text{level}]

Example Calculations:

  1. Extreme 3+ on a WTF map:
level=16,length=9,matrix[9][16]=0.0914probability=((16160.6)+(990.4))0.0914=(10.6+10.4)0.0914=10.0914=0.0914100=9,14%\text{level} = 16, \, \text{length} = 9, \, \text{matrix}[9][16] = 0.0914 \\ \text{probability} = \left( \left( \frac{\text{16}}{\text{16}} \cdot \text{0.6} \right) + \left( \frac{\text{9}}{\text{9}} \cdot \text{0.4} \right) \right) \cdot 0.0914 \\ = \left( 1 \cdot 0.6 + 1 \cdot 0.4 \right) \cdot 0.0914 \\ = 1 \cdot 0.0914 = 0.0914 \cdot 100 = 9,14\%
  1. Easy 1 on a XXS map:
level=1,length=1,matrix[1][1]=0.0198probability=((1160.6)+(190.4))0.0198=((0.06250.6)+(0.11110.4))0.0198=0.081940.0198=0.001622100=0.1%\text{level} = 1, \, \text{length} = 1, \, \text{matrix}[1][1] = 0.0198 \\ \text{probability} = \left( \left( \frac{\text{1}}{\text{16}} \cdot \text{0.6} \right) + \left( \frac{\text{1}}{\text{9}} \cdot \text{0.4} \right) \right) \cdot 0.0198 \\ = \left( \left( 0.0625 \cdot 0.6 \right) + \left( 0.1111 \cdot 0.4 \right) \right) \cdot 0.0198 \\ = 0.08194 \cdot 0.0198 = 0.001622 \cdot 100 = 0.1\%
Show Map Event Probability Matrix

ATTENTION: The matrix levels have been reversed to make it easier to read. There is no mathematical expression, the values are purely based on random numbers between a specific threshold.

LevelEASY 1EASY 2EASY 3MAIN 1MAIN 2MAIN 3HARD 1HARD 2HARD 3INSANE 1INSANE 2INSANE 3EXTREME 1EXTREME 2EXTREME 3EXTREME 3+
WTF0.01260.01940.02630.03310.04000.04690.05370.06060.06740.07430.08110.08800.09130.09130.09130.0914
XXXL0.01270.01950.02640.03320.04010.04690.05370.06060.06740.07430.08110.08800.09110.09110.09110.0912
XXL0.01280.01970.02650.03330.04010.04700.05380.06060.06740.07420.08110.08790.09090.09090.09090.0910
XL0.01300.01980.02660.03340.04020.04700.05380.06060.06740.07420.08100.08780.09050.09050.09050.0906
L0.01330.02010.02680.03360.04040.04710.05390.06070.06740.07420.08090.08770.09010.09010.09010.0902
M0.01370.02040.02720.03390.04060.04730.05400.06070.06740.07410.08080.08750.08940.08940.08940.0895
S0.01440.02110.02770.03430.04090.04750.05420.06080.06740.07400.08060.08730.08820.08820.08820.0883
XS0.01580.02230.02870.03510.04160.04800.05450.06090.06740.07380.08030.08590.08590.08590.08590.0860
XXS0.01980.02570.03170.03760.04360.04950.05540.06140.06730.07330.07920.07910.07910.07910.07910.0792
Implementation detail
Python implementation
import random
PROBABILITY_MATRIX = [
[0.0198, 0.0257, 0.0317, 0.0376, 0.0436, ..., 0.0791, 0.0792],
...,
[0.0126, 0.0194, 0.0263, ..., 0.0913, 0.0913, 0.0914]
]
MAX_LEVEL = 16
LEVEL_WEIGHT = 0.6
MAX_DIFFICULTY = 9
DIFFICULTY_WEIGHT = 0.4
# For demonstration purpose, no out of bound checks are performed
def trigger_event(level: int, difficulty: int):
# Look up the probability
probability_multiplier = PROBABILITY_MATRIX[level][difficulty]
level_multiplier = (level / MAX_LEVEL) * LEVEL_WEIGHT
difficulty_multiplier = (difficulty / MAX_DIFFICULTY) * DIFFICULTY_WEIGHT
probabilty = (level_multiplier + difficulty_multiplier) * probability_multiplier
# Check if the event should be triggered
if random.random() <= probability:
return True
else:
return False

New - For Server Providers Rewrote DNSBL public api

We have rewritten the DNSBL public API to be more efficient and faster. You dont need to change anything, the old DNSBL will be redirected to the new system. If you encounter any issues, please report them to us.

Change Changes

  • /power now shows the remaining time until it can be used again. KoG-teeworlds/community#25
  • Skipping non important events in the backend if older than 20 minutes (faster processing after servers reconnect again)
  • Merge upstream DDNet 18.9.1. DDNet-Release 18.9.1
  • Refactoring network-wide protocol
    • PlayerFinishEvent and TeamFinishEvent now unified into a FinishEvent, to check if its a solo run you can rely on the length of the player list and the team attribute (Team 0 is special and can be considered a solo finish).
    • Minor renamings
    • Removed unused fields
    • Removed unused events
    • Removed unused commands
  • Renamed [ACC] to [Accounts] for consistency.
  • Prepared some services for the upcoming backstage.io integration.

Bugfix Bugfixes

  • Using /roll after being muted is now fixed. KoG-teeworlds/community#24
  • Fixing a possible crash. (KoG internal report)
  • Fixed a cache invalidation bug.