I am working on a stupid-simple jME3 game (an avatar can navigate a simple/small 3D world and interact with simple objects) and am tinkering around with the possibility of conducting automated functional/acceptance testing on it. I’d like to be able to run automated “tests” against this game, where each test:
Defines the initial state of everything in the game (the avatar’s position, game items, world state, etc.); similar to a JUnit @Setup method or a Spock given: block label
I will create a User API that the test can programmatically drive; this allows me to do things like make the character/avatar walk, jump, pick up an item, etc. Each test will use this User API to actually conduct tests
Tests pass/fail by evaluating some final assertion (or set of assertions); I will be able to query any aspect of the game/world/user state and make these assertions
I want to get this working as a proof-of-concept first, and then plan on integrating it with standard test frameworks like JUnit or (more likely) Spock. Although I currently don’t have the need, I’d like to try and evolve this capability so that I can run several tests concurrently at the same time (if humanly possible).
The main thing here is that these tests will ultimately be ran on a headless (Linux) CI server. So I don’t require (or really, even want) graphics/visualizations. My hope is that there is a way to run jME3 “headlessly”, such that the game logic (that I write) as well as the core engine code can run totally normally, but just aren’t pumping graphics anywhere.
So I ask: Is it possible to run jME3 in a headless manner, where the specific use case here is executing automated tests on a CI server? If not, why?!? And if so, how?
Just curious here: with jME3, what does the architecture/topology of a multiplayer/networked game look like?
I would have thought it would be something like this:
Each player is running an instance of the jME3 game (the ‘client’) on their PC
A server is running somewhere (AWS, data center, wherever)
This server’s sole responsibility is to relay inputs from one connected client/game to all the others
So if a user presses a button to walk forward, the client/game relays this movement to the server, who then broadcasts it on to all the other connected clients
The other connected clients receive a message (from the server) that a particular peer (in control of a particular avatar) has walked forward, and each of them - on their own - react accordingly, calculating and updating tha player’s/avatar’s position
But from that link you sent, it’s almost as if:
Each player runs their own instance of the game/client on their PC, like normal; but
The central server is just another instance of the game/client running in that headless state
Again, just curious: which of these two scenarios is the case? Or is it something else entirely different?!? Thanks again!
For almost any game, you really don’t want to use the architecture you described. The reason for this is that the server is just forwarding what the players do without anything to prevent cheaters, and you also have a high probability of data races. As an easy example, suppose you write an FPS like this. A compromised client could auto-shoot at any enemies in sight, and making the clients smart enough to protect against this (and more importantly, agree on who’s cheating and who’s not) would be quite difficult to do. For data races, consider the case where two players shoot at each other at the same time. Due to network ping differences and packet loss/reordering, the messages will not reach the server at the same time and will not reach to the clients until even later. In this case, it’s very easy to have clients that both think their player hit the other guy. Now you have a conflict where two clients think they scored a point, where really only one did. Sure, you could come up with some elaborate way to sync the clients so that these cases are taken care of, but (a) this kind of synchronization is extremely difficult to get right, and (b) it’s likely that any solution is very costly in terms of time. Yes, it’s possible to build a synchronized, distributed, peer-to-peer architecture that will work, but in terms of runtime performance and development time (and ease), you will do much, much better by making the server authoritative. This means that the server is running some “world simulation,” and may or may not even be running as a standard jME SimpleApplication. Whenever somebody running the client does something, instead of the client “doing it” the client sends a message to the server saying “Player X wants to do Y,” the server checks if it’s a valid thing to do, updates its internal state, and then notifies Player X’s client (and anyone else who is in range to see/should know/etc.) that Player X just did Y. This makes it far easier to prevent cheating and ensure that all clients stay in sync (or that out of sync clients don’t mess up everybody else).
You certainly can run a server as a headless (authoritative) jME application, like you mentioned, but it’s not strictly necessary. The server for my project uses a totally different internal architecture and just embeds SpiderMonkey (the jME network stuff) for communicating with the client (which is a very typical jME application that gets all its data about the world state from the server). That being said, unless you can identify a very good reason why your server shouldn’t be a jME application, you probably want to write your server as a headless application. jME’s architecture gives you a lot of power and gives you a lot of functionality that you easily find you need/want later down the road.
Well you don’t want to broadcast user actions, for sure. You process the action on server and broadcast its result. I’d tend to resemble even player interface on server actually - to prevent fake players creation (i.e. bots), than to give player even more freedom. Disclaimer: I’m not there yet, in practice, but that’s an approach that I consider real, when I think of it from time to time.