Releases: hopskipnfall/EmuLinker-K
0.14.0 Don't crash game on drop, better ping, cache optimized
Major changes in this version:
- When a user drops from a game, if two or more players remain the game will not stop #133
This is how things worked from version 0.11.2 and before, but was lost when we moved to running the entire server on a single port. This has not been thoroughly tested and there is a rare edge case where the game may pause for up to one minute before continuing. If you notice strange behavior when a game ends, please let us know.
- Ping calculation is more accurate
Until now, ping has been measured at only millisecond-level precision and the average ping was calculated by truncating instead of rounding.
- Significant performance boost for the game data cache
The protocol uses a cache to avoid sending multiple packets of identical game data. After some inspection I realized that the specialized data structure being used was almost optimally inefficient 😂 I made some small changes which reduce cache lookup time by about 80% in practice. I haven't run the full suite of performance tests for comparison with previous versions, but it's possible this results in a noticeable improvement.
Other changes:
- I switched from Dagger to Koin for dependency injection. This removes the need for annotation processing, which speeds up build times and removes nearly all generated sources. This was a big hurdle to making it possible to comfortably edit the server code using VS Code.
- Some game data processing code that was previously synchronized with locks had the locks removed (presumed unnecessary), which may have a performance benefit.
- Some changes in how dependencies are defined means the jar is close to half the size.
- I some changes that may mitigate lag spikes experienced when a user joins the server (please provide feedback on this).
As always if you notice bugs feel free to create a GitHub issue or post in the Kaillera Reborn Discord server.
PRs
- Allow two or more users to continue playing a game when someone drops by @hopskipnfall in #133
- Switch from Dagger to Koin for DI by @hopskipnfall in #134
- Make mid-game dropping more reliable by @hopskipnfall in #136
Full Changelog: 0.13...0.14
0.13.2 Lagstat changes and ESF admin client fix
0.13.2 update: The latest update in this release includes #130 which fixes a bug causing users to be kicked for inactivity incorrectly. It also allows all users to use /lagstat
, not just admins and game owners.
I first want to thank everyone who tried out and gave feedback on ELK 0.12.0. As of now there are ELK servers running in:
🇦🇺 Australia
🇧🇷 Brazil (x2)
🇨🇱 Chile
🇨🇳 China (x2)
🇫🇷 France
🇯🇵 Japan
🇳🇿 New Zealand
🇵🇪 Peru
🇿🇦 South Africa
🇸🇪 Sweden
🇺🇸 USA (x4)
🇻🇳 Vietnam
Many ELK users gave feedback (thank you!) that the new lagstat data isn't always helpful. It turns out the lag statistics weren't being calculated correctly for users on higher than 1 frame delay, or when there were more than 2 players in a single room. I took this opportunity to completely redesign the lagstat feature. I'm working on a long-form document describing specifically how lag is measured, but for now here is quick description of how to use it:
17:56:50 <nue> /lagstat
17:56:50 <Server> Total lag over the last 3m: 1821ms
17:56:50 <Server> Lag caused by players: P1: 10ms, P2: 1801ms
The total lag should be a relatively accurate measurement of the total lag that occurred over the measurement period, and should be a good reference point for how objectively laggy a game is. I would be interested to hear feedback on what ranges feel good, laggy, and unplayably laggy. The lag caused by individual players is a measurement of how much lag each player definitively caused. Note that if multiple players are lagging but one is lagging worse, the current lag measurement strategy may only be able to identify that the player causing the most lag is lagging. If the game feels laggy, use the /lagstat
command to identify the player causing the most lag and then ask that player to fake ping to a higher frame delay. If lag continues you should repeat the process.
While you can still use /lagreset
to reset lag measurements, note that /lagstat
now will only show information for the last 3 minutes.
Other improvements:
- Anybody (not just the game owner) can use both the
/lagstat
and/lagreset
commands. - Support for the ESF Admin Client is fixed.
- The server version will now be listed in server lists (not just "elk").
- Dependencies have been updated, most importantly we are now using the Kotlin K2 compiler.
- Some small optimizations in the
GameData
andCachedGameData
action handlers which may provide better JIT compilation on high volume code paths - Extended the amount of time between some periodic logic, most significantly checking in with the central server (every 30m instead of 1m) and checking for user timeouts etc.
Full Changelog: 0.12.0-beta...0.13
0.12.0 Single Port/Netty
This version contains some major architectural changes to the code—most significantly running the server off of a single port instead of allocating a port for each user—which results in higher performance on resource-limited hardware.
If you run into issues with this release feel free to look for help in the Discord:
Feature changes since previous release:
- The option
server.improvedLagstatEnabled
has been removed and improved lagstat is now the only option - As the server now runs on only one port, the following settings now do nothing:
controllers.v086.portRangeStart
,controllers.v086.extraPorts
- When posting to Twitter, the server will now not attempt to post duplicate tweets (as they will fail anyway)
- When the server shuts down it will now log users out first, notifying them that the server is turning off
- You can configure a server chat message displayed to users as they enter or create a room using
KailleraServerImpl.JoinGameMessage.1=This is the first message KailleraServerImpl.JoinGameMessage.2=This shows up second KailleraServerImpl.JoinGameMessage.3=And so on...
Performance
After rigorous testing under high load with simulated clients on a single-core machine, this release is found to outperform EmuLinkerSF v0.93.2 (which this server is based on), EmuLinker-K v0.11.2 (the previous stable release of this server), as well as Emulinker-X v3.6 (another Emulinker fork emphasizing performance improvements).
What's Changed
- Add CONTRIBUTING.md by @hopskipnfall in #107
- Run on a single port using Netty by @hopskipnfall in #109
- Performance improvements for user actions, fix scheduled tasks by @hopskipnfall in #115
- Gracefully handle SIGTERM, GameDataEvent performance improvements by @hopskipnfall in #116
Full Changelog: 0.11.2-beta...0.12.0-beta
0.11.2 Twitter integration
Adds a feature where the server will post to twitter when someone opens up a new game.
This feature is experimental and may be removed or changed at any time. If you like this feature or have feedback, please let us know in the
To set it up:
-
Create a new Twitter account for your server's bot (you can also share one between multiple servers).
-
Make a new app in the Twitter developer dashboard using the Free tier.
-
Configure the following values in
config/emulinker.cfg
:
twitter.enabled=true
# Delay (in seconds) before sending a tweet.
twitter.broadcastDelaySeconds=20
# Comma-separated list of phrases that, if found in the name
# after a "@", will prevent tweet posting.
twitter.preventBroadcastNameSuffixes=waiting,restart
# If true, will simply delete the tweet when the game starts.
twitter.deletePostOnClose=false
# Fill these in from the Twitter app you created:
twitter.auth.oAuthAccessToken=
twitter.auth.oAuthAccessTokenSecret=
twitter.auth.oAuthConsumerKey=
twitter.auth.oAuthConsumerSecret=
- You will also need to configure some messages in
config/language.properties
:
KailleraServerImpl.TweetPendingAnnouncement=Posting a tweet in {0} seconds. Type \"/stop\" to disable.
KailleraServerImpl.TweetCloseMessage=(opponent found)
KailleraServerImpl.CanceledPendingTweet=Canceled pending tweet.
With these settings, users whose name ends in @waiting
(meaning they are waiting for a specific person to join their game) or @restart
(meaning they are restarting the game and are waiting for the same person to join) will not have tweets sent. Similarly, users will be notified and given 20 seconds to type /stop
to stop the tweet from sending. After the game starts, the account will respond to the original tweet with the text "(opponent found)".
What's Changed
- Start adding documentation on Kaillera messages. by @hopskipnfall in #98
- Update Twitter logic to work with recent API changes. by @hopskipnfall in #102
- Fix a bug where the server won't start without Twitter credentials by @hopskipnfall in #103
Full Changelog: 0.10.7-beta...0.11.1-beta
0.10.7 Public Beta Launch
This is the first stable (beta) release of EmuLinker-K, which is an improved version of EmulinkerSF, rewritten in Kotlin.
This release is intended for server admins who are already familiar with running EmuLinker servers. If you are brand new to hosting a server, you might want to skip this release. I will write more detailed instructions on setting up a server after we get some initial feedback.
Launching the server is almost identical to ESF, and it's compatible with your existing ESF config files. There are two important differences from ESF however:
- A minimum Java version of 17 is required.
- Your config files (
emulinker.cfg
andlanguage.properties
) need to be saved in UTF-8 format. If the file only contains English words, this probably doesn't matter.
There are a few new features in this build, but with this release I am more interested in getting feedback about core functionality. One difference you may notice is that the /lagstat
command is overhauled and more accurately tracks lag caused by players. Currently this doesn't count lag spikes, it counts individual lagged frames (classified into "big" and "small" amounts of lag for the frame).
Feedback
Feel free to file bugs and feature requests on this repository in the Issues tab, or find our channel in the Kaillera Reborn discord:
What's Changed (all PRs since EmuLinkerSF 0.92.4)
- Restructure as Maven project by @hopskipnfall in #1
- Add github CI maven config by @hopskipnfall in #2
- Fix support for charset Shift_JIS by @hopskipnfall in #3
- Format with google-java-format by @hopskipnfall in #4
- ErrorProne support and suggested patches by @hopskipnfall in #5
- Add RuntimeFlags config class by @hopskipnfall in #6
- Use Maven dependency for picocontainer, also get rid of more jars by @hopskipnfall in #7
- JP support for messages config. v0.93.1 (Beta) by @hopskipnfall in #8
- Add ability to package to a single jar. by @hopskipnfall in #9
- Delete more deps and avoid issues with java 9+ by @hopskipnfall in #10
- Add a run command by @hopskipnfall in #11
- Integrate EmuLinkerSF v92.7 changes by @hopskipnfall in #12
- Fix formatter by @hopskipnfall in #13
- Documentation and string changes. by @hopskipnfall in #14
- Random cleanups by @hopskipnfall in #15
- AutoValue for V086 Actions by @hopskipnfall in #16
- Use Strings.isNullOrEmpty() and fix one last Shift_JIS-related bug by @hopskipnfall in #17
- Replace picocontainer with dagger for Dependency Injection by @hopskipnfall in #18
- Use a stable config that can be set by tests by @hopskipnfall in #19
- Use generics for V086 actions and handlers by @hopskipnfall in #20
- Read project info (including version) from pom. by @hopskipnfall in #21
- Add application metrics for RPC latency, etc. by @hopskipnfall in #22
- Fix logging to file. by @hopskipnfall in #23
- Add Docker and Graphite by @hopskipnfall in #26
- Add ability to automatically post tweets when users create games by @hopskipnfall in #27
- Convert most of the code base over to Kotlin by @hopskipnfall in #28
- Rewrite most of the rest of the codebase to Kotlin by @hopskipnfall in #29
- Rewrite Java threading logic to Kotlin by @hopskipnfall in #30
- Kotlin kleenup by @hopskipnfall in #31
- Probably fix the bug that caused multiplayer to break by @hopskipnfall in #32
- Assorted cleanups by @hopskipnfall in #36
- Address vulnerabilities in maven dependencies by @hopskipnfall in #37
- Fix bug where updating server lists does not correctly show the number of users/games by @hopskipnfall in #38
- Refactor some common statues to enums by @hopskipnfall in #39
- Begin to refactor some stuff. Do some other things too. by @hopskipnfall in #40
- Code cleanup by @hopskipnfall in #42
- Improve /lagstat command by @hopskipnfall in #43
- Patch improved lagstat bug by @hopskipnfall in #44
- Bump kotlin and dagger to the latest versions. by @hopskipnfall in #45
- Fix /lagreset to work with improved lagstat big spikes. by @hopskipnfall in #46
- Fake kaillera client code for intensive testing by @hopskipnfall in #48
- Re-implement threading logic to use coroutines by @hopskipnfall in #47
- Move the maven pom to the parent directory so Intellij likes it better by @hopskipnfall in #49
- More coroutines cleanup by @hopskipnfall in #50
- Update deps by @hopskipnfall in #51
- Changes by @hopskipnfall in #52
- More cleanup by @hopskipnfall in #53
- Cleanups on a long flight by @hopskipnfall in #54
- Fix logging by @hopskipnfall in #55
- Switch to ktfmt by @hopskipnfall in #57
- Refactor v086 protocol message serialization/deserialization by @hopskipnfall in #58
- Remove channel buffer, which may improve performance by @hopskipnfall in #59
- Rename Request and Notification message names as their toString representations are not clear by @hopskipnfall in #60
- Set maximum parallelism to 1 for TwitterBroadcaster. by @hopskipnfall in #65
- Improve logging, mark areas for fixing, update metrics logging. by @hopskipnfall in #66
- Apply changes from #67 to HEAD, improve cleanup logic for users. by @hopskipnfall in #68
- Add CompiledFlags by @hopskipnfall in #69
- Upgrade Kotlin version, remove some sources of lag by @hopskipnfall in #70
- Update master servers list address. by @hopskipnfall in #74
- Require minimum Java version 11 by @hopskipnfall in #75
- Random cleanups by @hopskipnfall in #76
- Invoke user timeout logic, tweak large lag spike threshold by @hopskipnfall in #77
- Get rid of KailleraUser, KailleraGame, and KailleraServer interfaces by @hopskipnfall in #79
- Revert to before coroutines by @hopskipnfall in #82
- Remove guava dependency, clean up logging. by @hopskipnfall in #83
- Add a server info welcome message, make KailleraServer a singleton. by @hopskipnfall in #84
- Revert Kaillera(User|Server).* string names which were changed accidentally. by @hopskipnfall in #85
- s/EmuLinkerSF-netsma/EmuLinker-K/ for Kotlin by @hopskipnfall in #86
- Code cleanup by @hopskipnfall in #87
- Prompt admins to update the server if one is available when they log in by @hopskipnfall in #88
- Tweak large lag threshold 70ms -> 50ms. by @hopskipnfall in #89
- Add CheckinTask to call a central server by @hopskipnfall in #90
- Update mast...
0.9.2-alpha Fix several critical latency bugs
This fixes a long-standing bug where lag abruptly occurs after a certain amount of time passes (see the description of #70).
v0.6.3 remains the latest "stable" release, but this is probably comparable. More load testing is required to tell for sure.
Known bugs:
- #72 At the end of load tests, the server lags significantly when users leave the server.
- #71 Stale/inactive users are not getting timed out correctly.
What's Changed
- Add CompiledFlags by @hopskipnfall in #69
- Upgrade Kotlin version, remove some sources of lag by @hopskipnfall in #70
Full Changelog: 0.9.1-alpha...0.9.2-alpha
0.9.1-alpha
Candidate for comparing against 0.6.3.
What's Changed
- Rename Request and Notification message names as their toString representations are not clear by @hopskipnfall in #60
- Set maximum parallelism to 1 for TwitterBroadcaster. by @hopskipnfall in #65
- Improve logging, mark areas for fixing, update metrics logging. by @hopskipnfall in #66
- Apply changes from #67 to HEAD, improve cleanup logic for users. by @hopskipnfall in #68
Full Changelog: 0.9.0-alpha...0.9.1-alpha
0.6.3 Improve monitoring for comparison against stable version
0.9.0-alpha Remove user events channel buffer
The main change in this release is #59, where an infinite loop for each user waiting on a Channel
is removed and replaced with individual ad-hoc coroutines for each user-directed event.
This is release hopes to address a bug present starting in 0.7.0 (specifically #47) where the server dramatically slows down responding to requests after a few hours and general slowness.
The current mostly stable version of the server is 0.6.2.
What's Changed
- Cleanups on a long flight by @hopskipnfall in #54
- Fix logging by @hopskipnfall in #55
- Switch to ktfmt by @hopskipnfall in #57
- Refactor v086 protocol message serialization/deserialization by @hopskipnfall in #58
- Remove channel buffer, which may improve performance by @hopskipnfall in #59
Full Changelog: 0.8.0-alpha...0.9.0-alpha
0.8.0-alpha Additional cleanup and possible optimizations
This is essentially no different from 0.7.0-alpha, but notably the number of IO dispatchers is greatly reduced (see ServerMain.kt
) which might address the issue of the server slowing down after a few hours.
Again, this is a very much alpha release. Testing is appreciated but please know this and the previous release are very experimental.
What's Changed
- Update deps by @hopskipnfall in #51
- Changes by @hopskipnfall in #52
- More cleanup by @hopskipnfall in #53
Full Changelog: 0.7.0-alpha...0.8.0-alpha