Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/menduz/zig-steamworks
Steamwork bindings for Zig
https://github.com/menduz/zig-steamworks
game-development steamworks zig
Last synced: 3 months ago
JSON representation
Steamwork bindings for Zig
- Host: GitHub
- URL: https://github.com/menduz/zig-steamworks
- Owner: menduz
- License: apache-2.0
- Created: 2023-06-06T22:27:04.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-09-28T23:43:43.000Z (4 months ago)
- Last Synced: 2024-11-01T07:33:18.531Z (3 months ago)
- Topics: game-development, steamworks, zig
- Language: C++
- Homepage:
- Size: 4.7 MB
- Stars: 17
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# zig-steamworks
Zig bindings for Steamworks, compatible with v1.57 (March 2023).
The bindings are autogenerated from the C bindings and are compatible with
- macOS (both Apple Silicon and Intel)
- linux (x86_64)
- windows (x86_64)This project uses Zig 0.11.0-dev
# Including the Steamworks SDK
Due to licence agreements, you must bring your own SDK. This project assumes it is located in the ./steamworks folder. But you can have it anywhere else.
# Linking the Steamworks libraries.
```zig
// build.zig
const zig_steamworks = @import("zig-steamworks/linker.zig");fn main() !void {
// ...
const exe = b.addExecutable( ... );// link steamworks to this executable
_ = try zig_steamworks.linkSteamLibrary(b, exe, "steamworks");
// relative path to steamworks ^^^^^^^^^^// you must include the steam_appid.txt file in your final directory
try zig_steamworks.copy(comptime zig_steamworks.thisDir() ++ "/src", "zig-out/bin", "steam_appid.txt");
}
```# Build it
For convenience, this repository offers already built bindings for Zig in the `src` folder. Until Zig modules and package manager are mature, the recommended course of action is to copy these files into your project.
To re-build the files run the following command
```
node generate.js path_to_steamworks/public/steam/steam_api.json
```# Example
```zig
const std = @import("std");
const steam = @import("steam.zig");/// callback hook for debug text emitted from the Steam API
pub fn SteamAPIDebugTextHook(nSeverity: c_int, pchDebugText: [*c]const u8) callconv(.C) void {
// if you're running in the debugger, only warnings (nSeverity >= 1) will be sent
// if you add -debug_steamapi to the command-line, a lot of extra informational messages will also be sent
std.debug.print("SteamAPIDebugTextHook sev:{} msg: {s}\n", .{ nSeverity, pchDebugText });
}/// get an authentication ticket for our user
fn authTicket(identity: *steam.SteamNetworkingIdentity) !void {
var rgchToken: *[2048]u8 = try std.heap.c_allocator.create([2048]u8);
var unTokenLen: c_uint = 0;
var m_hAuthTicket = steam.SteamUser().GetAuthSessionTicket(rgchToken, 2048, &unTokenLen, identity);
std.debug.print("GetAuthSessionTicket={} len={} token={s}", .{ m_hAuthTicket, unTokenLen, rgchToken });
}pub fn main() !void {
if (steam.SteamAPI_RestartAppIfNecessary(480)) {
// if Steam is not running or the game wasn't started through Steam, SteamAPI_RestartAppIfNecessary starts the
// local Steam client and also launches this game again.// Once you get a public Steam AppID assigned for this game, you need to replace k_uAppIdInvalid with it and
// removed steam_appid.txt from the game depot.
@panic("SteamAPI_RestartAppIfNecessary");
}if (steam.SteamAPI_Init()) {
std.debug.print("Steam initialized correctly. \n", .{});
} else {
@panic("Steam did not init\n");
}steam.SteamClient().SetWarningMessageHook(SteamAPIDebugTextHook);
defer steam.SteamAPI_Shutdown();
std.debug.print("User {?}\n", .{steam.SteamUser().GetSteamID()});
var sock = steam.SteamNetworkingSockets_SteamAPI();
var pInfo: *steam.SteamNetworkingFakeIPResult_t = try std.heap.c_allocator.create(steam.SteamNetworkingFakeIPResult_t);
defer std.heap.c_allocator.destroy(pInfo);sock.GetFakeIP(0, pInfo);
std.debug.print("GetFakeIP: {}\n", .{pInfo});
if (!pInfo.m_identity.IsEqualTo(pInfo.m_identity)) @panic("not equal");var pDetails: *steam.SteamNetAuthenticationStatus_t = try std.heap.c_allocator.create(steam.SteamNetAuthenticationStatus_t);
defer std.heap.c_allocator.destroy(pDetails);var connectionStatus = sock.GetAuthenticationStatus(pDetails);
std.debug.print("GetAuthenticationStatus: {} {}\n", .{ connectionStatus, pDetails });var pIdentity: *steam.SteamNetworkingIdentity = try std.heap.c_allocator.create(steam.SteamNetworkingIdentity);
std.heap.c_allocator.destroy(pIdentity);
var r = sock.GetIdentity(pIdentity);
std.debug.print("GetIdentity={} {}\n", .{ r, pIdentity });try authTicket(pIdentity);
}
```# Alignment
Steamworks is packed with `pragma packs`, I've tried dozens of approaches even brute forcing all structs, but getting the right alignment for every struct was impossible. So I took the good-enough-and-not-so-elegant path of delegating the alignment to the C compiler entirely and then forcing Zig to copy everything with the generated code. In effect, you will see a lot of `align(...)` in the generated code.
In practice both Mac and Linux alignments are the same.
Please do the following steps for each steamworks release that is added to this repo. Mind the diff in the steamworks headers to remove the private fields (search for `// ZIG:`).
## To generate the linux alignment file from aarch64 Mac hosts
```bash
# open a docker container using x86_64
docker run -v $(pwd):/mnt -w /mnt --rm -it --platform linux/amd64 mcr.microsoft.com/devcontainers/typescript-node:0-18 zsh
# install zig
sudo bash .devcontainer/install-zig.sh
# run the script and grab a coffee
bash ./create-align-info-linux.sh
```## To generate the mac alignment file from Mac
```bash
# run the script
bash ./create-align-info-mac.sh
```## To generate the mac alignment file from Windows
```bash
# run the script
.\create-align-info-mac.bat
```