Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Mutoh

Pages: [1]
1
General / Client-host networking strategy
« on: March 23, 2015, 05:03:18 pm »
In the process of making a platformer with plans for a local multiplayer I have begun considering giving it an online multiplayer as well. I have done some research on networking an I want some input on my strategy.

Overall idea:
(click to show/hide)

---

Clients would only send input to the host, perhaps with intervals of once every [physics' step duration] seconds, but how the host should organize its received input packets is a more blurry area for me.

Should I use TCP when clients are sending inputs to the host, so that no inputs are received out of order by the host? I plan on having the host not wait for inputs from its clients, and keep gathering the inputs it receives into a queue. The queue would be depleted as it advances its physics' steps. The following pseudo-code should exemplify the procedure:
(click to show/hide)

I am worried about possible too bothersome delays between the clients and response time. After all, it takes on average 100-200ms for a client to receive response from the packet it just sent. I am willing to limit the online gameplay only to LAN connections if the only solutions are complicated predictions - a client-host architecture is still effective against preventing the lockstep asynching problem of peer-to-peer and even allows late-join.

---

I apologize for writing so much, but I want some critiques, suggestions and overall guiding from developers here with more experience with networking in games and SFML, as it hasn't been long since I started studying networks and I have done pretty much no experiments. Developing of the game has only started and this is the best time to decide on such critical points.

2
So far, it has happened to all Windows XP (and Windows 7 Starter) users to whom I have shared releases of my game: the .png files are opened, but SFML either isn't able to load it, or it is technically loaded (in that SFML doesn't complain of errors) but the Texture is left a blank.

Unfortunately, I haven't been able to trace the error further from "SFML is acting weird" because I don't have Windows XP myself, I use Windows 8. Running the .exe with Compatibility Mode here works just as fine for me as without, so I cannot even "pretend" that I have Windows XP. I compile my game with gcc 4.7 on CodeBlocks and from there I just share the .exe and data files with whomever it is needed through .rars.

I at first suspected that it's a problem of incompatibility between OS's, but there are times in which the Textures work as expected in their computers. I wish I could provide more information, but as I said, I don't have exactly the environment for debugging this. :-\ I just want to know, for now, if there have been developers with similar problems here. But maybe, later, I can provide excerpts of code demonstrating the problem. It's just that I can't just press F9 and check it it simulates the conditions, I have to send the program to a friend to truly check it!

And before anyone mentions that Windows XP has been discontinued... I'm afraid that these issues might manifest themselves when porting my games to other platforms, even if I put Windows XP aside.

3
Graphics / Screen starts flickering when on fullscreen
« on: March 06, 2014, 04:11:24 am »
This is hard to explain. Whenever my game goes fullscreen, whatever is being drawn by the main RenderWindow gets erased patches over it, in a pattern. The following drawing illustrates what would happen if my window was drawing a sprite with a black background and a red smile, if the window had a 64 bits per pixel depth VideoMode (so that the sprite could be centered in such a way) and was calling clear(sf::Color::White).



The patterns go up and down through the sprite, but in a low framerate, it appears to be rather appearing in random spots through it.

These patterns only show up when I call clear() for the RenderWindow every tick. If I don't, no patterns show up, but the game still runs "choppy". I suspect that my window is skipping one every two frames.

Everything runs perfectly when windowed.

I can show some code if the community would like, but I would rather first have some insight of what could be the possibilities. It's somewhat messy code. Can a missing .clear() call have such an effect? .display()? As in, does this have any relation to double-buffering? Has anyone even seen this before?

---

edit:

Apparently, this was the excerpt of code that was making everything go haywire:

{

                        static const float separation = 3.5f;
                        static const unsigned char white = 160;

                        sf::Text continueText("Continuar", lib::defaultFont(), lib::defaultFontSize());
                       
                        // continueText.setColor(sf::Color::White);
                        // auto continueLocal = continueText.getLocalBounds(); /*1*/
                        // auto continueBounds = continueText.getGlobalBounds(); /*1*/ /*2*/
                        // continueText.setPosition(
                                // windowWidth / 2 - continueBounds.width / 2.f - continueLocal.left,
                                // windowHeight / 2 - continueBounds.height - continueLocal.top - separation);
                               
                        sf::Text quitText("Sair", lib::defaultFont(), lib::defaultFontSize());

                        // quitText.setColor(sf::Color(white, white, white));
                        // auto quitLocal = quitText.getLocalBounds(); /*3*/
                        // auto quitBounds = quitText.getGlobalBounds(); /*3*/ /*2*/
                        // quitText.setPosition(
                                // windowWidth / 2 - quitBounds.width / 2.f - quitLocal.left,
                                // continueText.getPosition().y + continueLocal.height + separation);

                        sf::Text disclaimerText(L"O jogo está pausado", lib::defaultFont(), lib::defaultFontSize());
                        disclaimerText.move(5, 0);
                       
                        m_pauseTex.create(windowWidth, windowHeight);
                        m_pauseTex.setSmooth(true);
                       
                        m_pauseTex.clear(::pausedBlack);
                       
                        // m_pauseTex.draw(disclaimerText);
                        // m_pauseTex.draw(continueText);
                        // m_pauseTex.draw(quitText);
                       
                        m_pauseTex.display();

                        m_pauseScreen.setTexture(m_pauseTex.getTexture());
                       
                        } // This block (and subsequent deaths of the Texts) isn't actually necessary, as the bug shows up even if the following 'while' is right below the m_pauseScreen.setTexture above.

Variables with the m_ prefix are indeed member variables. m_pauseTex is an sf::RenderTexture and m_pauseScreen is an sf::Sprite.

lib::defaultFont() returns a const sf::Font& reference to a font stored in static resources. lib::defaultFontSize() returns a simple int.

This m_pauseScreen is drawn every tick by something as simple as:

while (m_window.isOpen()) {
    sf::Event event;
        while (m_window.pollEvent(event));
       
        m_window.clear();
        m_window.draw(m_pauseScreen);
        m_window.display();
}

The error shows up whenever I uncomment any of the line combinations with the numbers. For example, if I uncomment only the two lines with that /*1*/, the error would show up. If I uncommented only the two lines with the /*2*/ in the end, the error would show up as well. Same for /*3*/

In the end, it's all because of calls to sf::Text::getLocalBounds() and getGlobalBounds(). I haven't yet nailed what exactly causes the problem, and I don't think I'd even be able to. I knew sf::Text had specially buggy boundary management, but I didn't know it was extreme enough that it could interfere with completely unrelated instances; even commenting the m_renderTex.draw calls doesn't prevent the bug.

Can anyone reproduce the situation with only what I've provided? The window is created with .create(sf::VideoMode(640, 480, 64), "", sf::Style::Fullscreen);

4
System / Problems with making my own InputStream
« on: November 17, 2013, 04:11:11 am »
Apparently, searching the forum and the internet for help regarding derivations of sf::InputStream was fruitless, so hello! I've just registered, to ask some help for making my own stream class. :)

I tried following the tutorial here: http://www.sfml-dev.org/tutorials/2.0/system-stream.php

My class is basically a copy and paste of it, and I want to simply be able to read and decrypt my own encrypted files. As of now, though, it does nothing in special, I have left the encrypting methods empty for testing. Problem is: I haven't been able to load anything with it. Every time I try to call a loadFromStream from a sf::Font or sf::Texture, be it for a .jpg or a .png on the latter, the application crashes. What could be it? Is there already a working sf::InputStream derivation out there?

Here are my codes, you can even try to to compile them by yourself. No custom libraries and all. I wonder if it's a problem of my machine?

#pragma once

// "EncryptedStream.h"
// ---

#include <string>
#include <cstdio>
#include <stdexcept>

#include <SFML/System/InputStream.hpp>

namespace ds {

        class FileCouldntOpen : public std::runtime_error {
                public:
                        FileCouldntOpen(const std::string& filePath);

                        const std::string& filePath() const;

                private:
                        std::string m_filePath;
        };

        // ---

        void encryptFile (const std::string& inputPath, const std::string& outputPath);

        class EncryptedStream : public sf::InputStream {
                public:
                        EncryptedStream();
                        EncryptedStream(const EncryptedStream&) =delete;
                        EncryptedStream(const std::string& filePath);

                        ~EncryptedStream();

                        void open (const std::string& filePath);
                        void close();

                        sf::Int64 read (void*, sf::Int64);
                        sf::Int64 seek (sf::Int64 position);
                        sf::Int64 tell();
                        sf::Int64 getSize();

                private:
                        void decrypt (char*, int);

                        std::FILE* m_file;
        };

}
 

#include <do/EncryptedStream.h>

// "EncryptedStream.cpp"
// ---

namespace ds {

        FileCouldntOpen::FileCouldntOpen(const std::string& filePath)
                : m_filePath(filePath),
                  std::runtime_error("Couldn't open " + filePath)
        {       }

        const std::string& FileCouldntOpen::filePath() const {
                return m_filePath;
        }

        // ---

        EncryptedStream::EncryptedStream()
                : m_file(nullptr)
        {       }

        EncryptedStream::EncryptedStream
                (const std::string& filePath)
        {
                open(filePath);
        }

        void EncryptedStream::open (const std::string& filePath) {
                if (m_file)
                        std::fclose(m_file);

                m_file = std::fopen(filePath.c_str(), "rb");

                if (!m_file)
                        throw FileCouldntOpen(filePath);
        }

        void EncryptedStream::close() {
                if (m_file)
                        std::fclose(m_file);
        }

        void encrypt (const std::string& inputPath, const std::string& outputPath) {
                // ...
        }

        void EncryptedStream::decrypt (char* data, int size) {
                // ...
        }

        // ---

        sf::Int64 EncryptedStream::read (void* data, sf::Int64 size) {
                if (m_file) {
                        sf::Int64 result = std::fread(data, 1, static_cast<std::size_t>(size), m_file);
                        decrypt(static_cast<char*>(data), size);

                        return result;
                }
                else {
                        return -1;
                }
        }

        sf::Int64 EncryptedStream::seek (sf::Int64 position) {
                if (m_file) {
                        std::fseek(m_file, static_cast<std::size_t>(position), SEEK_SET);
                        return tell();
                }
                else {
                        return -1;
                }
        }

        sf::Int64 EncryptedStream::tell() {
                if (m_file)
                        return std::ftell(m_file);
                else
                        return -1;
        }

        sf::Int64 EncryptedStream::getSize() {
                if (m_file) {
                        sf::Int64 position = tell();
                        std::fseek(m_file, 0, SEEK_END);
                        sf::Int64 size = tell();
                        seek(position);
                        return size;
                }
                else {
                        return -1;
                }
        }

        // ---

        EncryptedStream::~EncryptedStream() {
                if (m_file)
                        std::fclose(m_file);
        }

}

 

Pages: [1]
anything