Jump to content
    1. Past hour
    2. Hello ! Here is a new tutorial on how to create a Jet Pack sound effect for your video games. In this video I will show you how I created the jet pack sound for the multiplayer online game ExoCorps ! You can find this sound and loads more at: http://www.ogsoundfx.com
    3. Nick Mok

      Unity Discord

      https://discordapp.com/channels/243005537342586880/401076282869415946 Here is one.
    4. Regarding Unity, I switched from Cocos2D-x to unity fews years ago because of company decision. I have to say, while it has lots of features its slow on doing things. I am not talking about getting task done but operating with Unity. Every time I change some code, it it take quite a long time to recompile on unity side (not from visual studio). Every time I import something it hang a little. Many basic functions are missing or in complete. Can you imaging you need to write your own blend code just to have two images blend together with some blend mode. Many people ended up just buying something like https://assetstore.unity.com/packages/tools/particles-effects/blend-modes-28238 because they don't know how to write shader like me. I was surprise when I saw there are so many masking plugin on their store https://assetstore.unity.com/search?q=masking&k=masking. That's because masking feature they provide is weak and could not satisfy user in many cases. And that is a many years old game engine! I even think they intend not to provide those nicely so that Unity could take 30% commission off their assetstore purchase. On other engines, many features are just basics and fundamental features. But it doesn't mean I don't like unity. It has its strength especially it is coding with C#. Writing in C# is more comfortable even through I have quite some years of c++ experience. When il2cpp is enabled, code will be translate to c++ for building which could improve performance but according to some sources, it is still easy for people to hack the game as it is still holding c# source somewhere for certain purpose. e.g. for debugging, generating crash log / bug report, etc. Without il2cpp, anyone could read your source code by decompiling the built DLL. Thus, another kind of addon is required to protect your code https://assetstore.unity.com/search/?k=obfuscator&order_by=relevance&q=obfuscator&rows=42. But then it would be harder to debug a release build as the reported crash log callstack will become junky and require "treatment" to restore. The story goes on and on. Maybe Unreal is better at some point but I never tried it. Anyway, don't try to write your own game engine if your goal is just to make game! It will work but will probably not be as good as using an engine. A good engine consist of good resources management and complex algorithm to optimize many part of the game. They also handle platform compatibility for you.e.g. When a device don't support certain type of texture format, they fall back to use another less optimized format. Sometime like that. A good engine take care of lots of stuff that people do not realize they need to deal with when publishing a game. Those issues arise when the game is run on another PC or OS version or platform, etc.
    5. The answer will depend on a few specifics. For these questions, assume the correct phrase is "mars". What is the expected result if the input is "sram"? (All input characters are correct, but order is not correct.) What is the expected result if the input is "mar"? (All input characters are correct, but correct phrase not solved.) What is the expected result if the input is "marss", "mmars", etc.? (All characters from the correct phrase are present and in the correct order -- but with additional characters.) What is the expected result if the input is "MARS"? (Case sensitivity.) An example solution could be something like (pseudo): auto minCount = min(correctPhrase.count(), guessedPhrase.count()); int numMatching = 0; for (int i = 0; i < minCount; i++) { if (correctPhrase[i] == guessedPhrase[i]) { ++numMatching; } } But like mentioned, it depends on the specifics of the expected results.
    6. BitsNPiecesMusic

      Bits & Pieces Music

      Good morning and happy Sunday! I finished another track yesterday, which is essentially a follow-up to "Persistence is Futile". Using some of the similar sounds from that track, I am creating a story with the tracks. I hope you like it! Thanks for checking it out!
    7. thanks Zakwayda, I appreciate the feedback very much. Regarding my question, there is no code actually doing the check yet, as I'm unsure as to how to go about doing it. Basiaclly if the user input is 'bars' and the correct answer is 'mars' I need the program to say 3 characters match, but I don't know how best to write a function to count this, although thinking about it again now, possibly I'll have a look at passing a function the above in 2 vectors of chars, iterate through the answer for each character in the user input, and count the matches... I've probably just answered my own question
    8. PROGRESSThought I'd reach out for some feedback on my little project. This is an android two-player game for top-down boxing matches. The core mechanics are all that I have accomplished thus far, later I want to add different configurations for your boxer (special effects, increased health or damage, etc) and maybe even a single player AI to practice against.SCREENSHOTS #1 *****************************************************************#2 FEEDBACKRight now the gameplay feedback I'm looking for is on the fundamental mechanics of the game.One area of particular concern is the window of opportunity for a player to block after their opponent has begun a punch. Currently that window is one-tenth of a second, otherwise you will be to late to counter their blow. I want it to be difficult to successfully pull off a block and have it be something that requires real attention to accomplish. I'm wondering though if it isn't too difficult right now, which may encourage mindless button mashing, which is certainly not what I want to condone.Another consideration is whether having three main actions (block, attack, charge) provides a good balance. My idea with having three main areas is that your two thumbs will have to leave one section uncovered at all times. This should result in hand movements that telegraph actions to the opponent.Aside from these, any other constructive criticism is very welcome.LINKMy game can be found at the Google Play Store here: https://play.google.com/apps/testing/com.meatandgrain.PunchABunchNOTE There is a known graphics error when performing a special punch. There are no doubt other unknown errors as well. Thank you for your time, I hope you'll be able to find some fun in this little game!
    9. Today
    10. I'm not sure if it's what you're looking for, but AppGameKit can create games for the Raspberry Pi.
    11. Hello! When I implemented SSR I encountered the problem of artifacts. Screenshots here Code: #version 330 core uniform sampler2D normalMap; // in world space uniform sampler2D colorMap; uniform sampler2D reflectionStrengthMap; uniform sampler2D positionMap; // in world space uniform mat4 projection, view; uniform vec3 cameraPosition; in vec2 texCoord; layout (location = 0) out vec4 fragColor; void main() { mat4 vp = projection * view; vec3 position = texture(positionMap, texCoord).xyz; vec3 normal = texture(normalMap, texCoord).xyz; vec4 coords; vec3 viewDir = normalize(position - cameraPosition); vec3 reflected = reflect(viewDir, normal); float L = 0.5; vec3 newPos; for (int i = 0; i < 10; i++) { newPos = position + reflected * L; coords = vp * vec4(newPos, 1.0); coords.xy = 0.5 + 0.5 * coords.xy / coords.w; newPos = texture(positionMap, coords.xy).xyz; L = length(position - newPos); } float fresnel = 0.0 + 2.8 * pow(1 + dot(viewDir, normal), 4); L = clamp(L * 0.1, 0, 1); float error = (1 - L); vec3 color = texture(colorMap, coords.xy).xyz; fragColor = mix(texture(colorMap, texCoord), vec4(color, 1.0), texture(reflectionStrengthMap, texCoord).r); } I will be grateful for help!
    12. Regarding your question about matching characters, for me at least it would take some time to analyze your code as it's presented. Maybe someone else will comment on that, but meanwhile here's a couple suggestions: use the debugger to step through your code to figure out what it's doing and where it's going wrong (assuming it's going wrong), and/or post a small, self-contained example that includes only the functionality of interest (that would make it easier for others to analyze the code and maybe try it out themselves). Here's a few suggestions. Issues of coding style and convention can sometimes prompt strong reactions from people, so let me clarify that I'm only offering my personal opinions in response to your explicit request for feedback. Also, I'm going to mention some best practices and conventions here without going into great detail on the reasoning behind them (otherwise this post would probably be excessively long). I'm happy to elaborate on anything though, and you can find plenty of information on these topics elsewhere. - In C++, the use of macros is generally discouraged unless it's the only solution or arguably the optimal solution. (At or near the top of the list of reasons for this is that macros don't respect scope.) In your code for example, for the 'clear' functionality, in C++ you'd typically use a function for that rather than a macro. - If you haven't already, you might look further into the use of 'const' in C++. Opinions differ as to how liberally 'const' should be used. Personally I prefer to use it almost everywhere possible, including function arguments and local variables where mutability isn't needed. In any case, I'd suggest investigating that further and coming to your own conclusions as to what conventions and practices you prefer (again, if you haven't already). - It looks like you're using pre-increment for loop counters in some cases and post-increment in others. Although the chances of the choice having any practical impact in the given context are probably about zero, there are arguments for pre-increment being preferable unless post-increment is needed. In any case, I'd suggest using one or the other exclusively, just for clarity and consistency. - Some would argue that braces should always be used for control structures even when there's only one statement. I see a few other little things, but the above items are most significant, I think. Again, you can find plenty of discussion of all these topics online and elsewhere if you're interested in investigating them further.
    13. Link: https://www.kongregate.com/games/Vandallord/idle-stone-history A wicked witch turned the main hero into the stone, you need to find a way to break the spell. INSTRUCTIONS Click on the objects and they will open. Click on the stone and its skill to attack the animals will grow as well as a the losses from clicking on animals. Click on the river to improve the function to manage time and clicks on the animals will be more precise. Click on the tree and it will give you things from animals and the level of luck will grow which give you an opportunity to Harder hits. The higher the level of monsters the more animal can visit the stone and give presents which are essential to make a portion. Screenshots:
    14. DexterZ101

      Frogger GameDev Challenge Entry

      Downloaded and play with it a couple of try.. it's cool... but too hard for the first level... I go as far to see the boatman with a spear ^_^y
    15. If the company shuts down and doesn't transfer the IP then no one owns it. and it becomes public domain. But that rarely happens usually they sell it off or it gets acquired as part of bankruptcy settlement.
    16. In Cuda we can declare a variable this way - __device__ int someVar; Then via cudaMemcpyToSymbol we can copy/transfer a value to that variable. And we can refer to this variable from kernels. This variable will be available through the whole app life. This is some sort of static variable of TU and this is really handy beasue we don't need to pass such variables as kernel arguments. I see now these is no such thing in OpenCL. I'm not doing anything specific, just learning OpenCL/Cuda and facinated by their opportunities.
    17. just functions to clear the screen and print characters slower like an old terminal #define CLEAR system("cls") void print(std::string s) { for (auto& c : s) { std::cout << c; std::this_thread::sleep_for(std::chrono::milliseconds(5)); } }
    18. Are you interested in speculative answers? Or are you specifically looking for information on how it was actually done in the game?
    19. This doesn't address your question directly, but just out of curiosity, what are 'print' and 'CLEAR'?
    20. 3dBookman

      The 3D book

      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 intput from a game pad. An anatomy text for a future surgeon, with the a beating heart in 3D animation. A childrens' 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.
    21. Not really - the only way to write/read/copy buffers between host and device are: clEnqueueCopyBuffer - one cl_mem buffer to another cl_mem buffer (e.g. copy on device) clEnqueueReadBuffer - device cl_mem buffer to host memory (e.g. device -> host) clEnqueueWriteBuffer - host memory to cl_mem buffer (e.g. host -> device) clEnqueueCopyImageToBuffer - image object into cl_mem buffer object clEnqueueCopyBufferToImage - cl_mem buffer object to image object clEnqueueCopyImage - image object to image object clEnqueueReadImage - image object to host memory clEnqueueWriteImage - host memory to image object These are the commands that enqueue read/write/copy operations into command queue. Additionally you can: clEnqueueMapBuffer - maps region of cl_mem buffer object to host memory clEnqueueMapImage - ditto for image object clEnqueueUnmapMemObject - unmaps previously mapped object (either cl_mem or image object) Compared to CUDA you will however have to pass in pointers as kernel arguments (their memory can be initialized in advance of course). Kernel arguments don't usually hold too much data (mostly just few variables, and pointers to memory that is going to be used). Out of curiosity (as not many people use OpenCL) - if you can share - what are you trying to do?
    22. Hi @_Flame_, Ok, I will chek it
    23. I'm trying to make a terminal hacking game the same as fallout, but I'm struggling to get the number of characters matching between the user input and the correct password. I've tried searching but so far I haven't found any simple solutions. Please can someone suggest a way? I've also included the full class code below for any tips on improving it void computer::terminal::create_pass() { int lower, upper; switch (diff) { case difficulty::easy: lower = 2; upper = 4; break; case difficulty::medium: lower = 5; upper = 7; break; case difficulty::hard: lower = 8; upper = 12; break; } int a = rand_eng(lower, upper); fill_vec(a); this->fill_addresses(a); this->fill_characters(); int vec_size = passwds.size(); int b = rand_eng(0, vec_size-1); answer = passwds[b]; return; } void computer::terminal::fill_addresses(int amount) { int ran{}; std::string text{}; for (int i = 0; i <= amount; i++) { ran = rand_eng(100, 999); text = "0xF" + std::to_string(ran); bool dupe{ false }; std::vector<std::string>::iterator it = adds.begin(); while (it != adds.end()) { if (*it == text) { dupe = true; break; } ++it; } if (dupe == false) { adds.push_back(text); } else this->fill_addresses(amount); } return; } void computer::terminal::fill_characters() { std::vector<char> temp = { '?', '/', '\\', '-', '_', '[', ']', '$', '%', '&', '*', '"', '<', '#', '>' }; int ran{}; for (int i = 0; i <= 14; i++) { ran = rand_eng(0, 14); chars.push_back(temp[ran]); } return; } void computer::terminal::fill_vec(int amount) { std::vector<std::string> temp{ "biscuit", "jupiter", "mars", "wellington", "statue", "radio", "sponge", "universe", "capture", "penny", "thunder", "hurricane", "knight", "bishop", "queen", "king"}; int r{ 0 }; for (int i = 0; i <= amount; i++) { bool dupe{ false }; r = rand_eng(0, 15); std::string s = temp[r]; auto it = passwds.begin(); while (it != passwds.end()) { if (*it == s) { dupe = true; break; } ++it; } if (dupe == false) { passwds.push_back(s); } } return; } void computer::terminal::login(bool first_login) { CLEAR; std::cout << "ROBCO INDUSTRIES (TM) TERMLINK PROTOCOL\nENTER PASSWORD NOW\n\n" << tries << " ATTEMPT(S) LEFT: "; for (int i = 1; i <= tries; i++) { std::cout << "| "; } std::cout << "\n\n"; std::random_device shuffle_device; for (int i = 0; i != passwds.size(); ++i) { print(adds[i]); std::cout << '\t'; int before = rand_eng(0, 10); int end = rand_eng(0, 10); std::shuffle(chars.begin(), chars.end(), std::mt19937(shuffle_device())); for (int i = 0; i <= before; i++) { std::cout << chars[i]; } print(passwds[i]); if (answer == passwds[i]) print("THIS IS THE ANSWER"); std::shuffle(chars.begin(), chars.end(), std::mt19937(shuffle_device())); for (int i = 0; i <= end; i++) { std::cout << chars[i]; } std::cout << '\n'; } print("\n\nCHARACTERS MATCH: "); std::cout << chars_correct; if (first_login) guess(); else return; } bool computer::terminal::guess_valid(const std::string& guess) { auto validity_check = [&guess](const std::string& pw) { return guess == pw; }; return std::any_of(passwds.begin(), passwds.end(), validity_check); } void computer::terminal::check_valid(std::string& s) { while (!guess_valid(s)) { print("\n\nINVALID PASSWORD"); std::this_thread::sleep_for(std::chrono::seconds(1)); std::cout << "\n\n> "; std::cin.clear(); std::getline(std::cin, s); } } void computer::terminal::guess() { std::cout << "\n\n> "; std::string s{}; std::cin.ignore(); std::getline(std::cin, s); check_valid(s); while (tries > 0) { if (pass_correct(s)) { print("\n\nPASSWORD ACCEPTED"); std::this_thread::sleep_for(std::chrono::seconds(1)); return; } else { print("\n\nWRONG PASSWORD"); std::this_thread::sleep_for(std::chrono::seconds(1)); std::vector<std::string>::iterator it = passwds.begin(); while (it != passwds.end()) { if (*it == s) { passwds.erase(it); break; } ++it; } tries--; std::cout << "\n\n"; login(false); } std::cout << "\n\n> "; std::cin.clear(); std::getline(std::cin, s); check_valid(s); } CLEAR; print("\n\nTERMINAL LOCKED. PLEASE CONTACT YOUR SYSTEM ADMINISTRATOR"); std::this_thread::sleep_for(std::chrono::seconds(3)); }
    24. Clone Wars Emu and Star Wars Redemption are two projects that are also a good illustration to the topic. https://www.youtube.com/channel/UCtILCC-rFo3P0njxke-SCFg https://www.artstation.com/artwork/gO4Pm
    25. The way I see it, the main problem with Unity is that it uses C# and that means you are generally going to take a performance hit whenever you code something significant. That being said, the more stuff you push down into the engine that performance hit becomes less and less. And to be fair a lot games probably don't need to be maxed out for speed. I even look at the stuff I'm coding, and I often think, can it work with Unity or Unreal or will they just get in the way too much? I assume I could get it to work, but I worry I'll be using such a small part of the engine that it will just bloat my project for not much appreciable gain. There's always a trade of make vs buy (or use, in this case) but it's not always clear what the best solution is. There is always this kind of scary scenario where you go down a path using some 3rd party package, and you start to hit roadblocks. At first these may be little work arounds, but sometimes they are more than that. I've seen this happen enough times to give me pause.
    26. Yes. The main setback for a programmer was having to develop tools such as level and sprite editors, which was a distraction from coding the game itself. For the artists they were willing to push-the-boat-out and learn some scripting but not languages such as C++. "Dammit Jim, I'm an artist not a programmer!". That said, project maintenance is what holds many developers to their own engines. You have only yourself to blame and are at least in a position to fix it. With a program like Unity you are relying on it's developers to do their job right and if they haven't then you could find yourself in Admiral Ackbar's shoes... But going forward in games development, these engines+editors will only improve in time.
    27. JensB

      Unity Discord

      Anyone know of a good beginner-intermediate Unity discord? Seems like they are pointing to IRC on the website, and I rather not install mIRC again after not using it for 5+ years
    28. First off, again there is no "standard implementation" only standard behavior. However there are probably some commonality between implementations. You can imagine memory being an unused paper tape. When you allocate something you draw a line on it. From the begging of the tape to the line is what you allocated. Now if you allocate again draw a line after the first one. That chunk is from the first line to the second line and so forth. But now if de-allocate something you might have a space in the middle that's unused. However it's only the size of the piece of memory that you previously allocated there. It's up to the memory manager to figure out what to do with it. It has to save it somehow so if you allocate new piece of memory that is smaller than that space it can give that piece back to you. However let's say all your following allocations are all bigger than that space. In that case it will never be reused and you have a hole. Now it can get even more complex. Let's say you allocate a piece of memory smaller than that space, so it gets reused. But it's slightly smaller, so a sub-piece of memory that's not big enough to be useful for anything is left over at the end. So now you have a sliver of lost memory. So this is where the memory manager comes in. It might think in advance that this situation is sub-optimal and try to give you a different chunk of memory instead. Then there is the situation where you de-allocate two chunks of memory next to each other. The allocator has to be smart enough to merge them into a bigger chunk. There are really a lot of variables. That's why there are a lot of implementations. Years ago I worked on IBM workstations. Someone brought a program to me and said it was crashing on exit or rather it would go into and infinite loop. After debugging it for a while. I found that it got stuck in the memory deallocator. But it did eventually end after 10 minutes. He was allocating millions of tiny objects. On a hunch I simply replaced mallaoc/free with my own routines and boom, it fixed the problem. The standard implementation was simply way sub-optimal for his particular memory usage model. In general for a lot of things I use slab allocators. You can read up on them. But again they aren't good for everything. It all depends on what you are doing. For a lot of gaming stuff, some form of slab allocation probably works pretty well though. They are basically good where you have a lot of objects of similar size, or objects can be categorized in groups of similar sizes. Strings are it's downfall but you can do a different heaps for those. I use a lot "placement new" in C++ to allocate in different heaps. You can read up on that too. Over the years I have built up a big library of different heap libraries. I try to pic the ones that best suit my job. If you are really trying to optimize memory, there is a lot you can do, but you should try to figure out if it's an issue first. For many people the built in routines work well enough.
    29. Game engines like Unity will always have a large market.. I really doubt that Unity or any other engine like it will ever completely displace major custom engines. You just can't optimize these engines as much as a custom built one. Unity/Unreal/etc are great for small and independent developers though. They allow individual creatives, and small teams the chance to make nice things too. The real difference between custom engines and things like Unity is that custom engines DON'T include 90% of the things that make Unity or Unreal nice/easy to use. That equates to MASSIVE performance gains that you really can't get from DIY game engines. Do most games need that? No, but some do.. And some always will.
    30. Allocators either garbage collect and compact the heap (in garbage collecting runtimes), ask the OS for more memory to expand the heap (ex: VirtualAlloc), return null, throw an exception, or produce some other type of error. Successfully allocated memory is ALWAYS contiguous from the perspective of the program (code assumes that data structures are always arranged the same way). However, protected mode virtual memory allows the addresses that the program uses to map to different actual physical RAM (or even hard drives)
    31. Septopus

      Pub/Sub for game Servers... Are you?

      Those are song lyrics man, not reality.. Everything changes except human perception. We're keying in here on a long standing rivalry between Systems guys and Coders I think.. Every coder I've known takes your perspective on this.. And every network/server guy I've known thinks y'all are crazy. It seems as though coders like to behave like the changes in the hardware never really make any difference because their code never really has to change significantly. Just because it doesn't HAVE to change significantly, doesn't mean it couldn't become something better in it's newer environment if it did. You keep snagging on Redis, I don't think I'm using it how you think I'm using it, it I think. I was considering possibilities for it, earlier on, that proved not to be feasible. Documentation is very helpful. It's just my database man, and a WICKED fast one! Aside from that, yes. I'm building the system to fit the game I'm making. The game I'm making will be different. But I think it also has potential to be a platform for more different games. Possibly even done differently. ... No, certainly done differently. You might be pushing me into a Slogan here! hahaha
    32. There can be no resorting to anything, the promise of contiguity shall not be broken - if you demand a block, you're guaranteed to get a block or nothing. Imagine that the pool administred by an allocator is 16B and the granularity is 1B with zero overhead (totally fine for our demonstration). You allocate eight times 2B. All is good. Then you deallocate every other allocation you got. All is good, there's 8B free. Yet, when you now try to allocate 4B, the allocation shall fail and you get nothing. It is THAT simple.
    33. Thanks, I have already figured out that the only way in OpenCL to transfer data from host to device is through function parameters. There is no analog of cudaMemcpyToSymbol in OpenCL.
    34. 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.
    35. In OpenCL you have 4 address spaces (OpenCL 1.1): __private - for every work item __local - for all work items inside work group __global - for all work items inside whole NDRange __constant - for global read-only variables In addition OpenCL 2.0 (pass in -cl-std=CL2.0 into clBuildProgram), which allows for variable in program scope and static variables to be declared in __global address space. They may be initialized with constant expressions only in code.
    36. hplus0603

      Pub/Sub for game Servers... Are you?

      I think you don't have enough experience yet to realize that, the more things change, the more they stay the same. Yes, Redis wasn't available in 2010. But, you know what? Redis can't magically do something that code written in 2010 couldn't. You had to do a little more yourself, but given the primitives available in Erlang, not a lot more. And the solution in Erlang scales horizontally with adding more nodes, whereas Redis does not (Redis Cluster is a joke, technically speaking.) (Yes, you can do application-level sharding for particular use cases.) If you have a specific kind of game that you want to build, with specific use cases and requirements that aren't met by existing technology, you may be on to something! If you're just trying to "build a system," without any kind of strong evolutionary pressure on the features and implementation of that system, then experience (not just mine!) says you won't build something that's all that useful. The reason is that many billions of dollars, and tens of thousands of man years are spent on networked games every year, and the market will already have explored most implementation nooks and crannies for the kinds of games that have already been generally funded and delivered. It doesn't matter if it's games, financial trading, car maintenance or movie production -- if there's already a large market, and you don't really have a very specific use case that's not currently served by the market, then you're quite likely not going to make something successful. Or to put it another way: Do things differently, is not particularly compelling and generally don't build successful projects. Do different things, is where it's possible to truly innovate and push the envelope of what's possible. And sometimes, you need to do things differently to be able to do the different things, but it's the different things that are the reason you win. That being said, building systems is fun and educational. As long as you learn the right lessons, and draw the right conclusions, testing a bunch of things and pushing them until they break is always a good way of gaining more experience. After all, good choices come from experience, and experience comes from bad choices 😄
    37. Lactose

      collision sprite

      Putting exit in code to debug is not something I would recommend. Research breakpoints and debugging.
    38. phil67rpg

      collision sprite

      ok I will work on it
    39. Rutin

      Card Game

      Great work on the card game. I tried all the modes and they work great. I like how you can select deck amounts and even the high card that will display. Awesome job!
    40. Renmazuit

      Composer Available

      Thank you.
    41. Hi I am trying to understand how Cities Skylines did grid alignment based on the curvature of the roads. Here is an image example: Cities Skylines: https://imgur.com/a/0PuykKT Whilst grids are generally easy to understand, having them not aligned to x:y:z is what i am am not sure of how its done. I can't find much resources on it, does any one have any guidance on this?
    42. DabbingTree

      Join my Ludum Dare team!

      I am joining a team for Ludum Dare 43, and I need a designer and an artist. We will use Unity3D for the game engine. https://crowdforge.io/jams/ludumdare/teams/2621
    43. Yesterday
    44. hi. im not sure that im asking it in right place but i think its a technical question. ten years ago making game was a very hard task. there was game studio, flash and.... but they were so limited. now every one is making games with unity. its a first solution on every game maker that has no tool. certainly still there are limitations on unity specially on platform-specific topics but unity is being updated with new tools and asset store is supporting special Utilities free or with low prices. there will be one question. will studios like naughty dog or santa-monica or Dice stick to their in-house engines or there will be time that they turn to such engines(specifically unity) for more simplicity and faster development. certainly study on specific hardware like ps4 or xbox can let you make better results about optimizations and quality but how much it is a priority. there are teams on these studios to always make new tools but can they be as good as and as fast as a company and a community that their job is to make tools?
    45. CyberFlash

      Y'all ever just get wayyyy to distracted time n time again?

      Hmm what DID you have in mind though? I like the idea of making an RPG, I'm just a bit stumped atm
    46. CyberFlash

      Getting back to it

      Nice! TIme to play some cards!!
    47. Gooey

      Y'all ever just get wayyyy to distracted time n time again?

      Nice house this has made me consider maybe making a 2d rpg next rather than whatever I had in my mind.
    48. Gooey

      Getting back to it

      @Rutin@CyberFlash if you take a peek at my newest blog entry the game is avaliable to download for win32
    49. Gooey

      Card Game

      After alot of messing about in windows I have finally sorted out the game for people to play in a .zip compiled for win32 any feedback is welcomed. If anyone is interested in a linux version this will be much easier for me CardGame.zip
    50. KaiserJohan

      Smooth normals and Tessellation

      Any pointers are much appreciated 🙂
    51. This article will introduce you to a range of introductory concepts used in artificial intelligence for games (or ‘Game AI’ for short) so that you can understand what tools are available for approaching your AI problems, how they work together, and how you might start to implement them in the language or engine of your choice. We’re going to assume you have a basic knowledge of video games, and some grasp on mathematical concepts like geometry, trigonometry, etc. Most code examples will be in pseudo-code, so no specific programming language knowledge should be required.
    52. I'm just curious how standard implementations of new and malloc() work. Do they use continuous memory allocation or something else? Because as you sad the memory could end up fragmented and we could arrive at the case where we have enough free memory but not a block (with continuous memory) big enough that we can use another new. In this case we would have to resort to some other implementation that does not use continuous memory and therefore not an O(1).
  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!