Jump to content
  • Advertisement

SYJourney

Member
  • Content Count

    20
  • Joined

  • Last visited

Community Reputation

230 Neutral

About SYJourney

  • Rank
    Member
  1. Thanks for all the replies again. I will look into replacing my using doubles with direct calculations or storing integers. As for what _SKYe said above,  I tried to play around with using different speeds and in fact there are some which look somewhat better.
  2.   I'm sorry but I just don't see it, I've read the article multiple times and I also read the other article it is linking too. I must say your post is a bit cryptic too, do you already see what is wrong with my implementation and are saying it is one of the things explained in the article?
  3.   I'm not sure how to check this. But shouldn't this also make the jitter happen when just always updating once before rendering like I tested (this makes it smooth).     Do you mean basing the position on time only? I tried the following (this still jitters): // in draw() double x_inter = 800.0 - static_cast<double>( (std::chrono::high_resolution_clock::now().time_since_epoch().count() / 16000000) % 800 ); Interesting is that when using this it also jitters when always updating once, whereas in the previous case it would atleast not jitter then. I also tried the above without using doubles, and using GLshort instead for my coordinates.   One other thing I forgot to mention is that it doesn't matter wether I have vsync on or off.
  4. I've been using the fixed-timestep loop (as described in "Fix your timestep") for a while now but hadn't actually noticed that the movements in my game are not smooth. It's a bit harder to notice when things are accelerating, deaccelerating, stopping etc. but it does become very apparent if there's something that moves at constant speed across the screen. I've now been trying to fix this problem for days but I have no clue where to look next or how to find a solution. I'm actually convinced that what I'm doing must be conceptually wrong instead of it being a bug that I can spot myself in my code. So I'm turning to the forums for help. I'll first try to describe what I'm doing and then post some code.   So here's what I'm doing: I measure time between game loops right before I would call update and add this value to an accumulator. Then while the accumulator is greater equals the timestep, I update while decreasing the accumulator. I then divide the now remaining value by the timestep to obtain the alpha. The alpha is then passed to the rendering where it's used for linear interpolation. After I have obtained the interpolated position, the coordinates of an object are used to create a quad which stores them as GLdouble. All the quads are put into a buffer with glBufferData and then at the end of the rendering step I call glfwSwapBuffers.   Here's the code, I changed a lot of things to obtain a minimal example but this is what I am running and it's not working:   Loop: int64_t timestep = 1000000 / 60; int64_t accumulator = 0; using clock = std::chrono::high_resolution_clock; using unit = std::chrono::microseconds; clock::time_point now = clock::now(); while (running) { clock::time_point before = now; now = clock::now(); unit duration = std::chrono::duration_cast<unit>(now - before); int64_t elapsed = duration.count(); accumulator += elapsed; for(; accumulator >= timestep; accumulator -= timestep) { update(); } double alpha = static_cast<double>(accumulator) / timestep; draw(alpha); } In this example I'm trying to move a rectangle across the screen. Update: x_before = x_now; x_now = x_now < 0.0 ? 800.0 : x_now - 1.0; Draw: double x_inter = (1.0 - alpha) * x_before + alpha * x_now; // draw_rectangle(double x, double y, width, height...) graphics.draw_rectangle(x_inter, 0.0, 100, 100, Color::White); // Buffers data graphics.buffer_data(); // calls glfwSwapBuffers window.render(); Methods of Graphics component: void Graphics::draw_rectangle(double x, double y, int16_t w, int16_t h, const Color& colour) { // this creates a quad and puts it into a vector of quads. // the other parameters just mean that it will be an empty rectangle filled with a colour quads.emplace_back(x, x + w, y, y + h, Atlas::NULLOFFSET, colour, 0.0); } // Here's Quad and it's constructor class Graphics::Quad { public: static const size_t NUM_VERTICES = 6; struct Vertex { GLdouble x; GLdouble y; GLdouble s; GLdouble t; Color c; }; Quad(GLdouble l, GLdouble r, GLdouble t, GLdouble b, const Offset& o, const Color& colour, GLdouble rot); private: Vertex vertices[NUM_VERTICES]; }; // Constructor of quad { vertices[0] = { l, b, o.l, o.b, colour }; vertices[1] = { l, t, o.l, o.t, colour }; vertices[2] = { r, b, o.r, o.b, colour }; vertices[3] = { r, b, o.r, o.b, colour }; vertices[4] = { r, t, o.r, o.t, colour }; vertices[5] = { l, t, o.l, o.t, colour }; } // Putting quads into the buffer void Graphics::buffer_data() { glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); GLsizei csize = static_cast<GLsizei>(quads.size() * sizeof(Quad)); GLsizei fsize = static_cast<GLsizei>(quads.size() * Quad::NUM_VERTICES); glEnableVertexAttribArray(attribute_coord); glEnableVertexAttribArray(attribute_color); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, csize, quads.data(), GL_STREAM_DRAW); glDrawArrays(GL_TRIANGLES, 0, fsize); glDisableVertexAttribArray(attribute_coord); glDisableVertexAttribArray(attribute_color); glBindBuffer(GL_ARRAY_BUFFER, 0); } // Here's how I create the atlas, etc. { glBindTexture(GL_TEXTURE_2D, texture); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Atlas::WIDTH, Atlas::HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glVertexAttribPointer(attribute_coord, 4, GL_DOUBLE, GL_FALSE, sizeof(Quad::Vertex), 0); glVertexAttribPointer(attribute_color, 4, GL_DOUBLE, GL_FALSE, sizeof(Quad::Vertex), (const void*)32); } I feel like I've tried pretty much everything I could to fix it. If I do not use the fixed-timestep loop at all, but simply update once before doing a draw, the movement look's fine. I can only imagine that this is because I'm my rectangle now always moves exactly one pixel between each draw. But this of course doesn't work for me because then my simulation is no longer synchronized to the real time, which I want to be the case.   To describe the jittery movement some more: It seems to randomly skip ahead, as in, it sometimes moves one pixel and sometimes two. I have also used the console to print this to the screen. But as far as I understand the idea of the fixed-timestep loop, this shouldn't be a problem right? The whole idea is that we sometimes update once, sometimes twice or not at all and it still works.   All help and advice is appreciated, I've been working on this for a while now but I definitely see myself as a beginner still and I just can't figure this one out myself.
  5. SYJourney

    When you realize how dumb a bug is...

    There is this one bug which has been bothering me for months, every now and then I will try to fix it but ultimately fail. On the top of my UI, I added a scrolling text message. However the movement looks really jittery and bad to me. The code for it is trivial: The component which controls the movement is the same as all other movements, which do look smooth. So I actually would have a smoothly scrolling background, with the jittery text above it mocking me.   Just now I was playing some game when I noticed a kind of scrolling text in it very similiar to the one I want to have. But guess what: It also seems to have the same jitter to me. Now I'm completely lost on what to think. Does that game somehow have the same bug as mine? It can't be the graphics library: From the files I can tell that that game uses DirectX whereas I use OpenGL. Are my eyes actually just unable to properly follow moving text on a screen? I guess the only way to find out would be to find yet a third game which has this kind of scrolling text...
  6. I don't think it's related to the code you posted, instead you should check the type of "m_components" and "Arrivals" again. Maybe your Base is not polymorphic? You could fix that by atleast adding a virtual destructor.
  7. Thanks for the replies.   I usually end up using those ranged-for loops, but I'd prefer to use the for_each if it wasn't so much to type. In Java I use it all the time because you can do exactly the thing I gave as an example: HashMap<Integer, Foo> myFoos = new HashMap<>(); myFoos.values().forEach(Foo::bar); // not 100% sure about syntax but something like this About the data structures, alot of times I will need data which I can access by some name or id, but where I really only care about the value when looping over it.
  8. Sorry if this question has been asked before, the search didn't turn up anything. I'm wondering about the pros/cons of adding alternatives to the std::algorithm library to my codebase. I've done this in a couple of beginner projects, but I always felt like it's probably a bad practice to do so. Now I'm at the point again where I feel that I could write my code alot more clearly just by adding a few methods. For example, consider the following: struct Foo { void bar(); }; // I want to call bar on all foos. std::map<int, Foo> my_foos; // using for_each from std::algorithm std::for_each(my_foos.begin(), my_foos.end(), [](auto& iter){ iter.second.bar(); }; // but consider how much nicer it could be for_each_value(my_foos, &Foo::bar); In the above example, I have an alternative that: - applies a function to the values only - takes the name of the collection instead of having to write both iterators - can use a member function instead of a lamba as we are iterating over the values only   So overall, is it okay to do this?
  9. SYJourney

    Learning from Other's Code

    Is your goal to just learn or also to end up with something usable? You mention that you want to create a small turn based rpg, but you also talk about writing a game engine. I'm actually working on a simple rpg too and I think an important part of the process is to decide what you are making. So are you writing a game or an engine? To ask bluntly, what is so special about this rpg that you need to use code written for professional game engines? Arguably the code from those engines might not actually be suited for a small game. In fact your own simple solutions might be a much better fit, they will be easier to understand and maintain. Take graphics for example: Do you really need the most efficient rendering pipeline? Unless the term "small rpg" means something different to you than me, I'm pretty sure you don't need that stuff. If you still want to figure out an optimal solution, I would say do that after you have written your own, the learning effect will be much better that way.
  10. Thanks for the advice. After reviewing all of it, here's a rough sketch of what I'm using now: Item effects such as in the OP and similiar sequences of events will be scripted. For the scripts I use my own syntax which translates to how I handle messages in game. The way I will create the scripts is by using a GUI where you can drag and drop more abstract tasks into a structure, edit their properties etc.   In the c++ code I have an interface 'ITask' which declares an 'update' and an 'is_done' method. Every component in my game that receives these tasks has a container which calls update on all it's tasks and removes them once they are done. This way I can treat all actions as happening over a certain period of time. Actions which occur once just always return true for 'is_done'. Then I also have some special implementations of 'ITask' which are composed of other tasks. For example 'TaskSequence' which is a queue of tasks, updates it's front task and is done when the queue is empty. Or 'TaskBranch' which evaluates an 'ICondition' once and then delegates to it's sub-'ITask' mapped to the result. So essentially the core of my design is that all of these are 'ITask's, so I can combine asynchronous/synchronous processing, branching logic (and whatever else I can come up with) arbitrarily.
  11. There is this kind of design problem that I seem to encounter with every game I try to make. Basically, I will try to take into account some feature that just doesn't seem to fit into how I coded so far. Most often it's an item or special ability that a player can use.   For example, I want different items which can do the following: - Transport the player to a different level - Increase some stat of the player - A key which opens a door if you are standing in front of it - Change the player's sprite   The question is where in my code do I put all this stuff? The kind of design I'd actually want is something like this: class ItemEffect { public: virtual void use() const = 0; } class WarpItemEffect : public ItemEffect { WarpItemEffect(int target_level_id); void use() const override; } class KeyItemEffect : public ItemEffect { KeyItemEffect(KeyType key_type); void use() const override; } So suppose I have some "Item" class. When I create a new instance of the class I will then simply plug in the subclass of ItemEffect I need. To me as an amateur this seems pretty good so far. But there's an obvious problem. If we take the key example, I most likely will need the "Player", to know which direction he is facing, then I need the "Level", to check if there is a door in front of him, and then I need to open the "Door". All these are things which I cannot just code within my "use" method. If I tried implementing it I'd most likely end up with something like this: void KeyItemEffect::use(const IPlayer& player, ILevel& level) { Direction direction = player.getDirection(); Position position = player.getPosition(); IDoor* door = level.findDoor(position, direction); if (door) door->unlock(key_type); } So what's happened is that half of the code which actually does something is now in the other classes. I guess that for Level::findDoor(), I can probably find other uses but the main problem is: If I continue this, I will end up with more and more methods in "Level" (or other classes) which just execute services specific to ItemEffects. So how can I design this so that it makes sense?
  12. SYJourney

    When you realize how dumb a bug is...

    Not exactly a game related bug but still: Had a c++ exam last semester, overall pretty simple stuff with making some class hierarchies, doing math with console input etc. In our college we do programming exams by coding solutions on a linux computer for some tasks we are given. This exam was after the summer break, so about a month after the last lecture. During the break I had started coding some projects in c++, all on Windows in Visual Studio and much more advanced than the exam topics. So it didn't feel that I needed to practice the stuff from the lecture.   Guess how stressed I got when I couldn't get my code to compile in the exam. I just absolutely could not figure out why it would not compile, it kept complaining about my includes like <iostream> and some basic functions. I spend most of the exam trying to solve this, but eventually realized I had no other choice than to submit all my solutions 'blindly'.   After coming home and trying to recreate my solutions on my own computer, it suddenly hit me: I had tried to compile my c++ files with the -gcc unix command during the whole 2 hour exam. That one month since I last used gcc and linux was enough to forget that it should've been -g++. I ended up passing with a good grade out of sheer luck, but I didn't make the same mistake of not practicing under exam conditions again since then.
  13.   My reason for wanting to multithread is that blocking the main thread for serialization, encryption and passing the message to the socket seems a bit awkward/clumsy. I feel like it should return as soon as the (high level) data needed for the message has been obtained. For example: If I click on an npc, which causes a message with the npc's identifier to be sent, I feel like it should return after finding out the identifier. But currently, it will serialize the identifier from an int to 4 bytes, then encrypt those bytes, then add a header, then pass the header and body to the socket before returning. Of course this is only my feeling as someone who is relatively new to programming.   I checked with the diagnosis tool from my IDE (Visual Studio) and the cpu cost of sending packets is very low. It's surprising to me because alot of messages are sent per second, and each has to be encrypted with two different algorithms. So I am assuming that even If I were to do it better, the performance gain will be neglegible. But If I do end up having a measurable performance gain, I will report it back here for future reference.
  14.   It's an old game of which the server already exists. There is open source code for the server which I could edit, but I want to focus on just the client. I am doing this so that I can focus on just learning c++, and don't have to make choices related to game design. The point about costs of creation makes sense, what about creating one thread at startup which I pass all arguments for my messages to?
  15. Hello gamedev.net, I am developing a client for an MMORPG in c++. So far I have not used any multithreading in my networking components. I simply receive messages on the same thread that updates my world state and I am also sending messages on this same thread. I've been wondering wether I should be serializing my messages on a seperate thread, or even have one thread for every message? I should note that I don't have concrete performance problems, it's more a question of what a better practice is. I have read through the FAQ and used the search function, but found nothing that matches the specifics of my case.   I only have control of the client, I cannot change specifics of the server. The server uses TCP. Each message to the server has to be encrypted, and the key for encryption changes with every message. So If I were to send each packet on it's own thread, I would still need atomicity for that. For the most part, all the messages are fairly simple, they only require somewhere from 1-20 calls to serialization methods to construct, but they are frequent and there are hundreds of different message types. There are also some messages that need to read data from stl containers. Currently I can just pass these as references but I'm assuming that I would need copying if serialization happens on a different thread.   Any help is appreciated, it's a private project done for learning and I'm still a beginner with game making.
  • Advertisement
×

Important Information

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

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

Sign me up!