- Clone the repository
- Run
npm installto install all required dependencies
- Run
npm run natives:buildto compile the native libraries and automatically copy them to the app-electron/public folder - Run
npm run natives:addon:buildto compile the addon module and copy it to the app-electron/public folder
-
Run
npm run startto launch the application. This will:- Copy all native components to the dist folder
- Build the application and copy it to the dist folder
- Start the renderer-window to serve the overlay-api on port 4000
- Start the overlay-window to serve the overlay-api on port 4100
- Open an Electron window displaying google.com and another hidden window with the overlay-api
- By default, the app-electron will hook into the window titled "Forager by HopFrog" (you can modify this target in the main.ts file)
-
Launch your game and verify that the overlay-api is properly rendering inside the game window
The native components are split into two main parts: win-natives and node-natives.
This library contains the core logic for the game overlay functionality on Windows.
n_overlay: The primary DLL responsible for hooking into DirectX APIs (DX9, 10, 11, 12) within the target game process. It handles rendering the overlay UI, managing overlay windows, and processing input.n_ovhelper: A helper executable used to inject then_overlay.dllinto the target game process.- Detours: Utilizes the Microsoft Detours library for function hooking.
- IPC: Implements an Inter-Process Communication mechanism for communication between the overlay DLL and external applications (like the Node.js addon).
This is a Node.js C++ addon that acts as a bridge between the JavaScript/Electron environment and the win-natives overlay library.
- Binding: Provides JavaScript bindings to the
win-nativesAPI, allowing the Electron application to control the overlay (e.g., create windows, send frame data, manage input). - Communication: Facilitates the IPC connection with the
n_overlay.dllrunning inside the game process. - Integration: Simplifies the interaction with the native overlay code from the Electron application's main and renderer processes.
The communication between the Electron application (JavaScript/TypeScript) and the node-natives addon is defined by the OverlayNodeApi interface (apps/app-electron/src/native/overlay-api/interfaces/overlay-lib.interface.ts). This interface exposes the native functionalities to the JS side, enabling actions such as:
- Injecting the overlay into a game process (
injectProcess). - Managing overlay windows (
addWindow,closeWindow,sendWindowBounds). - Sending frame data for rendering (
sendFrameBuffer,sendSharedTextureHandle). - Handling input events (
startGameInputIntercept,stopGameInputIntercept,translateInputEvent). - Configuring hotkeys and other settings (
setHotkeys,sendCommand). - Receiving events from the native layer (
setEventCallback).
The TypeScript façade you import as OverlayApiLib is just a thin wrapper on top of the pre-built native addon overlay-api.node. This addon exposes the OverlayNodeApi interface described above and performs three main tasks:
- IPC bridge – Maintains a bi-directional IPC channel with the injected
n_overlay.dllthat lives inside the game process. - Resource management – Marshals shared memory buffers/texture handles between Electron and the overlay DLL, translating JS friendly types (
Buffer, numbers) into the raw handles expected by DirectX. - Event pump – Propagates asynchronous events coming from the native layer back to the JavaScript world through
setEventCallback.
- The hidden off-screen Electron window paints a new frame.
- A
paintevent is emitted in the main process:- CPU path –
image.getBitmap()is copied into a NodeBufferand delivered viasendFrameBuffer. Every frame incurs a full GPU→CPU→GPU copy.
- CPU path –
- Inside the game process the DLL receives the shared handle, opens it with
OpenSharedResourceand renders it directly on the in-game swap chain.
startInjectInterval()pollsoverlayApi.getTopWindows()every 5 s.- Matching windows are sent to
overlayApi.injectProcess(), which in turn runsn_ovhelper.exeto inject the DLL. - When the DLL is fully initialised it emits
game.hookandgraphics.windowevents that are captured throughsetEventCallback. OverlayApiLibupdates its internalAppsManagerstate machine and keeps emitting higher-level observables such asonHook$.