On to the engine
In this part, I’ll describe how the game server actually works.
This was written in one sitting. I didn’t edit it very much. Excuse it being poorly formatted, I’m just really busy!
When I first started on the MMO server a year ago, I knew that in the future I might want to have a 3D MMORPG sort of like Ragnarok Online but with hentai on it.
I knew I could make something that doesn’t care too much about what the client is like, if it’s open ended enough.This has the advantage of having LEWD to test having thousands of people playing on it(when we get to that point), so I can profile it and get it performing great and running stable before the next game starts being made. In the context of programming, profiling means to get an outline of performance.
It also has the advantage of having a set of tools developed to make content for LEWD, and to have those same ones to use in the next game. This is pretty typical with most companies, where they stick to a certain engine because they’re familiar with it, and know its capabilities and limitations, instead of making and/or learning new tools.
This is great for me and all, but in making something that’s open ended enough to be used either for this text adventure game, and a future 3D MMORPG or whatever I decide on next, it means it’s open ended enough to be used for a wide variety of other games, like your game, and for those to be web based.
I’ll have more about what the process of making your own game on the engine would be like, and what it’d require, in part3.
Lets look at sort of the foundation, the “maps”
It looks like the Wilderness area in the game, except in color. The color is seen in the dev tools, and by the engine. It’s actually exposed to the client, too, and can be used to style the tiles.
This is really not about being a visual thing; it’s to store data.
Maybe you’ve seen different “maps” in other games. Normal maps, spec maps, diffuse maps, cost maps, biome maps. It’s a bit like that, especially the later two.
I knew this was something I could scale up really dense to work for collision and event detection in a fully 3D game with the usual smooth movement you’d have there, but can also be used to store data like it’s a 2D array to use the same thing in a side scrolling game. It doesn’t matter how the client ends up seeing it, what matters is that it makes visualizing that data easy in development tools.
But if you want them styled? The server provides information to make that easy. I don’t want sprites for LEWD, but it’s done this easily:
The game already assigns some classes to elements to make them.
CSS, or Cascading Style Sheets, is the markup language used on web pages to assign styling to elements. There is a selector, and then the properties and values. It’s simple, and there’s lots of resources on the internet to understand it.
Here what I’m going is setting the background to use that image url for all squares with the b80 glass, or blue 80.
So you can see, you can restyle things just like a third party theme for a website, like 4chan and reddit themes. It’s the same concept if someone was doing their own game, and wanted to add graphics.
Setting a background for a sprite tile is one example. You can add elements to the squares as well. This is just a line of javascript that you’d have run after the map building code runs.
Then you end up with something like this, after also adding styling to some other areas:
I should have used an example for like a big tree that overlaps them, but I didn’t want to make that much art. >_>
Now, that’s one example.
What I want for LEWD itself is to have a full sized background for the entire Zone, in which case I’d just be setting a background image for the whole thing, instead of individual sprite tiles.
And there’s no reason why a 2d grid has to be displayed to the player at all. Again, that’s just how data is arranged on the server and in the tools. For LEWD, it just happens to be a pretty literal translation.
The core of the engine is a highly variable, persistent world that efficiently modifies content and figures out what content to deliver based on a wealth of criteria, as well as making sure player actions are all legitimate(not cheating). It’s made to handle tens of thousands of people on a single server, so I’ve been really anal about performance.
It might be less open ended than some engines, really. It assumes you want triggered Events. It assumes you have a player, items, and quests as well.
You don’t have to use all of those, but there also isn’t a solution for adding new objects types at the moment. But you can repurpose the same data with how the client interprets it.
If someone wanted to make a 2D fighting game, it’d be best to have all the combat be client side, and the server just be triggering the starting of it with Events.
There currently is no sort of combat engine on the server, and even if there was it’d add a strain. It’s best to simply make it possible to cheat/hack in the combat, and have it all be client side.
I do plan to add something like that at in the future, but it’s not coming soon.
Anyway, on to more of how it works, to be so efficient.Lots of what is on the web is programmed in PHP, or something like that.
LEWD’s game server is written in Node.js. It runs on Google’s V8 Virtual Machine, which basically runs Javascript on the server almost as if it were native C. It’s by far the fastest virtual machine; nothing else is close. Being Javascript makes writing code easy so I can make this so quickly, and being run on that VM helps make it efficient.
It’s only as efficient as the code itself, though.
The game server is based on a lot of other things I’ve learned in the past, even though I started from scratch on it.
In most web apps, they use a database like MySQL or Postgre to pull information from. These are great databases, that are capable of so much, but really bloated and not nearly the performance I can achieve with my own specialized database.
While I am using one of those databases with LEWD, it’s only to store data to the disk permanently, in the event of a crash and so it’s still there after a server restart, as my custom database stays in memory. When a computer is restarted, or the custom database is, all the information is gone, so it needs some permanent storage.
The other reason is that most cheap servers that someone can host a website on has support for a database, so this gives a way for others to store that data on their server for their own games, while a different file system might not even though it would work fine for me.
For my custom DB, content is fetched at a rate of roughly 800,000,000(that’s millions) per second.
With MySQL… eh, 1500-2000 per second or so? You can optimize it to go faster, with memory caching. You can even have an SQL database be entirely in the memory like mine, but you’d need more memory because it’s far more overhead. You can see benchmarks of MySQL in the hundreds of thousands of operations per second, but they aren’t real world examples and they aren’t on a $20 server.
While the database is currently using around 1.6mb of overhead on the disk for the content. Very little, yeah, it’s just text and such and the game is lacking content at the moment. But my custom database uses only about 0.15-0.2mb of memory, when it contains a lot more information after it’s parsed what it’s taken from the database to turn it from JSON into game content.
Keep in mind, that’s just the overhead for the stories, there is more than that.
See, the way it delivers content is very similar to how content is delivered on a forum, but just imagine if every time you selected an option it took as long as it takes to load a page on a forum. That’s way too slow. For example, loading a thread on forum.playlewd.com took 2.75s when I just tested it. As for LEWD, it’s hard to measure, but your ping is going to be more than 99% of the delay.
Now, for the LEWD game server, here’s the result of my quest of being anal with performance:
- 0.436951115 seconds, received request to move from player
- Server verifies the player
- …checks if the player is allowed to move
- …sends basic always-send data about the area that’s moved to
- …sends an update to all other players in the Zone that the player has moved to an area
- …rolls Events for the player to see if any need to be sent.
- 0.439237088 finished sending the new scene writing, options, etc to the player.
So 0.0024s compared to 2.75s. It’s doing the same sort of things a forum does to load a page. A forum has to verify the user, check that they can view that post, update some information, personalize it the page to different settings, and then finally send it to them. It’s just that the LEWD game server is 1000 times faster at doing it.
Realistically, the delay is 0.05s-0.3s because of someone’s ping with that 0.0024s added.
There can be delays when selecting options and such since they have to be computed one page at a time on the server, and the player’s ping is involved each time. I’ve been thinking of ways to cache this, so for people that do have slow connections it’d only be slow the first time. I know of many ways, it’s just a matter of selecting and implementing the best one. One is to use IndexedDB or WebSQL, and another is to deliver scenes as JSON files with a hash at the end of the url.
Lastly, a bit on how the server set up works:
I thought about saving this for the third part, since it has a lot to do with how someone would be setting up their own game, but it has a lot of overlap with how the server actually works.
If it was just for me to use, I’m not sure I’d do it this way. But from the start, I figured it might come to a point where I want to set something up where others can make their own game on the same engine. Because of this, I decided I’d have part of it be a traditional webserver with PHP just for the development tools, and to deliver the static pages, and then in those static pages it connects to the game server to handle the real time messages. I’ll break it down.
- The game server is primarily what’s been described here. That’s the super efficient part that handles the real-time data going back and forth from the player to the server and back to other players.
- The database is where a site’s user accounts(at least necessary to authorize who can use dev tools, but can also be required for a persistent game) are stored, as well as the permanent storage for what is saved in the dev tools, and changes to the world.
This can be integrated with the web server, on the same server, or it can be something like RDS. Either way, it must be remote accessible for the game server to communicate to it. - The web server is just a basic web server. You can get a php+mysql shared host server for like $10 a month, and that’s the only thing needed besides the game server. This is the part that delivers the initial pages to the player, before the game server takes over.
This will give something that’s more familiar to people who have already hosted a forum or something similar before, since most people understand how PHP works but not how Node.js does. Plus, all that game server Node.js has to be kept on my end since it’s closed source.
It’s actually rather beyond my expectations. I was just so anal about performance from the start because I knew what I was doing, with how content can change so much based on series of events, could have a high overhead. I wanted to make sure I could do that, and have thousands of people playing without lag.
From what I’ve seen so far, far, 50 people playing the game only uses about 5% of the CPU and memory of this little $20/month server, and I still have some optimizations in mind.
By contrast, I’ve heard people with Space Station 13 servers using Byond can only handle two or three dozen on a $50/month server, and I’ve trying playing it myself and it’s so laggy.
I’m actually kind of sitting here wondering what else I can go over to explain why I get such good performance, while other programs are so bad. I guess it’s just often that some people write so much code that does so little, and I try to write so little code that does so much.
Future plans include departmentalizing different things so they can run on separate cores, or separate servers, all connected together. When I start work on my 3D MMORPG, and I have a combat engine running on the server to make sure people aren’t cheating/hacking, there’s going to be increased load and I’ll have to split things up between servers to have that and still have tens of thousands or hundreds of thousands of people playing on a single shard.
This, the whole crazy performance, is just another of the reasons I think this is ideal, and I really would like to push it forward to make it available to people that wants to make an applicable game.
Besides the development tools, this is the other reason to use this game server. The performance is just crazy good. Even if someone does have the knowledge to make their own web game, say with PHP or even Node.js themselves, with this the performance is already nailed as good as it can get.
Any perceived lag is just high pings from the client. I’m going to be adding interpolation to alleviate much of that.
The downside is, yes, that you have to host a webserver, and a server must be hosted for the game server by me, but that cost is very low for what the owner of a game and the people that play it get. The owner gets easy to use tools, and lots of potential in an engine. The players get to simply go to a webpage in order to play instead of having to jump through any hoops with downloads and dependencies.