Jump to content
  • Advertisement
Time4Tea

Java Looking for advice on Java game server

Recommended Posts

This is linked to another question that I asked here a couple of days ago:

I'm looking at making a client-server game with a game server programmed in Java. The game will be a 2D turn-based game (like a board game), with a maximum of around 50-100 games going on at any one time. So, the performance requirements are not very high. The reason I would like to use Java for the server are because I already have some familiarity with it and I would like the server to not be tied to one particular platform. I would also like to design it so that the client interface to the server is as generic as possible, so that the same server could be used with multiple different clients. For example, there might be a web-based client, or someone else might design a stand-alone 3D client application later on, using the same server.

So, I am looking for some advice on where to start with this, as I have very little experience with coding servers.

I was planning to use web sockets for the client-server connection, which apparently uses Java EE (Enterprise Edition), which seems to require the use of the GlassFish server. However, I have been advised that a fully-fledged application server, like GlassFish, may be overkill for a game server. So, here are my questions:

  1. Should I use something like GlassFish? Does it makes sense for the type of game server I am describing?
  2. If not, then what sort of networking protocol/library would experienced Java game designers recommend? Are there any existing, general-purpose Java game servers that exist, which I might be able to use as a starting point? (Or even free software/open-source client-server games?)
  3. Or, should I look at coding my own game server from scratch? In which case, again, what sort of connection type/library would be recommended?
  4. Does anyone know of any suitable introductory tutorials that deal with how to make this sort of game server in Java?

I guess my priority is probably minimizing the learning curve and the amount of time/effort involved, over performance. How much effort is this sort of undertaking going to require?

Thanks in advance! :-)

Share this post


Link to post
Share on other sites
Advertisement

There isn't really a lot of overhead to using a "bigger" server than you need. Yes, it will load a bit more code and use a bit more memory, but if it has features you need, that's probably OK.

There MAY be a cost to using a server that doesn't have a good match to your needs. For example, if you need to scale across more than one server instance, then if your application server assumes that applications are stateless web apps, you will have a poor match to requirements.

One common model of development is to build the servers as intermediate layers, using some kind of messaging system (ZeroMQ, Thrift, GRPC, protocol-buffers-over-TCP, or whatever) and then build a separate front-end/gateway for the particular kinds of communication protocols you need. Thus, you could use a Node.js server with socket.io for translating websockets to your server mechanism, you could use an nginx/PHP gateway to translate polled HTTP to your server, and you could use something in Erlang to translate between mobile phone UDP packets and mobile push. Or whatever other combination you want. You'd define game packets using whatever your RPC mechanism is, and implement that mechanism for the server. Define some way to map "game instance id" to "which server does this live on." Have the gateways know how to map traffic for a particular game instance to the appropriate server, and forward traffic/requests as appropriate. These gateways may also have some kind of semi-persistent store for session authorization state (or use signed tickets/cookies.)

The game servers would, in turn, talk to databases or whatever your persistent store is. This ends up being a four-tier architecture -- client tier, gateway tier, game server tier, and storage tier.

Of course, if you'll only ever use a single server, and don't need scalability, just rolling it all into one is simpler, by far, and costs less to get started, too (no need to spin up and manage multiple different server processes.)

The only general-purpose Java game server I've tried to use was Darkstar, and it ... didn't scale. I don't recommend it.

Share this post


Link to post
Share on other sites

@hplus0603 Thank you for your detailed reply. I know my question is quite broad - I'm trying to feel my way to a good place to start with this.

I'm not so sure about the 4-layer system that you describe though. It sounds quite complex and like it might be quite a lot of work to learn how to put all of that together. Sorry, I didn't quite follow what the advantages would be of using a 4-tier architecture, over a simpler 3-tier one. Could you please clarify?

In terms of the communication protocol, I think I've narrowed it down to some sort of socket (either websocket or TCP). This is because I want my game to have a turn timer, which the server would pause, if one of the clients got disconnected. So, because of that, I think I will need to have the persistent connection of a socket (as opposed to HTTP requests), so that the server can be aware of when a connection has been lost. Does that make sense?

So, in terms of whether it should be a websocket or TCP, the other thing is that I want the server to be able to connect to different types of clients. One might be browser-based, but others might not. Would either websockets or TCP sockets be better-suited for that? I assume that a websocket could be implemented in a client that is not necessarily browser-based? Otherwise, perhaps I could make my server able to handle both types of sockets, depending on the type of client that is trying to connect?

At this point, I think I'm leaning towards writing my own server, with just the functionality that I need.

Share this post


Link to post
Share on other sites

I didn't quite follow what the advantages would be of using a 4-tier architecture, over a simpler 3-tier one.

The fourth (gateway) tier can do protocol translation for you, so that the back-end only needs to understand one canonical protocol.

Additionally, if you have multiple shards/servers, the gateways can do the dispatch to the correct server for a player connection, no matter which gateway the player happens to connect to.

Yes, this is more complex, because it buys you certain kinds of freedoms and flexibilities, especially if you need protocol translation and if you're using TCP or HTTP connections. On the other hand, if you want the shortest path between client and server, three-tier is smaller and less complex.

If you need to talk to web browsers, and you need a connection that's persistent, then you need to use websockets. Else you should probably use TCP, because it's simpler and needs less supporting libraries. One option is to start with TCP, a 3-tier architecture, and not support web browsers, and when you need that support, you add a fourth tier that translates from websockets to your TCP protocol.

Share this post


Link to post
Share on other sites

One gotcha in developing a server-client application is that you can run into a chicken-egg situation. In order to test the server, you need a fully functional client. In order to test a client, you need a fully functional server. Which one do you develop first? Developing both at the same time can be time consuming if you do not have a solid protocol specification. If you change the protocol, you are updating both server and client code. What packets are being sent to clients when a player disconnects, when a player moves, etc. etc. Did the server respond correctly? Did the client respond correctly? What happen if they get out of synced?

There is a lot of details that need to be hashed out before your server and client applications can even reach their alpha status.

I have found out in the past that supporting HTTP can be helpful in testing some functionalities of the server, because HTTP is widely supported by the browsers. In other words, you have already gotten a fully functioning client, without the game logic obviously. Some people also recommend using telnet as your first client. However, I find telnet to be too rudimentary for testing once the logic gets a bit complicated.

Share this post


Link to post
Share on other sites

I don't think that's so bad. You typically develop a low-level framing protocol (what's at the beginning/end of a datagram, and how do multiple messages fit in.) That can be tested using unit tests, and then using two processes that just send well-formed empty packets between each other.

Then, you develop a message dispatch and serialization protocol -- for each message within the protocol, how do you know what data type it is, and how do you know who should get it, and once you know the data type, how do you know to unpack it. (And, conversely, how do you pack it.) At this point, you'll typically build some kind of simple reflection system on top of your language, that lest you describe each data type with simple macros or "builder" function calls once, and then marshal to/from the format. Again, this code can be tested using unit tests, and then using simple processes that send/receive messages of designated data types, without putting any gameplay behind it.

Btw, in this phase, some developers try using built-in serialization mechanisms in languages like Java, C#, Python, and so forth, and realize that those mechanisms have totally different design goals than games, and end up generating way too big packets. You will want to define your own packet formats, that rely on both sides agreeing on schema (so field order/types/names aren't needed in the packets) and then implement serialization using reasonably efficient byte packing.

Finally, you tie the gameplay to the messages (entities created/destroyed, players giving commands, entities moving, and so forth,) and at that point, you should be able to build bigger integration tests in your code (poke at the game code to generate the intended kind of events, make sure the right kind of messages are generated into the network code.)

Only after all this is done do you need to set up the full client/server integration test, where you need the "fully formed" (as far as you've gotten) client and server to talk to each other.

Share this post


Link to post
Share on other sites

I am going to answer specifically for Java & Websockets. I can't tell you whether this is the best technology choice or not for your game that's entirely up to you.

There is no correct choice here but there are a variety of solid options available to you. And by that I mean they're tried, tested, well(ish) documented and have active communities using them so you can ask questions online and reasonably expect someone out there will know the answer.

This is not an exhaustive list mind you. Just some of the more common options to help you evaluate:

  • Use a full-blown JavaEE appserver like Glassfish, Wildfly, TomEE, Weblogic, Websphere. This is the enterprise way to go, you have everything and the kitchen sink available to you. This is particularly useful if you think that you'll want to use other JEE standards for the purposes of managing logic & state, transactions, databases, etc.
  • Use a JEE servlet container like Tomcat or Jetty - Good if you are only interested in the web subsets of the JEE (like servlets & websockets). These can also be embedded so that your application can run standalone. Here's an example I found of Jetty embedded as a websocket server
  • Use a JEE server generator like Wildfly Swarm - This lets you pick and choose just the bits of the JEE that you need and lets you link them into your application so you can package the whole thing up into a single jar. Allowing for more light-weight servers when you only need a few JEE dependencies.
  • Use the JSR 356 (websockets) reference implementation - If you are simply only interested in running a websocket server using Java's websocket API but without any other JEE gumpf then this is how to do it.
  • Use the Play Framework - This is not JEE, it's not 'standard'. It's a Java & Scala web framework with a fresh and modern air to it. This is probably the newest player to the field.
  • Use Spring Boot - Spring has always been the main alternative to JEE. JEE has come along way in recent years but historically where JEE has been lacking features or was complex to use then Spring was easier, cleaner and more feature rich.  You can use the Spring Boot websocket starter to get up and running quickly.
Edited by dmatter

Share this post


Link to post
Share on other sites

@alnite and @hplus0603: Regarding the client/server development, what hplus0603 said is more-or-less the sort of thing I had in mind. I think I will have to develop them both in parallel, starting very simple and gradually building up. The first thing I will probably do is go through some tutorials for whichever web server option I decide on and try to make a very simple client to interact with it. For example, just a web page with a single button that sends a request to the server when it is pressed and then displays the response from the server. As hplus0603 says, I imagine I'll probably have to get the communication protocol side working first, before I try to build up to more complicated functionality and eventually do the actual game coding.

Although, I haven't done any of this before, so it seems like it will be a lot of work and a lot of things to learn! :-)

Share this post


Link to post
Share on other sites

@dmatter: Thanks for your post and for listing all those options - many of them seem very interesting. With so many options available, it seems difficult to figure out where to start. Which one would you recommend to someone who is very new and inexperienced with client-server web app design?

Of those options, I think I'm leaning towards the Jetty servlet container, as it seems to incorporate websockets and seems to be more dedicated towards web applications. So, with that, my game server would be implemented as a Java servlet, running inside Jetty? Does Jetty also provide functionality for user authentication and communicating with a MySQL database? Also, how would I implement the other pages of the website with that option (i.e. outside of the 'game' application page)?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
  • Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By DevAndroid
      Hello everyone,
      I'm trying to display a 2D texture to screen but the rendering isn't working correctly.
      First of all I did follow this tutorial to be able to render a Text to screen (I adapted it to render with OpenGL ES 2.0) : https://learnopengl.com/code_viewer.php?code=in-practice/text_rendering
      So here is the shader I'm using :
      const char gVertexShader[] = "#version 320 es\n" "layout (location = 0) in vec4 vertex;\n" "out vec2 TexCoords;\n" "uniform mat4 projection;\n" "void main() {\n" " gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);\n" " TexCoords = vertex.zw;\n" "}\n"; const char gFragmentShader[] = "#version 320 es\n" "precision mediump float;\n" "in vec2 TexCoords;\n" "out vec4 color;\n" "uniform sampler2D text;\n" "uniform vec3 textColor;\n" "void main() {\n" " vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);\n" " color = vec4(textColor, 1.0) * sampled;\n" "}\n"; The render text works very well so I would like to keep those Shaders program to render a texture loaded from PNG.
      For that I'm using libPNG to load the PNG to a texture, here is my code :
      GLuint Cluster::loadPngFromPath(const char *file_name, int *width, int *height) { png_byte header[8]; FILE *fp = fopen(file_name, "rb"); if (fp == 0) { return 0; } fread(header, 1, 8, fp); if (png_sig_cmp(header, 0, 8)) { fclose(fp); return 0; } png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fclose(fp); return 0; } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); fclose(fp); return 0; } png_infop end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); fclose(fp); return 0; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); return 0; } png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); int bit_depth, color_type; png_uint_32 temp_width, temp_height; png_get_IHDR(png_ptr, info_ptr, &temp_width, &temp_height, &bit_depth, &color_type, NULL, NULL, NULL); if (width) { *width = temp_width; } if (height) { *height = temp_height; } png_read_update_info(png_ptr, info_ptr); int rowbytes = png_get_rowbytes(png_ptr, info_ptr); rowbytes += 3 - ((rowbytes-1) % 4); png_byte * image_data; image_data = (png_byte *) malloc(rowbytes * temp_height * sizeof(png_byte)+15); if (image_data == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); return 0; } png_bytep * row_pointers = (png_bytep *) malloc(temp_height * sizeof(png_bytep)); if (row_pointers == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); free(image_data); fclose(fp); return 0; } int i; for (i = 0; i < temp_height; i++) { row_pointers[temp_height - 1 - i] = image_data + i * rowbytes; } png_read_image(png_ptr, row_pointers); GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, GL_ZERO, GL_RGB, temp_width, temp_height, GL_ZERO, GL_RGB, GL_UNSIGNED_BYTE, image_data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); free(image_data); free(row_pointers); fclose(fp); return texture; } This code just generates the texture and I store the id on memory
      And then I want to display my texture on any position (X, Y) of my screen so I did the following (That's works, at least the positioning).
      //MY TEXTURE IS 32x32 pixels ! void Cluster::printTexture(GLuint idTexture, GLfloat x, GLfloat y) { glActiveTexture(GL_TEXTURE0); glBindVertexArray(VAO); GLfloat vertices[6][4] = { { x, y + 32, 0.0, 0.0 }, { x, y, 0.0, 1.0 }, { x + 32, y, 1.0, 1.0 }, { x, y + 32, 0.0, 0.0 }, { x + 32, y, 1.0, 1.0 }, { x + 32, y + 32, 1.0, 0.0 } }; glBindTexture(GL_TEXTURE_2D, idTexture); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferSubData(GL_ARRAY_BUFFER, GL_ZERO, sizeof(vertices), vertices); glBindBuffer(GL_ARRAY_BUFFER, GL_ZERO); glUniform1i(this->mTextShaderHandle, GL_ZERO); glDrawArrays(GL_TRIANGLE_STRIP, GL_ZERO, 6); } My .png is a blue square.
      The result is that my texture is not loaded correctly. It is not complete and there are many small black spots. I don't know what's going on ? It could be the vertices or the load ? Or maybe I need to add something on the shader. I don't know, I really need help.
      Thanks !
    • By LuigiLuigi
      I've been working on my own Metroidvania via GameMaker Studio for the past few years. You play as a bat named Ralph as he goes on an adventure to obtain 7 Crystal Medallions hidden in dungeons with the help of a cult known as the Crimson Fog. Along the way, there will be quests unlocked in Cedrus Village as you progress through the game. I've managed to complete a demo of the game up to the first dungeon and boss fight.
      I have only a PC build available, and the only gamepads I managed to install were Logitech Precision and Xbox PC gamepads. I had some trouble on gamepad detection though, so they may have connection issues. The desktop controls are similar to Terarria's control scheme if it's too much trouble. I don't have any music at this point, I'll need to get someone else to compose it later on. The music I make isn't bad, but it doesn't fit the aesthetic that well.
      I'm really hoping I can get feedback regarding the general content.
      Crimson Fog.0.2.zip
    • By Alexander Winter
      Jumpaï is a game about creating platformer levels and playing them online with everyone. Will you become the most popular level maker or will you be a speedrunner holding world records on everyone's levels? More into casual play? No problem! You can happily play through the giant level database or chill at people's hub. Meet new people, make new friends, learn to master the game by asking pros or ask for people's favorite tricks on level making. Download here: https://jumpai.itch.io/jumpai Discord: https://discord.gg/dwRTNCG   Trailer:      (The following screenshots are older but still a bit representative)  





      Unlike other games of its genre, Jumpaï is about playing levels with everyone in real time. You have the fun to see how other people are playing and get to realize you are not the only one failing that jump!

      The game is currently into development and still have lots to do. I am looking for people willing to help how they can. Developer? Graphist? Play tester? Sound designer? Game designer? I'm welcoming any talent. The project is so big I have a lot of work to do in all areas. Server backend, UI/UX, Game networking, Gameplay and even the website some day. As you can see from the default buttons, the game has been made with LibGDX. This project is a perfect opportunity for you to get better in various fields as well as showing off your skills.

      If you plan to take an important role into the development of the game, we will discuss how you will get paid once the game generates money. Note that I'm not working on the game full-time. I'm studying full-time and working on it is a hobby. The project has started in november 2016 and experiences heavy progress.

      So, are you interested? If so join me on my discord https://discord.gg/dwRTNCG and I'll answer all your questions.

      Additionnal screenshots:
       



       
    • By Shtabbbe
      I've had a game idea for a while, and I wanted to finally try to create it.
      Its a 2D open-world tile-based MMO. The concept is it is one world and multiplayer only, so everyone shares one world no matter region, platform, etc.
      I am having problems finding out what to use to start development, I tried Unity but saw some of the negatives and refrained and now im stuck, could anyone recommend some intermediate friendly 2D engines that can support what I am looking for? Preferably in languages that are or are somewhat like Java, C#, Python, JavaScript, Lua.
      Thanks for your help, im very new at this if you cant tell
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!