Jump to content

  • Log In with Google      Sign In   
  • Create Account

ClickerMonkey

Member Since 19 Nov 2011
Offline Last Active Apr 25 2013 06:43 PM

Topics I've Started

Article #2: Managing Entities (gameprogblog)

13 January 2013 - 03:09 PM

Here's my second article, it's on managing game entities!

 

http://www.gameprogblog.com/managing-entities/

 

Thanks for any input!


Article - Generic Game Loops (gameprogblog)

07 January 2013 - 09:12 PM

I posted this article yesterday (fairly detailed article about game loops, with code and applet), let me know what you think.

 

http://www.gameprogblog.com/generic-game-loop/


Game Engine - Networking Library

19 November 2011 - 09:17 PM

I've been working diligently on a 2d and 3d game engine for a couple months now (actually 6 years if you were to count all the times I started to make one and then switched graphics or languages). Currently I've developed the engine in Java utilizing LWJGL. I'll share with you my current networking design (what I have programmed), and I hope you can help me decide how to structure the final pieces!

Terminology:
  • Attribute: any variable that can be read or written to a buffer and can be interpolated between a start and end value.
  • Field: has the reference to a specific attribute, the value of the attribute in the last update frame, and the most recent value from the server ( for interpolation )
  • FieldType: defines several properties of a field, such as how often it gets sent to the server, when it gets sent (on entity creation, deletion, on request, on update, on change)
  • RemoteEntity: has a remote state and is notified when it has been created, updated, or deleted (remotely and locally).
  • RemoteType: defines several properties for a remote entity, such as the list of field types, and how often the entity is transmitted.
  • RemoteState: has a remote type, a reference to the remote entity, and a list of all the fields in the remote entity.
  • Message: something that's sent across the wire, an entity create, update, deletion, event, RPC, etc. Has a priority, a retry count, among other things.
You may be thinking "a lot of these sound the same" or "are all those classes necessary?" and to that I say yes, here's an example class with angle, center, velocity, and health. I use the static FieldType and RemoteType to avoid repetitious data in memory. I have the class level fields final because "immutability" in Java games is really important to me.


public class Example implements RemoteEntity
{
	// the unique ID that says "I'm an Example entity"
	public static final short TYPE = 23;
	
	// a generic factory for creating this entity
	public static final Factory<RemoteEntity> factory = new Factory<RemoteEntity>() {
		public RemoteEntity create() {
			return new Example();
		}
	};
	
	// the set of types that describe a field
	private static final FieldType angleType = new FieldType( 2, OnCreation | OnChange ); // sent at most every 2 network updates
	private static final FieldType centerType = new FieldType( OnCreation | OnChange | OnDeletion );
	private static final FieldType velocityType = new FieldType( OnCreation | OnChange );
	private static final FieldType healthType = new FieldType( OnCreation ); // server controlled
	// the type that describes the entity
	private static final RemoteType remoteType = new RemoteType( TYPE, angleType, centerType, velocityType, healthType );
	
	// the set of attributes
	private final Scalarf angle = new Scalarf();
	private final Vec2f center = new Vec2f();
	private final Vec2f velocity = new Vec2f();
	private final Scalari health = new Scalari();
	
	// the state the holds the fields of this instance
	private final RemoteState state = new RemoteState( this, remoteType,
		// the set of fields that hold the attributes, and their types
		new Field<Scalarf>( angle, angleType ),
		new Field<Vec2f>( center, centerType ),
		new Field<Vec2f>( velocity, velocityType ),
		new Field<Scalari>( health, healthType )
	);
	public Example() { }
	public RemoteState getRemoteState() {  return state; }
	public void onCreate() { }
	public void onUpdate() { }
	public void onDelete() { }	
}

So basically when I do:

Example ex = new Example();
network.create( ex );
... some time later
network.delete( ex );
OR
ex.onDelete() is invoked because server said so.
OR
ex.expire() was invoked by client, notifying "network" to automatically delete it.

It will send the create request to the server, which can deny it, or accept it (and give proper field values if any are wrong). then the server (if accepted) will notify all clients that should care about the entity a creation notification. this also will automatically handle when the entity changes values, to send a proper update message.

Features Done:

  • Prioritized messages
  • Retry count on messages (if a message can't be fit in the next payload to be sent, it will be queued)
  • Optional interpolation of attributes between the last update cycle and the most recently received.
  • Each attribute has its own "reliability", when its sent ( on create, delete, update, request, changed ), and how often it would be sent (if its sent on update)
  • Easy integration into existing game (using engine). Nothing additional needs to be done, it can track the attributes of an entity by it self and handle synchronization. Only thing that needs to be done is the server logic.
Todo:
  • Define the interface for the player view.
  • Define the interface for the player. It has an id, a view, a set of created entities, a set of currently/previous/maybe interested entities.
  • Define the interface for the server. It must have all players, an optional set of non-player entities, and must permit the network to accept creation, updating, and deletion. Through various methods this interface must give permission, adjust incorrect information, manage the sets of interested entities for each player, maintain a set of game states for the past 128 (?) updates to properly handle collision detection (so when player A thinks they hit player B, the server can actually test that), and many more things (need help here)
Thoughts:
  • Should I enforce that each entity has a "bound", and I should use this for determining interest (intersects with players view, or the area which surrounds their view - "may be interested in") I could use this then to make the world a huge grid of bounds - essentially an index for quick searching and collision detection. Is there an instance where you think an entity won't have a bound?
So basically, I was wondering what you think are good designs for the player, player view, and server interfaces. Important note: I also plan on adding continuous world functionality into the networking library - so you can span a world across multiple servers.

Anything would be well appreciated!

PARTNERS