|
So there is a general consensus that Apollo is the best written server going (at least for RS2) but I wanted to revisit some interesting topics of discussion that have not really been dealt with in a long time and some new ones. The informative thread section is basically dead, all the detailed stuff is from when RS2 was current. So knowing what we know now and given the technological advantages made in the past fifteen or so years what would a modern server look like?
Multithreading - Discussed in detail in the past, in particular with respect to the player updating and packet processing in parallel, would this still be beneficial? Do any current servers do this? Does it introduce too many locks and synchronization issues?
Build systems (Gradle, Ant, Maven) are they too intimidating for new users? You used to be able to just download a server and run it without much effort as long as you had Java, obviously to build it you needed to set the PATH variable but there was a low barrier to development. Now most servers require an IDE because they do not ship a simple run script.
Do you think the growth of servers is suffering as a result of the initial learning curve being too high to attract new blood?
Scripting - Ever since Hyperion I remember sophisticated scripting systems based on Ruby, Python or some variant, and now recently Kotlin. The original design decision seems to be based on RAD (rapid application development) principles, ruby and python are considered more simple, interpreted, less barriers for content writing etc, however they do not appear to have been taken up much and they seem like they have been passed over for writing Java instead.
Unit testing - Discussed rather recently, seems beneficial in respect of testing container systems and reducing dupes - Has this been successfully used in practice or is it just additional development overhead that we can probably skip?
Object orientation - A common criticism of many modern servers is that they are very complicated in terms of design. Object orientation when used properly can provide great benefits and reduce unnecessary code duplication. However we do run the risk of creating artificial and inane systems (blakeman8192 pointed this out a while back). How many objects is too many? Runewiki points out around 83 client opcodes in the 317 server (there are probably more). If we have a system of event listeners that is 83 distinct classes (assuming one per class) you could probably significantly reduce in some cases (for example sharing banking ones or option interaction) however it is still quite complicated and you risk your server getting overrun by a gazillion classes where it isn't clear what is what.
I'd like to have a discussion about general aspects of server design and perhaps even provide a big thread on some of the best threads around, like a compilation of the 'best bits' of the informative threads section so it is easily accessible.
Hi, no worries when you are free I would love to hear them.
By 'growth of servers' I mean attracting new people to the community. People have to start somewhere. It used to be that servers came with easily runnable bat files or whatnot which was frustrating for developers because we always told them to use an IDE but it was good because it meant people could download, run it and get into playing their own servers immediately. Everyone starts somewhere and I worry one of the reasons this community seems to be stagnant in some places is because the learning curve is now too high for new users. They get bored and think it is too complicated instead of sticking around and seeing what cool things they can do.
Standards are much higher than they were back then. You used to be able to get away with half assed coded servers. Now a days it's a dick measuring contest of who's code runs .000972 ms faster.
Wish we were all back in 2008 playing around with WinterLove and no clue at all what an IDE was.
The biggest issue I see with server's, Apollo included, is coupling around updating.
Player updating as it stands in all released server's I've seen "calculates nearby players, checks each for updates, creates and encodes updates", which naturally breaks single-responsibility. Updating should only "send updates to players", the players and the updates themselves should already be calculated beforehand in separate systems. Handling it this way also comes with the benefits that updates themselves can be cached and you only need to re-encode when something changes. No more, encoding updates every tick for every player just once.
By splitting the game tick into three stages; Input, Mutation & Output. Updates themselves are mutations and because they only mutate a single entity can be ran in parallel, and updating happens at a time when it is garanteed nothing more will change until the next tick, so it too can be parallized without any locks or issues.
No, it's like 4 clicks to load a build system project in a modern ide and there's videos on youtube if you get stuck.
These tools exist to make life easier and every project outside of rsps uses them.
Having now just starting to write content with kts I'm not convinced scripting is the best way forward for content development, it makes testing a lot harder, but I need more time with it to come to a decision.
Quite the opposite, TDD is normally faster in practise but feels slower when you do it. Also people often overlook the overhead of not having tested code and put it down to inexperience. How many times have you heard someone spend 2+ hours debugging one thing? That wouldn't be an issue if the server had proper testing coverage.
Blake always focuses on simplicity, K.I.S.S. However putting multiple listeners into giant "handler" classes isn't any simpler than individual ones.
83 classes isn't the issue, it's that they're always in one package; they're unorganised.
"build systems", "testing" & "modern server complex" all seem like psychological barriers to me, it's probably due to the lack of guidence or introduction when joining the community.
Thanks for the thorough response Greg appreciate the input. As for the build systems thing I think maybe just including a run file alongside the build system would help a little bit ? But yes as you point out some of these are definitely psychological barriers that are due to lack of guidance. I know I probably wouldn't have joined all those years ago if servers were the way they are today, it was hard enough setting the path variable back then lol.
A note on packaging what do you think is the most logical way to group event listeners. ? I've been thinking about it but grouping them didn't seem that easy to me.
Proper deployment with docker, CI etc... I will agree is far more work than a "simple run.bat". There's no reason a developer couldn't include a gradle run task bat with./gradlew build run
for simple deployment on a windows vps. I assume there's a Maven equivalent, and as far as I'm concerned it's not worth bothering with Ant.
Naming and organisation will always be down to personal preference, I'm always constantly shuffling things around, I see no issue with a structure like so:
I do think combining packets that have overlapping data and verification e.g entity option 1, 2, 3...8, map & minimap walk is fine even though it's not strictly the simpliest solution, SOLID after all are guidelines that can be ignored given appropriate discretion.Code:/entity/npc/NPCOptions /entity/player/PlayerOptions /interface/InterfaceActions
It isn't really a strong argument for or against something if it being in current servers or successfully in practice. We know that almost every production server does not have a great codebase. If it's currently used in our community is irrelevant. What we should do is take inspiration from the larger realm of software programs.
I lack knowledge to speak in regards to Multithreading. I just think (based on threads that I read) it is too much work for not much gain. 2,000 players actions being processed every 600 milliseconds (which is a lot of time) does not justify the need for multiple threads.
Side note, I remember once upon a time, for fun, I wished to try making a server using Concurnas which, like Kotlin, is a JVM language with an emphasis on multi-threading and concurrency.
Quite the opposite really. Build systems literally exist to not require much effort. If the argument of "simple run script is not provided" was even valid to begin with (I don't think it is), you can just run the gradle / mvn commands in your run script. Hell, even the run scripts would be easier with build systems than without (who wants to define all those classpaths when gradle build can do it for you?).
Idk, don't see your point here really.
I don't get what is trying to be said here. The topic is "scripting" but the description transformed into "language choice" rather than "scripting or not?" A lot of the community has ditched non-JVM languages for scripting due to the lack of true interoperability. Like, the lack of IDE support, the lack of "I call you, you call me," etc.
Now, as for scripting itself, I assume you mean the whole plugin system? Different terms. The community in general recognizes that plugins are beneficial, but its mostly been about who will take up the work in making a server to such a state where one actually uses servers with plugin systems. Notable projects include Apollo and RSMod.
Just because testing is "extra work" doesn't mean we can just dismiss it as development overhead. It is an even bigger production overhead having code that is untested. Unfortunately, Unit testing is not that prevalent in our community due to the coupling nature of most of our sources. Just try making a mock class for anything, like an Inventory class, and see what happens.
SOLID principles in mind while developing will lead to a much more flexible codebase. Refer to Unit testing response for a benefit with following SOLID principles whilst doing our object oriented development.
« Previous Thread | Next Thread » |
Thread Information |
Users Browsing this ThreadThere are currently 1 users browsing this thread. (0 members and 1 guests) |