GithubHelp home page GithubHelp logo

ggpo's Introduction

  Appveyor build status

(日本語ドキュメントはこちら)

What's GGPO?

Traditional techniques account for network transmission time by adding delay to a players input, resulting in a sluggish, laggy game-feel. Rollback networking uses input prediction and speculative execution to send player inputs to the game immediately, providing the illusion of a zero-latency network. Using rollback, the same timings, reactions, visual and audio queues, and muscle memory your players build up playing offline will translate directly online. The GGPO networking SDK is designed to make incorporating rollback networking into new and existing games as easy as possible.

For more information about the history of GGPO, check out http://ggpo.net/

This repository contains the code, documentation, and sample applications for the SDK.

Building

Building GGPO is currently only available on Windows, however efforts are being made to port it to other platforms.

Windows

Windows builds requires both Visual Studio 2019 and CMake. Make sure you've installed both before starting. Make sure to add CMake to your path when installing.

  • Run the build_windows.cmd in the root directory of the SDK to generate the Visual Studio 2019 solution files.
  • Open build/GGPO.sln solution for Visual Studio 2019 to compile.

You can also run the cmake-gui tool if you prefer.

Sample Application

The Vector War application in the source directory contains a simple application which uses GGPO to synchronize the two clients. The command line arguments are:

vectorwar.exe  <localport>  <num players> ('local' | <remote ip>:<remote port>) for each player

See the .cmd files in the bin directory for examples on how to start 2, 3, and 4 player games.

Licensing

GGPO is available under The MIT License. This means GGPO is free for commercial and non-commercial use. Attribution is not required, but appreciated.

ggpo's People

Contributors

assemblaj avatar bocom avatar gnawnom avatar guestnone avatar jakethejake74 avatar ksmit799 avatar mawglhf avatar mfindlater avatar mrjnumber1 avatar nykwil avatar philtothetop avatar pond3r avatar pondy avatar seasidelab avatar shugyousha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ggpo's Issues

No tests

Is there a plan to add tests in the future? In my opinion it is very hard to recommend ggpo in a professional setting when there are possible breaking points such as custom data structures.

Tests could make it easier to understand each working parts of the lib as well. I find that the vector war example is a bit bloated because you have to parse through rendering and game logic. I only care about what happens with the inputs and the game state.

Use with no prediction

Could ggrs set prediction to 0?
Currently it crashs with max_prediction 0 or 1.

This would be useful when it is difficult to provide savestate, ex; unofficial netbattle project.

GGPO_ERRORCODE_PREDICTION_THRESHOLD after every ggpo_add_local_input

I apologize if this might be a stupid question, but I am having troubles in implementing this library in a sample project of mine.
While running the vectorwar demo, everything seems to work fine, without issues. I can compile and execute the game without troubles and the synchronization via GGPO works flawlessly.
However, when I try to implement GGPO in my own project, after the connection between the players has been established (GGPO_EVENTCODE_RUNNING has been issued), whenever I call a ggpo_add_local_input command, it always fails with the above return value (GGPO_ERRORCODE_PREDICTION_THRESHOLD).
Is there any step I have to perform between the first time I receive a GGPO_EVENTCODE_RUNNING and the first ggpo_add_local_input / ggpo_synchronize_input that I am missing?
If not, what could be the cause of this error?

To summarize:

  • I start the session with ggpo_start_session (result = GGPO_ERRORCODE_SUCCESS)
  • add the two players with ggpo_add_player (result = GGPO_ERRORCODE_SUCCESS)
  • call for ggpo_advance_frame (result = GGPO_ERRORCODE_SUCCESS) at 60fps. Otherwise, call ggpo_idle
  • the two players connect and I get the events GGPO_EVENTCODE_SYNCHRONIZED_WITH_PEER, then GGPO_EVENTCODE_RUNNING
  • after this, whenever I call ggpo_add_local_input, it fails with result GGPO_ERRORCODE_PREDICTION_THRESHOLD, thus preventing synchronization between the clients.

The above issue happens even when running two instances of the game on the same machine, on different ports.

Quick Question about missing bin file in build.

so I build ggpo using cmake with it shared path with all, (middle option during installation)

but it lacks the build bin while which has the ggpo.dll and ggpo.pdb file, how do I make it so that I can have these files.
explorer_l8tAPTBkSy

WSANOTINITIALISED 10093 Error Code

Dependencies Used

  • Visual Studio 2019
  • Windows 10
  • ggpo.lib
  • ggpo.dll
  • SDL2

Summary

When I attempt to build ggpo as a .dll and .lib file to use as a dependency for my own project, I end up receiving the following error below:

image

Looking at the code snippet below (udp.cpp):

void
Udp::SendTo(char *buffer, int len, int flags, struct sockaddr *dst, int destlen)
{
   struct sockaddr_in *to = (struct sockaddr_in *)dst;

   int res = sendto(_socket, buffer, len, flags, dst, destlen);
   if (res == SOCKET_ERROR) {
      DWORD err = WSAGetLastError();
      Log("unknown error in sendto (erro: %d  wsaerr: %d).\n", res, err);
      ASSERT(FALSE && "Unknown error in sendto");
   }
   char dst_ip[1024];
   Log("sent packet length %d to %s:%d (ret:%d).\n", len, inet_ntop(AF_INET, (void *)&to->sin_addr, dst_ip, ARRAY_SIZE(dst_ip)), ntohs(to->sin_port), res);
}

I end up getting a SOCKET_ERROR when the sendto(...) function is called. It turns out the error I get back is error code: 10093. Based on Microsoft's documentation, error code https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2, error code 10093 means that Win Sockets dependency hasn't been initialized yet.

Steps to Reproduce:

  • The following simplified code will reproduce the issue:
// assume callbacks, game state, non game state,  and port numbers are already defined somewhere else

const int NUM_PLAYERS = 2;
GGPOSession *ggpo = NULL;

GGPOSessionCallbacks cb = { 0 };
cb.begin_game      = vw_begin_game_callback;
cb.advance_frame	 = vw_advance_frame_callback;
cb.load_game_state = vw_load_game_state_callback;
cb.save_game_state = vw_save_game_state_callback;
cb.free_buffer     = vw_free_buffer;
cb.on_event        = vw_on_event_callback;
cb.log_game_state  = vw_log_game_state;

ggpo_start_session(&ggpo, &cb, "rollback_tech_demo", NUM_PLAYERS, sizeof(int), localPort);

ggpo_set_disconnect_timeout(ggpo, 3000);
ggpo_set_disconnect_notify_start(ggpo, 1000);

// Calls to ggpo_add_player() made but omitted to keep simple

int maxTimeIdleMillis = 6;
ggpo_idle(ggpo, maxTimeIdleMillis);

// sends input request over the network using UDP protocol internally
// Looks like this fails because Winsockets hasn't been initialized yet.
ggpo_add_local_input(ggpo, ngs.local_player_handle, &localInputsThisFrame, sizeof(localInputsThisFrame));

ggpo_synchronize_input(ggpo, (void *)allInputs, sizeof(int) * NUM_PLAYERS, &disconnectFlags);

ggpo_advance_frame(ggpo);

Separate network protocol from the rollback logic

I don't know how tightly coupled they are but it would be nice if they could be isolated from each other and maybe show how to combine them in an example. For example if I use an engine which has its own protocol I might want to skip ggpo's implementation and only use the rollback.

Secure P2P Without Dedicated Server

I was wondering if there was a way to securely use GGPO without dedicated servers. If I'm not mistaken, games like Brawlhalla use dedicated servers to connect via IP/port. I'm no networking expert, but using NAT traversal techniques like STUN to get an IP and plug that in isn't recommended right?

I was thinking about using Steam P2P so it's not exposing the client IPs but it seems like it'd be a lot of work. If that's been done before, there's a better method, or if I could have some pointers on the best way to implement it I'd be very grateful!

Add Linux support

This is something I'm interested in working on but I figured I'd create an issue to track the work in case anyone else wants to jump in.

Currently building fails on Linux with this totally unsurprising error about a missing winsock2.h:

[  7%] Building CXX object CMakeFiles/ggpo.dir/src/lib/ggpo/main.cpp.o
In file included from /home/kkremitzki/Desktop/Source/ggpo/git/src/lib/ggpo/main.cpp:8:0:
/home/kkremitzki/Desktop/Source/ggpo/git/src/lib/ggpo/types.h:12:10: fatal error: winsock2.h: No such file or directory
 #include <winsock2.h>
          ^~~~~~~~~~~~
compilation terminated.
CMakeFiles/ggpo.dir/build.make:62: recipe for target 'CMakeFiles/ggpo.dir/src/lib/ggpo/main.cpp.o' failed

Once the build works on Linux I can proceed to getting it packaged for Debian/Ubuntu.

Technical Specifications document

I propose that a technical specifications document should be created for GGPO. I believe this will make it easier for people to create their own implementations vs having to parse the reference implementation.

I'm currently going through the source code and willing to volunteer to do the bulk of the work on a technical specification document as I was considering making one for myself.

Things that should be included

  • User Interface specification
  • Protocol specification (packet formats, sequence diagrams, etc for the low level protocol [found in udp_proto.cpp/h])
  • Event handling
  • Application flow

etc etc

Licencing is unclear

The license section of the readme states:

GGPO is available under The MIT License. This means GGPO is free for commercial and non-commercial use. Attribution is not required, but appreciated.

The MIT licence requires some degree of attribution, but this line says GGPO doesn't require attribution. Can this be clarified? Is the intent "no attribution beyond what the licence otherwise requires"?

No documentation for GGPO_ERRORCODE_INPUT_DROPPED

I did a search on the whole project and couldn't find any usage off it.
When is this errorcode returned?
Because I do have issues with input dropping in my project when this ping is 2x higher than set delay input. (this is only an issue with hitinput, block/movement input are handled correctly

GGPO Session with Local Players Only -- What's the Intended Behavior?

I've been testing GGPO on my current game project and ran into a roadblock. Specifically, in regard to a session with only local players, it seems like GGPO will always return GGPO_ERRORCODE_NOT_SYNCHRONIZED when trying to add inputs or synchronize inputs.

After spending some time trying to find the source of my issues, I caught this code and comment:

p2p.cpp

void
Peer2PeerBackend::AddRemotePlayer(char *ip,
                                  int port,
                                  int queue)
{
   /*
    * Start the state machine (xxx: no)
    */
   _synchronizing = true;
   
   _endpoints[queue].Init(&_udp, _poll, queue, ip, port, _local_connect_status);
   _endpoints[queue].SetDisconnectTimeout(_disconnect_timeout);
   _endpoints[queue].SetDisconnectNotifyStart(_disconnect_notify_start);
   _endpoints[queue].Synchronize();
}

So it seems to me that GGPO only enters its internal synchronization state machine when at least one remote player is added to the game session. Is this correct? So if I wanted to simulate an online game for local play (I.E. uses the GGPO synchronize_inputs to respect frame delay settings) how would this be achieved?

Is there a maximum size in bytes for an input when creating a GGPOSession?

So I've been testing GGPO on Linux, which I know isn't a supported plaform yet, and I've run into a small problem. I've noticed that GGPO crashes when the input size is anything larger than 18 bytes. Is 18 bytes the maximum input size that GGPO supports? Or is this simply a bug? I'm using a branch based on PR #52 .

Questions about developer guide

When I translated it into Japanese, there was a part I didn't understand.
(By the way, I'm not good at English.)

your 2-second flash will be entirely consumed by the rollback (line 180)

Is this "2-second" a mistake of "2-frame"?

GGPO will call your advance frame callback many times during a rollback. (line 208)

Does this "advance frame" mean "ggpo_advance_frame" or user defined callback function?

Add Japanese documentation

There is no Japanese documentation yet which would be good to have.

I would like to start the translation of the current documentation into Japanese.

Should we add a subdirectory in the doc/ folder (i. e. doc/ja/) or just add a suffix to the markdown documents (i. e. DevelopmentGuide.ja.md)?

Style questions

Granted I have never done extensive C style programming, it might be my lack of familiarity talking.

  • what use is that empty struct
    } local;
    I found some info about tagging structs but I'm not sure that's what is happening here.
  • is there a reason to return a GGPOErrorCode when there is only one return value possible? Maybe for async uses?
  • while (Pump(100)) {
    I've seen these kinds of while in a few places, and they scare me :p

Inquiry - Crossplatform Support

I was wondering if any of the Cross platform pull requests are being considered. Some have been submitted since the beginning of the year & I was wondering if there was a certain direction that this project is going. Is there any assistance needed? #57 looks interesting...

[Arch Linux] compilation fails with "x" not found, did you mean "y"?

log:

[  6%] Building CXX object src/CMakeFiles/GGPO.dir/lib/ggpo/bitvector.cpp.o
[ 13%] Building CXX object src/CMakeFiles/GGPO.dir/lib/ggpo/game_input.cpp.o
/home/fabx/Desktop/ggpo/src/lib/ggpo/game_input.cpp: In member function ‘void GameInput::desc(char*, size_t, bool) const’:
/home/fabx/Desktop/ggpo/src/lib/ggpo/game_input.cpp:44:20: error: ‘sprintf_s’ was not declared in this scope; did you mean ‘sprintf’?
   44 |       remaining -= sprintf_s(buf, buf_size, "(frame:%d size:%d ", frame, size);
      |                    ^~~~~~~~~
      |                    sprintf
/home/fabx/Desktop/ggpo/src/lib/ggpo/game_input.cpp:46:20: error: ‘sprintf_s’ was not declared in this scope; did you mean ‘sprintf’?
   46 |       remaining -= sprintf_s(buf, buf_size, "(size:%d ", size);
      |                    ^~~~~~~~~
      |                    sprintf
/home/fabx/Desktop/ggpo/src/lib/ggpo/game_input.cpp:52:18: error: ‘sprintf_s’ was not declared in this scope; did you mean ‘sprintf’?
   52 |          int c = sprintf_s(buf2, ARRAY_SIZE(buf2), "%2d ", i);
      |                  ^~~~~~~~~
      |                  sprintf
/home/fabx/Desktop/ggpo/src/lib/ggpo/game_input.cpp:53:10: error: ‘strncat_s’ was not declared in this scope; did you mean ‘strncat’?
   53 |          strncat_s(buf, remaining, buf2, ARRAY_SIZE(buf2));
      |          ^~~~~~~~~
      |          strncat
/home/fabx/Desktop/ggpo/src/lib/ggpo/game_input.cpp:57:4: error: ‘strncat_s’ was not declared in this scope; did you mean ‘strncat’?
   57 |    strncat_s(buf, remaining, ")", 1);
      |    ^~~~~~~~~
      |    strncat
/home/fabx/Desktop/ggpo/src/lib/ggpo/game_input.cpp: In member function ‘void GameInput::log(char*, bool) const’:
/home/fabx/Desktop/ggpo/src/lib/ggpo/game_input.cpp:65:9: error: ‘strcpy_s’ was not declared in this scope; did you mean ‘strcpy’?
   65 |         strcpy_s(buf, prefix);
      |         ^~~~~~~~
      |         strcpy
/home/fabx/Desktop/ggpo/src/lib/ggpo/game_input.cpp:67:4: error: ‘strncat_s’ was not declared in this scope; did you mean ‘strncat’?
   67 |    strncat_s(buf, ARRAY_SIZE(buf) - strlen(buf), "\n", 1);
      |    ^~~~~~~~~
      |    strncat

Player's game crashes when spectator stops spectating them

This happens 100% of the time for me in both the latest version (commit 7ddadef) and the initial GitHub commit (commit 02b9eff), both in my own game and in the VectorWar sample app.

Repro steps

  • Download the GGPO repository (commit 7ddadef)
  • Run configure_windows.cmd, open GGPO.sln, rebuild solution in Release/x64 (Windows 10, Visual Studio 2019 version 16.8.5)
  • Run start_vectorwar_2p_4s.cmd
  • Close one of the spectator windows
  • Roughly one second later, player one (who was connected to that spectator) will get an error window with the following text:
GGPO Assertion Failed
Assertion: _size != (N-1) @ C:\Dev\ggpobugtest\ggpo-master\src\lib\ggpo\ring_buffer.h:39 (pid:16416)
  • Clicking 'OK' on that error window causes the game to close

Here's the call stack I get when running player one in a Debug build:

 	VectorWar.exe!Platform::AssertFailed(char * msg) Line 23	C++
>	VectorWar.exe!RingBuffer<GameInput,64>::push(const GameInput & t) Line 39	C++
 	VectorWar.exe!UdpProtocol::SendInput(GameInput & input) Line 106	C++
 	VectorWar.exe!Peer2PeerBackend::DoPoll(int timeout) Line 139	C++
 	VectorWar.exe!Peer2PeerBackend::IncrementFrame() Line 335	C++
 	VectorWar.exe!ggpo_advance_frame(GGPOSession * ggpo) Line 139	C++
 	VectorWar.exe!VectorWar_AdvanceFrame(int * inputs, int disconnect_flags) Line 351	C++
 	VectorWar.exe!VectorWar_RunFrame(HWND__ * hwnd) Line 426	C++
 	VectorWar.exe!RunMainLoop(HWND__ * hwnd) Line 84	C++
 	VectorWar.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * __formal, wchar_t * __formal, int __formal) Line 181	C++

And here's a video of it:

ggpo_crash_when_spectator_leaves.mp4

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.