Jump to content
  • Advertisement

Leaderboard

The search index is currently processing. Leaderboard results may not be complete.

Popular Content

Showing content with the highest reputation on 06/01/19 in all areas

  1. 2 points
    Looks mighty close to 30 divided by the skill level.
  2. 1 point
    Hi! I hope I'm in the right forums, because none of the others seemed fitting for me. I recently launched my first mobile game after years of work and a lot of money invested for visuals. Now when I show my game around people always praise me for it and tell me that it looks really interesting, but nobody really plays it. I'm a little frustrated, because I don't know where to go with my game except for investing thousands of dollars into marketing. But, I don't want to invest into marketing, if I'm not sure what most people actually think about my game. I have also shown the game in some forums already and subreddits, but it seems to not spike much interest. Probably because it seems like it's just another beginner's mobile game. So, what would you recommend me to do in my situation? I quit my job to do this and spent thousands of hours into this project. I feel like just dropping it and trying a hyper casual mobile game next, but then all of my hard work would have gone to waste except for the experience. What would you recommend me?
  3. 1 point
    Small update: I was up a bit late yesterday trying to come up with a good level design, but I'm going back and forth a bit so it has been yet another time sink. Even my meshes are still not textured but in the game and working just fine. I'm going to work on the music and sound effects shortly as I'm almost done the boss battle phase. If I have time I'll do a quick texture job, but if not I still meet the requirements and will clean up the game after the deadline. It is 4:54 PM UTC now, so I have until 11:59 PM UTC to finish up! Time to pull out my midi keyboard and get one music track out, and some very basic SFX done.
  4. 1 point
  5. 1 point
    Atum is a great game engine but one important feature was missed until now. Finally a full version of documentation is available. Documentation available via link https://atumengine.com/doc_html/html/index.html. Documentation covers basic work with editor, how script system is working and description of script and C++ classes.
  6. 1 point
    Opcode (http://www.codercorner.com/Opcode.htm) may be a good choice.
  7. 1 point
    Doh, I misread that. I thought it was due June 1st Midnight.
  8. 1 point
    It has been quite some time since we posted something. And it's true, for the most part we didn't really do much. Work on Lyfe just wasn't such a high priority as university for example. But we're back. And with that we switched engines. To be fair, there wasn't much work we had to replicate. Most of the time we invested so far was learning how to handle simple things in Unreal when we all had way more experience in working with Unity. A mistake. But I think we're on the right path now. This of course means there is no real gameplay footage to show. The actual gameplay is simply less of a priority compared to the editor so we're focusing on that and trying to get a stable version running. For more information on the concept behind the cell editor or at least the basic sculpting check out this entry. I won't go into detail about it here. Today I will focus on the technical side of implementing metaballs and having the calculation run on your GPU rather than your CPU. I'm doing this partly to show we're actually working again but als since it took me way too long to figure out how this works and I didn't have good resources. So feel free to use our code and adapt it to your needs. Anybody here who doesn't know how metaballs work or what they even are? Here are some links for you if you're interested: metaballs (what even are they?) metaballs in blender (a bit more detailed) maths behind metaballs Let's start with the basics: The basic shape of the cell is formed by nodes that are connected to each other. Each of these nodes is the center/anchor for a metaball. This means each of these nodes exudes a charge in the field around it. This field is simply represented by points in 3d space. If two nodes are close to each other the charges sum up. This results in smooth transitions between blobs/metaballs. For more details click on the third link or write a comment. On to the C# script of our editor. This is where we prepare our data and read the chargefield once it's done computing. private float[] CalculateCharges(Vector3Int _resolution) { float[] charges = new float[_resolution.z * _resolution.y * _resolution.x]; List<SNode> nodes = baseNode.GetAllChildNodeMetaData(new List<SNode>()); int kernel = cs_Charges.FindKernel("CSMain"); ComputeBuffer nodeBuffer = new ComputeBuffer(nodes.Count, SNODE_SIZE); nodeBuffer.SetData(nodes.ToArray()); ComputeBuffer chargeBuffer = new ComputeBuffer(charges.Length, sizeof(float)); chargeBuffer.SetData(charges); cs_Charges.SetBuffer(kernel, "nodes", nodeBuffer); cs_Charges.SetBuffer(kernel, "charges", chargeBuffer); cs_Charges.SetVector("EDITOR_GRID_DIMENSION", new Vector4(_resolution.x, _resolution.y, _resolution.z, Meta_CellEditor.SCULPTING.GRID.SCALE)); cs_Charges.SetVector("basePos", transform.position); cs_Charges.SetInt("numNodes", nodes.Count); cs_Charges.Dispatch(kernel, _resolution.x / 8, _resolution.y / 8, _resolution.z / 8); chargeBuffer.GetData(charges); chargeBuffer.Dispose(); nodeBuffer.Dispose(); return charges; } So. Since the basis for metaballs is chargefield this method takes a Vector3 for the resolution of this field. We then make a float array of that size to give to our compute shader and have it filled there. List<SNode> nodes = baseNode.GetAllChildNodeMetaData(new List<SNode>()); This line simply collects all child nodes and stores their metadata in a simple struct that can be transferred to the shader. public struct SNode { public Vector3 position; public Vector3 distortion; public float cubePortion; public float radius; } This is how the struct looks. The information in cludes the position within the charge field with 0/0/0 being the center. The distortion/deformation of the sphere so if it's more of an oval. The cube portion, so if it's more of a sphere or a cube (not fully implemented yet) and the radius. Pretty simple stuff. int kernel = cs_Charges.FindKernel("CSMain"); Next we find our kernel within our shader so we can pass values to it and run it. The actually initialized this shader in an Init method beforehand. cs_Charges = Resources.Load<ComputeShader>("Shaders/cs_Charges"); ComputeBuffer nodeBuffer = new ComputeBuffer(nodes.Count, SNODE_SIZE); nodeBuffer.SetData(nodes.ToArray()); For this next part I can only recommend using ComputeBuffers. Just initialize it with the count of elements and the size of each element. In our case this is the size of 8 floats. After that we push our data into the buffer. ComputeBuffer chargeBuffer = new ComputeBuffer(charges.Length, sizeof(float)); chargeBuffer.SetData(charges); We do exactly the same thing for our charges. And this is where buffers come in handy: You can not only use them to get data into your shader but also to read it from there if you write it into a buffer. cs_Charges.SetBuffer(kernel, "nodes", nodeBuffer); cs_Charges.SetBuffer(kernel, "charges", chargeBuffer); cs_Charges.SetVector("EDITOR_GRID_DIMENSION", new Vector4(_resolution.x, _resolution.y, _resolution.z, Meta_CellEditor.SCULPTING.GRID.SCALE)); cs_Charges.SetVector("basePos", transform.position); cs_Charges.SetInt("numNodes", nodes.Count); Next we set the buffers in our shader. It's important that every one of these strings corresponds to a variable of the same type in your shader. If you only want to transfer a single value, you don't need to use the big ComputeBuffers. The simple methods SetVector/SetInt/SetFloat will do. This is actually where the naming of your variables is shown to not be the best: resolution isn't actually the relsolution but rather the dimension and together with the scale makes up the resolution. cs_Charges.Dispatch(kernel, _resolution.x / 8, _resolution.y / 8, _resolution.z / 8); And this is where we actually run our shader code. I'll behonest here and tell you that I'm not quite sure how these last 3 parameters work but so much: each one stands for the number of core groups. So basically we're using 8 groups of 8 groups of 8. So we divide what we need to calculate to split it evenly on all these cores. This becomes really important if you want the parallelization to work. chargeBuffer.GetData(charges); chargeBuffer.Dispose(); nodeBuffer.Dispose(); return charges; At the end we simply read the data our shader stored in the buffer and dispose our buffers to free the memory. Anybody familiar with C or C++ knows this is to prevent memory leaks. That is all the C# code basically. Simple stuff and no maths. It only get's worse from here on. // Each #kernel tells which function to compile; you can have many kernels #pragma kernel CSMain struct Node { float3 position; float3 distortion; float cubePortion; float radius; }; StructuredBuffer<Node> nodes; //node positions in world space int numNodes; float4 EDITOR_GRID_DIMENSION; //xyz are dimension, w is scale float3 basePos; //position of the base node RWStructuredBuffer<float> charges; float3 GridPosToLocalPos(float3 _gridPos) { _gridPos -= EDITOR_GRID_DIMENSION.xyz / 2.f; _gridPos *= EDITOR_GRID_DIMENSION.w; return _gridPos + basePos; } float CalculateCubeCharge(Node _node, float3 _voxelPos) { return 0; } float CalculateSphereCharge(Node _node, float3 _voxelPos) { float3 d; d.x = pow(_voxelPos.x - _node.position.x, 2); d.y = pow(_voxelPos.y - _node.position.y, 2); d.z = pow(_voxelPos.z - _node.position.z, 2); float r_squared = (d.x * _node.distortion.x + d.y * _node.distortion.y * 12.f + d.z * _node.distortion.z) / pow(_node.radius * 12, 2); if (r_squared < 0.5f) { return 1.f - r_squared + pow(r_squared, 2); } else { return 0; } } float CalculateCharge(Node _node, float3 _voxelPos) { float r = (_node.cubePortion * CalculateCubeCharge(_node, _voxelPos)) + ((1.f - _node.cubePortion) * CalculateSphereCharge(_node, _voxelPos)); return r; } [numthreads(8,8,8)] void CSMain (uint3 id : SV_DispatchThreadID) { float3 voxel = id; float3 voxelPos = GridPosToLocalPos(voxel); for (int n = 0; n < numNodes; n++) { int index = id.z * (EDITOR_GRID_DIMENSION.x * EDITOR_GRID_DIMENSION.y) + id.y * EDITOR_GRID_DIMENSION.x + id.x; charges[index] += CalculateCharge(nodes[n], voxelPos); } } So. This is the entirety of our shader code for the metaballs. We still need to tweak some of the static values so please, feel free to experiment when using this code. The struct at the top is basically our SNode. After that our buffers and set values follow. Note that nodes is just a StructuredBuffer while charges is a RWStructuredBuffer. The RW means read-write. So the shader can not only read the values stored but also write in there. I think the best way to go through this is from top to bottom. float3 GridPosToLocalPos(float3 _gridPos) { _gridPos -= EDITOR_GRID_DIMENSION.xyz / 2.f; _gridPos *= EDITOR_GRID_DIMENSION.w; return _gridPos + basePos; } This method simply turns a gridposition to a position in local space. Easy as that. Calculate cube charges is not implemented yet. (sorryyyyyy... We'll add how that works once we got it figured out.) float CalculateSphereCharge(Node _node, float3 _voxelPos) { float3 d; d.x = pow(_voxelPos.x - _node.position.x, 2); d.y = pow(_voxelPos.y - _node.position.y, 2); d.z = pow(_voxelPos.z - _node.position.z, 2); float r_squared = (d.x * _node.distortion.x + d.y * _node.distortion.y + d.z * _node.distortion.z) / pow(_node.radius, 2); if (r_squared < 0.5f) { return 1.f - r_squared + pow(r_squared, 2); } else { return 0; } } And here we simply calculate the charge one node exudes on one point in space. I myself am not sure about all the maths in there but again, you can read up on that by clicking on the third link at the begininng of this. float CalculateCharge(Node _node, float3 _voxelPos) { float r = (_node.cubePortion * CalculateCubeCharge(_node, _voxelPos)) + ((1.f - _node.cubePortion) * CalculateSphereCharge(_node, _voxelPos)); return r; } This function again calculates the charge on one point from one node but factors in the cube and sphere portion of the corresponding node. [numthreads(8,8,8)] void CSMain (uint3 id : SV_DispatchThreadID) { float3 voxel = id; float3 voxelPos = GridPosToLocalPos(voxel); for (int n = 0; n < numNodes; n++) { int index = id.z * (EDITOR_GRID_DIMENSION.x * EDITOR_GRID_DIMENSION.y) + id.y * EDITOR_GRID_DIMENSION.x + id.x; charges[index] += CalculateCharge(nodes[n], voxelPos); } } And finally we come to the actual core method. And here we find our 8/8/8 again. These values need to correspond to the ones when dispatching the shader. Otherwise you won't be able to use the id correctly. In your case the id points to the point in space we want to calculate the charge for. We use our GridPosToLocalPos here. This is important or all our beautiful metaball would be anywhere but where we want them to be. Below that we iterate over all nodes and sum up their influences on this one point in space. For a 200 * 200 * 10 chargefield with 10 nodes in it this code runs in less than a second. And that's why we use compute shaders, children. But for real, this would not be feasable when running on a CPU. But I'm 100% sure this code could be improved even further. Anyway, I hope this code helps someone who wanted to use compute shaders but didn't know how or wanted to implement metaballs. Cheers and keep on evolving.
  9. 1 point
    Erin Catto gave an exhaustive presentation on this topic this year at GDC: http://box2d.org/files/GDC2019/ErinCatto_DynamicBVH_Full.pdf
  10. 1 point
    Hey all, Together with 22 other students i have been working on this game for almost a full year. We're closing in on our release date (End of June) and i would really love to get some feedback as well as some exposure/tips on how to get exposure. Here's a short description: Captain Starshot is a roguelike dungeon crawler in which you play as the mighty Captain himself! You explore the galaxy in search for hostile aliens to defeat. Travel through sectors in order to find the alien mothership and take on their leader. Transition between open space battles to intense on-foot alien encounters. Upgrade your squad with different abilities and vanquish the evil aliens from the universe! You can find our game here: I realize this is a bit of shameless marketing but it seems like this way you'd be able to give me the best feedback. What information should i add on the storepage? How can i get people to view our game more?... Anything you feel like could help us get this game out there. We worked hard on it for the past year and i really hope to share our efforts with the world and have people enjoy our game! You can find a video of the narrative intro to the game attached Thanks, Nick CaptainStarshotNar.mp4
  • Advertisement
  • Advertisement
  • Popular Contributors

  • Member Statistics

    • Total Members
      257337
    • Most Online
      6110

    Newest Member
    alex-seifarth
    Joined
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!