• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.


  • Content count

  • Joined

  • Last visited

Community Reputation

10967 Excellent

About rip-off

  • Rank
  1. You are partially correct, many exceptions can be avoided by placing explicit checks instead. In the example you quoted, catching a FileNotFoundException could be considered poor style (abusing exceptions as flow control), an alternative approach would be to check if the file exists explicitly before opening it. However, as Kylotan mentioned, exceptions can still happen - in your example, even if you manually check whether the file exists, there is a "race condition" between the two steps - maybe the file is on a network share and the Wi-Fi suddenly drops! Another source of exceptions can be misunderstanding the code. When the codebase becomes large, and the team working on it grows, it can happen that two pieces of code with differing expectations can interact. For example, maybe one module was written with a strict policy of no "null" references being passed or returned, but another module allows null. If someone who doesn't remember this fact is writing code on the boundary of the two modules, they could pass "null" references into code that isn't prepared to handle it. This can happen even as a solo developer, with enough time passing the code you wrote a year or more ago will feel like it was written by someone else! Given that exceptions can occur despite your best intentions, it is very common in Java programs to have a high level try ... catch statement to handle all unexpected exceptions that were thrown, and try to show some kind of error report to the user. Even if you're quite thorough in trying to avoid exceptions, once you release software into the wild world someone will eventually break your program, so having a way to capture the error so that the user can submit a useful bug report to you can be quite useful. A related issue is throwing your own exceptions. Obviously, you have limited choice when it comes to exceptions that the language, standard library or crucial third party libraries might throw at you. It can be a quick way to "bail out" of an operation, but overuse of exceptions can make the program difficult to reason about and can contribute to requiring catch blocks to handle them. Whether to use exceptions over return values is somewhat of a philosophical question. I would say that try ... catch is a useful construct, but one that you should try to use sparingly. If you find yourself using it often, consider whether there is some other way to avoid the error in the first place. Note that try ... finally is a different construct, you should not worry about using that where necessary. My advice would be to avoid throwing exceptions, but don't be afraid to do so when the alternative would be worse. They are particularly suitable for handling programmer error, where something is wrong with the internals of the program, for example a critical array is empty but it should never be. An example of this kind of usage is the "assert" keyword, which can result in an AssertionError being thrown. Trying to handle all unexpected situations with return codes can lead to lots of complexity, because "unexpected" errors can happen in lots of places and you would need to propagate this error to every caller.
  2. Again, watching a video is a different experience from actually playing the game, but looks like a big improvement to me - well done! Just the movement alone looks way better, it gives the entire thing a different feel I think. Is the game playing a bit more like what you were looking for now? A potentially simple thing to look into is toning down or changing the particle effect when somebody is hit - it looks a bit like an explosion at the moment. I'm not an animator, but the sword attack animations look like they could use some attention. That said, I would also say that the player's kick attack looks more dangerous - where it looked a bit too weak before. Have you playtested the game with anyone? Would it be hard to package up a demo? Soliciting feedback about videos, while better than nothing, will tend to result in a focus overly on the visual impact and will not give you as much insight into the interactions. As an example, imagine if people could have given feedback on Tetris during development. The game is aesthetically simple and arguably even boring to watch, but actually playing it is a different experience altogether! But the feedback Alexey Pajitnov might have gotten would not have been about gameplay (e.g. the ability to commit a shapes position and drop it immediately), but rather would naturally be on the more superficial elements. Finally, remember we lack a lot of context about the game. I don't know if this is the only mode, or if there might be others. I don't know what kind of enemies you're thinking of having, nor what kind of levels and level elements. Will there be multiplayer? I don't even know whether it is a purely action game, or if there might be other aspects (e.g. stealth mechanics). Fleshing out your vision might help us understand what you're aiming for and whether that is coming through to us.
  3. You can change the feel of of a game without altering the fundamental mechanics by polishing how the game responds to your actions. I found this video very good: As for your game, hard to say without playing it or seeing more. The player in question isn't doing very well, which makes the game look less fun than it might actually be, if they were slicing up opponents without taking a hit I'd say the opposite...
  4. Can you explain what you're trying to achieve? Is this something that you might be able to pre-process during a build, or is it something you want to be able to dynamically detect at runtime?
  5. Excellent observation, that is indeed the sequence of IDs that you might expect, that you see a deviation is significant. 3452816845 is an interesting number, not by itself but rather because many of your variables seem to have this value. Googling it gives me https://stackoverflow.com/questions/18673913/why-variables-are-initialized-with-max-value-instead-of-zero, which reveals that the value has a special meaning: (I knew about this already, but this shows how you might investigate yourself).   So what is happening? This example program might illustrate: #include <iostream> #include <vector>   struct Foo {     Foo() {     std::cout << "Constructor for " << this << std::endl;   }     ~Foo() {     std::cout << "Destructor for " << this << std::endl;   }     Foo(const Foo &other) {     std::cout << "Copying " << &other << " into " << this << std::endl;   }     Foo &operator=(const Foo &other) {     std::cout << "Assigning " << &other << " to " << this << std::endl;     return *this;   }   };   int main() {   std::vector<Foo> v;   std::cout << "Before insertion" << std::endl;   v.push_back(Foo());   std::cout << "End of main" << std::endl; } If you run this, you'll see something like: Note that a Foo object was created, copied and destroyed during the "push_back". This is the lifecycle of the temporary Foo() instance. The copy lives on in the vector, and is destroyed after the last line of main(). It looks like your Particle class is more complex than it seems at first, it has complex inner types. The question is really whether these complex inner types can be copied and / or assigned. Remember the [url="https://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)"]rule of three[/url], which is that any class that has a destructor should probably have a copy constructor and assignment operator (leaving aside move for the moment), or be "non-copyable", which can be done (in modern C++) by deleting the problematic functions (to prevent them being automatically generated), or simulated in older C++ by declaring the functions private and leaving them unimplemented. Generally you do not want to implement copying semantics for external resources, such as textures that reside on the graphics card. Not only is it tricky, but also it is likely to have performance issues. You don't generally want to have lots of distinct copies of the same texture on the GPU, that is just wasting memory and wasting time switching between textures. I'd recommend changing your Texture, Vbo and Ebo classes to be non-copyable. Once you do this, code that attempts to insert Particles into the container should stop compiling. I was never much of a graphics programmer, and it has been a long while since I've dabbled, but my guess would be to think about managing the textures and related objects at a higher level than the particles, for example the emitter could manage these resources. Particles should be as lightweight as possible, managing GPU resources is the opposite of this.
  6. Indeed, most programmers would write "i < N" for loops that should run N times, rather than i <= N - 1. It would be a good idea to do this consistently from now on, to prevent such bugs. Now, it sounds like you've discovered something very interesting from a debugging perspective, which is you have two versions of the program, one of which behaves as expected and another which does not. As Lactose says, you can start running the two versions and comparing the various variables involved. Keep the number of particles small and it might be easier to debug.
  7. Progress, excellent! So, take another look at the code: void Emitter::Draw(Shader &shader) {     for (int i = 0; i < particles.size() - 1; i++)     {         particles[i].Draw(shader);     } }   void Emitter::Update(GLfloat dt) {     for (int i = 0; i <= particles.size() - 1; i++)     {         particles[i].Update(dt);     } }   void Emitter::SetParticlesAttributes() {     for (int i = 0; i <= particles.size() - 1; i++)     {         particles[i].setLife(10.0f); //(((rand() % 10) + 1) * 15);         particles[i].setVelocity(glm::vec3(0.0f, 2.0f, 0.0f)); //(((rand() % 10) + 1) * 2));     } }   Can you spot any reason why Draw might not draw the last element? In particular, can you see any differences between the Draw() function and the others?
  8. So that is a good start! There is more narrowing down to do. Here are some examples: * Have you tried an emitter with just one particle? * Have you tried two particles without the emitter? * Have you tried making the particles stationary?
  9. Tell us what you have tried. I see you have a few other similar topics, the pattern is that you get blocked and post your full program here, looking for someone else to spot the problem. This approach is inefficient. You need to wait for someone to spot your error, which is a waste of your time. Also you have different people reading large amounts of code every time, as you cannot narrow down the source of the issue. A better approach would be to invest some time into learning how to debug these situations for yourself. For example, in a recent thread you were strongly advised to add more error checking code. Start there, before you do anything else. Part of this is learning to use your tools, such as a debugger. As a beginner, I remember finding the debugger rather intimidating so I learned to use "printf debugging", which is basically inserting print statements at different points to allow you to understand how your program is running and what values different variables might have at the time. While it is worth your time investing in a proper debugger, even using printf debugging you'll be able to find and fix many bugs. There are techniques to speed up debugging, for example disabling portions of your program so you can focus on a smaller part and checking that for correctness. For example, start by checking that a single static particle will draw as expected, before enabling multiple particles and movement.
  10. Hard to be certain without context. This appears to be for deserialization? I think it has a happy path that could work as expected. For example: int main() {    int x = 42;    char buffer[sizeof(x)];    memcpy(buffer, &x, sizeof(int));      int index = 0;    int result = read_int_from_stream(sizeof(int), index, buffer);    printf("Result: %d\n", result); } That said, there are a few things you could change about the code. A likely issue is if the caller passes a value of "count" that is not equal to "sizeof(int)". If "count" is bigger, then you have undefined behaviour (likely manifesting as overwriting adjacent memory to "dst"). If "count" is smaller, then you have undefined behaviour as some part of "dst" remains uninitialised, likely manifesting as unexpected return values. It would be simpler to remove the parameter and use sizeof(int) rather than accept a parameter that could be potentially incorrect. Other possible issues include: [list]  [*] Caller passes a negative "count" [*] Caller passes an invalid "src" buffer pointer (e.g. uninitialised, null) [*] Buffer pointer is valid but points to uninitialised data [*] Buffer data was never generated from the bit pattern of an int [*] Buffer data comes from another system with different endianess or sizeof(int) [*] "index" is or becomes out of range with respect to the buffer length [/list] Also, it would be nice if "src" were const.
  11. Bregma has a good approach, albeit one that might be a little advanced for "For Beginners", without additional explanation.   Are there any additional pointers to the Sprites, apart from those held in the vector? Is SpriteGroup::remove(...) being called (directly or indirectly) from the Spite / Enemy instance itself? Are you (directly or indirectly) calling SpriteGroup::remove(...) while you are iterating over the same vector?
  12. Also when you detect an error (e.g. window == null), try printing SDL_GetError() to the console before quitting. If you get an error with SDL_TTF, use TTF_GetError(). If you "return false" from main(), technically you are reporting your program ran successfully. Main returns an "Int", not a boolean (although a boolean will convert to an Int). So when an error occurs, use " return 1" instead, or you can use EXIT_FAILURE (http://en.cppreference.com/w/cpp/utility/program/EXIT_status).
  13. I think both sides are arguing from a position of good faith. It is a matter of worldview and which definition of the words you subscribe to. Indeed, I feel I've sat on different sides of that fence at different times in my career. IMO, assertions are a special case of error handling. I like the idea in Joe Duffy's blog, between unexpected program states and legitimate external conditions in a hostile world. Personally, I think this is a useful distinction to make and it is worthwhile considering having different strategies for these situations. The economic impracticality of eradicating the former case before software is released is one factor, balanced against the difficulty specifying behaviour for what should happen for such cases. The essence of these worldviews is a fault line running through the industry, contrast C with its undefined behaviour vs Java which tries to give consistent and safe behaviour, e.g. for out of bounds array accesses. Interesting as some of the discussion has been, I'd like to bring the discussion back to Angelic Ice's question now, which is "what would you do"? In particular, for these " hostile world " cases - modulo cosmic rays flipping bits I suppose.
  14. The overall program is probably short? If so - why not post it all? Sometimes compilers don't mark the logical point in the source code where a human would agree the error is - for various reasons (implementing a compiler is a fascinating project) some types of mistakes make the compiler see the code very differently than a human would. You should post the exact error messages you are seeing, including line numbers.
  15. I'm not familiar with Android development, but typically processes on the same machine can talk to one another on the loopback address. If I were you, I'd think about just writing some non-Android based networking applications to experiment and get familiar with the topic, adding Android and Emulators into the mix is only going to make things a little harder. Writing small console applications is a great way to learn, trying to do your learning by building your desired functionality in an already complex application is a recipe for lots of unrelated issues to slow you down. Well blocking I/O still has a place for simple use cases. For example, if you want to make a quick web request as part of a larger program, then a non-blocking solution would actually be quite complicated - particularly if you want to use the result immediately. Just throwing a quick timeout on a blocking request can be acceptable. The audience of examples on the Internet is people new to the subject of networking. Better to start with the basics, sockets, ports, hostnames, etc in the simpler environment of blocking I/O. Examples typically try to get to the core of what is being taught, and actually try to avoid being too large as it can distract from the subject at hand. One suspects that sometimes the people who write these examples are often just graduated from being beginners themselves.