Jump to content

SpiderPig

Developers
  • Posts

    2,203
  • Joined

  • Last visited

Blog Entries posted by SpiderPig

  1. SpiderPig
    Thought I'd show off what I've been working on this weekend.  I have implemented procedural grass as found here at Outerra.  There is still more work to be done on it but so far it looks promising.

  2. SpiderPig

    The Seventh World
    After months of work on various base classes I have finally started to re-build my game in Ultra.  There is still a lot of work to do to these classes (voxel terrain especially) but my aim is to keep the ball rolling by getting them to a workable state so I can build a playable game and then work on fine tuning later.  Plus, I find it more fun to fine tune classes when there is a working game at your finger tips rather than just a bland test project.
    I started off with voxel terrain.  Basically the terrain is a cuboid structure with 6 terrains projected onto each face, each one being called it's own world (six worlds).  Each face has it's own gravity direction.
    First I created 8 points to form a cube where the bottom 4 corners are pulled in slightly.  The yellow lines indicate each worlds up direction.  Gravity is simply the inverse of this.

    Then I can project a heightmap onto each world.  First worlds heightmap:

    All six:

    All maps are the same at the moment and the edges need to be blended together so they don't form sharp 45 degree angle slopes.  But in some spots the maps line up and the blending is quite nice.

    This is so much better than what I achieved in Leadwerks and I'm really excited to knuckle down and get the terrain completed.
  3. SpiderPig
    Took some time to figure out the best approach to do this but I've got it now.
    To start with I created components that are all the same size.  I am using 16x16x16 components.  The voxel terrain is 128^3 so dividing that evenly is 8^3 components.  In this image there is 512 of them.  The red are inactive and the green are active (they have a model the represents the surface).  This posed a problem for very large terrains.  I would need a component size small enough so that LOD and real-time editing are fast but too small and the component count would become unmanageable.

    So I made an option to create dynamic components.
    voxel_object->EnableDynamicComponents(true); This means instead of a component being exactly 16m cubed in size (the lowest LOD level would have 4 vertices and two triangles for a flat plane) it would now be resized to have a mesh that is 16 nodes cubed (16x16 vertices for a flat plane regardless of LOD level).  Which mean it now looks like this;

    Instead of 512 components there is only 36 and 10 of them are active.  It means I can lower the component size to something really small like 8x8x8 or even 2x2x2.  I can experiment with this to find a balance between speed of LOD updates and editing updates.
    Wireframe;

    And the terrain can be represented by a minimum of 1 component.  It also means I can try creating steaming voxel terrain which would be fun!

    I need to finalise the real-time LOD system to work with this and then I can begin making large terrains and test it's performance.
     
     
  4. SpiderPig
    The Seventh World is a Medieval Fantasy Survival game, inspired by the likes of Skyrim and ARK Survival Evolved.
     
    It's been under development for the last two years but only in the last eight months has a real commitment been made to it.  Spending every night after work and every other day working on it I've achieved a base from which to build on.
    The cuboid landmasses are called fragments.  They are arranged as a sphere to make up a planet.  Game-play will eventually include moving from one fragment to another.
    Each fragment face has a gravity direction toward the center of the land mass.  Each face is known as a World.  The top most face is the First World.  The left, The Second World.  The right, The Fourth World.  The North face is The Fifth World and the South face is The Sixth.  The last face, opposite to the top is The Third World.
    Each World is separated by an area of weak gravity known as the gravity void, making it difficult to travel between them without the right equipment.  Each world will also have unique features and biome characteristics.
    In total, there will be approximately 12.5 million square kilometers of explorable terrain.
     
     
     
     
     
     

    There is minimal game-play at the moment.  You spawn in one of the procedurally generated towns and the most you can do is;
    Harvest trees. Drink from the well. Sell/buy items from the shop. Eat equitable editable items. Run around.  
     
     
    What I'll be working on next is fixing the obvious graphics issues.  This will include;
    Terrain patch seams. Billboard trees and their many issues. Bugs when nearing the gravity void. Distant fragment seams.  
     
     
     
     
     
    The Plan
    My overall plan is to get this to an alpha stage so it can be released on Steam.  For this stage I want to have the following implemented;
    VR Multiplayer Building mechanics. Basic Missions. Improved Graphics.  
    Bug Warning
    Physics shapes are not releasing and are causing memory usage to increase.   Various other small memory leaks. Crashes in the gravity void sometimes. Feedback and suggestions are welcome.  I hope to have a progress update every one to weeks.
    Download Here
  5. SpiderPig
    After three weeks of work, Pre-Alpha v1.1 is ready.
     
    Terrain
    The terrain has seen some behind the scenes improvements with speed as well as visual improvements to geometry and texturing.  When I manage to get Texture Arrays working I will be able to finish of the new texturing shader that will include Tessellation and over 16 different texture maps as well as various masks that will paint according to erosion and forest locations.
    An image of one of the mountains randomly placed in the First World, textured with two 4k textures.  The way the generator works is there is a predefined list of terrain features, like mountains, rivers and valleys.  Based on a low resolution base map which is unique for each fragment, these features are placed at different scales, positions and rotations.  They will also merge with one another to provide enough variation that it will be hard to see any similarities.
    At the moment though there are not enough maps to make this unnoticeable.
     
     
     
     
     
    Saving and Loading
    I have now implemented the ability to save and load a game.  Currently the only states that are saved are the players position, stats and inventory.
    Each slot shows the date and time that it was saved on as well as the save name and version number.  Slots can be deleted and overwritten.  The version number will change over the course of the updates, but the ability to load older versions will always be available.  And to save a new game, click the empty slot then click save.
    Now that this mechanic is done I can work on more game play.
     
     
     
     
     
     
    What's Next
    The next step is to improve the blacksmith and general store.  These two places will be the first to provide work opportunities for the player.  These opportunities will improve skill and eventually allow you to buy and use crafting equipment outside of the towns.
    I will also be implementing some other mercenary characters and animals to hunt.  The mercenaries will just offer some fun conflict to begin with and the animals will offer another source of income.  I hope to have a deer and wolf done by the next update in a few weeks.
     
    The full change log is packaged with the game, here.
  6. SpiderPig

    The Seventh World
    The Seventh World
     
    Lately I have been hard at work implementing all the basic classes in Leadwerks 5.  My aim is to get the game playable by the end of the year.  Once I've achieved that I'll slowly hack away at bugs and visual quality before release.  These are what are planned for the first release;
    Menus Main Pause Gravity Multiple Sources Edge of the World Foliage Pine Tree Fern Berry Bush Animals Deer Wolf Rabbit Character Harvesting Hunting Crafting Basic Building  
    Here are some screenshots.
    The World will be hidden behind a vail of clouds.  In the future I hope these can be dynamic volumetric clouds.
     
     
     
     
     
     
     
     
     
     
    The basic foliage system uses two noise maps.  One decides if a plant should exists at the terrain vertex, the other gives the plant a random offset to that vertex (so to not have a grid like appearance), and a random scale, and a random rotation.
     
    <- Offset, Scale & Rotation map.
     
     
     
     
     
     
     
    In game Pause Menu.
     
     
     
     
     
     
     
     
     
     
     
    Inventory system.  Certain parts of the players body will be able to hold items such as baskets and backpacks.  By default the player will only have a slot available in each hand and the shoulders.  This will give the player enough space to collect the materials needed to craft a basic backpack that you can then equip onto your back, expanding those slots.  Upgrades to the backpack can further increase these slots up to a maximum.
    Items in the vicinity of the player that have an inventory will also appear in the left hand side.  Such as wheelbarrows, or baskets left on the ground.  Multiple wheelbarrows will enable the player to collect more than they can carry at one time.
    The quick change can only be linked to items that are carried on the player.
     
     
     
    On Monday I'll start work on creating the other worlds.  I also hope to be able to create a Perlin Noise generator for heightmaps.  I will create a system to disable the player controller if you get too close to the edge of the world.  This way my own gravity system can take over and pull the player into oblivion - unless your quick to react you may be pulled into an orbit around the land mass!
    I will also be working on a system to place cliff models around the terrain based on the slope of the terrain, and how close to the edge of the world it is.
     
    ~ Matt
  7. SpiderPig

    Voxel Terrain
    Instead of settling for one way only to voxelize a terrain I decide to make it possible to select between a few of them depending on what was required.  They're are basically just two methods, forward or backward.
    enum VoxelMethod { VOXEL_METHOD_FORWARD, VOXEL_METHOD_FORWARD_CONTOUR, VOXEL_METHOD_BACKWARD, VOXEL_METHOD_BACKWARD_CONTOUR }; Forward starts with a parent node and checks each corner against some function that says if the corner is above or below some user defined surface.  If the node has been determined to represent some part of the surface it is subdivided into eight new nodes and the process repeated until the lowest subdivision level is achieved.
    Backward creates a 3D grid of points that are iterated through in a three layer nested for loop.  The points are spaced at the lowest node size required (1m cubed in this case) and then tested with the same user defined function for forward voxelization.  The points and then looped through again to find which ones represent the surface and then the parent node is subdivided until it reaches the node that represents these points.  It starts from the end and works it's way back.
     
    As shown here the forward method is fast but in most cases leaves a few holes in the mesh as stated in my previous entry.  I've left the method in there because it might be useful in some situations.

     
    Here is the result from using the backward method.  Ignoring the bounds of the terrain you can see there are no more holes in the surface.  I haven't done any speed comparisons yet but for this small 128x128x128 terrain I can't tell a difference.  It also uses a bit less memory too than the forward method.  Most likely due the fact only the nodes that represent the surface are actually created.  This was a feature I removed from the forward method because it made more holes with it than without it, but it could be re-introduced later know that I know what the issue is.

     
    A view from inside looking out.

     
    This leads me to the small floating fragments caused by using 3D noise and the potential resolution by the contouring method.  I'm thinking in either the forward or backward case, when a surface is found it will start to follow the surface by calculating where it might be based on the surface it's already found.  This should mean that only a surface connected the previous nodes surface will actually be created.  It may even be faster due to it only having to sample the noise when it knows it's close to it.  The issue though is first determining which surface is the main surface, otherwise it could find the small fragment first (pictured) and class that as the main surface and therefore disregarding the larger main surface.  This requires more thought.

     
    Next though I am going to work on render methods.
    enum RenderMethod { RENDER_METHOD_MARCHING_CUBES, RENDER_METHOD_TRANS_VOXEL, RENDER_METHOD_CUBOID, RENDER_METHOD_SURFACE_NETS, RENDER_METHOD_DUAL_CONTOURING };  
  8. SpiderPig

    General
    For the last for years I've been lurking in the forums waiting patiently for the release of Ultra.  I thought I'd be a good time to start up my blogs again about The Seventh World.  The game that has been in the works for over a decade!  I started this game in the Leadwerks 2 days.  It started off as a very simple game but as I'm sure you're all aware, simple ideas can quickly grow into monsters of an undertaking if you let them!
     
    A few years ago, as I started fleshing out gameplay I was running into performance issues.  Three things were happening;
    Leadwerks wasn't the best at handling large amounts of objects on screen and culling them efficiently. I had vast amounts of code to draw the inventory system which relied heavily on the drawing commands, which again dropped the FPS. I added a second camera into Leadwerks for the placement of items onto a character model which dropped the FPS further like a stone. Ultra was in the works at the time and I was faced with a decision.  Reduce the scope of my game, move to a different engine or wait for Ultra.  I dabbled in other engines but Leadwerks and Ultra can not be replaced for me.  I prefer the SDK approach to game making over an editor.  Even though you can code C++ in many other engines, they just felt too clunky for my liking.  So I waited.
     
    Now, with Ultra on the visible horizon and the fact that I know it will handle the scope of my game with ease, I've been spending the last few months preparing assets and my code library's for Ultra.  Things are going super well and I have started work on plugins for the game that I plan to release when they are done.  So far I have started;
    Shader Editor Edit shaders in game and instantly see changes 80% complete Voxel Terrain Realtime editable terrain 20% complete Procedural Foliage Volume Place multiple volumes that can spawn on any mesh, not just terrain 20% complete Dynamic Atmosphere Day night cycle + volumetric clouds 10% complete Gravity Manager Multiple gravity sources 90% complete Sound Manager Takes into account the speed of sound and adds a delay to playing sounds that are far away 90% complete Console manager 90% complete Procedural Roads & Paths Set two points on a map and a road or path will be made between them, adapting to the terrain.  E.g. If there's a mountain the road will go around 10% complete  
    Most of the code is done for these plugins, I just need Ultra to port it over too and get it working.  I'll be making these plugins as I develop my game and when they're in a stable enough state thy will be released with the shader editor being the first.
    Very excited to get my hands on Ultra!
  9. SpiderPig

    Voxel Terrain
    For the past few months I've been working on Voxel Terrain for Ultra.  I started by creating an octree whose parent node encapsulates the bounds for the entire terrain and must be a perfect cube with dimensions that are a power of two.  This ensures all child nodes can be neatly subdivided.  If a more rectangular terrain is required the octree creates more than one parent node to make up the rectangle.
    The next step was to subdivide the parent node to a level where each node would represent a portion of the terrain called components (or chunks).  Each component has the potential to be a model with one mesh that forms the surface.  Here the terrain dimensions are 2048 x 1024 x 2048 which are composed of four parent nodes each with a size of 1024x1024x1024.

    The next step was to create a recursive function that would start by checking each component to see if it intersects the surface, if it does it will subdivide it adding eight children which are then also checked.

    The intersects_surface() function is a custom function and must return true if the current nodes needs subdividing, it also sets the current nodes voxel_index which says how the node is to be rendered later on.  There is a few issues with this technique though that I need to re-think.
    If I voxelize a large plane, all is well.

     
    However adding some noise to the mix results in some gaps.

     
    Upon closer inspection it turns out that even though a node's corners may all be inside or outside the surface, it's child node may yet still represent the surface.  I guess that's why we use noise - because it's random!  Below shows a components node has the lower four corners outside of the surface, however if it were subdivided further at some point the surface will intersect its children.

     
    A way around this is too just subdivide every node until I reach the surface depth (or voxel size, usually 1m cubed) needed.  However this takes time and uses a lot more memory!  Other work arounds may be to test all nodes at the lowest depth required (depending on LOD) and then cache the result and work my way back up to the root node, creating parent nodes for a collection of eight nodes only if they represent a surface, and then deleting those who are complete in air or in solid ground.  Seeing as I'm using multiple threads and the surface_intersection functions is very fast (at least for now) this might be the best and only choice.
    I did toy with the idea to predict whether or not a node intersects a Perlin Noise sample based on it's frequency, amplitude and octaves and what values each of its corners were... but, yeah.  Maybe.
    Here I tried it in 2D but am stumped if I can take the idea any further.  You can see each corner is a negative number so by the standard test I'm using the node shouldn't be subdivided, yet clearly if it were it's children would represent some of the surface (shown in white).

     
    Who knows, maybe this has been solved already by someone a lot smarter than I am or large amounts of time and memory is just what voxel terrain does?  I know it's not what a SpiderPig does...

×
×
  • Create New...