FlutterTal / godot_ggpo

A custom module in C++ to implement GGPO to Godot Engine
MIT License
45 stars 6 forks source link

How to set the callbacks in godot? #7

Open Zenchess opened 4 years ago

Zenchess commented 4 years ago

Hi, I have used GGPO in c++ project, but am having difficulty using this module in godot. I've compiled it successfully and built it and I'm not sure I'm setting the callbacks right. This is what I'm doing in godot:

I have also tried adding WSAStartup() method call to the module as I had to do that in my c++ project...

I have tried opening 2 godot's and using port 8000 for one and 8001 for the other...

None of my callbacks are being fired but ggpo seems to be working. I'm going to check wireshark to see if any connection attempts are made.

extends Node

var localPlayerHandle

Called when the node enters the scene tree for the first time.

func _ready():

GGPO.connect("advance_frame", self, "_onAdvanceFrame")
GGPO.connect("load_game_state", self, "_onLoadGameState")
GGPO.connect("log_game_state", self, "_onLogGameState")
GGPO.connect("save_game_state", self, "_onSaveGameState")
GGPO.connect("event_connected_to_peer", self, "_onEventConnectedToPeer")
GGPO.connect("event_synchronizing_with_peer", self, "_onEventSynchronizingWithPeer")
GGPO.connect("event_synchronized_with_peer", self, "_onEventSynchronizedWithPeer")
GGPO.connect("event_running", self, "_onEventRunning")
GGPO.connect("event_disconnected_from_peer", self, "_onEventDisconnectedFromPeer")
GGPO.connect("event_timesync", self, "_onEventTimesync")
GGPO.connect("event_connection_interrupted", self, "_onEventConnectionInterrupted")
GGPO.connect("event_connection_resumed", self, "_onEventConnectionResumed")
var result = GGPO.startSession("ggpo test", 2, 8001)
var localHandle = GGPO.addPlayer(GGPO.PLAYERTYPE_LOCAL, 1, "127.0.0.1", 8001)
localPlayerHandle = localHandle["playerHandle"]
GGPO.setFrameDelay(localPlayerHandle, 2)

GGPO.addPlayer(GGPO.PLAYERTYPE_REMOTE, 0, "127.0.0.1", 8000)

var stats = GGPO.getNetworkStats(1)
print ("start session result", result)
print(GGPO.ERRORCODE_SUCCESS)
print(GGPO.ERRORCODE_INVALID_SESSION, "invalid session")
print("network stats player 1:" , stats)

func _onAdvanceFrame(): print("On Event onAdvanceFrame")

func _onLoadGameState(buffer, length): print("On Load Game State")

func _onLogGameState(filename, buffer): print("On Log Game State")

func _onSaveGameState(buffer, length): print("On SaveGameState")

func _onEventConnectedToPeer(player): print("on connected to peer")

func _onEventSynchronizingWithPeer(player, count, total): print("On Event Synchronizing With Peer")

func _onEventSynchronizedWithPeer(player): print("On Event Synchronizing With Peer")

func _onEventRunning(): print("On Event Running Callback")

func _onEventDisconnectedFromPeer(player): print("disconnected from peer")

func _onEventTimesync(frames_ahead): print("frames ahead")

func _onEventConnectionInterrupted(player, disconnect_timeout): print("connection interrupted")

func _onEventConnectionResumed(player): print("connection resumed")

func _physics_process(delta):

This is called every physics frame.

GGPO.idle(2)
var result = GGPO.OK
var inputs = []
result = GGPO.addLocalInput(localPlayerHandle, 1)
if(result == GGPO.ERRORCODE_SUCCESS):
    result = GGPO.synchronizeInput(inputs, 2)
    if(result == GGPO.ERRORCODE_SUCCESS):
        _advanceFrame(inputs, 0)
#draw current frame

func _advanceFrame(inputs, disconnect_flags): print("in advanced frame")

Zenchess commented 4 years ago

Strange, I ran wireshark and I'm seeing some network activity when I start the game, but not on ports 8000 and 8001...

Zenchess commented 4 years ago

Ok turns out I had my player #'s set wrong, I am now firing the callbacks, got an assertion error and i will report further progress :)

Zenchess commented 4 years ago

Ok so I'm getting an assertion error on ggpo that i'm assuming is related to the saveGameState callback. I'm not sure how what to set for buffer and length, i've tried func _onSaveGameState(buffer,length): print("On SaveGameState") buffer = [16,20,15, 30,] length = 4*32 return true

Googlging some godot docs said that an array was 32 * count in bytesize

i've also tried:

func _onSaveGameState(buffer : int, length : int): print("On SaveGameState") buffer = 4 length = 4 return true

and tried that with length = 8 buffer:Object in the parameters, etc.
I know that in ggpo you have to modify buffer to save the game state into ggpo. So how can I properly use buffer to save the game state into ggpo? Thanks for your help, almost got it working :D

btw the assertion error is always: GGPO Assertion Failed Assertion: state->buf && state->cbuf @

in \lib\ggpo\sync.cpp

FlutterTal commented 4 years ago

Alright, I see there's many things you did here ^^' Can you just precise your issue here? I don't know how I can answer you right now

Zenchess commented 4 years ago

Ok so I am wondering how to use the save_game_state callback. It does not appear to be working. The parameters are (buffer, length). ggpo expects that you will modify buffer and length to save the game state into ggpo. I have tried buffer = (various) and no matter what I try, ggpo does not seem to be getting anything written into the buffer. Perhaps you can show me a very simple example of the proper way to use the saveGameState callback from gdscript, or point me in the right direction? I really appreciate it

FlutterTal commented 4 years ago

That's also what I was thinking, I was like "why did I put the length parameter in that callback?" So for now I've updated the module on my side, but I wanted to make sure I didn't miss anything before I can update that repository. I'll update it in a few days. But if anything goes well, you wouldn't be worried about that useless length parameter.

Zenchess commented 4 years ago

Well the issue that I see is that in the save state callback, you are supplied a pointer called buffer, which you have to use malloc and memcpy to set the buffer to the game state you wish to save, and then also set length to the bytesize of what you set buffer to. GGpo then uses these values to save the game state internally and later gives them back to you with load save state callback.

Here is the demo example of how the callback was implemented in the ggpo voidwars example /*

Will it be possible to duplicate this behavior from gdscript in godot?

FlutterTal commented 4 years ago

Well, I don't know if there is a equivalent of sizeof in godot. But what is sure is that with the new version of the module I'll update in a few days, the buffer will be a PollByteArray to simplify the thing. Also yeah, even if there's a equivalent to sizeof in godot, you shouldn't worry about it anyway, as array length are dynamically declared.