Jump to content
  • Advertisement
  • entries
    12
  • comments
    41
  • views
    4783

About this blog

This journal is dedicated to my auto formation and my experimentations.

Entries in this blog

 

Our first hater

So we had our first hater... but first please listen to one of our music we think we was bashing against. After that, let's hear the context. Context Our development blogs on gamedev mainly focus on the actual development of our game(s) and any related research that we've done. So, our target audience is other video game developers. We also have our own subreddit where our target audience is everyone. Thus, we decided to make our subreddit public and allow subscribers to post content that follows the rules, which they are mainly about posting relevant content.  Recently, we've been gaining more popularity and finally gained our 25th subscriber! 🎉 However, with popularity means more human attention. One thing I know about humans is that there are among them douchebag, troll, egoist, evil [and so forth] people. Inevitably, we were bound to attract the attention of one of those toxic people and so we had our first experience with what we call a hater. The Hater The hater firstly unannouncedly posted this on our subreddit : The person actually posted music of his game [I suppose]. It is an electronic music video. While it's true that we post vaporwave music videos on our subreddit, they follow the rule that it's about our game and our company.

So I decided to remove his post and send him a warning as a message : Now, I don't clearly understand exactly what he meant by "Someone better than you, and wanted to make you feel better" but I do understand that this guy is saying he's better than us and that him posting his content on our subreddit would make us feel better (lol). I suppose the "better than us" part is related to our music, which is meant to be that way to fit into the game design of the game. Anyway, as you can see, this guy is so cool because he breaks rules. Wow. But wait, there's more! Just before I banned him, he posted this on our subreddit :  Of course we banned you for posting content about your game on our subreddit to gain popularity. Our subreddit specifies precisely through rules that it is meant to be a platform of communication for our company and a way to keep our subscribers in touch with the development of our games. Just look at r/fallout for example. Their first rule says that all posts must be directly related to Fallout. Are they not cool to ban people who disrespect that rule? No, it does not make sense. Reddit is a magnificent social network that allows specific sub-forums as ours and it's actually what defines it. Anyway, I decided to ban him and then ignore him. I've always been more of an observer than someone who needs to express his opinion loudly and publicly on social networks but because this is the first time we had a hater for our game, I just needed to post about this. What we learned from this : Added a rule about not spamming that allows us to give warnings and ban people from our subreddit. Ignore banned people. Made our subreddit restricted instead of public. Now, only approved redditors are able to post on our subreddit. Toxic people take time from us video game developers that we could put into making our game(s)

thecheeselover

thecheeselover

 

Low poly terrain

Subscribe to our subreddit to get all the updates from the team! Recently I've been tackling with more organic low poly terrains. The default way of creating indices for a 3D geometry is the following (credits) :   A way to create simple differences that makes the geometry slightly more complicated and thus more organic is to vertically swap the indices of each adjacent quad. In other words, each adjacent quad to a centered quad is its vertical mirror.   Finally, by not sharing the vertices and hence by creating two triangles per quad, this is the result with a coherent noise generator (joise) : It is called flat shading.
 

Marching cubes

Subscribe to our subreddit to get all the updates from the team! I have had difficulties recently with the Marching Cubes algorithm, mainly because the principal source of information on the subject was kinda vague and incomplete to me. I need a lot of precision to understand something complicated  Anyhow, after a lot of struggles, I have been able to code in Java a less hardcoded program than the given source because who doesn't like the cuteness of Java compared to the mean looking C++? Oh and by hardcoding, I mean something like this :  cubeindex = 0; if (grid.val[0] < isolevel) cubeindex |= 1; if (grid.val[1] < isolevel) cubeindex |= 2; if (grid.val[2] < isolevel) cubeindex |= 4; if (grid.val[3] < isolevel) cubeindex |= 8; if (grid.val[4] < isolevel) cubeindex |= 16; if (grid.val[5] < isolevel) cubeindex |= 32; if (grid.val[6] < isolevel) cubeindex |= 64; if (grid.val[7] < isolevel) cubeindex |= 128; By no mean I am saying that my code is better or more performant. It's actually ugly. However, I absolutely loathe hardcoding.   Here's the result with a scalar field generated using the coherent noise library joise :  
 

Zone division

Subscribe to our subreddit to get all the updates from the team! A friend and I are making a rogue-lite retro procedural game. As in many procedural rogue-lite games, it will have rooms to complete but also the notion of zones. The difference between a zone and a room is that a zone is open air whilst a room is not. Rooms are connected mainly by corridors while zones are mostly naturally connected / separated by rivers and mountains.   Because we want levels with zones to be generated, we need to tame the beast that is procedural generation. How can we generate each zone itself and also clearly divide them? Until now, I had only been using the Java noise library called Joise, which is the Java community port of JTippetts' Accidental Noise Library. I needed the zone data to be generated with basis function modules, i.e. Perlin noise, but in contrast I needed a more structured approach for the zone division. Joise library does have a cell noise module that is a Worley noise. It looks like this depending on its 4 parameters (1, 0, 0, 0) :    Using math modules, I was able to morph that noise into something that looks like a Voronoi diagram. Here's what a Voronoi diagram should look like (never mind the colors, the important parts are the cell edges and the cell centers) : A more aesthetic version :   The Worley noise that I had morphed into a Voronoi-like diagram did not include the cell centers, did not include metadata about the edges and was not enough deterministic in a sense that sometimes, the edges would around 60 pixels large. I then searched for a Java Voronoi library and found this one called Voronoi-Java. With this, I was able to generate simple Voronoi diagrams :   Relaxed : 1 iteration   Relaxed : 2 iterations The relaxation concept is actually the Lloyd's algorithm fortunately included within the library.   Now how can I make that diagram respect my level generation mechanics? Well, if we can limit an approximated number of cells within a certain resolution, that would be a good start. The biggest problem here, is that the relaxation reduces the number of cells within a restricted resolution (contrary to the global resolution) and so we need to keep that in mind. To do that, I define a constant for the total number of sites / cells. Here's my code : private Voronoi createVoronoiDiagram(int resolution) { Random random = new Random(); Stream<Point> gen = Stream.generate(() -> new Point(random.nextDouble() * resolution, random.nextDouble() * resolution)); return new Voronoi(gen.limit(VORONOI_SITE_COUNT).collect(Collectors.toList())).relax().relax().relax(); }   A brief pseudo-code of the algorithm would be the following : Create the Voronoi diagram Find the centermost zone Selects X number of zones while there are zones that respect the selection criteria Draw the border map Draw the smoothed border map The selection criteria is applied for each edge that is connected only to one selected zone. Here's the selection criteria : Is connected to a closed zone, i.e. that all its edges form a polygon Does have two vertices Is inclusively in the resolution's boundaries   Here's the result of a drawn border map!   In this graph, I have a restricted number of cells that follow multiple criteria and I know each edge and each cell center point. To draw the smoothed border map, the following actions must be taken : emit colors from already drawn pixels and then apply a gaussian blur. Personally, I use the JH Labs Java Image Filters library for the gaussian blur. With color emission only : With color emission and a gaussian blur : You may ask yourself why have we created a smoothed border map? There's a simple reason for this, which is that we want the borders to be gradual instead of abrupt. Let's say we want rivers or streams between zones. This gradual border will allow us to progressively increase the depth of the river and making it look more natural in contrast with the adjacent zones. All that's left is to flood each selected cell and apply that to a zone map.
 

Zone generation

Subscribe to our subreddit to get all the updates from the team! I have integrated the zone separation with my implementation of the Marching Cubes algorithm. Now I have been working on zone generation. A level is separated in the following way : Shrink the zone map to exactly fit an integer number of Chunk2Ds, which are of 32² m². For each Chunk2D, analyse all zones inside its boundaries and determine all possible heights for Chunk3Ds, which are of 32³ m³. Imagine this as a three dimensional array as an hash map : we are trying to figure out all keys for Chunk3Ds for a given Chunk2D. Create and generate a Chunk3D for each height found. Execute the Marching Cubes algorithm to assemble the geometry for each Chunk3D.   In our game, we want levels to look like and feel like a certain world. The first world we are creating is the savanna. Even though each Chunk3D is generated using 3D noise, I made a noise module to map 3D noises into the 2D to able to apply 2D perturbation to the terrain.   I also tried some funkier procedural noises :  An arch!   The important thing with procedural generation, it's to have a certain level of control over it. With the new zone division system, I have achieved a minimum on that path for my game.
 

Unit Vision

Subscribe to our subreddit to get all the updates from the team! First off, here's a video that shows the unit vision in action :    So, what is the unit vision? It's a simple mechanism that notifies a unit when another unit enters its vision field. It also takes into account if the vision is blocked by entities. This is how it is implemented step by step : A cone ghost control is attached to the unit's head All units intersecting with the cone's AABB fire events (AABB because of how Bullet Physics work) Cast a ray towards the visible unit and then adjust the angle so that it fits in the cone If the ray cast touches the supposedly visible unit, then it is truly visible   Using the debug view of Bullet Physics in the jMonkey Engine 3.1, we're able to see what the vision cone actually looks like.   And when inside the cone we can't see it because of culling. However, we can see the enemy's arm moving, which is a test I did for when a unit see another unit.   Behind a box, the enemy does not move its arm because he can't see me.   But when I leave my hiding spot, he can see me again.
 

Simple organic and brute force dungeon generation

Subscribe to our subreddit to get all the updates from the team! Last month, I made a pretty simple dungeon generator algorithm. It's an organic brute force algorithm, in the sense that the rooms and corridors aren't carved into a grid and that it stops when an area doesn't fit in the graph. Here's the algorithm : Start from the center (0, 0) in 2D Generate a room Choose a side to extend to Attach a corridor to that side If it doesn't fit, stop the generation Attach a room at the end of the corridor If it doesn't fit, stop the generation Repeat from steps 3 to 7 until enough rooms are generated It allowed us to test out our pathfinding algorithm (A* & String pulling). Here are some pictures of the output in 2D and 3D : 
 

Pathfinding Navigation Mesh : Wall Collision Avoidance

Subscribe to our subreddit to get all the updates from the team! Introduction In our 3D game (miimii1205), we use a dynamically created navigation mesh to navigate onto a procedurally generated terrain. To do so, only the A* and string pulling algorithms were more specifically used until our last agile sprint. We recently added two new behaviors to the pathfinding : steering and wall collision avoidance. In this article, I will describe how I achieved a simple way for agents to not walk into walls. Configuration 3D or 2D navigation mesh, as long as the 3D one is not cyclic. Navigation cells and their : polygonal edges, connections (other cell), shared edges (the line intersecting between two connected cells), centroids and normals. An A* and string pulled (not tested without string pulling) generated path consisting of waypoints on the navigation mesh. The Algorithm The agent is the pink low-poly humanoid and the final destination is the flag.   The ideal algorithm (yet unoptimized) would be to cast an oriented rectangle between each consecutive waypoint where its width is the two times the radius. Think of the agent's center position being in the middle of the width. Anyway, this algorithm is too complicated, too long to develop for our game, too big for nothing and so I thought about another algorithm, which has its drawbacks actually. However, it's more suited for our game. Psss, check this article if you haven't seen it yet. The algorithm is the following : For each waypoint, pick the current one and the next one until the next one is the last. Iterate over the current navigation cell's edges, which is defined by the agent's 3D position. To do that, you need a spatial and optimized way to determine the closest cell of a 3D point. Our way to do it is to first have have an octree to partition the navigation mesh. After that, get all the cells that are close to the point plus an extra buffer. To find the cell that is the closest to the point, for each picked cell, cast a projection of the position onto each one of them. This can be done using their centroids and normals. Don't forget to snap the projected position onto the cell. After, that compute the length of the resulting vector and pick the smallest one. Convert each edge to a 2D line by discarding the Y component (UP vector). For each side left and right, which are defined by the agent's position and direction towards the next waypoint, cast a 2D line that start from the agent's position, that goes towards one of the two perpendicular directions related to the direction to the next waypoint and that has a length of the defined radius. If there's an intersection on a connection and that it's on the shared part of the connection, then continue with the connected cell's edges. If there are any intersections other than #5, create a new waypoint before the next waypoint. This new one's position is defined by the intersection's position translated by a length of two times the radius and projected towards the agent's current direction as a 2D line. The same translation is applied to the next waypoint. Cast two 2D lines, one on each side of the agent as described before, starting from the sides, going towards the same direction as the agent and of the same length between the current and next waypoint. Check for #5. If there is an intersection on a connection and that it's on the unshared part of the connection, then do #6 (no if). If there's an intersection on a simple edge, then translate the next waypoint as described in #6.   Here's a video of the algorithm in action :   

Fresnel Outline Shader for Picking up Items

Subscribe to our subreddit to get all the updates from the team! Idea We wanted units in our game to be able to pick up items, including the player. But how can the player know which item will be picked up when he executes that action? Traditionally, video game developers and designers do this by using an outline shader. However, in our game, we thought that it was too "normal", cartoonish and not enough A E S T H E T I C. Solution The solution was to use Fresnel optics to simulate a cooler outline. The Fresnel Effect is used, approximated actually because it is extremely complex, in shaders such as a reflection shader for specular colors. In real life, this visual effect occurs on surfaces that reflect and refract light. An object that refracts light lets a fraction of the incoming light pass through its body. A good example for this is water. Examples and Tutorials Here are examples and tutorials for the Fresnel Effect in computer graphics programming : Simple demonstration of what is the Fresnel Effect Tutorial and more profound explanations on the subject Simple get to the point tutorial with Unity as tool How to Do It Here's how I did it with the jMonkeyEngine, which is a Java 3D game engine. Firstly, you need to create a material definition that will describe what will be the shaders and their inputs. Material Definition MaterialDef Fresnel Outline { MaterialParameters { Color FresnelOutlineColor Float FresnelOutlineBias Float FresnelOutlineScale Float FresnelOutlinePower } Technique { VertexShader GLSL100: shader/vertex/fresnel_outline/fresnel_outline_vertex_shader.vert FragmentShader GLSL100: shader/fragment/fresnel_outline/fresnel_outline_fragment_shader.frag WorldParameters { WorldViewProjectionMatrix WorldMatrix CameraPosition } } } Material Parameters As you can see, there are 4 uniforms that we need to specify to the shaders for them to function properly : FresnelOutlineColor - The color of the Fresnel Effect. Usually, it is an environment map that deals with that. FresnelOutlineBias - Acts like a diffuse color for the specular component. FresnelOutlineScale - How far the Fresnel Effect affects the model. The smaller the angle between I and N (the surface's normal), the less Fresnel Effect there is and the more scale is needed for that surface to be lit by it. FresnelOutlinePower - Exponentially increases the Fresnel Effect's color but decreases the scale. We will need to either set them in the material or in the code. You'll see about that later in the article. Technique The technique describes what shaders to execute and their engine's uniforms. There's no need to use a recent version of OpenGL / GLSL for this shader. The first GLSL version will do. For the Fresnel shader, we need to the following uniforms to be supplied by the game engine : WorldViewProjectionMatrix - The MVP matrix is needed to compute each vertex' position WorldMatrix - The world matrix is needed to compute the position and normal for each vertex in world coordinates CameraPosition - The camera position is needed to calculate the I (incident) vector Material The material uses a material definition and then applies render states and parameters to it. It is instantiable codewise. Material Fresnel Outline : material_definition/fresnel_outline/fresnel_outline_material_definition.j3md { MaterialParameters { FresnelOutlineColor : 1.0 0.0 0.0 1.0 FresnelOutlineBias : 0.17 FresnelOutlineScale : 2.0 FresnelOutlinePower : 1.0 } } As you can see, we can set the uniforms right here instead of doing so in the code, which saves us programmers from dealing with design components. Vertex Shader #import "Common/ShaderLib/GLSLCompat.glsllib" uniform vec3 g_CameraPosition; uniform mat4 g_WorldMatrix; uniform mat4 g_WorldViewProjectionMatrix; uniform float m_FresnelOutlineBias; uniform float m_FresnelOutlineScale; uniform float m_FresnelOutlinePower; attribute vec3 inPosition; attribute vec3 inNormal; varying float fresnelOutlineR; void main() { vec3 worldPosition = (g_WorldMatrix * vec4(inPosition, 1.0)).xyz; vec4 worldNormal = normalize(g_WorldMatrix * vec4(inNormal, 0.0)); vec3 fresnelI = normalize(worldPosition - g_CameraPosition); fresnelOutlineR = m_FresnelOutlineBias + m_FresnelOutlineScale * pow(1.0 + dot(fresnelI, worldNormal.xyz), m_FresnelOutlinePower); gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0); } This is how each vertex position, normal, color, texture coordinates [...] are transferred into the vertex shader by the jMonkeyEngine. attribute vec3 inPosition The same procedure is applied onto g_ and m_ variables. g_ variables are definied by the engine, whilst m_ variables are defined by the material definition. Here's how to do the Fresnel outline shader on the vertex side : Compute the world position and normal Compute the eye to vertex direction Compute the Fresnel Effect R variable (description reference)    Fragment Shader #import "Common/ShaderLib/GLSLCompat.glsllib" uniform vec4 m_FresnelOutlineColor; varying float fresnelOutlineR; void main() { gl_FragColor = mix(vec4(0.0, 0.0, 0.0, 1.0), m_FresnelOutlineColor, fresnelOutlineR); } All that's left to do is a linear interpolation between the black color and the desired color with R being the interpolation value between the two. Because this is a simple tutorial, it only shows how to compute the Fresnel outline specular color. Result And with a bias of 1.0. Teal! Tested on a pickable item    
 

Voxels

Voxels! Unlike my old Xna application, this one's code is way more beautiful to the eye. Zero "switch" or "if and else" for cube faces, as I did with my cubic planet faces. My only problem with voxels is that it's a 3D grid. A 3D grid take a lot longer to compute than six 2D grids.
250 * 6 = 1500 quads to compute and draw.
2503 = 15,625,000 voxels to compute and maybe draw. As I use more and more complex objects to abstract the computation and the drawing part, the code slows. Following this entry, I'll make another one but with two videos:
1) Spherical planet made of voxels
2) Cubic planet made of voxels

thecheeselover

thecheeselover

 

Grouping of my [new] work so far

I'm an amateur and hobbyist video game developer. I've been programming for 9 years now even though I'm almost 21. When I started, it was rough being extremely bad with the english language and a noob programmer. Instead of helping me, people over multiple forums were only degrading my lack of skills and so I stopped being an active user. I have now finished what we call in Quebec a "technique". A technique is an academic degree of 3 years that is the equivalent of college degree. The technique I've done was called "Technique de l'informatique de gestion", which is a computer science technique applied to management softwares. As I finished college, I noticed I've improved my programming competencies and so I started again to research and program for fun, which I did 4 years ago. See I'm currently working on planet generation. Everything was done using the jMonkey Engine 3, Java 8, Eclipse Mars and Joise (a java adaptation of the accidental noise library from JTippetts). The following videos sum up what I've done so far:

thecheeselover

thecheeselover

  • Advertisement
×

Important Information

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

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!