Hello everyone!
This challenge! I voted for Doom and Dungeon Crawler and I am really happy with the results of the poll. The main goal will be trying to create something with his own touch. For my last and first challenge I pretty much only tried to meet the basic requirements. This time I want to try to go a little bit further.
Basics
For this challenge, I want to try to get into 3D again. I actually tried to improve my Blender "skills" over the last couple of weeks. Since I was also excited for the Doom challenge I will also make this an FPS game trying to combine ideas I had for both challenges. I already started working on the main weapon. Sadly I don't have any screenshots on this laptop. The look of the models will be pretty basic since my ability to use Blender is still on a rookie level.
Gameplay
The game will take place in a high tech robot base that contains a lot of different rooms and hallways. If I have enough time these actually might dynamically change. The art style will be a shiny white look with simple mapping elements in order to keep things simple. The goal of the player is to find and open a portal that leads into the next level. In order to activate the portal, the player has to collect energy crystals that are scattered around each level.
Enemies
As enemies, I will try to create a couple of different robots that are trying to stop the player from opening the portal. These robots can either be destroyed or the player can try to sneak around them. Destroying these robots will allow the player to collect upgrades in order to improve the stats of the player's robot.
Loot
The main loot of the game will be the energy crystals which are needed in order to open the portal to the next level. Furthermore, enemies will drop a different sort of crystals that act as energy restoring functions of the robot or adding new abilities to his kit. There will also be other items like maps or stealth devices that help the player to get through each level. The energy of the robot will also be usable in order to purchase upgrades at rare upgrade stations which can be found once in each level.
Audio
This is a thing I am kinda worried about. Usually, I use a simple piece of software in order to create some retro sound effects very fast. Sadly I think these will not fit the style of this game. If this does not work I will either have to pick up some free sound effects, what I really don't like, or I will have to find a different way.
Visual Art
I kinda want to achieve a very "clean" and high-tech looking art style. This is kinda hard to explain without showing some visual references. I will talk more about this in my next posts. The reason for this is first, that I think this art style fits the game idea very well and second, that my Blender skills should be good enough to create some models in this style.
Project Scope
Completing this challenge in time will be pretty hard for me this time. First of all, I am going to try a lot of new stuff that I have not done before. Second, creating 3D Models takes a lot more time than creating simple 2D sprites, at least for me. I actually have a lot of ideas for this project. I kinda would like to implement procedurally generated levels. I don't think I will have enough time for this though. If I still have motivation left after the challenge is completed I might continue this project afterward!
Sadly I can not show my current progress of the project since I can not access the project until I am back home on Thursday.
Will try to make another post next weekend!
Thanks for reading!
Good look to everyone who is also going to join this challenge!
- Znippy

Project Title:SteamFallDescription:The player begins the game in a underground cryogenic lab where he wakes up after 70 years of being cryogenically frozen. The player goes to the surface only to find a desolate wasteland. You must find out what happened.Includes:
Post-Apocalyptic & Steampunk atmosphere.
Unique Story
First person view point.
Ambitious in scope.
Team Name:Team DATA7 Previous Work:N/A - first title as a team.Talent Required:3D Artist (2+)
Ability to export to FBX format.
Experience with UE4 toolset a bonus.
Expected to create additional props & Hardsurfaces And environments And 3D Characters
Expected To Rig & Animate any creature
Unreal Engine Programmers (2)
Experience with Unreal required.
Experience with UE4 toolset a bonus.
Expected To Code in-game Systems
Must Be Able To Work with and be nice to others
Contact:E-mail: Data7games@gmail.com

Hello, I just want to have a few questions which are bugging my mind lately. I really didn't touch directX for probably 6 years now and since I did many things changed, so I would like to ask few questions, I would be really happy if someone could help me. I have started playing with a really old game (DX9, ~2005) some time ago. It uses very old indexed skinning method, using INDEXEDVERTEXBLENDENABLE and softwarevertexprocessing. This got broken though after some Windows Update, I believe it was 14393, it runs on max 2 fps while the sw processing is used, I tried to reverse engineer the dll, but I think I'm kinda out of luck, but if anyone has idea why that is, that would be the first question. Second question is, what's the best alternative to this without using shaders? Even if it means the same perfomance, but that it would at least work on the new Windows. Next Question is maybe kinda dumb, but I still couldn't exactly figure out how do shaders work. Let's say a mesh has a vertex buffer of 100 points, how do we pass those to the shader and let the shader know which ones should be moved? And the last is just to confirm my hope, can I lock the vertex buffer to skin the points right there?
Thanks a lot, any help is greatly appreciated, even if only one question, I'm really struggling.

After a break of several years the 3D book project is back on. A few short words now on what this blog is about. I have to deliver my wife to the bus station in a few minutes, then a week alone so may have the time then to explain things. But the 3D book is something I started in 014 and put several years into, then the break, now on again. A win32 app with a text window and an ogl window.
I just remembered I had something written on this so here it is
I write to see if anyone in this community of game developers, programmers, enthusiasts, may be interested in a project I have been developing[off and on] for several years now.
So follows a short description of this project, which I call the 3D-Book project.
The 3D-Format Reader: A new format of media. Imagine opening a book, the left page is conventional formatted text - on the right page a 3D animation of the subject of the text on the left hand page. The text page with user input from mouse and keyboard, the 3D page with user input from a game pad.
An anatomy text for a future surgeon, with the a beating heart in 3D animation.
A children's story adventure book with a 3D fantasy world to enter on the right page.
...
Currently 3D-Format Reader consists of a C++ Windows program: Two "child" windows in a main window frame. Two windows: a text-2D rendering window and a 3D-rendering window. The text-2D window, as its' name implies, displays text and 2D graphics; it is programmed using Microsoft's DirectWrite text formatting API and Microsoft's Direct2D API for 2D graphics. The 3D-rendering window uses the OpenGL API.
A 3DE-Book page is formatted in one of two possible modes: DW_MODE or GL_MODE. In GL_MODE both windows are shown; the text-2D rendering window is on the left and the 3D OpenGL window is on the right. In DW_MODE, only the text-2D rendering window is shown, the OpenGL window is hidden (Logically it is still there, it has just been given zero width).
The 3D-Format Reader reads text files, which consists of the text of the book, control character for the formatting of text, (bold, underline, ...), display of tables, loading of images(.jpg .png ...), and control of 2D and 3D routines.
3D-Reader programming is based on a Model-View-Controller (MVC) architecture. The MVC design is modular: The Controller component handles user input from the operating system , the Model component processes the input, and the View component sends output back to the user on the display. Typical Parent-Child windows programs have multiple "call back" window procedures(winProcs): One for the parent window and one for child window. The MVC model, simplifies message routing by using a call-back window procedure which receives Windows messages for the main window, the text-2D window and the OGL window.
A sample MVC program by Song Ho Ahn was used as a template for the 3DE-Reader.
Rushed for time now, so a hasty sign off and thanks for reading.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
8 - 21 -18
I spent the last few days working on procedural mesh generation. First looking to find a bit of code to do what I had in mind. Which begs the question: What
did I have in mind? I just wanted a cube mesh generator such that...
Requirements
Input: An integer n = units from origin to cube face.
Output:
The vertices for a unit cube centered on the origin.
8n² triangles per cube face.
3 times 8n² verts in clockwise winding order (from the outside of the cube) ready for the rendering pipeline.
Screenshot of some cubes generated with the procedural cube mesh generator.
That was about it for the output requirements. I did not want to hand code even a single vertex and did not want to load a mesh file. I was sure the
code was out there somewhere, but was not finding it. So, a bit reluctantly at first, I started coding the mesh generator. I started enjoying creating this thing and stopped searching for the "out-there-somewhere" code; although still curious how others did this.
Analysis
First question: How do we number the verts? It would be great to conceive of some concise algorithm to put out the cube face verts all in clockwise
order for the outside faces of the cube directly. That seemed beyond me so I plodded along step by step.
I decided to just use a simple nested loop to generate the cube face verts and number them in the order they were produced. The hope(and the presumption) was: The loop code was in some order, running thru the x y and z coordinates in order, from -n to +n, therefore the output would be a recognizable pattern.
The simple nested loop vert generator did not let us down: It gave us a recognizable pattern, at least for this face. It turned out (as expected now) that all six faces have similar recognizable patterns. Plotting the first row or two of verts you can easily see how to run the rest of the pattern.
Plot of the first(of six) cube faces verts output by the vert generator: Input of n: There are (2n+1)² verts per cube face, or 25 verts for n = 2.
This is looking at the x = -n face from the outside of the cube. To simplify the math it helps to define s = 2n. Then there are
(s + 1)² verts, or 25 for s = 4
s² cells on the face, or 16 for 4 = 2.
We are going divide each cell into 2 triangles, so there are 2s² triangles per face, or 32 for s = 4.
Second question: What pattern for the triangles? How to number the 2s² = 32 triangles? What we want in the end is a bit of code such that... for triangles T[0] thru T[2s²-1] or T[0] thru T[31]( for n = 4), we have T[N] = f0(N), f1(N), f2(N). Where f0(N) gives the first vertex of T[N] as a function of N. and f1 and f2 give the second and third verts, all in CW winding order looking into the cube of course.
Here the choice is a bit arbitrary, but it would seem to make things easier if we can manage to have the order of triangles follow the order of verts to a degree.
Numbering the triangles.
And now the problem becomes: Look at the triangle vert list, T0 - T8...T31 in the image, and try to discern some pattern leading us to the sought after functions f0(N), f1(N), f2(N) where N is the number of the triangle, 0 thru 2s²-1. This really is the holy grail of this whole effort; then we have T[N] = f0(N), f1(N), f2(N) and that list of verts can be sent directly to the rendering pipeline. Of course we want these functions to work for all six faces and all 12s² triangles to cover the cube. But first let's see if we can just do this one face, 0 thru 2s²-1..
Thru a bit of trial and error the 32 triangles(T0 - T31) were ordered as shown.
Now we have an ordered list of the triangles and the
verts from our loop.
T0 = 0 5 6
T1 = 6 1 0
T2 = 1 6 7
T3 = 7 2 1
T4 = 2 7 8
T5 = 8 3 2
T6 = 3 8 9
T7 = 9 4 3
T8 = 5 10 11 ... T30 T31.
If we can find a pattern in the verts on the right side
of this list; we can implement it in an algorithm and
the rest is just coding.
Pattern recognition:
It appears
T2 = T0 with 1 added to each component
T3 = T1 with 1 added to each component
In general T[N+2] = T[N] with 1 added to each component, until we come to T8 at least. Also it is hard to recognize a relation between the even and odd triangles,To see what is happening here it helps to look at an image of the generalized case where n can take on any integer value n > 0.
Looking for patterns in this generalized(for any n) vert plot we see...
We have defined s = 2n.
The 4 corner coordinates(+-n,+-n) of the x = - n cube face, one at each corner (+-n,+-n).
There are (s+1)² verts/face numbered (0 thru (s+1)² -1).
There are 2s² triangles/face numbered (0 thru 2s² -1). They are indicated in red.
It's not as bad as it looks iff you break it down. Let's look at the even triangles only and just the 0th vert of these triangles. For any row we see the number of that first vert of the even triangles just increases by one going down the row. We can even try a relation such as T[N].0 = N/2. Here T[N].0 denotes the 0th vert of th Nth triangle. Which works until we have to jump to the next row. Every time we jump a row we T[N+1].0 = T[N].0 + 2 for the first triangle in the higher row. So we need a corrective term to the T[N].0 = N/2 relation that adds 1 every time we jump a row. We can use computer integer division to generate such a term and N/2s is such a term. It only changes value when we jump rows and we get our first function ...
f0(N) = N/2 + N/2s. (even triangles)
Remember the integer division will discard any remainder from the terms and check this works for the entire cube face, but only for the even triangles. What about the odd triangles? Going back to the triangle vs vert list for the specific case n = 2, s = 4 for the first row; we see for the odd triangles T[N].0 = T[N-1].0 + s + 2. And adding this term, s + 2 to the formula for the even triangle 0th vert we get f0[N] for the odd triangles.
f0(N) = N/2 + N/2s + s + 2. (odd triangles)
Continuing this somewhat tedious analysis for the remaining functions f1(N), f2(N) we eventually have these relations for the x = -n cube face triangles.
for N = 0 thru N = 2s² - 1.
defining m = N/2 + N/2s.
T[N] = m, m + s + 1, m + s + 2 T[N] = f0(N), f1(N), f2(N). (even N)
T[N] = m + s + 2, m + 1, m T[N] = f0'(N), f1'(N), f2'(N) (odd N)
So it turns out we have two sets of functions for the verts, fn(N) for the even triangles and fn'(N) for the odd.
To recap here; we now have formulae for all the T[N] verts as functions of N and the input parameter n:
Input: An integer n = units from origin to cube face.
But this is only for the first face x = -n, we have five more faces to determine. So the question is: Do these formulae work for the other faces? And the answer is no they do not, but going through a similar analysis for the remaining face gives similar T[N] = f0(N), f1(N), f2(N) for them. There is still the choice of how to number the remaining triangles and verts on the remaining five faces, and the f0(N), f1(N), f2(N) will depend on the somewhat arbitrary choice of how we do the numbering. For the particular choice of a numbering scheme I ended up making, it became clear how to determine the f0(N), f1(N), f2(N) for the remaining faces. It required making generalized vert plots for the remaining five face similar to the previous image. Then these relation emerged...
For face x = -n T[N] N(0 thru 2²-1) we have the f0(N), f1(N), f2(N), even and odd
For face x = n T[N] N(2s² thru 4s²-1) add (s+1)² to the x=-n face components and reverse the winding order
For face y = -n T[N] N(4s² thru 6s²-1) add 2(s+1)² to the x=-n face components and reverse the winding order
For face y = n T[N] N(6s² thru 8s²-1) add 3(s+1)² to the x=-n face components
For face z = -n T[N] N(8s²0 thru 10s²-1) add 4(s+1)² to the x=-n face components
For face z = n T[N] N(10s²0 thru 12s²-1) add 5(s+1)² to the x=-n face components and reverse the winding order
And these are enough to allow us to write explicit expressions for all 12n² triangles for all 6 faces T[N] and what remains to be done is to implement these expression in code. Which turned out to be a much simpler task than finding the f0(N), f1(N), f2(N) and resulted in a surprisingly short bit of code.
Implementation
I have attempted to make this C++ snippet of code as generic as possible and have removed any dev-platform specific #includes and the like. GLM, a C++ mathematics library for graphics developed by Christophe Riccio is used. It is a header only library.
https://github.com/g-truc/glm/releases/download/0.9.9.0/glm-0.9.9.0.zip
That is the only outside dependency.
// Procedural cube face verticies generator
#include <vector>
#include <glm/gtc/matrix_transform.hpp>
struct Triangle
{
glm::vec3 vert[3]; // the three verts of the triangle
};
/*
std::vector<Triangle> cube_Faces(int n)
Input: integer 'n'; the units from origin to cube face.
Output: vector<Triangle> glTriangle; container for the
12*(2*n)² triangles covering the 6 cube faces.
*/
std::vector<Triangle> cube_Faces(int n){
size_t number_of_triangles(12*(2*n )*(2*n));
size_t number_of_face_verts(6*(2*n +1 )*(2*n+1));
std::vector<glm::vec3> face_verts(number_of_face_verts);
std::vector<Triangle> glTriangle(number_of_triangles);
// Generate the 6*(2n +1 )² face verts -------------------------------
int l(0);
for(int i = 0; i < 6; i++){
for(int j = -n; j <= n; j++){
for(int k = -n; k <= n; k++){
// Below "ifS" strip out all interior cube verts.
if( i == 0){ // do yz faces
face_verts[l].x = (float)(-n); //x
face_verts[l].y = (float)j; //y
face_verts[l].z = (float)k;}//z
if( i == 1){ // do yz faces
face_verts[l].x = (float)(n); //x
face_verts[l].y = (float)j; //y
face_verts[l].z = (float)k;}//z
if( i == 2){ // do zx faces
face_verts[l].x = (float)j; //x
face_verts[l].y = (float)(-n); //y
face_verts[l].z = (float)k;}//z
if( i == 3){ // do zx faces
face_verts[l].x = (float)j; //x
face_verts[l].y = (float)(n); //y
face_verts[l].z = (float)k;}//z
if( i == 4){ // do xy faces
face_verts[l].x = (float)j; //x
face_verts[l].y = (float)k; //y
face_verts[l].z = (float)(-n);}//z
if( i == 5){ // do xy faces
face_verts[l].x = (float)j; //x
face_verts[l].y = (float)k; //y
face_verts[l].z = (float)(n);}//z
l++;
}
}
}
// Generate the 12*(2*n)² triangles from the face verts -------
int s = 2*n; int q = 2*s*s; int a = (s+1)*(s+1);
int f(0); int r(0); int h(0);
for( int N=0; N < number_of_triangles; ){
// triangles already in CW winding
if( N < q || N < 5*q && N > 3*q - 1 ){
// do the even indicies
f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r;
glTriangle[N].vert[0] = face_verts[h];
glTriangle[N].vert[1] = face_verts[s + 1 + h];
glTriangle[N].vert[2] = face_verts[s + 2 + h];
N++; f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r;
// do the odd indicies
glTriangle[N].vert[0] = face_verts[s + 2 + h];
glTriangle[N].vert[1] = face_verts[ 1 + h];
glTriangle[N].vert[2] = face_verts[h];
N++; f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r;
}
// triangles needing reverse order for CW winding
if( N > 5*q - 1 || N < 3*q && N > q - 1 ){
// do the even indicies
glTriangle[N].vert[0] = face_verts[s + 2 + h];
glTriangle[N].vert[1] = face_verts[s + 1 + h];
glTriangle[N].vert[2] = face_verts[h];
N++; f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r;
// do the odd indicies
glTriangle[N].vert[0] = face_verts[h];
glTriangle[N].vert[1] = face_verts[1 + h];
glTriangle[N].vert[2] = face_verts[s + 2 + h];
N++; f= q*(N/q); r = a*(N/q); h = (N-f)/2 + (N-f)/(2*s) + r;
}
}
// Normalize the cube to side = 1 ------------------------------
for(int i = 0; i < number_of_triangles; i++){
glTriangle[i].vert[0].x = glTriangle[i].vert[0].x/(2.0*(float)n);
glTriangle[i].vert[0].y = glTriangle[i].vert[0].y/(2.0*(float)n);
glTriangle[i].vert[0].z = glTriangle[i].vert[0].z/(2.0*(float)n);
glTriangle[i].vert[1].x = glTriangle[i].vert[1].x/(2.0*(float)n);
glTriangle[i].vert[1].y = glTriangle[i].vert[1].y/(2.0*(float)n);
glTriangle[i].vert[1].z = glTriangle[i].vert[1].z/(2.0*(float)n);
glTriangle[i].vert[2].x = glTriangle[i].vert[2].x/(2.0*(float)n);
glTriangle[i].vert[2].y = glTriangle[i].vert[2].y/(2.0*(float)n);
glTriangle[i].vert[2].z = glTriangle[i].vert[2].z/(2.0*(float)n);
};
return glTriangle;
}
The rendering was done using OpenGl.
// OGL render call to the cube mesh generator - PSUEDOCODE
int n(2);
int cube_triangle_Count = (12*(2*n)*(2*n));
std::vector<Triangle> cube_Triangles(cube_triangle_Count);
cube_Triangles = cube_Faces(n);
glBindBuffer(GL_ARRAY_BUFFER, uiVBO[0]);
glBufferData(GL_ARRAY_BUFFER, cube_Triangles.size()*sizeof(Triangle), &cube_Triangles[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), 0);
glEnableVertexAttribArray(0);
glDrawArray(GL_TRIANGLES,0,3*cube_triangle_Count);
This just gets the position attribute of the cube face triangle verts; for the color and other attributes there are a couple of options: Use separate GL_ARRAY_BUFFERS for the color and other attributes. Or add attributes to the Triangle struct...
struct Triangle
{
glm::vec3 vert[3]; // the three verts of the triangle
attribute1;
attribute2;
...
};
Screenshot of the spherified cube.
What's next?
Now that we have the cube mesh what we can do with with it practically unlimited. The first thing I did was turn it into a sphere. Playing with tesselating the cube or sphere or stellating it with different patterns; might do. Ended up trying a few matrix transformations on the cube mesh. These are shown in the image below.
These shapes are result short bits of code like the code for the column shape below.
//Column
for(int i = 0; i < number_of_triangles; i++){
for(int j = 0; j < 3; j++){
if( glTriangle[i].vert[j].y < 0.5f && glTriangle[i].vert[j].y > -0.5f ){
float length_of_v = sqrt((glTriangle[i].vert[j].x * glTriangle[i].vert[j].x) + (glTriangle[i].vert[j].z * glTriangle[i].vert[j].z));
glTriangle[i].vert[j].x = 0.5f*glTriangle[i].vert[j].x/length_of_v;
glTriangle[i].vert[j].z = 0.5f*glTriangle[i].vert[j].z/length_of_v;
}
}
}
Doing this; the blacksmith at his forge analogy soon presents. The mesh is the ingot, hammer matrices stretch, round and bend it against the fixed geometry of the anvil - coordinate system. I am the smith.
Tetrahedron
The tetrahedron is the platonic solid with the least number of faces(4), edges(6), and verts(4). In antiquity it was associated with the element of fire due to its' sharp vertices. The algorithm for the tetrahedron mesh was developed in a similar way to the cube, but here it seemed simpler to get a routine for just one face - an equilateral triangle - and use matrix translations and rotations to form the complete tetrahedron. So more like origami or tinsmithing than blacksmithing.
Procedural tetrahedron screenshot.
The n = 4 and the general case
To get an routine for the general case, n an integer > 0, a bit of what I think is known as mathematical induction was used.
PSUEDO-CODE
Algorithm to generate equilateral triangle face with
unit side composed of n² "sub-triangle" in the xy plane.
std::vector<Triangle> equilateral(int n){
std::vector<Triangle> tri_Angle(n²);
// Create the seed triangle in xy plane .
// This is triangle "0" in the image above.
// This is in the xy(z=0) plane so all the
// tri_Angle.vert[0 thrue n -1 ].z = 0.
// We just work with the x and y verts.
tri_Angle[all].vert[all].z = 0;
// The seed triangle
tri_Angle[0].vert[0].x = 0; tri_Angle[0].vert[0].y = 0;
tri_Angle[0].vert[1].x = 1/2n; tri_Angle[0].vert[1].y = sin(π/3)/n;
tri_Angle[0].vert[2].x = 1/n; tri_Angle[0].vert[2].y = 0;
// Build the equilateral triangle face.
int count(0);
for(int row = 0; row < n; row++){
count = 0;
Spin = glmRotateMatrix( π/3, zaxis );
// The magic happens here!
for(int i = 2*n*row - row*row; i < 2*n*row - row*row + 2*n - 2*row - 1; i++)
{
if (count % 2 == 0 ) // Triangle is even in the row - just translate
{
// more magic.
x_Lat = glm_Matrix((count + row)/2n, row*sin(π/3)/n, 0.0f);
tri_Angle[i].vert[0] = x_Lat* tri_Angle[0].vert[0];
tri_Angle[i].vert[1] = x_Lat* tri_Angle[0].vert[1];
}
else // Triangle is odd in the row - rotate then translate
{
//and more magic.
x_Lat = glm_Matrix((count + row + 1)/2n, row*sin(π/3)/n, 0.0f);
tri_Angle[i].vert[0] = x_Lat*Spin*tri_Angle[0].vert[0];
tri_Angle[i].vert[1] = x_Lat*Spin*tri_Angle[0].vert[1];
}
}
count++;
}
return tri_Angle;
}
This is the psuedocode version of the routine which generates the verts for the n² triangles in a face. Getting this algorithm was a bit of a brain drain but looking for patterns in the image of the face allowed it to happen. We use a "seed" triangle, which is triangle 0 on the lower left of the figure. The verts of this one triangle are input; the rest of the n² triangles verts are generated by translating and rotating this seed triangle.
Notice: There are n rows, every row has 2 less triangles than the row below. If we number the triangles from 0 to 2n - 2*row - 2, where the rows run 0 to n; the even triangles just need to be translated ...
in the x direction by (count + row)/2n where count = their position in the row 0 to 2n - 2*row - 2.
in the y direction by row*height. height = height of seed triangle.
The odd triangles need to be rotated pi/3 = 60 degrees around the z axis then translated ...
in the x direction by (count + row + 1)/2n where count = their position in the row 0 to 2n - 2*row - 2.
in the y direction by row*height. height = height of seed triangle.
Now we have a single face for the tetrahedron, to join the four faces together we need the angle between the faces called the dihedral angle.
Dihedral Angle
Each of the five platonic solids has a characteristic called the dihedral angle. This is the angle between the faces. For the cube it is 90 degrees or pi/2 radians. For the tetrahedron it is 70.528779° = arccos(1/3) = atan(2*sqrt(2));
The tetrahedron, with just four faces, is the simplest of the platonic solids.
The simplest way I can think of to build it: Start with the four face stacked one on another, edges aligned. Imagine the top three faces each hinged to the bottom face along one edge. Then rotate each face around then hinged edge by arccos(1/3), the dihedral angle. That is the method of the bit of code shown below.
vector<Triangle> tetrahedron(int N){
std::vector<Triangle> tetra(4n²);
tetra[all].vert[all].z = 0;
// The seed triangle
tetra[0].vert[0].x = 0; tetra[0].vert[0].y = 0;
tetra[0].vert[1].x = 1/2n; tetra[0].vert[1].y = sin(π/3)/n;
tetra[0].vert[2].x = 1/n; tetra[0].vert[2].y = 0;
// ----- The first face -----
// generate the first equilateral triangle face with unit side
// composed of n² "sub-triangle" in the xy(z=0) plane.
int count(0);
for(int row = 0; row < n; row++)
{
count = 0;
Spin = glmRotateMatrix( π/3, zaxis );
for(int i = 2*n*row - row*row; i < 2*n*row - row*row + 2*n - 2*row - 1; i++)
{
if (count % 2 == 0 ) // Triangle is even in the row - just translate
{
x_Lat = glm_Matrix((count + row)/2n, row*sin(π/3)/n, 0.0f);
tetra[i].vert[0] = x_Lat* tetra[0].vert[0];
tetra[i].vert[1] = x_Lat* tetra[0].vert[1];
}
else // Triangle is odd in the row - rotate then translate
{
x_Lat = glm_Matrix((count + row + 1)/2n, row*sin(π/3)/n, 0.0f);
tetra[i].vert[0] = x_Lat*Spin*tetra[0].vert[0];
tetra[i].vert[1] = x_Lat*Spin*tetra[0].vert[1];
}
}
count++;
}
// ----- The second face -----
// generate the second equilateral face from the first
// by rotating around the X axis by the dihedral angle.
float tetra_Dihedral = atan(2*sqrt(2));
Spin = glmRotateMatrix( -tetra_Dihedral, xaxis ); //just rotate
for(int i = 0; i < n²; i++)
{
for(int j = 0; j < 3; j++)
{
tetra[n² + i].vert[j] = Spin*tetra[i].vert[j];
}
}
//The rotation gives CCW verts so need need to make them CW again
for(int i = n²; i < 2n²; i++)
{
swap(tetra[i].vert[0] ---- with --- tetra[i].vert[2];
}
// ----- The third face -----
// For the second face we rotated the first triangle around its'
// base on the X - axis. For the third face we rotate the first
// triangle around its' edge along the vector ( 0.5, 0.866025, 0.0 ).
Spin = glmRotateMatrix( tetra_Dihedral ,glm::vec3(0.5f,0.866025f,0.0f));
for(int i = 0; i < n²; i++)
{
for(int j = 0; j < 3; j++)
{
tetra[2n² + i].vert[j] = Spin*tetra[i].vert[j];
}
}
//need to make it CW again
for(int i = 2n²; i < 3n²; i++)
{
swap(tetra[i].vert[0] ---- with --- tetra[i].vert[2];
}
// ----- The forth face -----
// For the forth face we first translate the original face along the
// X axis so it right edge vector (-0.5f, 0.866025f, 0.0f) passes thru the origin.
// Then we rotate the first triangle around the that vector by the dihedral angle.
x_Lat = glm::translate( glm::vec3(-1.0f, 0.0f, 0.0f));
Spin = glmRotateMatrix( -tetra_Dihedral, glm::vec3(-0.5f,0.866025f,0.0f));
for(int i = 0; i < n²; i++)
{
for(int j = 0; j < 3; j++)
{
tetra[3n² + i].vert[j] = Spin*x_Lat*tetra[i].vert[j];
}
}
//need to make it CW again
for(int i = 3n²; i < 4n²; i++)
{
swap(tetra[i].vert[0] ---- with --- tetra[i].vert[2];
}
// We now have the complete tetrahedron, tetra(4n²), but its' base
// is not horizontal so let's make is so.
// put the base in the xz plane
// rotate 90 - dihedral angle around X axis.
Spin = glm::rotate( tetra_Dihedral - half_PI, xaxis);
for(int i = 0; i < 4n²; i++)
{
for(int j = 0; j < 3; j++)
{
tetra[i].vert[j] = Spin*tetra[i].vert[j];
}
}
// We now have the complete tetrahedron, tetra(4n²), sitting with its'
// base on the xz(y=0) plane, let's put its' center at the origin.
// For this we need another Platonic Solid attribute: The radius of
// the tetrahedrons circumscribed sphere which is sqrt(3/8). So the
// center of the tet is this vertical distance down from its' apex.
// To put the center at the origin we need to translate down this
// distance along the Y axis. We need also to xlat along the Z axis
// by 1/2(sqrt(3)) = 0.28867; the distance from the center of a face
// to the center of a side.
// Finally we need to center along the X axis( xlat -.5)
x_Lat = glm::translate( glm::vec3(-0.5f, -sqrt(3/8), sqrt(3)/2);
for(int i = 0; i < 4n²; i++)
{
for(int j = 0; j < 3; j++)
{
tetra[i].vert[j] = x_Lat*tetra[i].vert[j];
}
}
return tetra;
}
Notes:
Oops: Left out std::vector<Triangle> tri_Angles(4*n*n); Should be the first line of the function body!
Corrections to the corrections: First line of function definition
vector<Triangle> tetrahedron(int N){ should be
vector<Triangle> tetrahedron(int n){
Those last two for loops could and probably should be combined to do a translate*rotate*triangle in one statement, but I have not tried it.
All distances are for a tetrahedron with unit side.
The sign of the dihedral angle in the rotations was usually determined by trial and error. I.e.; I tried one sign, compiled the code and rendered the tet. If it was wrong I just reversed the sign.
The end result is a tetrahedron with its' center at the origin, its' base in the xz plane, and one edge parallel to the X axis.
Of the five platonic solids; three (tetrahedron, octahedron, icosahedron) are composed of equilateral triangle faces. One of square faces (cube). And one of pentagon faces (dodecahedron).
Two tetrahedrons fit nicely in a cube.
11-16-18: Corrections to code blocks for equilateral triangle and tetrahedron.
11-18-18: More corrections.
Icosahedron
Two faces = Icosahedron Petal
Five petals in this flower = 10 faces = half of the icosahedron
12-5-18
Understanding the icosahedron's 3d form via 2d images is difficult; we need to make a small, palm sized, 3d model. It takes nineteen paper triangles and some tape. The vertices of five equilateral triangles must come together at each vertex of the icosahedron. The icosahedron has 20 faces and 12 verts, but leaving one face off the model allows us to look in side. Besides; when where done we'll have a neat little icosahedron basket. You don't really need to make a model to code the icosahedron; but it helped me to see some properties which simplified its' construction.
Symmetries are important to the mathematician and perhaps even more so to the physicist. They say something has a certain symmetry if you perform a certain operation on it and the world remains unchanged. Unchanged in the sense that you can not even detect something has been done to it. Example: Rotate a square 90 degrees around its center in the plane; the square has that type of rotational symmetry. The square also has an inversion symmetry; if you take every point on the square and invert it through the origin you end up with the same square you started with. Inversion is simply negating all the coordinates. The center must be at the origin of course. This is true for the cube, but not for the tetrahedron.
Symmetries simplify the construction (coding) of an object. Going back to the cube; it might have been easier to do three faces and then just invert them thru the origin to get the other three. For the tetrahedron simple inversion is not a symmetry, but I am pretty sure inversion together with a rotation is. If so; we could do two faces and then perform an inversion - rotation on them in one step. And inversion in Cartesian coordinates just means to negate all the verts - easy!
Toying with our icosahedron model; holding it gently with our thumb on one vertex and our middle finger on the opposite vertex, lazily twirling it around an imaginary axis through those two vertices; we are struck with a thought: We are toying with our icosahedron model twirling it around an axis through - Eureka! - two opposite vertices: The icosahedron has inversion symmetry. This is great - our work has just been cut in half. We can code half of the icosahedron's verts and just invert(negate) to get the rest. Thank you inversion symmetry. But let's not stop now, we are on a roll (no pun intended); let's see if we can find more symmetries to make our work easier. Looking intently; holding our model as before, but still, not rotating. Then slowly rotating about the axis we see another symmetry. After one fifth of a revolution(2π/5 radians) the universe looks the same as when we started rotating it. The icosahedron has a 2π/5 rotational symmetry. Can we use this to cut our work load? You bet we can.
First we need to clear up a few points about something central to our construction efforts: The axis of symmetry. (Sorry, the puns just keep coming.) An axis of symmetry is a line passing thru two opposite vertices and the center of the icosahedron. The icosahedron has six of them: We only need one. We will use the Z axis.
Dihedral angle: To be precise, it is the angle between the normals of two adjacent faces.
The images:
Looking at the images we see a flower shape with five "petals". A petals is just two faces joined along a side. The angle between the two petal faces is the icosa's dihedral angle; arccos(- √5/3) radians. Five petals make a "flower" , which is ten faces, so it is half of the icosahedron. Once we have five petals joined to make this flower, we just copy/invert all its' verts to get the other half: We have our icosahedron.
The Plan: Refer to the figures
1.) Make a petal.
2.) Attach one tip of the petal the axis of symmetry.
(Oriented properly of course.)
3.) Copy/rotate the petal around the axis of symmetry
by 2π/5 radians four times to get five petals = a flower.
We are using the 2π/5 radians rotational symmetry here.
4.) Copy/invert( r -> -r ) our five-petal-ten-face flower to get
our 20 face icosahedron. Using inversion symmetry here.
So just four steps; sounds simple enough. Each step has its own steps of course, but they are mostly intuitive common sense things we must do to get the result.
Constants:
Before we get to the code we need four constants.
1.) The dihedral angle between two faces, the dihedral_angle.
dihedral_angle. = arccos(- √5/3) = 46.06322 radians = 138.18969°.
2.) The angle between the Z axis and the normal of a face of a petal at the vertex. 0.652351 radians
3.) The radius of a circumscribed sphere(A sphere that touches all 12 verts). In other words the distance from the icosahedron center to a vertex. Also called the circumradius.
R = sin(2π/5).
4.) The rotational symmetry: 2π/5 radians
Let's not do a blow by blow, or should say, a bend by bend, description of the code. If a picture is worth a thousand words, it seems safe to assume an animated 3D image is worth even more. I suggest we compile the code and render to the display step by step. In fact this is how the code was developed; with a projection matrix and a rotation around the Z axis.
Compile - Render the first face: F0.
" " the first petal: P0 from F0 and F1.
" " the second petal P1.
" " the third petal P2.
" " the fourth petal P3.
" " the fifth petal P4.
We now have the flower.
Compile - Render the inversion of the flower.
Done.
The icosahedron pseudocode.
struct Triangle
{
glm::vec3 vert[3]; // the three verts of the triangle
};
//PSUEDOCODE ICOSAHEDRON
/* input: integer n - number of triangles along
icosahedron edge.
output: std::vector<Triangle> icosahedron - mesh
with 20n² triangles.
*/
std::vector<Triangle> icosahedron( int n ){
const float dihedral_Angle = acos(-(sqrt(5.0f)/3.0f));
const float dihedral_Comp = π - dihedral_Angle;
std::vector<Triangle> T_icosahedron(20n²);
// Create the seed triangle T.
Triangle T;
T.vert[0].x = 0; T.vert[0].y = 0; T.vert[0].z = 0;
T.vert[1].x = 1/2n; T.vert[1].y = sin(π/3); T.vert[1].z = 0;
T.vert[2].x = 1/n; T.vert[2].y = 0; T.vert[2].z = 0;
// ----- F0 -----
// Create the first face; "F0" in the xy(z=0) plane
// from the seed triangle T.
int count(0);
for(int row = 0; row < n; row++){
count = 0;
for(int i = 2*n*row - row*row; i < 2*n*row - row*row + 2*n - 2*row - 1; i++){
if (count % 2 == 0 ){ // Triangle is even in the row - just translate .
x_Lat = glm::translate(count+row)/2n, row*sin(π/3), 0);
for(int j = 0; j < 3; j++){
T_icosahedron[i].vert[j] = x_Lat*T.vert[j];
}
}
else{ // Triangle is odd in the row - rotate then translate.
x_Lat = glm::translate( glm::vec3((count+1+row)/2n, row*sin(π/3), 0));
Spin = glm::rotate( π/3, zaxis );
for(int j = 0; j < 3; j++){
T_icosahedron[i].vert[j] = x_Lat*Spin*T.vert[j];
}
}
count++;
}
}
// At this point comment out the rest of the code,
// return T_icosahedron;
// Compile and render F0 to the display.
// ----- P0 -----
// Create the first petal "P0" in the xy(z=0) plane.
glm::vec3 axis(0.5f, sin(π/3), 0.0f);
Spin = glm::rotate( π/3, zaxis ); //just rotate
Spin2 = glm::rotate( -dihedral_Comp, axis );
for(int i = 0; i < n²; i++){
for(int j = 0; j < 3; j++){
T_icosahedron[n² + i].vert[i] = Spin2*Spin*T_icosahedron[i].vert[j];
}
}
// xlate P0 by -1.0 along x and bend down by epsilon from the xy plane
// epsilon is the angle we want between the Z axis and the normal of F0.
// epsilon = 0.6523581f;
x_Lat = glm::translate( glm::vec3(-1.0f, 0.0f, 0.0f));
Spin2 = glm::rotate( glm::mat4(1.0), -π/3, zaxis );
Spin = glm::rotate( glm::mat4(1.0), -epsilon, xaxis ); //just rotate
for(int i = 0; i < 2n²; i++){
for(int j = 0; j < 3; j++){
T_icosahedron[i].vert[j] = Spin*Spin2**x_Lat*T_icosahedron[i].vert[j];
}
}
// At this point comment out the rest of the code,
// return T_icosahedron;
// Compile and render P0 to the display.
// Create P1 from the P0 verts, rotate 2π/5 around z then
Spin = glm::rotate( 2π/5, zaxis ); //just rotate
for(int i = 0; i < 2n²; i++){
for(int j = 0; j < 3; j++){
T_icosahedron[i+2n²].vert[j] = Spin*T_icosahedron[i].vert[j];
}
}
// At this point comment out the rest of the code,
// return T_icosahedron;
// Compile and render P0 - P1 to the display.
// Create P2 thru P4 from P0 verts: rotate around z:
// 2*2π/5 for P2, 3*2π/5 for P3 and finally 4*2π/5 for P4
// P2
Spin = glm::rotate( 2*2π/5, zaxis ); //just rotate
for(int i = 0; i < 2n²; i++){
for(int j = 0; j < 3; j++){
T_icosahedron[i+4n²].vert[j] = Spin*T_icosahedron[i].vert[j];
}
}
// P3
Spin = glm::rotate( 3*2π/5, zaxis ); //just rotate
for(int i = 0; i < 2n²; i++){
for(int j = 0; j < 3; j++){
T_icosahedron[i+6n²].vert[j] = tSpin*T_icosahedron[i].vert[j];
}
}
// P4
Spin = glm::rotate( 4*2π/5, zaxis ); //just rotate
for(int i = 0; i < 2n²; i++){
for(int j = 0; j < 3; j++){
T_icosahedron[i+8n²].vert[j] = Spin*T_icosahedron[i].vert[j];
}
}
// At this point we should have the full flower.
// Comment out the rest of the code,
// return T_icosahedron;
// Compile and render P0 thru P4 to the display.
// Move everthing up along z to put the icosahedron center at the origin.
// radius of circumscribed sphere = sin(2π/5), for face side = 1.
x_Lat = glm::translate( glm::vec3(0, 0, sin(2π/5));
for(int i = 0; i < 10n²; i++){
for(int j = 0; j < 3; j++){
T_icosahedron[i].vert[j] = x_Lat*T_icosahedron[i].vert[j];
}
}
// invert all the verts and reverse for cw winding
// this creates the other half of the icosahedron from the first 10 triangles
for(int i = 0; i < 10n²; i++){
for(int j = 0; j < 3; j++){ // invert
T_icosahedron[i+10n²].vert[j].x = -T_icosahedron[i].vert[j].x;
T_icosahedron[i+10n²].vert[j].y = -T_icosahedron[i].vert[j].y;
T_icosahedron[i+10n²].vert[j].z = -T_icosahedron[i].vert[j].z;
}
// Swap verts 0 and 2 to get back to CW winding.
hold = T_icosahedron[i+10n²].vert[0];// reverse
T_icosahedron[i+10n²].vert[0] = T_icosahedron[i+10*n²].vert[2];
T_icosahedron[i+10n²].vert[2] = hold;
}
return T_icosahedron;
// Spherify - uncomment the code below to spherify the icosahedron
/*
for(int i = 0; i < 20n²; i++){
for(int j = 0; j < 3; j++){
float length_of_v = sqrt(
(T_icosahedron[i].vert[j].x * T_icosahedron[i].vert[j].x) +
(T_icosahedron[i].vert[j].y * T_icosahedron[i].vert[j].y) +
(T_icosahedron[i].vert[j].z * T_icosahedron[i].vert[j].z));
T_icosahedron[i].vert[j].x = T_icosahedron[i].vert[j].x/length_of_v;
T_icosahedron[i].vert[j].y = T_icosahedron[i].vert[j].y/length_of_v;
T_icosahedron[i].vert[j].z = T_icosahedron[i].vert[j].z/length_of_v;
}
}
*/
return T_icosahedron;
}
Screen-shots: First petal P0 and five petal icosahedron flower.

Why hello there! What a nice thing to see you again! This is another entry of your favourite Weekly Update!
This time it's all about (artificial) intelligence. Most new features are linked to AI in one way or another, so let's get right to it!
Step It Up!
First, let's talk about sound!
Previously, the game was almost devoided of sounds. It was pretty miserable, but lately, I've tried to remedy the situation by adding many different sounds.
It gave a whole lot of life and overall made the game much more enjoyable. Now I've also made another big step (sorry for the pun): I've added stepping sounds.
This means that walking around now makes noise. There are also various types of sound for each type of surface.
This applies to both player and AI steps.
Those sounds are also played when the player is either going to jump or is landing from one. It's quite nice to hear and it's a pleasant way to give audio feedback for jumping.
Coming up to our senses
Second, AIs are generally smarter than before with the help of senses. Right now there are only two types of senses: hearing and communicating.
I'm All Ears
First, let's talk about hearing things.
Previously, AIs were lacking any type of ears, meaning that they would only react to a direct line of sight or just by being in their "bubble". This meant that as long as the player avoided any of these situations no ones would be able to spot said player.
But now this all changes: AIs can "hear" sounds like footsteps and gunshots. This system works in an elegant way...
First of all, everyone sounds in the game are fully 3D. This means that a sound has a given position, and because of this there's also a spatial volume roll-off.
By using the sounds' 3D position and applying the volume roll-off we can calculate a perceived volume for each listener. We then compare that to the listeners' hearing threshold to tell whenever or not the sound is heard. If so, then there's an appropriate reaction from the listener.
Communicative
Next, there's also the communication sense. Although broad, the idea is that an AI can broadcast a message to any other ones close enough to hear it. In that sense, it kinda works like the hearing one, except it's completely silent, is exclusively for AIs and also have a meaning.
Like hearing, each message has a perceived volume (or urgency, as I like to call it) which is defined by the emitters 3D position and a spatial roll-off curve.
Right now, each AI can choose to respond or not to a broadcasted message depending on their willingness. For example, a healthy AIs would be more akin to respond to any messages, while injured ones might be more hesitant to make a move.
Urgencies also depend on the emitter's current condition: if an enemy attacks an AI and the latter is getting dangerously close to death then the broadcasted message base urgency would be high. It's quite a complex thing to decide which is the appropriate urgency level for each message, and it also figures that it would change based on which type of AI are involved.
There are, as of now, only two types of messages:
Help
This message is sent mainly when the AI needs assistance. Right now this is mainly used when an AI is injured. The more injured the AI gets the bigger the urgency is.
Look
This message is sent when an AI wants other AI to take their attention to in a specific direction. Right now this message is sent when AIs spots an enemy.
That's about it for messages.
Enemies reactions
Next, there's another AI upgrade.
Enemies are now properly reacting to attacks and injuries. If the injured AI didn't spot the attacker they would try to investigate the supposed attacks. This means that the player could technically set up an elaborate trap to lure the AI near and give a lethal blow away from its friends.
Pretty insignificant on its own, but paired with the other AI upgrade this makes gameplay a whole lot better in my opinion.
Bosses
Yes, you read that right. Bosses are now technically in! (although there's a lot of bugs with their AI and whatnot)
Bosses are usually encountered at the end of a level. They guard the exit and in order for the player to advance they need to take them out.
Type of Bosses
In the finished game there would be two different types of bosses:
Sedentary Bosses
As the name suggests, this type of boss doesn't move at all.
Instead of depending on movements to attack and escape players they would use environmental way to distance themselves from the player.
These would generally have a lot more HP than the other type of boss to try to balance things out.
Nomadic Bosses
This type of boss will, unlike the sedentary ones, be mobile and move around the room.
They're also using that mobility of theirs to control the distance between their enemies and themselves.
Boss Behaviours
All bosses will use behaviour trees to decide their behaviour and attack patterns. In general bosses attacks are split in two: their announcement and the actual attack.
Before attacking the boss need to "announce" (or telegraph) it first. The player can then easily predict attacks and plan accordingly.
There are also two types of attacks: melee or range. If the target is close enough, a melee attack is used. Otherwise, we use a range one.
Some bosses are restricted to melee attacks while others can do both.
In the final game, there might be multiple cyclic types of attacks per bosses.
Boss death
Once the player kills the boss a reward is given and the passage to the next level is opened.
The reward got from the encounter is currently randomly chosen, but will most of the time either be pieces of equipment or relics.
The player can either dismiss or collect them. That's where the strategy part comes in!
First ＡＥＳＴＨＥＴＩＣ boss
Right now there's only one particular boss that is fully modelled, textured and even animated (thanks Mixamo).
It's supposed to represent a Greek statue. (Verry ＡＥＳＴＨＥＴＩＣ if you ask me.)
Here you can see it telegraphing a melee attack:
There will be more that one boss but this is a start.
Next Week
Now that bosses are in there's still a whole lot of work ahead to really polish and fix their behaviour tree, as I'm not much familiar enough to behaviour tree and have still a lot to learn.
I also need to finish attacks so that they do damage.
So next week will be boss-themed I guess.
Other than that the work ahead of me is mostly modelling. I need to really polish each level so they feel different enough from each other to keep the interest and curiosity level up throughout the game.

Atum engine is a newcomer in a row of game engines. Most game engines focus on render
techniques in features list. The main task of Atum is to deliver the best toolset, that’s why,
as I hope, Atum will be a good light weighted alternative to Unity for indie games. Atum already
has fully workable editor that has an ability to play test edited scene. All system code has
simple ideas behind them and focuses on easy to use functionality. That’s why code is minimized
as much as possible.
All source can be found here - https://github.com/ENgineE777/Atum
In case you have questions related to Atum engine do not hesitate to contact me via email enginee777@gmail.com
Currently the engine have follow features:
- PC, Android and iOS platforms are supported
- Scene Editor with ability to play test edited scene
- Powerful system for binding properties into the editor
- Powerful assets system
- Track based editor for creation of animated objects
- Sprite Editor
- Render system that supports DX11 and OpenGL
- UI system bassed on assets
- Script system based on angel script
- Controls system based on aliases
- Font system based on stb_truetype.h
- Support of PhysX 3.0, there are samples in repo that's using physics
- Network code which allows to create server/clinet; there is some code in repo which allows

I'm very interested in the snow physics in Red Dead Redemption 2.
Here is a demo video from YouTube.
Does anyone know the techniques behind this snow physics?
For example,
What is the shading model of the snow?
How do they create snow deformation?

Hi,
My name's Jamie and I'm 19. I made a post similar to this one about a year ago, looking for a team.
A little about me; I'm a 3D modeller and game designer. My primary modelling software is Blender, I have recently began to use Substance Painter 2018 for texture and material work and I have far more experience with Unreal Engine 4 than I did when I first posted here. Organic models are not really my forte and I tend to focus on hard surface modelling and environmental work.
I feel now is a good time to get involved with a team and sink my teeth into a project. Whether it be an already formed team or a team which is just getting together. I don't have much of a preference as far as game genre goes but with me being a 3D modeller, a 3D based project is a requirement. I'd love to work with a group of similar minded individuals who are passionate, ambitious and who have a desire to learn and grow as developers.
If you're interested in working together or have any further questions then feel free to send me a PM!
Link to my portfolio: https://jamierwilcock.wixsite.com/jwportfoilio
(If you have any issues accessing the portfolio link then please let me know - the link has been a bit hit and miss recently, apologies about that)
Thanks
Jamie

Hello!
I would like to introduce Diligent Engine, a project that I've been recently working on. Diligent Engine is a light-weight cross-platform abstraction layer between the application and the platform-specific graphics API. Its main goal is to take advantages of the next-generation APIs such as Direct3D12 and Vulkan, but at the same time provide support for older platforms via Direct3D11, OpenGL and OpenGLES. Diligent Engine exposes common front-end for all supported platforms and provides interoperability with underlying native API. Shader source code converter allows shaders authored in HLSL to be translated to GLSL and used on all platforms. Diligent Engine supports integration with Unity and is designed to be used as a graphics subsystem in a standalone game engine, Unity native plugin or any other 3D application. It is distributed under Apache 2.0 license and is free to use. Full source code is available for download on GitHub.
Features:
True cross-platform
Exact same client code for all supported platforms and rendering backends
No #if defined(_WIN32) ... #elif defined(LINUX) ... #elif defined(ANDROID) ...
No #if defined(D3D11) ... #elif defined(D3D12) ... #elif defined(OPENGL) ...
Exact same HLSL shaders run on all platforms and all backends
Modular design
Components are clearly separated logically and physically and can be used as needed
Only take what you need for your project (do not want to keep samples and tutorials in your codebase? Simply remove Samples submodule. Only need core functionality? Use only Core submodule)
No 15000 lines-of-code files
Clear object-based interface
No global states
Key graphics features:
Automatic shader resource binding designed to leverage the next-generation rendering APIs
Multithreaded command buffer generation
50,000 draw calls at 300 fps with D3D12 backend
Descriptor, memory and resource state management
Modern c++ features to make code fast and reliable
The following platforms and low-level APIs are currently supported:
Windows Desktop: Direct3D11, Direct3D12, OpenGL
Universal Windows: Direct3D11, Direct3D12
Linux: OpenGL
Android: OpenGLES
MacOS: OpenGL
iOS: OpenGLES
API Basics
Initialization
The engine can perform initialization of the API or attach to already existing D3D11/D3D12 device or OpenGL/GLES context. For instance, the following code shows how the engine can be initialized in D3D12 mode:
#include "RenderDeviceFactoryD3D12.h"
using namespace Diligent;
// ...
GetEngineFactoryD3D12Type GetEngineFactoryD3D12 = nullptr;
// Load the dll and import GetEngineFactoryD3D12() function
LoadGraphicsEngineD3D12(GetEngineFactoryD3D12);
auto *pFactoryD3D11 = GetEngineFactoryD3D12();
EngineD3D12Attribs EngD3D12Attribs;
EngD3D12Attribs.CPUDescriptorHeapAllocationSize[0] = 1024;
EngD3D12Attribs.CPUDescriptorHeapAllocationSize[1] = 32;
EngD3D12Attribs.CPUDescriptorHeapAllocationSize[2] = 16;
EngD3D12Attribs.CPUDescriptorHeapAllocationSize[3] = 16;
EngD3D12Attribs.NumCommandsToFlushCmdList = 64;
RefCntAutoPtr<IRenderDevice> pRenderDevice;
RefCntAutoPtr<IDeviceContext> pImmediateContext;
SwapChainDesc SwapChainDesc;
RefCntAutoPtr<ISwapChain> pSwapChain;
pFactoryD3D11->CreateDeviceAndContextsD3D12( EngD3D12Attribs, &pRenderDevice,
&pImmediateContext, 0 );
pFactoryD3D11->CreateSwapChainD3D12( pRenderDevice, pImmediateContext, SwapChainDesc,
hWnd, &pSwapChain );
Creating Resources
Device resources are created by the render device. The two main resource types are buffers, which represent linear memory, and textures, which use memory layouts optimized for fast filtering. To create a buffer, you need to populate BufferDesc structure and call IRenderDevice::CreateBuffer(). The following code creates a uniform (constant) buffer:
BufferDesc BuffDesc;
BufferDesc.Name = "Uniform buffer";
BuffDesc.BindFlags = BIND_UNIFORM_BUFFER;
BuffDesc.Usage = USAGE_DYNAMIC;
BuffDesc.uiSizeInBytes = sizeof(ShaderConstants);
BuffDesc.CPUAccessFlags = CPU_ACCESS_WRITE;
m_pDevice->CreateBuffer( BuffDesc, BufferData(), &m_pConstantBuffer );
Similar, to create a texture, populate TextureDesc structure and call IRenderDevice::CreateTexture() as in the following example:
TextureDesc TexDesc;
TexDesc.Name = "My texture 2D";
TexDesc.Type = TEXTURE_TYPE_2D;
TexDesc.Width = 1024;
TexDesc.Height = 1024;
TexDesc.Format = TEX_FORMAT_RGBA8_UNORM;
TexDesc.Usage = USAGE_DEFAULT;
TexDesc.BindFlags = BIND_SHADER_RESOURCE | BIND_RENDER_TARGET | BIND_UNORDERED_ACCESS;
TexDesc.Name = "Sample 2D Texture";
m_pRenderDevice->CreateTexture( TexDesc, TextureData(), &m_pTestTex );
Initializing Pipeline State
Diligent Engine follows Direct3D12 style to configure the graphics/compute pipeline. One big Pipelines State Object (PSO) encompasses all required states (all shader stages, input layout description, depth stencil, rasterizer and blend state descriptions etc.)
Creating Shaders
To create a shader, populate ShaderCreationAttribs structure. An important member is ShaderCreationAttribs::SourceLanguage. The following are valid values for this member:
SHADER_SOURCE_LANGUAGE_DEFAULT - The shader source format matches the underlying graphics API: HLSL for D3D11 or D3D12 mode, and GLSL for OpenGL and OpenGLES modes.
SHADER_SOURCE_LANGUAGE_HLSL - The shader source is in HLSL. For OpenGL and OpenGLES modes, the source code will be converted to GLSL. See shader converter for details.
SHADER_SOURCE_LANGUAGE_GLSL - The shader source is in GLSL. There is currently no GLSL to HLSL converter.
To allow grouping of resources based on the frequency of expected change, Diligent Engine introduces classification of shader variables:
Static variables (SHADER_VARIABLE_TYPE_STATIC) are variables that are expected to be set only once. They may not be changed once a resource is bound to the variable. Such variables are intended to hold global constants such as camera attributes or global light attributes constant buffers.
Mutable variables (SHADER_VARIABLE_TYPE_MUTABLE) define resources that are expected to change on a per-material frequency. Examples may include diffuse textures, normal maps etc.
Dynamic variables (SHADER_VARIABLE_TYPE_DYNAMIC) are expected to change frequently and randomly.
This post describes the resource binding model in Diligent Engine.
The following is an example of shader initialization:
ShaderCreationAttribs Attrs;
Attrs.Desc.Name = "MyPixelShader";
Attrs.FilePath = "MyShaderFile.fx";
Attrs.SearchDirectories = "shaders;shaders\\inc;";
Attrs.EntryPoint = "MyPixelShader";
Attrs.Desc.ShaderType = SHADER_TYPE_PIXEL;
Attrs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;
BasicShaderSourceStreamFactory BasicSSSFactory(Attrs.SearchDirectories);
Attrs.pShaderSourceStreamFactory = &BasicSSSFactory;
ShaderVariableDesc ShaderVars[] =
{
{"g_StaticTexture", SHADER_VARIABLE_TYPE_STATIC},
{"g_MutableTexture", SHADER_VARIABLE_TYPE_MUTABLE},
{"g_DynamicTexture", SHADER_VARIABLE_TYPE_DYNAMIC}
};
Attrs.Desc.VariableDesc = ShaderVars;
Attrs.Desc.NumVariables = _countof(ShaderVars);
Attrs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_STATIC;
StaticSamplerDesc StaticSampler;
StaticSampler.Desc.MinFilter = FILTER_TYPE_LINEAR;
StaticSampler.Desc.MagFilter = FILTER_TYPE_LINEAR;
StaticSampler.Desc.MipFilter = FILTER_TYPE_LINEAR;
StaticSampler.TextureName = "g_MutableTexture";
Attrs.Desc.NumStaticSamplers = 1;
Attrs.Desc.StaticSamplers = &StaticSampler;
ShaderMacroHelper Macros;
Macros.AddShaderMacro("USE_SHADOWS", 1);
Macros.AddShaderMacro("NUM_SHADOW_SAMPLES", 4);
Macros.Finalize();
Attrs.Macros = Macros;
RefCntAutoPtr<IShader> pShader;
m_pDevice->CreateShader( Attrs, &pShader );
Creating the Pipeline State Object
To create a pipeline state object, define instance of PipelineStateDesc structure. The structure defines the pipeline specifics such as if the pipeline is a compute pipeline, number and format of render targets as well as depth-stencil format:
// This is a graphics pipeline
PSODesc.IsComputePipeline = false;
PSODesc.GraphicsPipeline.NumRenderTargets = 1;
PSODesc.GraphicsPipeline.RTVFormats[0] = TEX_FORMAT_RGBA8_UNORM_SRGB;
PSODesc.GraphicsPipeline.DSVFormat = TEX_FORMAT_D32_FLOAT;
The structure also defines depth-stencil, rasterizer, blend state, input layout and other parameters. For instance, rasterizer state can be defined as in the code snippet below:
// Init rasterizer state
RasterizerStateDesc &RasterizerDesc = PSODesc.GraphicsPipeline.RasterizerDesc;
RasterizerDesc.FillMode = FILL_MODE_SOLID;
RasterizerDesc.CullMode = CULL_MODE_NONE;
RasterizerDesc.FrontCounterClockwise = True;
RasterizerDesc.ScissorEnable = True;
//RSDesc.MultisampleEnable = false; // do not allow msaa (fonts would be degraded)
RasterizerDesc.AntialiasedLineEnable = False;
When all fields are populated, call IRenderDevice::CreatePipelineState() to create the PSO:
m_pDev->CreatePipelineState(PSODesc, &m_pPSO);
Binding Shader Resources
Shader resource binding in Diligent Engine is based on grouping variables in 3 different groups (static, mutable and dynamic). Static variables are variables that are expected to be set only once. They may not be changed once a resource is bound to the variable. Such variables are intended to hold global constants such as camera attributes or global light attributes constant buffers. They are bound directly to the shader object:
PixelShader->GetShaderVariable( "g_tex2DShadowMap" )->Set( pShadowMapSRV );
Mutable and dynamic variables are bound via a new object called Shader Resource Binding (SRB), which is created by the pipeline state:
m_pPSO->CreateShaderResourceBinding(&m_pSRB);
Dynamic and mutable resources are then bound through SRB object:
m_pSRB->GetVariable(SHADER_TYPE_VERTEX, "tex2DDiffuse")->Set(pDiffuseTexSRV);
m_pSRB->GetVariable(SHADER_TYPE_VERTEX, "cbRandomAttribs")->Set(pRandomAttrsCB);
The difference between mutable and dynamic resources is that mutable ones can only be set once for every instance of a shader resource binding. Dynamic resources can be set multiple times. It is important to properly set the variable type as this may affect performance. Static variables are generally most efficient, followed by mutable. Dynamic variables are most expensive from performance point of view. This post explains shader resource binding in more details.
Setting the Pipeline State and Invoking Draw Command
Before any draw command can be invoked, all required vertex and index buffers as well as the pipeline state should be bound to the device context:
// Clear render target
const float zero[4] = {0, 0, 0, 0};
m_pContext->ClearRenderTarget(nullptr, zero);
// Set vertex and index buffers
IBuffer *buffer[] = {m_pVertexBuffer};
Uint32 offsets[] = {0};
Uint32 strides[] = {sizeof(MyVertex)};
m_pContext->SetVertexBuffers(0, 1, buffer, strides, offsets, SET_VERTEX_BUFFERS_FLAG_RESET);
m_pContext->SetIndexBuffer(m_pIndexBuffer, 0);
m_pContext->SetPipelineState(m_pPSO);
Also, all shader resources must be committed to the device context:
m_pContext->CommitShaderResources(m_pSRB, COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES);
When all required states and resources are bound, IDeviceContext::Draw() can be used to execute draw command or IDeviceContext::DispatchCompute() can be used to execute compute command. Note that for a draw command, graphics pipeline must be bound, and for dispatch command, compute pipeline must be bound. Draw() takes DrawAttribs structure as an argument. The structure members define all attributes required to perform the command (primitive topology, number of vertices or indices, if draw call is indexed or not, if draw call is instanced or not, if draw call is indirect or not, etc.). For example:
DrawAttribs attrs;
attrs.IsIndexed = true;
attrs.IndexType = VT_UINT16;
attrs.NumIndices = 36;
attrs.Topology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
pContext->Draw(attrs);
Tutorials and Samples
The GitHub repository contains a number of tutorials and sample applications that demonstrate the API usage.
Tutorial 01 - Hello Triangle
This tutorial shows how to render a simple triangle using Diligent Engine API.
Tutorial 02 - Cube
This tutorial demonstrates how to render an actual 3D object, a cube. It shows how to load shaders from files, create and use vertex, index and uniform buffers.
Tutorial 03 - Texturing
This tutorial demonstrates how to apply a texture to a 3D object. It shows how to load a texture from file, create shader resource binding object and how to sample a texture in the shader.
Tutorial 04 - Instancing
This tutorial demonstrates how to use instancing to render multiple copies of one object using unique transformation matrix for every copy.
Tutorial 05 - Texture Array
This tutorial demonstrates how to combine instancing with texture arrays to use unique texture for every instance.
Tutorial 06 - Multithreading
This tutorial shows how to generate command lists in parallel from multiple threads.
Tutorial 07 - Geometry Shader
This tutorial shows how to use geometry shader to render smooth wireframe.
Tutorial 08 - Tessellation
This tutorial shows how to use hardware tessellation to implement simple adaptive terrain rendering algorithm.
Tutorial_09 - Quads
This tutorial shows how to render multiple 2D quads, frequently swithcing textures and blend modes.
AntTweakBar sample demonstrates how to use AntTweakBar library to create simple user interface.
Atmospheric scattering sample is a more advanced example. It demonstrates how Diligent Engine can be used to implement various rendering tasks: loading textures from files, using complex shaders, rendering to textures, using compute shaders and unordered access views, etc.
The repository includes Asteroids performance benchmark based on this demo developed by Intel. It renders 50,000 unique textured asteroids and lets compare performance of D3D11 and D3D12 implementations. Every asteroid is a combination of one of 1000 unique meshes and one of 10 unique textures.
Integration with Unity
Diligent Engine supports integration with Unity through Unity low-level native plugin interface. The engine relies on Native API Interoperability to attach to the graphics API initialized by Unity. After Diligent Engine device and context are created, they can be used us usual to create resources and issue rendering commands. GhostCubePlugin shows an example how Diligent Engine can be used to render a ghost cube only visible as a reflection in a mirror.

Current Project
-Action/Adventure/Puzzle
-Over the Shoulder/3rd person
-Steampunk/Medieval aesthetic
-Co-op (2 Player story line)
Calling all content creators and programmers of any skill and experience level to join the team. Please be at least 16+ years of age. Artist(s) NEEDED (Unspecific; 3D Models, Concept Art, Animation, Ads, Graphic Design, ...)*
*Artist(s), We currently do not have any art styles set. We are looking for an original artist to set the art style for our production. This is a big opportunity. Feel free to ask questions. I am super excited to get started and meet some new people. Comment or message me for Discord server invitation.

Hey All!
Its been a while, these last few months after the summer was rough, and involved a lot of hard work considering we have no budget and we have to keep such an ambitious project alive!
We had our last community build out a while back and used a lot of the feedback we got from the greatest community on earth to fix and tweak things, so here is a list of what we have been up to, lets get straight to it!
Animations:
Our great animator Captain Lee spent a whole lot of time doing animations for us, as you saw in our previous update he spent most of his time on the first person hands. We have now added some of those in the build, after that he spent even more time doing some animations for the crew members, the focus this time was mostly idle animations.
Conversations is always crucial for having "life" on the ship, so constantly finding out what fits is not only a fun progress but challenging.
Having the crew do random idle animations that would make sense on a ship is also very important
Build Notes:
Lets jump to some tech stuff!
-=- Version 0.4.1 Notes -=-
* Implemented TRADING - Players can now buy / sell goods at ports. Each port has its own economy!
* Modified the 'Third-person' camera view (Pressing 'V') with limiters and slightly smoother transitions (WIP)
* Added the Crew System which includes two different behaviors (Deck Scrubbing, Talking). (In the future, Crew members will be able to dynamically switch between tasks)
* Crew Members now have their clothing and beard randomized
* Added a weather system (it can rain, clouds can change, etc.)
* Added a day & night system (currently too fast!)
* Completed Crafting System and UI overhaul
* Added the character customization screen (portrait)
* Added the ability to use a candle ("L") when its dark
* Added the ability to pick up and hold a pipe ("P")
* Added lanterns throughout the ship which can be turned on/off ("E")
* Added cannons that can be fired (X6) ("E")
* Sails are now animated (only an idle cycle for the time being)
* Integrated audio hooks on the character (walking)
* Integrated audio tracks and ambient loops (including a dynamic ambient audio system that is synchronized with ship water movement)
* Added some crafting recipes
* Improved water physics (buoyancy) and ship's navigation controls (WIP)
* When using the whipstaff to navigate, can now lean left/right using "Z" and "C"
* Replaced previous islands with new models, textures and lighting
* Improved the Quest System by adding a new series of new Quest Categories: Craft a good, Buy a good, Sell a good. A new quest relating to crafted is now active by default.
* Added contextual UI callouts -> When nearby an 'interactive station' (Whipstaff, Fiddler, etc.), when close to a Port, etc.
* Multiple improvements to the ship's collisions
* Changed the compass (now using a 2D UI asset) and waypoints
* Added 'water splash' effects for the ship to make it feels a bit more realistic
* Partial reskin of the Quest Book
* Skinned multiple UI elements (popups, callouts)
* Fixed multiple issues relating with 'game context' which resulted in mouse locks and other unwanted behaviors
* Fixed multiple animation quirks and issues
* Fixed multiple critical level shader issues that would prevent the game from working on various tech configurations
* Optimized volumetric light performances
* Optimized and streamlined visual assets to improve performances on lower end systems (GTX 580 / 8gb RAM)
* Added a demo version text overlay to quickly walk through new controls
Character Customization:
Previously this was only tested outside the build. But we also added the option to change beards after some feedback from twitter, once we get more characters this option will be enabled in the build.
I did not have the time to finish the frame in time to get it in the build. But whatever picture you choose here, will be displayed on your Captains table.
Trade:
Whenever you reach a port now, you can buy and sell goods for either making a profit, or for crafting at the workshop.
As the game progresses we will add more and more goods for to sell or buy. The wallpaper will properly display the port you are in as well, creating a unique animation in the different ports.
Sailing:
We have of course worked on the physics, which seems to be a never ending thing. Steering feels a bit heavier now, so does the turn ratio. Also, sailing at night when you cant see anything? Of course, why not!
Crafting:
We have added a few crafting recipes, so harpoons and rum can now be made on the ship. If you run out of items you would have to buy these at port. Harpoons can be sold at outposts for a pretty nice profit. Adding new recipes is also something we will continue to add as we go.
Crew:
We have not added any crew interaction as of right now, except the fiddler (He will play a song if you want him to) But you can watch your crew mates work and talk around the ship.
Cannons:
Of course, firing cannons is the fun part! Later on you will be able to command your crew to do this for you!
Whats next?
As we throttle trough with tweaking and adjusting things on feedback, I have also started a new player ship! Yes, I know, very exciting!
This time its the Cocca Veneta, a 16th century was an unarmed merchant vessel , trading from the Mediterranean, in particular Venice. The term 'Cocca' was applied to small merchant ships sailing from Venice to the east.
Characterized by a high prow and stern and a simple, maneuverable rig with 3 square and 2 lateen sails.
Their length was 20-30 meters and under 2000 tonnes displacement.
This ship also has a different and earlier steering mechanism which provides a new play style.
Take a look at the model I am working from here:
If you want to reach out for whatever reason, you can always send us an email at contact@seasoffortune.com or check out our website at www.seasoffortune.com
Until next time Captains, Have a great Christmas and a happy new year!
- Captain Tommy

Want to play an epic turned based strategy inspired by games like Heroes of might and magic or Age of Wonders? Enter a fantasy world of Heroes of Flatlandia, where you lead your kingdom of noble elves or dreadful undeads as one of several powerful heroes. Raise mighty armies and crash your enemies in detailed tactical battles. Use variety of spells and abilities to gain advantage, explore the world, and conquer your enemies. The game contains plenty of maps and allow you to play either against computer AI or against your friends in hot-seat multiplayer.Game Features• Fantasy turned based strategy• Detailed tactical battles• Two distinct races of elves and undeads• 14 different units and 4 playable heroes• Cunning AI to outsmart• Hot-seat multiplayer• Tens of spells and special abilities• Stunning fairy tale graphics• No microtransactions
Trailer
Google Playdemo version - https://play.google.com/store/apps/details?id=com.HighlandStudio.HeroesOfFlatlandiafull version - https://play.google.com/store/apps/details?id=com.HighlandStudio.HeroesOfFlatlandia1App Store(only full version)
https://itunes.apple.com/us/app/heroes-of-flatlandia/id1445838121?ls=1&mt=8

We are pleased to announce the release of Matali Physics 4.4. The latest version introduces comprehensive support for Android 9.0 Pie, iOS 12.x and macOS Mojave (version 10.14.x). Latest version also introduces Matali Render 3.4 add-on with normal mapping and parallax mapping based on the distance from the observer as well as other improvements and fixes.
What is Matali Physics?
Matali Physics is an advanced, multi-platform, high-performance 3d physics engine intended for games, virtual reality and physics-based simulations. Matali Physics and add-ons form physics environment which provides complex physical simulation and physics-based modeling of objects both real and imagined.
Main benefits of using Matali Physics:
Stable, high-performance solution supplied together with the rich set of add-ons for all major mobile and desktop platforms (both 32 and 64 bit)
Advanced samples ready to use in your own games
New features on request
Dedicated technical support
Regular updates and fixes
You can find out more information on www.mataliphysics.com
View full story

We are pleased to announce the release of Matali Physics 4.4. The latest version introduces comprehensive support for Android 9.0 Pie, iOS 12.x and macOS Mojave (version 10.14.x). Latest version also introduces Matali Render 3.4 add-on with normal mapping and parallax mapping based on the distance from the observer as well as other improvements and fixes.
What is Matali Physics?
Matali Physics is an advanced, multi-platform, high-performance 3d physics engine intended for games, virtual reality and physics-based simulations. Matali Physics and add-ons form physics environment which provides complex physical simulation and physics-based modeling of objects both real and imagined.
Main benefits of using Matali Physics:
Stable, high-performance solution supplied together with the rich set of add-ons for all major mobile and desktop platforms (both 32 and 64 bit)
Advanced samples ready to use in your own games
New features on request
Dedicated technical support
Regular updates and fixes
You can find out more information on www.mataliphysics.com

I was tying to figure out what to do with my procedural planets and for an initial step and I wanted to fly a spacecraft in and establish a low orbit around my world starting from some distant point and initial velocity. I know how to set up the gravity and I think I can pretty much do manual controls that will simulate Newtonian physics. However what I'm looking for is some software or algorithms that let me establish the orbit by controlling thrust in the right direction at the appropriate points in a trip towards the planet.
So I guess the software would accept something like starting position, starting velocity, desired orbit height (I'm assuming circular for now) , and desired orbit plane. From there it would give me firing points, duration and trust vectors needed to for the orbit. To make things simpler I'm assuming infinite fuel. I figure NASA must do stuff like this all the time but I haven't been able to find something solid on how it's done. Perhaps it's too complex, I'm not really sure, but I thought I throw the question out there anyway.

Hello everybody! I decided to write a graphics engine, the killer of Unity and Unreal. If anyone interested and have free time, join. High-level render is based on low-level OpenGL 4.5 and DirectX 11. Ideally, there will be PBR, TAA, SSR, SSAO, some variation of indirect light algorithm, support for multiple viewports and multiple cameras. The key feature is COM based (binary compatibility is needed). Physics, ray tracing, AI, VR will not. I grabbed the basic architecture from the DGLE engine. The editor will be on Qt (https://github.com/fra-zz-mer/RenderMasterEditor). Now there is a buildable editor. The main point of the engine is the maximum transparency of the architecture and high-quality rendering. For shaders, there will be no new language, everything will turn into defines.

Hi guys! Our first game (Dongo Adventure) has just been released on Steam! I hope you have fun with the game! O/
The game was produced by me and my brother for 11 months. We did everything with free and open source software (Blender 3D and Gimp).
About the game: The game is 3D Platform style, inspired by the classic platform games (mainly 'Donkey Kong Country 2'), bringing all those challenges and fun of the genre. Thank you all for the support!
Steam Game Page: http://store.steampowered.com/app/811450/Dongo_Adventure/
Official Trailer:

Time to Marble is a game I have been working on and expect to have a product ready for release by the end of 2019, but in order to make sure I can reach that dream, passion, and goal, I will need a designer so that I can give more focus to the coding and mechanics aspect.
Revenue Share is promised at the release of the game to the Designer that joins and helps me reach this release.
I am Using Unity, and also have ProBuilder as an asset that helps bridge polygons between 3d modeling and unity.

Hi,
I wish to generate light map textures for objects in my scene containing ambient occlusion and global illumination.
Currently I can do this in 3D Max, but it is taking too long on my single computer for this to be feasible.
Does anyone know any rendering farms that supports this (light baking)? I checked "Rebusfarm" and they did not support this feature.
Any help appreciated,
Doggolainen

Tired of working on games that never get released? Then you're at the right place!
Game Description
Titanforged Entertainment is currently working on a 3D multiplayer game containing several board games. The environment of the game is something of an RPG tavern/potion/scroll shop and the game style is stylized with hand-painted texturing. You can think of the art style as in World of Warcraft or Fortnite or Warcraft 3, just to make it more clear. The environment is ONLY used for the looks. Meaning, the environment is only there as a lobby screen & waiting area. There will be a cinematic screen in the tavern and we will make it feel cozy and nice when people are in the menu's and waiting for a game. At the bottom of this post, you can see some screenshots from the game at its current state. Note that the screenshots are taken from the 3D software and are still not sculpted or textured which is why they look simple and plain. They will look more detailed at a later stage in development.
The game contains multiple board (and card) games where people play against each other in for example Chess, Ludo, Snakes & Ladders, Uno, Poker, Scrabble, Drawing/Guessing and more. The boards we are developing will also be in full 3D. For example, Chess would have a castle/monastery environment with the pieces designed as character pieces. In this game you can play to gain ranks and medals. You earn coins from playing, which you can use to buy skins and different pieces in the coin shop. There are more features in the game but these are just some of them.
Programmer Needed
Titanforged is looking for a highly motivated and talented Programmer. You will be provided all the assets from the artists and it is your responsibility to bring life to the game. If you’re up to the challenge, we want to hear from you!
Description:
- We do not require a specific programming language. It is up to you, as long as everything is written nicely and the game is working as it's supposed to.
- You should be able to program the game as a solo project. We only try to recruit members if necessary.
- You need to have a passion for board games.
- You are someone who finishes projects. Please do not apply if you have a hard time finishing a game. This will at least take 3-5 months before release.
- You are confident when it comes to Networking and Multiplayer programming. The game will be released on Steam.
- You should know how to build good security for the game to avoid cheating and 3rd party software.
- You are able to spend at least 15 hours a week on the project. If you can spend more, that's great. Currently we are spending 35 hours a week on the art.
- You are 18+ years old (Legal contract reasons)
Big plusses (NOT REQUIRED):
- You have previously released a game before.
- You have a degree in your field.
Notice that if you don't have a solid portfolio, you will be tested by creating a chess game. We will provide you the board, pieces and textures. You will "only" have to write the code. There is no AI / singleplayer programming.
Payment
The payment for the project is revenue share. This will be our first game to release on Steam and therefore we are currently all working for free. When the game is released on Steam, payment will be divided between each member as promised in the contract you will sign before working on the game.
Your revenue share for the project will be 35% and is not negotiable. We predict high income for this game when it is released on Steam. A lot of the money will be saved in Titanforged Entertainment so that we can create a better next-game and afford anything we need. Our goal is to progress such that we can do this full time and pay our members monthly.
Contact Information
If you're interested in joining us for this project and hopefully for the future projects, you can add me on discord Nafei#9413 or write an email to Nafei@titanforged.net
Screenshots

THE PROJECT
INT is a 3D Sci-fi RPG with a strong emphasis on story, role playing, and innovative RPG features such as randomized companions. The focus is on the journey through a war-torn world with fast-paced combat against hordes of enemies. The player must accomplish quests like a traditional RPG, complete objectives, and meet lively crew members who will aid in the player's survival. Throughout the game you can side and complete missions through criminal cartels, and the two major combatants, the UCE and ACP, of the Interstellar Civil War.
Please note that all of our current positions are remote work. You will not be required to travel.
For more information about us, follow the links listed below.
INT Official website
IndieDB page
Also follow social media platforms for the latest news regarding our projects.
Facebook
Twitter
3D ENVIRONMENT MODELER
We are looking for a 3D Modeller to create and polish 3D models for the game. You will be collaborating with the team in creating 3D models that meet polygon-count and texture quality requirements. You will also need to be able to enact upon instructions from the Art team Lead and the Project Lead.
Your duties include:
Create 3D models conforming to the polygon-count requirements.
Skinning and un-wrapping of models created.
Make adjustments to created models when required.
REQUIREMENTS
To be successful in this position, following requirements apply:
Have working knowledge of 3D modelling suites.
Understand import/export requirements for Unity Engine integration.
Excellent self-management skills.
Excellent attention to detail.
Excellent communication skills.
OTHER OPEN POSITIONS
Unity Engine Programmer
Website Manager
3D Character Modeller
REVENUE-SHARE
This is a great opportunity to get into the game development industry. Being an Indie team we do not have the creative restrictions often imposed by publishers or other third parties. We are extremely conscientious of our work and continuously uphold a high level of quality throughout our project.
We are unable to offer wages or per-item payments at this time. However revenue-sharing from crowd-funding is offered to team members who contribute 15-20 hours per week to company projects, as well as maintain constant communication and adhere to deadlines. Your understanding is dearly appreciated.
TO APPLY
Please send your Cover Letter, CV, Portfolio (if applicable), and other relevant documents/information to this email: JohnHR@int-game.net
Thank you for your time! Please feel free to contact me via the email provided should you have any questions or are interested to apply for this position. We look forward to hearing from you!
John Shen
HR Lead
Starboard Games LLC