|
The Cheshire Cat posted:I did the same thing! Pretty much the main reason why I posted here. Yeah, that is basically the #1 technical concern for the project that we foresee. We shouldn't be rendering things when the player is way too large to deal with them. We know we have a UDK license through the school, and they could probably get us other reasonably priced licenses, but we really have no clue what to use at this point.
|
# ? Apr 27, 2011 06:19 |
|
|
# ? May 11, 2024 16:40 |
|
Tw1tchy posted:Thanks for the help. I'll read through all that soon when I get the time. Also what I'd be using it for would be a tile-based game, so would all the stuff in it still be completely fine for what I need to do? And does it mention what libraries to use for netcode; because that's still a big problem of mine. TCP basically lets you "listen" on a port number on one machine, connect to it via another, and then just send data back and forth which is guaranteed to arrive and arrive in order as long as the connection stays up. Performance-sensitive games will usually use UDP instead, which doesn't handle negotiation and doesn't guarantee that data will arrive in order or at all, but doesn't stall and request resends when something goes wrong. i.e. Quake 3 doesn't care if you lose a world update packet if you've already received a more recent one, so it isn't going to stall the game and ask for a resend.
|
# ? Apr 27, 2011 06:29 |
|
ShinAli posted:Really digging SFML, should've used it instead of SDL in my project. Honestly, as someone who's been seriously stalled on trying to get his own project started because of this mindset, I'm going to say just go with what works rather than trying to find what's correct. Your engine might be "hacky", but do you know how you would implement those features in a more elegant manner the next time you want to build a game engine? Then you can just make use of that knowledge then (or rebuild your current engine from the ground up, but I don't recommend that since it's easy to get trapped in a constant cycle of re-creating your engine and never actually making the GAME). If you want to keep things under the hood, you could probably create a sort of interface class whose only function is to serve as a shorthand API for your friend to use without having to deal with any of the nuts and bolts of how the engine handles things. For example, if you want to say, add a new entity to the game world, instead of requiring your designer to actually manipulate the scene graph in order to insert it properly into the tree, you can write an addEntity() method for your API that will just take in some entity data produced by the user and then insert it all automatically. The actual structure of the back end really shouldn't matter, since everything your designer is doing will be high level. They shouldn't be worrying about the rendering pipeline or anything like that, they should be thinking about entities and game actions, and just plugging them into the interface through the methods you've written. You could even produce special classes to handle game objects in a more "human readable" format, whose sole purpose would be to be passed in as arguments to the API, which will then convert them into objects the game engine understands. It all really depends how complicated your project is, but my main point is that so long as your game works, don't worry too much about HOW it works. If you need someone else to be able to use your engine, it's a lot easier to produce an API that acts as a human-friendly interface layer than it is to try to structure your engine in a way that's human-friendly.
|
# ? Apr 27, 2011 06:37 |
|
The Cheshire Cat posted:Honestly, as someone who's been seriously stalled on trying to get his own project started because of this mindset, I'm going to say just go with what works rather than trying to find what's correct. Your engine might be "hacky", but do you know how you would implement those features in a more elegant manner the next time you want to build a game engine? Then you can just make use of that knowledge then (or rebuild your current engine from the ground up, but I don't recommend that since it's easy to get trapped in a constant cycle of re-creating your engine and never actually making the GAME). This is very important. Recently I've been working on something that's actually going somewhere, and the strategy I've been taking is to alternate between refactoring and adding features. Some of the refactoring is to clean up the messier parts of the new features, and some of it is in preparation of the next feature. But the important part is that you don't go back and rewrite old code that works. Code that works should never be rewritten, only refactored. If it looks bad but you can't think of a way to make it better you can put it off until later. Another important thing is to not worry too much about what you are going to be adding in the future. It just leads to analysis paralysis, especially when adding new classes. You can add things when you need them, even if it does require a bit of refactoring.
|
# ? Apr 27, 2011 14:56 |
|
crazylakerfan posted:At this point, my biggest concern about Unity isn't its power, but that I have heard a lot of people have had trouble with version control on unity projects, and version control is something that we definitely plan to use. Right now, we are basically just trying to decide what we should should pursue for making it. Honestly I can't speak to the version control problems (which are a well-documented shortcoming of free version Unity), but in terms of dynamic level loading/resizing, you shouldn't find any limitation imposed by Unity. You will have to get someone comfortable enough in the scripting layer to implement a lot of that functionality through script as opposed to kludging around with the editor, but the Unity API absolutely supports it.
|
# ? Apr 27, 2011 14:58 |
|
Does anyone know of a way to get information from a sound file, such as the current BPM, or the volume of the bass and treble? I've been looking around, wanting to make a game similar to Geometry wars, except it generates bullet patterns based off of how fast the music currently is, how loud the bass is vs the treble, etc etc. I've looked around, but I couldn't find any information. I don't even think that such information is stored in .oggs or .mp3s?
|
# ? Apr 27, 2011 17:48 |
|
It isn't. You will probably have to do a fast fourier transform and then extract the information you want from the results, which still isn't easy.
|
# ? Apr 27, 2011 18:20 |
|
An alternative to learning and implementing all the required audio analysis and feature extraction math would be to use the Echonest's track analysis API.
|
# ? Apr 27, 2011 19:25 |
|
ynohtna posted:An alternative to learning and implementing all the required audio analysis and feature extraction math would be to use the Echonest's track analysis API. Cool, I figured it wouldn't bee easy. Balls.
|
# ? Apr 27, 2011 19:46 |
|
The Cheshire Cat posted:Honestly, as someone who's been seriously stalled on trying to get his own project started because of this mindset, I'm going to say just go with what works rather than trying to find what's correct. I guess you're right. Only reason it took me so long to get started on graphics/games/etc was my mindset trying to understand everything about them before I could get started. It's just messy code unsettles me. I'll go through and refactor/clean up stuff before I start adding on more things.
|
# ? Apr 28, 2011 06:38 |
|
ShinAli posted:I guess you're right. Only reason it took me so long to get started on graphics/games/etc was my mindset trying to understand everything about them before I could get started. It's just messy code unsettles me. I'm still working through this, though I've actually forced myself to start making a game even though I haven't worked out exactly how I want the engine to work. I think the trouble with trying to come up with the perfect engine is that you're essentially trying to design the entire game before you design the game; the effort is redundant because that's what you're doing when you're writing the code anyway. Sure, knowing you want a particular feature can help you integrate it more elegantly, but you've got the source code and if you need to gut it to make something work, well, you can do that (assuming of course the feature absolutely cannot be made to work in a less work-intensive fashion). It's better to just get started and build momentum rather than stressing over ever detail; once you actually have momentum it's a lot easier to just go in and make changes. A non-game related example; at work I was putting together a program that saved its data to a file by just using a made up file type and serializing the data to the drive, but ended up replacing the entire thing with an XML interface, so data can be read in any text editor instead of requiring my program. Sure it would have been nice to have gone with XML initially, but I really didn't find it that much work to make the switch, since I'd already done so much ELSE on the project that it seemed really quick by comparison. Being able to see progress is a lot more motivating than having the "perfect" design, and any mistakes you DO make, you can avoid in the future. It's not as if this is the last thing you will ever code.
|
# ? Apr 28, 2011 08:13 |
|
Princess Kakorin posted:Does anyone know of a way to get information from a sound file, such as the current BPM, or the volume of the bass and treble? Seems like Unity 3D is the answer for everything these days... http://unity3d.com/support/documentation/ScriptReference/AudioSource.GetSpectrumData.html http://unity3d.com/support/documentation/ScriptReference/FFTWindow.html Some youtube examples: http://www.youtube.com/watch?v=3Rd8WBT2IZY http://www.youtube.com/watch?v=zvciEKEjuXI http://www.youtube.com/watch?v=fqQJTddKefo
|
# ? Apr 28, 2011 16:14 |
|
Anyone know of a way to get a unique integer for a Vector3 position? I was using index = x + (y * size) + (z * size * size) but that isn't as unique as I thought it'd be. The reasoning is that I have a Dictionary<Vector3,int> that stores a list of all visible cubes. I was thinking of changing it to Dictionary<int,int> since that takes a lot less memory, but I can't think of a good way to convert a Vector3 position to a unique integer.
|
# ? Apr 30, 2011 02:50 |
|
If you're asking whether or not there's a way of representing a 96-bit value in a 32-bit value without precision loss or collisions the answer is no. On the other hand since you're talking about a list of cubes maybe you don't need that much precision and could just, say, pack three 10-bit values into the 32-bit integer?code:
I just stumbled across a post you made on reddit which links to your blog where you explained the situation in a lot more detail. So it sounds like you're storing the absolute position of each block, and with a very large, streaming world, that's going to cause problems because you really can't afford the precision loss. So here's my suggestion: construct the index out of four 8-bit values. The first is going to be a key into an array of active chunks. The other three will be the block's local offset within that chunk. That allows you 256x256x256 addressing space within a chunk, and a maximum of 256 actively loaded chunks at a time. You can fudge those values around a bit (for example, 6-bit offsets for a maximum of 64x64x64 chunks, giving you a maximum of 14x14 active chunks. Or you can lower the precision for the y offset only. Paniolo fucked around with this message at 03:29 on Apr 30, 2011 |
# ? Apr 30, 2011 02:54 |
|
Assuming you are still working on your cube world project you could take each chunk's base index, divide each part by the size of a chunk, and then pack that result together as your dictionary lookup for the whole chunk at once. If you have 32x32x32 size chunks it'd reduce the number of bits you need to store one chunk by 5 in each direction. The chunk based at (0,0,0) maps to 0, the chunk based at 32,0,0 maps to 1, etc. Also, you likely don't need the same number of bits in the vertical and horizontal directions. You could take Paniolo's packing scheme and just use 8 bits in the vertical direction and 12 bits in each horizontal direction and pack the result into a uint instead of an int. That'd give you 4096x4096x256 chunks which would expand back into a 131072x131072x256 space for 32x32x32 element chunks. That's infinite enough for a game. e: In re-reading your post I think I may have misunderstood what you are doing. If you have a dictionary of all visible cubes then this idea might not work. I assumed that you were trying to track all visible chunks where a chunk contained a range of cubes like 32x32x32. Drawing only the visible cubes minimizes overdraw but you'll have to reconstruct your whole vertex/index list each frame. Drawing by chunks incurs a bit of overdraw penalty but you can also pre-calculate the vertex/index list of each chunk and have a minimal number of Chunk[x,y,z].Draw() calls per frame. Eating a bit of overdraw in favor of fewer Draw calls may prove to be more efficient depending on the size of your chunks. e2: To use the chuck drawing idea, you'd likely want to pass the base location of each chunk into your vertex shader and do the offset calculation there. The more I write the more I realize I'm imposing my own assumptions about your data structures onto the problem and I should most likely shut up until I know more. PDP-1 fucked around with this message at 04:11 on Apr 30, 2011 |
# ? Apr 30, 2011 03:41 |
|
Paniolo posted:If you're asking whether or not there's a way of representing a 96-bit value in a 32-bit value without precision loss or collisions the answer is no. On the other hand since you're talking about a list of cubes maybe you don't need that much precision and could just, say, pack three 10-bit values into the 32-bit integer? I took what you guys said + what someone mentioned on reddit + what I had already implemented and found a solution that worked. Each chunk has its own Dictionary of cubes local to itself. All cube lookups go through a single method that takes a Vector3. That method takes the Vector3, figures out which chunk the cube is in and then returns the cube from that specific chunk (if it exists). My mistake before was that there's no need to store the global position for each cube. I switched it so I only stored the local position relative to the chunk position. This made it so the formula (loc.X + (loc.Y * 256) + (loc.Z * 16)) worked and didn't collide since it was limited to 16x128x16 (my chunk size). Transforming that back into a Vector3 position is simply this: int y = index / 256; index -= (short)(y * 256); int z = index / 16; index -= (short)(z * 16); int x = index; So long story short, I greatly reduced my memory footprint. A 29x29 chunk world (Minecraft's version of far) used to take me ~500megs of ram. Now it takes me 300megs. Thanks for leading me in the right direction.
|
# ? May 1, 2011 20:04 |
|
I'm putting together a bundle. I want to bundle a few indie games together and have a sale. I'm looking for games that are: 1. FUN 2. Quirky/Different 3. < $20 4. > $0 5. PC Downloadable 6. Not too popular 7. Appeals to the core audience 8. Indie 9. No DRM If your game or a game that you know fits this description, please contact me, jorge@lunarworkshop.com
|
# ? May 1, 2011 22:50 |
|
dangerz posted:So long story short, I greatly reduced my memory footprint. A 29x29 chunk world (Minecraft's version of far) used to take me ~500megs of ram. Now it takes me 300megs. 500 Megabytes of ram? For this? 300 megabytes of ram just for a single chunk? Correct me if I'm wrong, but that seems absurdly high. That dictionary for a 16x16x128 chunk should be 64Kb, tops. Am I misunderstanding things here? You want an index into this dictionary that uses only a single short that can be translated back into local coordinates. That's 4 bits for the x axis, 4 bits for the z axis, and 8 bits for the y axis. Multiply that by the number of blocks in the chunk (32,768) and you should be at 64Kb. 16 * 16 * 128 * 16 bits
|
# ? May 2, 2011 00:44 |
|
Pfhreak posted:500 Megabytes of ram? For this? 300 megabytes of ram just for a single chunk? Correct me if I'm wrong, but that seems absurdly high. That dictionary for a 16x16x128 chunk should be 64Kb, tops. Uh, he said world not chunk.
|
# ? May 2, 2011 00:54 |
|
Paniolo posted:Uh, he said world not chunk. Apparently I am illiterate. Edit: Though I still don't know what he's doing with 300 megs of ram for a 29x29 world... Pfhreak fucked around with this message at 01:30 on May 2, 2011 |
# ? May 2, 2011 01:28 |
|
dangerz posted:The cube dictionary is already local to each chunk. Is there any reason why you're using a dictionary rather than an array?
|
# ? May 2, 2011 01:38 |
|
Pfhreak posted:Apparently I am illiterate. I think you are illiterate, because he said 29x29 chunks. :P
|
# ? May 2, 2011 01:47 |
|
Paniolo posted:I think you are illiterate, because he said 29x29 chunks. :P And from an earlier post, each chunk is 16x128x16, so that gives a grand total of 464x128x464 blocks, which is 27 million blocks. I can see how that could be 300 MB of ram. That's only something like 12 bytes per block.
|
# ? May 2, 2011 02:41 |
|
Scaevolus posted:Is there any reason why you're using a dictionary rather than an array? Dictionary let's me do a fast key lookup (o(1)) and iteration through the whole thing. Array has a fast iteration but not a fast lookup. I'm def open to suggestions if you have a better idea.
|
# ? May 2, 2011 02:45 |
|
If dict is ordered it's a balanced BST rather than a hash and thus doesn't have constant-time lookup
|
# ? May 2, 2011 02:47 |
|
dangerz posted:Dictionary let's me do a fast key lookup (o(1)) and iteration through the whole thing.
|
# ? May 2, 2011 03:13 |
|
Scaevolus posted:How many entries are in the dictionaries? Is it not 16 * 16 * 128? That way when I need to modify the chunk (add/delete cubes) and rebuild the vertex buffer, I only have to go through the buffer with the visible faces to save the time.
|
# ? May 2, 2011 03:47 |
|
Paniolo posted:I think you are illiterate, because he said 29x29 chunks. :P Right, I got that. (16*16*128)*29*29*16bits = ~52Megabytes. My actual illiteracy comes not in misunderstanding his world size, but in misunderstanding that he was storing more than just the dictionary of blocks. Now I'm curious about what other information is being stored for each block. Don't misunderstand my intent, I'm more curious than critical.
|
# ? May 2, 2011 16:33 |
|
Otto Skorzeny posted:If dict is ordered it's a balanced BST rather than a hash and thus doesn't have constant-time lookup http://msdn.microsoft.com/en-us/library/xfhwa508.aspx quote:The Dictionary<TKey, TValue> generic class provides a mapping from a set of keys to a set of values. Each addition to the dictionary consists of a value and its associated key. Retrieving a value by using its key is very fast, close to O(1), because the Dictionary<TKey, TValue> class is implemented as a hash table.
|
# ? May 2, 2011 16:41 |
|
Pfhreak posted:Right, I got that. public byte visibleFaces; public byte type; visibleFaces is a listing of the visible faces. type is the texture/cube type (sand, dirt, grass, etc.) Each chunk has this: public Vector3 position; public Dictionary<Vector3, cube> allCubes; public Dictionary<Int16, bool> allCubesLookup; public bool changed; public SerializableDictionary<Vector3, chunkChange> changes; position is the chunks world position. allCubes is a listing of all cubes with visible faces. allCubesLookup is a listing of all cubes that are available to the world. If a cube doesn't have any visible faces, it still has a listing here so I don't have to re-run the perlin noise algorithm. changed is a flag that tells me whether the chunk has changes in it (cubes added/deleted). changes is a serializable dictionary with a list of changes. I'm sure there's stuff I can be doing differently. Besides iPhone games, I've never written games before and I've definitely never written a 3d game before so all this is new to me. edit: Updated to my new cube format. dangerz fucked around with this message at 02:09 on May 4, 2011 |
# ? May 2, 2011 17:03 |
|
Well, plus your vertex buffers. That's where the majority of your RAM usage is coming from I'd wager, although if you're able to use geometry shaders, or with clever use of instancing, you can basically eliminate the need to store any vertices.
|
# ? May 2, 2011 17:09 |
|
Paniolo posted:Well, plus your vertex buffers. That's where the majority of your RAM usage is coming from I'd wager, although if you're able to use geometry shaders, or with clever use of instancing, you can basically eliminate the need to store any vertices.
|
# ? May 2, 2011 17:16 |
|
Watching you guys mess around with cube worlds has inspired me to try making one too. I wrote up a Perlin noise generator and marching cubes algorithm last night, hopefully within a few days I'll have a pretty screenshot to show off. One problem has been bugging me though - the marching cubes algorithm returns a pile of individual triangles that are unconnected to each other. How do you calculate good vertex normals from that data? The simple but lovely way to do it would be to calculate one normal for each triangle and use that same normal vector for each vertex. The triangles wouldn't blend nicely into their neighbors and identical normal vector info would be stored three times per triangle. Is there some slick way to do this or is the only option to do a brute-force reduction of vertices/index values that are shared between neighboring cubes? Also, are you guys doing anything to try to covert the pile of triangles into any kind of triangle strips?
|
# ? May 2, 2011 18:05 |
|
PDP-1 posted:Watching you guys mess around with cube worlds has inspired me to try making one too. I wrote up a Perlin noise generator and marching cubes algorithm last night, hopefully within a few days I'll have a pretty screenshot to show off. Are you doing a cube world or doing marching cubes, because marching cubes doesn't produce a blocky Mine-craft style world, but smooth meshes. Here is the code to calculate normals from my marching cubes geometry shader: code:
|
# ? May 2, 2011 19:21 |
|
Paniolo posted:Are you doing a cube world or doing marching cubes, because marching cubes doesn't produce a blocky Mine-craft style world, but smooth meshes. It's a marching cube world, not a Minecraft style block world. My generation steps look like: 1) Fill a 3D array with Perlin noise, scaled to (0.0, 1.0) 2) Run marching cubes on that noise, treating everything above 0.5 as solid and everything below as empty space. 3) Draw the output of the marching cubes algorithm for any blocks within the view frustum. (4?) Depending on how hard step (3) hammers the graphics card or memory I might also try to coalesce vertices and stripify into triangle strips. Hopefully it won't be needed. So far I have steps (1) and (2) done and it generates a 32x32x32 block in about 20ms. The blocks can be generated out of order so I hope to just queue up a bunch of MakeBlock() tasks on a background thread and get the visible part of the world to generate in < 1 second. Fingers crossed. Paniolo posted:Here is the code to calculate normals from my marching cubes geometry shader: If I read this right, you're generating normals by looking at the derivative of the Perlin density function. That makes sense, I'll have to take a look at doing that in my own code. Thanks for the tip.
|
# ? May 2, 2011 19:39 |
|
Do you guys have any screenshots of what you've done?
|
# ? May 2, 2011 23:34 |
|
dangerz posted:Do you guys have any screenshots of what you've done? I've posted it before but this is a video of my voxel-world project. I'm currently working on reimplementing it to run on the GPU for an outdoor streaming world. GPU marching cubes is several orders of magnitude faster than CPU marching cubes, but memory is the bigger issue.
|
# ? May 3, 2011 00:41 |
|
I'm not actually well versed in C++ or SDL_Mixer, but I'm asking this question anyway on behalf on the Doom community. Put simply, nobody writing Doom source ports can seem to figure out how to control normal sound volume and MIDI sound volume independently using SDL_Mixer on Windows Vista or 7. I'll let James Haley, author of Eternity Engine, put it in his own words:quote:Seems the concept of independent volume for native MIDI doesn't exist under Windows Vista or 7, as using MIDI volume sliders in any application that has them (including most games that use SDL_mixer) also affects the volume of digital sound output. This makes attempting to adjust the relative volume of music for comfort impossible. I've heard of various workarounds all involving a Timidity driver, but this requires the user go above and beyond simply installing the game on his system. The only port that I know of that definitively fixes this issue is ZDoom, but it uses the GPL-incompatible FModEx and is thus not a suitable solution. If you want some code to look at, Chocolate Doom is perhaps the easiest Doom source port to grok and you can grab its source here: https://chocolate-doom.svn.sourceforge.net/svnroot/chocolate-doom/trunk/chocolate-doom/ Any suggestions on other open-source sound and music libraries would be welcome as well. Unboxing Day fucked around with this message at 04:47 on May 3, 2011 |
# ? May 3, 2011 04:03 |
|
dangerz posted:Do you guys have any screenshots of what you've done? I only got started on it yesterday and tacked on a very unoptimized viewer tonight so I could see what things look like when I mess with the Perlin noise parameters. It only generates single blocks right now, so still a long way to go. It's a pretty much just a lovely modern art generator right now. Hopefully stuff will start looking better once there is more than one block shown at a time and the normals are generated from the Perlin noise derivatives.
|
# ? May 3, 2011 04:10 |
|
|
# ? May 11, 2024 16:40 |
|
dangerz posted:This is all that's stored for each block: This is pretty space-inefficient. Why do you need a cube ID? Can you perhaps make it implicit? Position shouldn't need to be stored as a Vector3 - can't you just figure out its position when you need it, given its index value which the chunk holds? You don't need a list of 16 bit integers to store face visibility. Just use a single byte, and set and test the visibility using bitwise operations (so "top is visible" = first bit set to 1, etc). You may be able to get away with storing the type as a byte too, if you don't think you'll need more than 256 types of block. I made my own Minecraft-alike last year - my blocks take up 3 bytes each at the moment (excluding the vertex buffers of course).
|
# ? May 3, 2011 09:29 |