Skip to content

Conversation

@ryan-linehan
Copy link

@ryan-linehan ryan-linehan commented Nov 5, 2025

When debugging my godot game I was noticing that the SteamNetConnectionStatusChangedCallback_t callback was giving odd/garbage data when I tried to print:

private void OnNetworkConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t param)
    {
        ulong steamId = param.m_info.m_identityRemote.GetSteamID64();
        ESteamNetworkingConnectionState oldStateEnum = param.m_eOldState;
        ESteamNetworkingConnectionState newStateEnum = param.m_info.m_eState;

        GD.Print($"[SteamMultiplayerPeer] Connection status changed: {oldStateEnum} -> {newStateEnum} (Steam ID: {steamId})");
    ... shortened for brevity
}

I believe this fixes #7 as I can seemingly now connect between my mac and my windows machines and play the demo game at this repo https://github.com/ryan-linehan/Godot.Steamworks.NET through steam p2p networking. I tried to follow how the files were being generated.

It seemed to me that since ISteamNetworkingConnectionCustomSignaling was skipped in the interfaces.py that the correct way to add the pack awareness call would be to implement it right in the template. Similarly I edited the nativemethods.txt to add the marshalling for the SendSignal call that I used in the ISteamNetworkingConnectionSignaling.cs.

Lastly, I added "SteamNetConnectionInfo_t" to the g_SequentialStructs so that the SteamNetConnectionInfo_t struct gets generated with:

[StructLayout(LayoutKind.Sequential)] instead of [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)]

I am unsure if these are the correct changes for this fix or if I am just misunderstanding all together. Happy to help implement this the proper way if this is not it.

Thanks!

Also, here is a video of the game being played between my arm64 mac and my windows machine:

Godot_v4.5.1-stable_mono_win64_VVrRyCT863.mp4

Copy link
Owner

@Akarinnnnn Akarinnnnn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, I will continue to investigate steam SDK parser to see if there some problems.

[return: MarshalAs(UnmanagedType.I1)]
public static extern bool SteamAPI_ISteamNetworkingConnectionSignaling_SendSignal(ref ISteamNetworkingConnectionSignaling self, HSteamNetConnection hConn, ref SteamNetConnectionInfo_t info, IntPtr pMsg, int cbMsg);

[DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamNetworkingConnectionSignaling_SendSignal", CallingConvention = CallingConvention.Cdecl)]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to guard with #if STEAMWORKS_ANYCPU

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure my Pr ever got updated with this. I should go back and add this still right? Or was it covered in another commit that this was merged into perhaps?


/// Describe the state of a connection.
[StructLayout(LayoutKind.Sequential, Pack = Packsize.value)]
[StructLayout(LayoutKind.Sequential)]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pack = Packsize.value is still necessary since steam using a different pack to platform default.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I tried it both ways and it only seemingly worked with this change. I was trying to follow how MatchMakingKeyValuePair_t struct worked that's why I made the change to interfaces.py so the generator would make this change

I'll put it back and test again and let you know the results later today

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I attempted to put this back to how it was and now I am back to getting in a endless 'connecting' state.

Logs from the windows x64 machine:

[SteamMultiplayerPeer] CreateClient called with remote Steam ID: 76561198191562071, port: 0
[SteamMultiplayerPeer] ConnectP2P succeeded, waiting for connection callback
[SteamMultiplayerPeer] Connection status changed: k_ESteamNetworkingConnectionState_None -> k_ESteamNetworkingConnectionState_None (Steam ID: 0)
[SteamMultiplayerPeer] Connection status changed: k_ESteamNetworkingConnectionState_None -> k_ESteamNetworkingConnectionState_None (Steam ID: 0)
[SteamMultiplayerPeer] Connection status changed: k_ESteamNetworkingConnectionState_None -> 7102840 (Steam ID: 0)

Note that everything goes from none -> none I assume because something is not right. The steam ID being 0 should not really happen here either. 7102840 is not a value that this enumeration supports so it seems something is not right when on windows with the

[StructLayout(LayoutKind.Sequential, Pack = Packsize.value)]

image

Back to using this change with no pack size declared:

[StructLayout(LayoutKind.Sequential)]

Gives the following logs on the windows machine:

[SteamMultiplayerPeer] CreateClient called with remote Steam ID: 76561198191562071, port: 0
[SteamMultiplayerPeer] ConnectP2P succeeded, waiting for connection callback
[SteamMultiplayerPeer] Connection status changed: k_ESteamNetworkingConnectionState_None -> k_ESteamNetworkingConnectionState_Connecting (Steam ID: 76561198191562071)
[SteamMultiplayerPeer] Connection status changed: k_ESteamNetworkingConnectionState_Connecting -> k_ESteamNetworkingConnectionState_FindingRoute (Steam ID: 76561198191562071)
[SteamMultiplayerPeer] Connection status changed: k_ESteamNetworkingConnectionState_FindingRoute -> k_ESteamNetworkingConnectionState_Connected (Steam ID: 76561198191562071)
Peer Connected: 1Self id: 1350075199

Which actually show the connection state and steam ids properly and I am able to successfully connect again.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this struct is using platform default alignment(in case of Packsize.value omitted), we may not need large pack version. Let me check parser.

Copy link
Owner

@Akarinnnnn Akarinnnnn Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tried add Packsize.value back on your Mac? I suspect this is a pack-size aware struct but is not auto generated.
If Mac with Packsize.value connected to Windows without that modifier, I think this is a alignment issue and can be manually fixed like what generator did.

Copy link
Author

@ryan-linehan ryan-linehan Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah actually I deploy it to both PCs when testing it. So they have always been the same version of the pack size param when testing

Copy link
Author

@ryan-linehan ryan-linehan Nov 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any updates on this? Trying to use the package in one of my games and I am currently building the package myself with my changes. Think we could get a new beta branch up with these changes soon?

@Akarinnnnn
Copy link
Owner

image

Seems our parser detected it's a pack aware struct, I'll check generator later.

@ryan-linehan
Copy link
Author

Yeah the parser seems to catch it but the generator doesn't because it's one of the few "custom templates" that aren't generated but rather they're copied straight from the template file from what I could tell

Let me know what you find!

@Akarinnnnn
Copy link
Owner

Akarinnnnn commented Nov 6, 2025 via email

@Akarinnnnn
Copy link
Owner

Akarinnnnn commented Nov 8, 2025 via email

@Akarinnnnn
Copy link
Owner

FieldOffsets-Microsoft Windows 10.0.26200.txt
FieldOffsets-Ubuntu 24.04.3 LTS.txt
I have scanned memory layout based on your branch, they are the same. Next I want to use some c++ tools to scan native layout.

@ryan-linehan
Copy link
Author

Well, I'm away from my testable machine which installed Windows and Ubuntu in WSL2. Next time I have holiday is 2 weeks estimated. If you think this one is a good fix and ready for previrw, please imform me so that I will push it as 2025.162.6-b .

No worries. I'm fairly confident in the changes but I can wait a bit longer so you can have the proper time to review.

FieldOffsets-Microsoft Windows 10.0.26200.txt
FieldOffsets-Ubuntu 24.04.3 LTS.txt
I have scanned memory layout based on your branch, they are the same. Next I want to use some c++ tools to scan native layout.

Sweet, keep me posted! Thanks for digging in with me 😀

@Akarinnnnn
Copy link
Owner

#1 (comment)

According this analysis, SteamNetConnectionInfo_t should have same layout across large and posix pack. Your solution is a good workaround, but it also discovered there are some bugs in our parser/generator.

@Akarinnnnn Akarinnnnn merged commit d1aea9d into Akarinnnnn:anycpu-packable-fix-align-by-conditionalmarshal Nov 18, 2025
@ryan-linehan
Copy link
Author

Sounds good, if I can help somehow please let me know.

In the meantime, do you think you could try out the GitHub action I pushed in a previous PR and publish a new beta branch build? Hoping to have a usable nuget package for myself and other Godot users even if it's not production ready yet for me it is seemingly "good enough" while the rest of the issues are hashed out.

Appreciate it!

@Akarinnnnn
Copy link
Owner

Akarinnnnn commented Nov 19, 2025 via email

@ryan-linehan
Copy link
Author

Btw new nuget package with fixes are working great for my use case! Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants