Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 04 Jul 2011
Offline Last Active Oct 01 2015 12:13 AM

Posts I've Made

In Topic: Best practices for packing multiple objects into buffers

17 February 2015 - 08:44 AM

Since my previous post went unanswered I will try once more, maybe stating what my problem is in a more clear way.



That said, IMHO handling terrain chunks and batching meshes of multiple objects are two distinct use cases. They are so distinct that both require their own solution. I would generate a single vertex buffer for terrain, replacing regions of content when necessary. Why? Because rendering terrain will happen also in situations where more than a single chunk is visible at a time. If you would use multiple buffer objects, then you would switch buffers even during a single rendering pass of terrain. Using multiple memory blocks would mean to duplicate chunks in GPU memory. On the other hand buffer memory management would be relatively easy, assuming that the memory footprint of chunks is fix.



What about terrain chunks whose size is not fixed? I have modifiable terrain (mesh is extracted from 3D binary volume) so size may differ greatly based on how fragmented the terrain is - it can be flat hill with lowest amount of vertices, but also can be totally rough and fractured with much bigger mesh surface and thus vertices amount. So far I used single VBO per chunk, but I plan on having really big draw distance and it starts to hurt especially that chunks go in 3 dimensions and there can be several hundreds of highest LOD chunks (of course more LOD levels and concatenating chunks into bigger ones will also be implemented but still I think there is a lot of VAO switching that could be avoided).


I'm trying to figure out some custom allocator that would manage a single VBO (or few big ones, depending on total size of terrain geometry), but I can't figure out how to modify chunks that were changed, and also stream new chunks in/out as player moves. With a buffer of fixed size with N slots it would be easy - just swap old chunk with new chunk (whether new one is because player moved or digged existing chunk, doesn't matter), but I can't figure it out for dynamic chunks.


My initial idea was to allocate slightly more than needed - check what's the max size of chunk that exists now, allocate maybe 1.5x as much so all chunks will be padded and this will allow for them to grow or shrink without affecting other chunks in the memory. Problems start if there is situation where chunks grow beyond fixed size - what to do then? It also wastes a bit of memory of course, but not sure if that would be any significant amount. 


Another idea would be to not pad to fixed size, but just allocate big enough buffer and put chunks one by one in linear way. If chunk that already exists changes it's geometry, I check if it's the same size or smaller - if so I just overwrite that chunk data. This will leave some portion of buffer orphaned, and it will probably be so small chunk of memory that it will be wasted forever. This can lead to buffer fragmentation at some point and also requires some fancy allocator that will keep track of memory use and find a place for new chunk to occupy if it exceeds it's current location space. 

In Topic: Best practices for packing multiple objects into buffers

04 February 2015 - 07:53 AM

What would be the best way to update something like terrain meshes, where you usually divide them into "chunks" that can be culled, but they could easily sit in a one big buffer. The problem is updating this buffer - if chunks change (some removed, some added, and with dynamic terrain geometry even the same chunk can be rebuilt with different amount of vertices) you need to change the buffer and for me this means reuploading all terrain data that's valid at a given point. Is there a way to somehow exchange data chunks of different size without reallocating buffer?


I was thinking about maybe aligning buffer sizes to some common "fit all" size, and wasting some storage (for padding) but gaining ability to easily remove single chunks, because they will all occupy the same size in buffer. Maybe I'm missing something, but for now I'm using single VBO for each chunk and thinking how this could be done better.


Reuploading whole buffer when just one chunk changes seems way too expensive and there surely are ways to do it better.

In Topic: Standard structure of a large scale game

29 January 2015 - 04:12 AM

That's a question I was going to ask many times myself but can't even phrase it clear enough. I started with small project but now it's grown, has over 300+ classes and client-server architecture. More and more I'm finding myself pondering how to approach something in terms of data-object interaction and it takes many hours to figure some things. For example, I have network synchronized modifiable terrain. I needed it to synchronize when player moves and changes grid position, but I didn't want to clutter player movement logic (which is tricky in itself, as it's over network with authoritative server) so I created some TerrainDb class that receives network messages and deals with response and updating terrain caches. What is my major problem is relation between different systems and classes. Then it turns out such class needs some networking access to receive/send data to server, requires access to World/Terrain and so on. And it starts to get messy already.


Top game logic is handled by GameState, each of which has access to several main objects (like Connection, ScriptingEngine etc.) but most of these states are simple (Login, LoadingScreen, Character menu) until I get to "gameplay" state. This is where so many things need to happen, so many systems need to be initialized and propagated that I have no idea how to design these relations. Should I initialize them all in state's Init() func, making it 100-200 lines long? Pass dependencies to constructors? So far I avoided singletons and I have not a single one, but the net of class relationships becomes very hard to maintain. 


While I'm not making an "MMO" but way smaller networked "sandboxy" game, I checked Ryzom/Planeshift sources and several others that had sources available. They all seem to be just as messed and without deep knowledge you have no idea what's going and and can't even track relations. So many weird classes initialized in weird places, passed around. Is that what every project ends up as? I admit I saw WarZ source code too and was terrified - 200kB classes that do every freaking thing from rendering to physics all messed up and mixed, not even divided into sections of similar theme. 


Mind that I'm talking about lower level and unique things - terrain, networking, scripting etc. I don't think this can and should be done as components (terrain itself is really unique, which would lead to a special case game object that has really unique components and has systems that work just on that one object which seems silly). Component systems seems more like game logic where you fit all pieces together, but this requires some bigger things to exist first. I don't really think I could fit everything in Component-System manner. 


So anyone has any pointers where such design could be learned? Is it just experience? Everyone starts talking about game loop and game states but these things are nothing compared to vast net of systems/services/"managers" required for a more complex game. 

In Topic: How to send input data

24 June 2014 - 03:19 AM

Ok, since I got so many replies dry.png , I think it may be better that I ask some precise questions, maybe this will attact more crowd than my last post that wasn't probably clear on what the issues might be. 


Summary: client-server simple (no advanced physics yet)  player movement simulation using RakNet that supports UDP in RELIABLE and UNRELIABLE mode, allows ordering and sequencing of packets and so on. Right now server receives input commands that are sampled on client at fixed rate 30Hz, they are sent as soon as they're sampled but may be grouped into packets by RakNet. Server puts each received input command into queue and only consumes one command at its simulation tick (also 30Hz). This means it works as long as rate of messages sent from client is steady, and disallows problems with sudden jumps if I were to receive many commands at once. 


Question 1: Should I send "empty" moves, where player does not press any key? 

If I send empty moves I have sequential stream of client ticks, so it always goes 1,2,3,4,5,6 and missing tick would let me know that some message got lost.  But then, I can use some of RakNet's delivery modes to make delivery reliable - would it be enough? This is where I'm really lost. For now I tried sending only real actions (so instead of 1,2,3,4,5,6 where 1,2,3 and 6 are empty actions, I'd send only 4, 5) and it seems to work when using ordered stream, only drawback I noticed are enormous lagspikes when some packet is greatly delayed (usually with some packet loss). But then, I'm not sure how would I solve it better using some UNRELIABLE mode and working with tick numbers? 


Question 2: What mode should I use for sending user input commands to the server? 

This is follow-up to previous question, because I'm confused what mode (reliable, unreliable, sequenced, ordered) should be used for sending commands. As I mentioned, when I use ordered reliable it means I get every message in the right order, but sometimes big lagspikes occur and this causes the server to stop simulating such player for a while, then it receives burst of messages. This makes the message queue longer, and makes the gap between client and server simulation bigger. When client stops, server easily catches up because it only consumes messages that are real actions, and client that doesn't move don't send them anyway. But considering client moving in some direction all the time, this gap will be bigger and bigger, to a point where server is behind client local simulation by more than several hundreds ms. 


On the other hand, using unreliable fast messages I could probably avoid spikes, but at the cost of gaps between messages, plus I wouldn't know if I really lost a message that contained command, or there was no action taken by the client (assuming the same model I described in previous question, that I don't send empty moves). 


Can I even afford to loose input messages or it will break things? Should I make sure that messages are either resend, or that I send some redundant information (I read about sending more than 1 input in message, like 1+N previous inputs in case previous ones are lost). 


I hope these questions are better than in my previous post and will get some response - I read every thread I could find on the forums about client input prediction and timestamping and there are many methods and often discussions don't even end with some clear solution. I'd really like to at least start some discussion, I know this topic may be boring already, but somehow there is always something uncertain, no matter how much I read on this topic (probably due to many solutions that exist, different network frameworks used and so on).

In Topic: Indie game - Town of Salem

31 January 2014 - 09:41 AM

Reminds me of Salem (http://www.salemthegame.com/) /in art department of course/ You guys were inspired by that game or came with that art style yourself? It's weird how this look fits into "salem" theme somehow, and I can't exactly say why :)