[SGS] DarkShooter

First off, I don’t know how far I will get with this :slight_smile: but I was thinking about a small home project to have a play with the SGS as it the the newest, shineyest thing around :slight_smile:

I’ve read through the tutorials and think I pretty much ‘get it’ howerver I do have a few questions in my mind. I can see how you would do a MUD like game, (cos that is in the examle :wink: ) or an EVE like game where the server is effectivly responding to user input in the form of commands. To some extent WOW too but I’m not sure on collision with terrain (see below).

What I’m not sure about is how you would do a more action orientated game (with dynamics and colission server side). I think this may be related to the physics question post sorry if I’m crossing topics.

With this in mind I have decided to try a little 2d shooter game (hence DarkShooter :slight_smile: ), very similar I supose to something Kev wrote a few years ago (Astroprime) for reference for those of you that remember it. I don’t intend it to to be a ‘game’ more a learning experience.

What I basically have in mind is to fly a little space ship around and death match with other players/enemy ai’s. There will be a few seperate ‘Sectors’ that can be jumped too. not much more than this. Collision isn’t intended to be very fancy, just circle to circle.

So my questions are:

  • how to regualary update position/perform collision on the server, as the examples I have seen so far just react to event from the client
  • how to regualary send info to the clients
  • how to get input (key presses) from the clients
  • how to keep the clients relativly in sync (to cut down on jumping)

From looking at the javadoc, my initial naive guesses about an approach are:

I think PDTimer is my friend to do regular updated server side (but I’m not sure how to use it, I think there may be a commented out example in the Hack code).

Basic architecture is to have a ‘Sector’ GLO that contains a load of references to ‘Actor’ GLO’s (space ships, asteroids, bullets etc). Player and AI’s will control the ‘Actors’ which will manage state (position, velocity, damage) etc

So to perform the dynamics (I hesitate to say physics) and collision on the server I would set up a regular timer to update these calculations. Basically for each sector the timer wakes up, gets all the Actors, update position perform collision, send any results to the players in that sector. I think this would have to be a GET.

To send info the the players another timer that looks at all the positions of actors in a sector (PEEK?) and sends pos and velocity to the clients. (so the clients can interpolate).

I’m really not sure on sending info from the client tot eh server, I can’t see that every keay press is viable but lets assume that for now.

keeping clients in sync. hmm. may be if the positiont hat comes in from the server is different to that the client thinks it should be the client ‘tends’ towards the position it should be so it dosn’t jump. (I think this has been discussed here before, probably by Kev).

So as I said this is pretty naive but is just initial thoughts from reading the docs and skimming the code examples. Any comments on this approach to using SGS?

Sorry it ended up so long.

Cheers
Dan.

Maybe a nice first step would be to separate what you can expect SGS to solve for you from things it can’t possibly solve.
Synchronizing between server and client is not an SGS problem, all it adds to solve that problem is a protocol-agnostic and optionally reliable communication channel. There are multiple possible solutions to this problem like dead-reckoning etc. But to not bloat the thread it would probably be wise to concentrate on SGS related problems?

I believe you’re right that subdivision into different sectors would be optimal.
This subdivision could be conceptual or geographical in terms of the game world.
Each host could then assume “ownership” of one or more sectors.
Inter-sector get() operations should be kept to a bare minimum but can’t be completely avoided as objects might move between sectors or otherwise influence objects in other sectors.
Old-skool sectors with “portals” are trivial: Only players and their attached objects (inventory, spell affects etc.) move between sectors. Seamless sectors are probably a must for any serious MMORPG. Obviously inter-section information flow management is critical here.

You’re talking about jumping between sectors so let’s assume we’re talking old-skool sectors - this is probably a good place to start as [postulate] every old-skool problem must also be solved in seamless subdivision [/postulate], so why not solve those problems first?

Hi

The problem with SGS is that you can’t assume ownership on one server. The whole backend knows about every sector.

Endolf

You’re right, you can’t enforce ownership, this is why I put ownership in quotes.
But a clever design could respect it as much as possible.

A paradigm-shift is needed to utilize SGS properly - patterns/concepts like game-loop etc. must be translated / rethought to create something that fits into the new framework.

Firstly thanks for discussing :slight_smile:

I was thinking of ‘Sector’ as more a game concept as in teh area of space round this planet/sun/spacestation that can be jumped to through some sort of hyper-space. I gon’t care what server it is on or if it is split over many. I don’t think, from what (limited) amount I know about SGS, I need to.

I must admit that my post was abit of a brain dump so not well organised.

What I wanted to try and discuss what SGS gives us all of this how would I use it for this type of project. My main question i suppose at this point is “Am I supposed to use PDTimer to set up reoccuring tasks from dynamics to collision to client updates?” and “How do I use it? :)”

The other thing about deadreconing etc were mor thing I know I’m going to need to look at. I also assume that these scanario’s have been thought about byt eh SGS designers. I wondered if there was a reccomended way of approaching this type of game with SGS as a back end.

Hope this make sense Im just trying to clarify my thoughts and hopefully promtoe some discussion around actually using SGS.

Regards,
Dan.

[quote]A paradigm-shift is needed to utilize SGS properly - patterns/concepts like game-loop etc. must be translated / rethought to create something that fits into the new framework.
[/quote]
kinda what I was trying to discuss with this, for now hyperthetical, DarkShooter project I want to try and write time permitting.

Collision is a seperable problem from general physics. BattleTrolls does server side collision cheat detection (I know, we’ll get it otu to you soon.) It does this using a WalkMesh, which is a simplified form of the geometry used just for blocking detection. You cn think of it as a blocking map which, instead of a grid, is made up of free form tri-angles. (Thsi is how NWN works and we just lifted their data for our demo, with their approval.)

In general, for responsiveness reasons, my sugegstion on any action game is to do local collision/physics and server side sanity checking for cheating. This allows you to decouple the server side response from your game response and get better local responsiveness.

Soudns cool, one fo my gednaken experiments whiel designing the system was space-wars. Be aware though that top-dpown 2D is actually harder in many ways then first-person. First person games have a much mor limtied view of the world at any given time and thus can “cheat” in ways that top down games can’t.

In general, for top down internet games, momentuum is a life saver…

Use the PDTImer utility class. My initial recomendation is to give each object, or at least scalable groups of obejcts, their own callback. This will allow those callbacks to be spread about the back-end ona multi-server stack.

Keep in mind that in order to have parallel processing, you need to avoid common locks. If every update needs to GET the board, then they cannot operate in parallel. In space wars what I did was just keep the list of objects in the board but let each object keep its own position. Update logic looked like this:

(1) GET my ship and Calculate new location
(2) PEEK (not GET, PEEK does not lock the obejct) the board for the obejct list
(3) Iterator over the GLOreferences in the list and…
(3a) PEEK each referenced object and compare with my new position for collision.
(3b) IF Collision then GET other object and do explode() on both it and me

Note that there is a certain in-built indteerminancy here. PEEK gets you the last comitted state, the object may in fact have moved from that location by the time you check. This is similar to the point sampling problem in movign and collision detection on a frame byframe basis ona client and the same solutions apply (eg dont move to much in any one update, calculate and check “in-between” positions, etc)

  • how to regualary send info to the clients

Send the info as a result of the timed calculations above.

  • how to get input (key presses) from the clients

I wouldn try to communciate key-presses, that kind fo low level info is very latency sensative. Instead, Id do it the same way 3D vehicle sims do and calculate currentr potision and movement vector locally and to the serve along with a time stamp.

  • how to keep the clients relativly in sync (to cut down on jumping)

Thsi really gets inot the same latency hiding tricks as a first person vehicle sim. As i mentioend above, momentuum is your friend, if it takes time for the ship to respond to chnages in motion then it gives you a lot mroe 'slop" to hide things in. Just like a 3D sim, you are going to do prediction based on last received position and momentuum and then correct at the next update.

Shoudl be fairly straightfoward,a re there no Javadocs for it? If not we’ll have to create some and get that up…

Also there shoudl be soruce code for PDTimer in theSDK, so you coudl do a javadoc yourself on it…

Basic architecture is to have a ‘Sector’ GLO that contains a load of references to ‘Actor’ GLO’s (space ships, asteroids, bullets etc). Player and AI’s will control the ‘Actors’ which will manage state (position, velocity, damage) etc

See above, GETTing all the actors would work fine ona single CPU, single slice system, but it will not scale.

I believe you coudl do this as part of your update. When you finish your update, send the new position and mvoement vector. (and a time stamp)

See my suggestion above.

Well if you’re doing an update of the objects I don’t see any way around a GET ?

Excellent Jeff thanks this is just what I was looking for :slight_smile: now all I need is time :slight_smile:

With regard to PDTimer it is part documented. I’ll have a look itneh API fro soem more details just liftign from javadoc that is there:

GLOReference addTimerEvent(SimTask task, SimTask.ACCESS_TYPE access, long delay, boolean repeat, GLOReference target, java.lang.String methodName, java.lang.Object[] parameters)

I assume that SimTask is the task you have grabbed when you set it up.

ACCESS_TYPE I assume is in the api (I’m guessign somthignlike GET, PEEK etc) but wat willthis be for?

delay time between updates I assume in millisec, what controls the time in the background the 1.5 high res timer?

repeat? I assume ture to loop false to just be woken up once.

target: the GLOReference to wake ip on a timer event

method name: the method to call on target when woken up?

parameters? a list of arguments to pass to the method?

void removeTimerEvent(SimTask task, GLOReference eventRef)
cancel the timer?

void start(SimTask task, long heartbeat)
start the timer running?

void timerEvent(long eventID)
? not sure on this one.

Also why do you create the PDTimer with a SimTask and then have to specify SimTask in most of the other methods?

Again thanks for answering I’ll read through the post more to make sure i don’t miss anything.

Cheers,
Dan.

I think you will have doeen a GET on the object you are dealing with which you will update, you are just PEEK ing on the rest to read their position/bounds/whatever info you need. I think.

EDIT :

Although if you do find you need to modify somthing you could always get it then I suppose

SimTask is your current SImTask at the tiem you make the call (that which SimTask.getCurrent() returns.)

There is an ENUM for these. This is what klind of access the object the timer calls back will be called with.
Think of it this way, the timer hodlsa GLOReference to your object to be called, this is what it does with that reference in order to call your object.

Actually I think its in seconds. At the moment thats hardwired in PDT thpugh we’ve talked about setting it fro ma property.

The actual heartbeat timer in the current stack is using System.currentTime Millis().

When start is called, a numerb fo seconds for a tick is passed in. This is the resolutionof PDTimer, so a 1 would be 1 second per tick, a 5 woudl be 5 seconds per tick.

You can alsways re-write the PDTImer as I believe source is included to use finer reolsution BUT you are going to risk putting much greater load on the system as a result.

yup

Yes

yep

Exactly

yes, your app calls this in its Boot method.

Thats actually the callback from the heartbeat manager in the stack. Its not a PDTimer user method.

because the lifetime of a SimTask object is only for the life of that task in which it is fetched. This is documented in the server coder’s guide.

[quote]In general, for responsiveness reasons, my sugegstion on any action game is to do local collision/physics and server side sanity checking for cheating. This allows you to decouple the server side response from your game response and get better local responsiveness.
[/quote]
It also allows for client cheating. If you want cheat-less physics-based games, you have to run physics on the server side. If you want non-physics-based games (like EverQuest or WOW), you can make them cheat-less without full server-side physics.

The non-determinism in simulation means that a lockstep communications model (as used in some physical MMOs like City of Heroes and in RTS-es like Warcraft III and Age of Empires) won’t actually be possible. This means that you can’t really fit a large world on a narrowband channel. What is the current thought about this limitation?

When it comes to scalability, keeping the entire collision mesh for the entire world on every physical server would be un-wise. You want objects that collide with a certain part of the world to be run on servers that keep that part of the world resident. Is there enough automatic object migration to make this happen? Can you talk about how objects will move between physical server processes, and what determines when this happens?

The trick is not all object have to be updated by the same task. By splitting it up you get parallelism.

It also allows for client cheating.
[/quote]
No it certainly does not. try re-reading the paragraph.particularly the part that says “sanity checking for cheating.”

This is what we do in JNWN. Client side collision test. Server side cheat detect. Both test the WalkMesh, its just that the server is doing it after the fact.

Um Ive played a LOT of COH. I do not believe it is in any way lockstep based on the behavior Ive seen which includes reliably fast local responses to motion physics and ocassional roll-backs on position when latency getts too extreme. With CoV Cryptic brought in Havok but it is STRICTLY local and purely for effects such as the shattering bank vault door.

If you have a hard reference to the contrary please present it.

As for RTS’s, see Kev Glass’s lock step approach discussed ina nother thread. very clever and decouples you from latency spikes.

Please explain the limitation you think you see in greater detail and Ill be happy to address it.

The SGS does notkeep data in slice server memory. It floats it through an extremely fast dsitributed database on the back end.

Having said that, one giant walk mesh would be a bad idea anyway and we dont do that. In JNWN we store the walk mesh data on a per-tile basis.

No server keeps any part of the world resident. All the servers can access the entire data set,

This division of data by virtual space into memory of physical servers is exactly what causes all the worst properties of MMO design today.

The ObjectStore is a very very fast distributed in-memory database. The current full scale implementation is based on a Sun technology called HADB. Tasks pull objects from the object store as needed and puts them back at the end of a task. (An SGS backend has the agreeable property of running in a serious machine room with a nice wide back-end pipe between systems and full control over its useage.)

We also can move users between slices if there is too much contention between slices for common resources.
Much more detail Im afraid gets into Sun proprietrary stuff.

Obviously you would only GET the objects that are updated - with sectors this would be objects “owned” by the sector to be updated (for object types that rarely change state an initial PEEk as you suggested before would probably be optimal) + objects from other sectors whose state is updated by interaction with objects from this sector.

Again Jeff thanks,

[quote]When start is called, a numerb fo seconds for a tick is passed in. This is the resolutionof PDTimer, so a 1 would be 1 second per tick, a 5 woudl be 5 seconds per tick.
[/quote]
So ont he server model would 1 second per tick be considered sufficient? I would be expecting to the run the client side at about 60 ticks per sec, would this not lead to lots of difficutlies syncing up the server and client?

So ont he server model would 1 second per tick be considered sufficient? I would be expecting to the run the client side at about 60 ticks per sec, would this not lead to lots of difficutlies syncing up the server and client?
[/quote]
1 Hz is pretty good for a poker game…

On the other hand, 60 Hz is not needed.
In a graphical realtime MMORPG 5-20 Hz is probably more realistic - fluid movements on the screen should be handled by interpolation.

It ought to be possible to get more than 1Hz by starting multiple timers that call the same GLO method, but staggered. I dunno how you can ensure they are staggered evenly through each second, though.

Since the SGS guys are planning to allow sub-second resolution on PDTimer the problem does away anyway :smiley:

Hi

I’m working on a 3d space based game and I’m working on 4 ticks per second. When the client rotates the ship thier client view rotates and then there is some ‘thurster lag’. The client send 4 times a second it’s average thrust vector for the last 1/4 of a second, and the server does some real simple checking on wether that ship type can do that quick a change, then it lets everyone know about it. At this point, the client is then allowed to move in that direction, along with everyone else. This will give the impression of sliding around the screen a bit, but hey, this is space, we don’t have a road to grip on to, so some slide is allowed, and there is no real physics in this :).

I don’t know how well it will work, but it’s home code, I can play :slight_smile:

Endolf