First off, thank you for considering contributing to steamworks-ffi-node! 🎮
This document provides guidelines and instructions for contributing to the project.
- Code of Conduct
- Getting Started
- Development Setup
- Project Structure
- Making Changes
- Testing
- Submitting Changes
- Style Guidelines
- Adding New Steam APIs
This project follows a simple code of conduct:
- Be respectful and inclusive
- Focus on constructive feedback
- Help others learn and grow
- Keep discussions on-topic
- Node.js 18.0.0 or higher
- Steam Client installed and logged in
- Steamworks SDK (download from Steamworks Partner)
- TypeScript knowledge (the project is written in TypeScript)
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/steamworks-ffi-node.git cd steamworks-ffi-node - Add the upstream remote:
git remote add upstream https://github.com/ArtyProf/steamworks-ffi-node.git
npm installCopy the Steamworks SDK redistributable binaries to the project:
steamworks_sdk/
└── redistributable_bin/
├── win64/steam_api64.dll
├── steam_api.dll
├── osx/libsteam_api.dylib
├── linux64/libsteam_api.so
├── linux32/libsteam_api.so
├── linuxarm64/libsteam_api.so
└── androidarm64/libsteam_api.so
npm run verify-sdknpm run buildsteamworks-ffi-node/
├── src/
│ ├── index.ts # Main entry point
│ ├── steam.ts # SteamworksSDK class (public API)
│ ├── internal/ # Internal manager implementations
│ │ ├── SteamAPICore.ts
│ │ ├── SteamAchievementManager.ts
│ │ ├── SteamLibraryLoader.ts
│ │ └── ...
│ └── types/ # TypeScript type definitions
│ ├── index.ts
│ ├── achievements.ts
│ └── ...
├── docs/ # API documentation
├── tests/
│ ├── js/ # JavaScript tests
│ └── ts/ # TypeScript tests
└── steamworks_sdk/ # SDK binaries (not committed)
git checkout -b feature/your-feature-name
# or
git checkout -b fix/your-bug-fix- Follow the existing code style
- Add/update TypeScript types as needed
- Update documentation if changing public APIs
- Add tests for new functionality
Use conventional commit messages:
feat: add new achievement notification API
fix: correct memory alignment on Linux ARM64
docs: update Workshop API examples
refactor: simplify callback registration
test: add matchmaking host/join tests
chore: update dependencies
Tests require Steam client to be running and logged in.
# Run specific manager tests
npm run test:achievements:ts
npm run test:stats:js
npm run test:cloud:ts
# Available test categories
npm run test:core:ts
npm run test:achievements:ts
npm run test:stats:ts
npm run test:leaderboards:ts
npm run test:friends:ts
npm run test:cloud:ts
npm run test:workshop:ts
npm run test:input:ts
npm run test:screenshots:ts
npm run test:apps:ts
npm run test:utils:tsSome features require two Steam accounts (matchmaking, networking):
# Terminal 1 - Host
npm run test:matchmaking:host:ts
# Terminal 2 - Join (with Steam ID from host)
npm run test:matchmaking:join:ts -- 76561198XXXXXXXXXnpx tsc --noEmitgit fetch upstream
git rebase upstream/maingit push origin feature/your-feature-name- Go to GitHub and create a Pull Request
- Fill in the PR template
- Link any related issues
- Wait for CI checks to pass
- Code compiles without errors (
npm run build) - TypeScript types are properly defined
- Tests pass (where applicable)
- Documentation updated (if changing public API)
- Commit messages follow conventional format
- Use
strict: trueTypeScript configuration - Prefer explicit types over
any - Use JSDoc comments for public APIs
- Follow existing naming conventions
// Good: Explicit types, descriptive names
function getAchievementUnlockTime(achievementName: string): number | null {
// Implementation
}
// Good: JSDoc for public methods
/**
* Unlocks an achievement for the current user
* @param name - The API name of the achievement
* @returns True if the achievement was unlocked successfully
*/
unlockAchievement(name: string): boolean {
// Implementation
}- One manager per file in
src/internal/ - Types in
src/types/with category-based files - Export public types from
src/types/index.ts
Add type definitions in src/types/newfeature.ts:
export interface NewFeatureResult {
success: boolean;
data: string;
}Export from src/types/index.ts:
export * from './newfeature';In src/internal/SteamLibraryLoader.ts:
// Add function declaration
public SteamAPI_ISteamNewFeature_DoSomething!: koffi.KoffiFunction;
// Add binding in load()
this.SteamAPI_ISteamNewFeature_DoSomething = this.steamLib.func(
'SteamAPI_ISteamNewFeature_DoSomething',
'bool',
['void*', 'str']
);Create src/internal/SteamNewFeatureManager.ts:
import { SteamLibraryLoader } from './SteamLibraryLoader';
import { NewFeatureResult } from '../types';
export class SteamNewFeatureManager {
constructor(private libraryLoader: SteamLibraryLoader) {}
doSomething(param: string): NewFeatureResult {
// Implementation
}
}In src/steam.ts, add the manager and expose methods.
Create tests in both tests/js/ and tests/ts/.
Create docs/NEW_FEATURE_MANAGER.md with:
- Overview
- Quick reference table
- Detailed function documentation
- Code examples
- Open an issue for bugs or feature requests
- Join our Discord for discussions
- Check existing issues before creating new ones
By contributing, you agree that your contributions will be licensed under the MIT License.
Thank you for contributing! 🚀