Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1] 2 3 4

Author Topic: C++ Cube based 3D engine: I give up. Starting fresh.  (Read 8453 times)

Siquo

  • Bay Watcher
  • Procedurally generated
    • View Profile
C++ Cube based 3D engine: I give up. Starting fresh.
« on: January 24, 2010, 08:26:15 am »

So I'm building a game (aka, another project that will probably never see the light of day). This is a rant more for my own benefit of getting my thoughts in order than for actual advice.

Right now I've got my own basic 3D engine (using C++, openGL), rendering a terrain made of blocks like minecraft.
But this is a static terrain, such as in DF mode. There is no dynamic loading/unloading when you move through the terrain.

However, I'd like this terrain to:
1. Extend into a horizon. Mountains should be visible in the distance.
2. Generate new terrain as soon as one reaches the edge of the world.
3. NON-2D: most games have a terrain which is really just a crumpled 2d blanket of vertexes (Wurm online). This terrain is truly 3D.
4. Editable: Mining/digging should be possible.
5. Practically Infinite.
6. Render in a decent amount of time.
And last but not least:
7. Multiple parts of the terrain can be in memory at the same time (multiplaying), and terrain should not "take a lot of space" because it'll be sent over teh internets.

Current design:
A terraintile is 1x1x1m. A Terrain is a virtual "parent", containing 7x7x7 of those blocks. Then there is another one above that, containing 7x7x7 of those blocks, and then turtles Terrains like that all the way down. When enlargement is necessary, take the topmost "world" block, and make another parent block around that. This increases world size exponentially. By having a -3, -2, -1, 0, 1, 2, 3 xyz system per block, absolute positioning doesn't change for the already existing world and it's objects, since for the existing world, only zeroes are added. All xyz locations in the game are relative to a parent, and those relative to their parent, etc. There's no real absolutes, except for the topmost block of Terrain which is 0,0,0. All Terrains are linked to eachother both hierachically (sp?), so top-down and bottom-up, and laterally, every block knows its direct (NESW and Up and Down) neighbours. This datastructure is a form of tree I have not been able to find examples of, and I probably implemented it quite inefficient.

Terrain is saved in SQLite. For small amounts it's ok, but I don't know what the performance will be when handling large amounts of blocks.

That is the static part, and due to the exponential nature, easily runs out of memory.

Now the dynamic part:
If a "Terrain" is totally empty (as in air), it won't have to render at all, or even be loaded. If all of the children-terrain of any block are empty, those children don't need to be loaded either. Same if the terrain is totally filled with rock, and never touches air. That limits the number of "Terrains" that need to be loaded severely. But the exponential nature is also way too much. You don't need to dig inifinitely deep or fly infinitely high. A network of "top"-level Terrains, each large enough to hold at least 1/2 of a players' view, all linked in a NSEW-fashion, should be enough.

Then there's objects. Now objects are linked to a Terrain-block, which is fine and dandy for calculating their vertices relative to the viewport. But if the terrain is loaded dynamically, and sometimes not even loaded at all because it's "empty", where's the object then? Registering the object to parent-terrains is a pain, because it increases the number of lists where the object resides.

Then there's rendering. Switching textures during rendering is inefficient, so I want to draw all the gneiss first, then all the soil, then all the chalk, then all the clay. To do this, terrain must be loaded into a list-per-texture. When terrain is unloaded, it needs to be removed from that list. Which necessitates either searching through the list for every block again (slow!), or having an inverse pointer to the list-element per terrain, which removes the list element when destructing the terrain. Having lists like that, and removing the terrain incorrectly will result in invalid pointers and certain DOOM.

So now I'm stuck.

1. I can't even write down the design in my head in an intelligible way, which is a sure sign my head can't wrap itself around the design all at once, which means I don't yet truly understand it. (Life lesson for everyone: If someone cannot explain something in clear language, he doesn't fully understand it himself).
2. The Loading and Saving Terrain is heavily dependent on the structure-design, so needs to be rewritten and rethought later. Saving and loading to HD is slow, and needs to be efficient. Also, I don't want terabytes of unnecessary terraindata.
3. The rendering is dependent on the structure-design. I want the rendering to be fully relative. The camera has a location within a terrain, and from that terrain we're going to loop through all the neighbours and check if there's anything to render there.
4. I am not a computer scientist. The type of structure needed, and the internal linking of the structure needs to be lean and mean, especially on the rendering-side and save/load side. But what is the fastest way?
5. Objects and players need to move freely throughout the world. Having no absolute xyz system, there is more extensive administration as to what is where. Moving objects need to re-register and unregister with several terrain-blocks. Or I do it differently. How so I do this fast?


tl;dr: Gief me the C++ code!!1! ;)



PS: Yes I know I'm in way over my head. Part of the reason of diving in too deep is because I like being there.
« Last Edit: March 02, 2010, 08:04:46 am by Siquo »
Logged

This one thread is mine. MIIIIINE!!! And it will remain a happy, friendly, encouraging place, whether you lot like it or not. 
will rena,eme sique to sique sxds-- siquo if sucessufil
(cant spel siqou a. every speling looks wroing (hate this))

qwertyuiopas

  • Bay Watcher
  • Photoshop is for elves who cannot use MSPaint.
    • View Profile
    • uristqwerty.ca, my current (barren) site.
Re: C++ Tile based 3D engine
« Reply #1 on: January 24, 2010, 09:10:48 am »

For the super-blocks, fhy not initialize each block to a null pointer? That way, even though a new superblock is added, only the centre and north actually exist, and north has N levels of mostly nulls before it reaches the fully generated blocks.


Also, being able to procedually generate the terrain based the the position would allow you to only store the altered blocks, saving space in the database. With the same seed per block, you don't have to send anything except an optional world seed to initialize the world for multiplayer. You would still need to send terrain modifications, but those don't happen nearly as frequently.

I think that it would be best to have a procedurally generated heightmap for the shape, and a procedurally generated material map for the contents. Maybe split each block into an imaginary 3x3x3 grid, with the outermost ones shared with the neighboring block (so they would have 3x3 in common) and have each point of that grid assigned a material based on it's absolute(hidden) position.

When I say procedually generated, I mean that it's contents can be calculated given the world seed and it's x/y/z coordinates, and the output is consistant for consistant input.

Noctis and some old games manage to fit an entire galaxy into an int(or similar number), so couldn't you fit the world into an int that is generated with the world? (And save changes, but since the player can't alter every block in the whole world, it will stay smallish when saving)
Logged
Eh?
Eh!

Siquo

  • Bay Watcher
  • Procedurally generated
    • View Profile
Re: C++ Tile based 3D engine
« Reply #2 on: January 24, 2010, 01:34:47 pm »

The null-levels are what I do now, but once a sub-block is "in view", it needs to be loaded. But not always, if it's just air or something, it doesn't. But if there's a bird in there, it does. Or does the bird get a superblock as its "parent"? But then it's relative xyz change dramatically... Or... ... I need to think this over some more. It's cool, seeing ideas slowly crystallising in your head. It'll work out.


The procedural seed is... Actually a really good idea.

There's more than just a seed that would determine the terraintype, such as the neighbours, (I'd rather not see glaciers next to scorching deserts), but it's really just a limited set of parameters per worldsection. And storing only the alterations is easy.

It's a chance of one in a million, but it just might work  ;D

Thanks for thinking along!
Logged

This one thread is mine. MIIIIINE!!! And it will remain a happy, friendly, encouraging place, whether you lot like it or not. 
will rena,eme sique to sique sxds-- siquo if sucessufil
(cant spel siqou a. every speling looks wroing (hate this))

eerr

  • Bay Watcher
    • View Profile
Re: C++ Tile based 3D engine
« Reply #3 on: January 24, 2010, 04:05:18 pm »

"Then there's rendering. Switching textures during rendering is inefficient, so I want to draw all the gneiss first, then all the soil, then all the chalk, then all the clay. To do this, terrain must be loaded into a list-per-texture. When terrain is unloaded, it needs to be removed from that list. Which necessitates either searching through the list for every block again (slow!), or having an inverse pointer to the list-element per terrain, which removes the list element when destructing the terrain. Having lists like that, and removing the terrain incorrectly will result in invalid pointers and certain DOOM"

What if you need to draw geneiss, chalk, then more geneiss?
Logged

Siquo

  • Bay Watcher
  • Procedurally generated
    • View Profile
Re: C++ Tile based 3D engine
« Reply #4 on: January 24, 2010, 04:21:56 pm »

Doesn't happen. The place where I draw is done with a transform (move cursor to location xyz), which is a lot more efficient to do than unloading/reloading a texture (allegedly). That means I can draw ALL the gneiss, then ALL the chalk. When I then have to draw gneiss again for... say a gneiss statue because objects are rendered after terrain, that's too bad. Optimising means stopping with optimising once the result is no longer worth the effort ;)

I have not dived too deep into renderer-optimalisation yet (writing your own shaders for example), but having code that is already somewhat optimised for rendering should make life easier when I get to the part where framerate becomes an issue.
Logged

This one thread is mine. MIIIIINE!!! And it will remain a happy, friendly, encouraging place, whether you lot like it or not. 
will rena,eme sique to sique sxds-- siquo if sucessufil
(cant spel siqou a. every speling looks wroing (hate this))

eerr

  • Bay Watcher
    • View Profile
Re: C++ Tile based 3D engine
« Reply #5 on: January 24, 2010, 05:22:51 pm »

So if you are writing the engine, who is writing the game?
Logged

Siquo

  • Bay Watcher
  • Procedurally generated
    • View Profile
Re: C++ Tile based 3D engine
« Reply #6 on: January 25, 2010, 12:07:50 pm »

Me. Engine comes before the game-logic. I have it on good authority that it's quite possible to write a game all by yourself ;)


Not that I'll ever finish it. I've never finished writing ANY game, they all died horribly of feature-bloat. This is the most ambitious project ever, though.
Logged

This one thread is mine. MIIIIINE!!! And it will remain a happy, friendly, encouraging place, whether you lot like it or not. 
will rena,eme sique to sique sxds-- siquo if sucessufil
(cant spel siqou a. every speling looks wroing (hate this))

Outcast Orange

  • Bay Watcher
  • [SOMETIMES_SQUID]
    • View Profile
    • The Outcast Orange
Re: C++ Tile based 3D engine
« Reply #7 on: January 25, 2010, 12:12:48 pm »

Nonsense!

Feature bloat FTW.
Like my game.
The maps don't even function properly,
 yet I'm pilling on more features.

The idea it to hope the game gets good enough
 to where you don't feel the need to abandon it.
Otherwise those broken maps might get the better of you.

If somebody told me I had to fix all the bugs before I could add anything else,
 I'd probably cry a while, then decide that life wasn't worth it.
Logged
[7:53:55 PM] Armok, why did you demand that I don't eat you?
[7:54:34 PM] [Armok]: woooooo

Burried Houses - Platform Explorer Demo H - Cloud Scream

Siquo

  • Bay Watcher
  • Procedurally generated
    • View Profile
Re: C++ Tile based 3D engine
« Reply #8 on: January 25, 2010, 01:31:33 pm »

Yeah, that's usually my point of view as well  ;D

The abandoning usually happens when you find out you have to redo the entire [somepart] because it can't do what you want. When you've finally finished, you find out you need to redo another [somepart] to make it actually work. Rinse, repeat, abandon.

So now I took the other direction. By making a game designed to have EVERYTHING, it can never be bloated enough.

For instance, game-design-technically, I'm still doubting as to how to implement ranged combat combined with the toribash-style slow-motion melee.
Logged

This one thread is mine. MIIIIINE!!! And it will remain a happy, friendly, encouraging place, whether you lot like it or not. 
will rena,eme sique to sique sxds-- siquo if sucessufil
(cant spel siqou a. every speling looks wroing (hate this))

eerr

  • Bay Watcher
    • View Profile
Re: C++ Tile based 3D engine
« Reply #9 on: January 25, 2010, 04:13:43 pm »

Yeah, that's usually my point of view as well  ;D

The abandoning usually happens when you find out you have to redo the entire [somepart] because it can't do what you want. When you've finally finished, you find out you need to redo another [somepart] to make it actually work. Rinse, repeat, abandon.

So now I took the other direction. By making a game designed to have EVERYTHING, it can never be bloated enough.

For instance, game-design-technically, I'm still doubting as to how to implement ranged combat combined with the toribash-style slow-motion melee.

Instead of bullet time, you have meelee time?

Also, when someone is in meelee time he can dodge ranged projectiles because they are slowed down.

If this means characters initiate risky death causing meelee combat to escape ranged, then so be it.
Logged

Siquo

  • Bay Watcher
  • Procedurally generated
    • View Profile
Re: C++ Tile based 3D engine
« Reply #10 on: January 25, 2010, 05:45:41 pm »

True, shield blocking and evading arrows can be done, but since you are moving in melee-time and the shooter is not, the shooter can easily "kite" you. Unless the shooter automatically enters the same bubble of melee-time as well, as soon as "combat is initiated". Problem solved, but...

But what if there are 3 actors? Once in melee-time, you move slower, and your opponent will as well. The opponent's ally, however, can move in real time because he's further away, and can easily walk around your slow person, enter the melee, and attack you in the back. Or even worse, get into position comfortably, enter the combat and shoot his bow. Dodge this.

Disallowing people to enter a melee that has already been initiated prevents you from helping someone that you stumble upon in the woods who is attacked by a bear. You will have to watch powerlessly while he's torn asunder.

So yeah, still thinking about that. But it's a long way away.
Spoiler: Design rant (click to show/hide)


Terraingenerator first though. Generating cool terrain piece-by-piece and still letting them seem to match together seamlessly is not trivial. Slow transitions in height, such as swamp-plains-hills-low mountain-mountainrange-mountainpeak, that span multiple terrain-parts, are hard to match together. Perhaps some kind of rudimentary "uber-map" is in order. Something very low-resolution, but spanning an area which is "infinite" for all practical purposes.

Rivers were an easy solution, they either always flow outwards from a beginning point (away from already generated terrain), or a river "endpoint" (lake, sea) is created from which the river is created in reverse. This might create too many "radially oriented" rivers though. The ubermap may solve that as well.



I feel kinda bad spouting how cool-my-game-is-gonna-be while having nothing to show for it yet. I don't like people who do that ;). So I'll keep this thread more technical-oriented, until it's actually time for game-dynamics.
Logged

This one thread is mine. MIIIIINE!!! And it will remain a happy, friendly, encouraging place, whether you lot like it or not. 
will rena,eme sique to sique sxds-- siquo if sucessufil
(cant spel siqou a. every speling looks wroing (hate this))

Outcast Orange

  • Bay Watcher
  • [SOMETIMES_SQUID]
    • View Profile
    • The Outcast Orange
Re: C++ Tile based 3D engine
« Reply #11 on: January 25, 2010, 09:57:33 pm »

I don't think you understand the basic assumptions of bullet time.
What the hell is a bullet time bubble?
Like you hit a button on your watch and your opponent is suddenly forced to move slow motion,
 along with you?

No.
Wrong concept.

The idea is that you are hyper alert,
 and time slows down for you.
It's not like you can walk into a room where people are fighting in bullet time,
 and just walk past their slow-motion battle and on into the bathroom.

That hurt my brain so bad when you started
 elaborating on ways a 3rd person could interfere.
Logged
[7:53:55 PM] Armok, why did you demand that I don't eat you?
[7:54:34 PM] [Armok]: woooooo

Burried Houses - Platform Explorer Demo H - Cloud Scream

timmeh

  • Bay Watcher
    • View Profile
    • My Portfolio
Re: C++ Tile based 3D engine
« Reply #12 on: January 25, 2010, 10:36:55 pm »

@Outcast Orange - I think they were discussing how to hand bullet-time in a multi-player setting.  Does everyone on the map slow down each time a fight starts, no matter how far away they are?  How would it tell who was in combat, and such.  The multiplayer half of Fear managed that by simply letting the score-leader choose when to use it, or something like that, and it effected everyone.

@Siquo - The concept for this is awesome!  I played Toribash with my brother a few days ago, and was thinking how awesome it would be if I could design move ahead of time and run them like macros...  Looking forward to watching this :D
Logged
On the Wall is a Masterfully engraved carving of Urist McHardcastle and Goblins. Urist McHardcastle is surrounded by the Goblins. The Golbins are stamping on Urist McHardcastle. Urist McHardcaste is laughing at the Goblins. The carving related to the prolonged and bloody death of Urist McHardcastle in the Fall of 1659, the Winter of 1659, and the Spring of 1660. On the engraving is an image of Cheese.

Outcast Orange

  • Bay Watcher
  • [SOMETIMES_SQUID]
    • View Profile
    • The Outcast Orange
Re: C++ Tile based 3D engine
« Reply #13 on: January 25, 2010, 11:13:30 pm »

Oh, I see.
Well, just do it by LOS.
If you have LOS to anybody in bullet time, you are in bullet time.
In odd situations, it would spread down a hallway,
 and everybody was kung fu fighting.
Logged
[7:53:55 PM] Armok, why did you demand that I don't eat you?
[7:54:34 PM] [Armok]: woooooo

Burried Houses - Platform Explorer Demo H - Cloud Scream

Siquo

  • Bay Watcher
  • Procedurally generated
    • View Profile
Re: C++ Tile based 3D engine
« Reply #14 on: January 26, 2010, 09:27:22 am »

LOS should fix a number of problems, but being forced into slow-motion when all you were doing is passing through can be annoying. If two players start a fight in the middle of a town square, and everyone around them is forced to slow-motion, that's griefing waiting to happen.

The best thing I could come up with so far is a choice, being given when you see a fight happening, whether you want to join or not. Your choice is permanent, for the duration of the fight. The "bubble" means a visible bubble of slowed-down space-time. Entering it (getting too close to the fighters) makes you go into slowmotion. Yes, it will look weird-ish, but that's a small price to pay. Also, you could set your preferred speed (from very slow to real-time), and the bubble would take the slow-motion settings of the player with the slowest settings. NPC's should be able to fight in real-time, if you have set it up that way. Blocking and attacking in melee in real-time is probably very hard, though.



I know the concept is awesome, but it's still a concept (or rather a whole library of concepts), in a galaxy far, far away. A LOT of stumbling blocks are on the road ahead. This project is more of a learning-experience into C++, multithreading, networking, etc. and has no hope of ever being finished. I may post the whole shebang of things that I want in the game in another thread.

Although DF isn't finished either so there's still some hope to have something playable in 2015.  ;D

Technical again:
Currently thinking on the ubermap. Probably going to do it chronologically, starting with plate tectonics, liquid erosion, then air erosion. Then some random stuff to make it more interesting. From there, generate blocks of world that interconnect seamlessly, and/or have some kind of overlapping-area (no straight lines between biomes, but grassland turning into patches of sand in the grass slowly turning into patches of grass in the sand turning into desert). Then add soil/rubble/rockface with limited liquid abilities (a cube of sand turns into a neat pile of sand) to create partly-filled tiles for a smooth landscape. Blocky mountains look odd.
« Last Edit: January 26, 2010, 09:31:23 am by Siquo »
Logged

This one thread is mine. MIIIIINE!!! And it will remain a happy, friendly, encouraging place, whether you lot like it or not. 
will rena,eme sique to sique sxds-- siquo if sucessufil
(cant spel siqou a. every speling looks wroing (hate this))
Pages: [1] 2 3 4