ScriptHookVDotNetCore 1.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package ScriptHookVDotNetCore --version 1.1.0
NuGet\Install-Package ScriptHookVDotNetCore -Version 1.1.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ScriptHookVDotNetCore" Version="1.1.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ScriptHookVDotNetCore --version 1.1.0
#r "nuget: ScriptHookVDotNetCore, 1.1.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install ScriptHookVDotNetCore as a Cake Addin
#addin nuget:?package=ScriptHookVDotNetCore&version=1.1.0

// Install ScriptHookVDotNetCore as a Cake Tool
#tool nuget:?package=ScriptHookVDotNetCore&version=1.1.0

ScriptHookV .NET Core

ScriptHookV for .NET Core using NativeAOT technology.

Installation

Download ScriptHookVDotNetCore.zip from release page and extract ScriptHookVDotNetCore.asi to your game root.

A screenshot from the AirStrike example script image

Features

Troubleshooting

  • Issue running with ScriptHookVDotNet
  • Since NativeAOT does not run under the normal .NET runtime, fatal crash is usally harder to debug. Normal CLR exceptions in script thread should be handled by the runtime, but a fatal error such as access violation or memory/GC corruption due to the use of unsafe code will result in a violent crash with few clues to debug. In that case, you should wait for the game and SHVDNC to fininsh loading, attach to the process with Visual Studio's debugger, then load your module through the in-game console, it isn't perfect, but at least gives you some insight of what might be causing the trouble.

How it works?

NativeAOT allow us to compile .NET code to native machine code, so it can be loaded like a regular Win32 module. Each module can have multiple scripts in it, just define a class that inherits from GTA.Script with default constructor. An instance will be automatically created.

Module loading/unloading is done by the C++ core with some tweaks to bypass unloading problems. But first, some entry points is required in the NativeAOT compiled assembly so the core can dispatch events to our module. This is done via the UnmanagedCallersOnly attribute, you can see how those are defined in the BaseScript.

Don't worry! You'll never have to write these yourself. The nuget package comes with a source generator that'll set up everything for you. If you want to define the entrypoints yourself, just mark your methods with the attribute like those in the base script, the generator is smart enough to recognize and skip that part of code.

Getting started

  • Make sure you have .NET 7 SDK installed
  • Create a project targeting .NET 7
  • Install the nuget package
dotnet add package ScriptHookVDotNetCore
  • Define a class that inherits from GTA.Script
  • Subscribe to events like you would in ScriptHookVDotNet, or override OnStart,OnTick and other methods as you need
  • Build the project and copy the dll in native folder of the output directory to GTAV\CoreScripts
  • Voila! Start the game and you'll see your script running.
  • Take a look at the examples to see how you can use the scripting API.

Limitations

As the entire runtime is based on NativeAOT, all limitations apply.

  • Limited use of reflection API
  • No dynamic assembly loading and code execution, executing code on the fly with console is thus impossible
  • Only scripts from the same module are visible to each other, see cross-module comunication
  • Longer compile time and larger binary size
  • No fail-safe script abortion, the game will hang if you block the main thread starting with 1.1, dedicated script thread was reintroduced
  • C# is the only language the source generator supports as for now, support for VB might be added in the future

Cross-module communication

To call functions from other modules, you first need to export functions in the target module:

using System.Runtime.InteropServices;
UnnmanagedCallersOnly(EntryPoint="MyFancyFunction")
public static void MyFancyFunction()
{
  // Do some fancy stuff
}

Then load the module with the NativeLibrary class

using System.Runtime.InteropServices;
public unsafe class MyScript : GTA.Script
{
 protected override void OnStart()
 {
   base.OnStart();
   IntPtr myModu = NativeLibrary.Load("MyModule.dll");
   var func = (delegate* unmanaged<void>)NativeLibrary.GetExport("MyFancyFunction");
   func();
 }
}

Upgrade & migration guide

The code is written in such way that should make the migration from ScriptHookVDotNet pretty easy.

  • Remove the reference from SHVDN
  • Upgrade project TFM to .NET 7
  • Remove WinForms reference as it's not supported by NativeAOT (yet). Keys and KeyEvent are now defined in the GTA namespace.
  • Install the nuget package, then you should be good to go.
  • Some internal APIs were removed, such as SHVDN.ScriptDomain and SHVDN.Console. A new static class GTA.Console was introduced in 1.1, which expose access to the in-game console.
  • If you use the reflection api(or serialization library such as Newtonsoft.json), you'll probaly need to configure trimming options, using the descriptor format xml file is recommended.

Building the project

  • Install .NET 7 SDK, C++ desktop development workload and build tools v143
  • Clone the repo
  • Install vcpkg manually or using scoop.
  • Install dependencies
vcpkg integrate install
vcpkg install minhook:x64-windows-static
vcpkg install boost:x64-windows-static
  • Download and extract ScriptHookV SDK to sdk folder
  • Build the solution with Visual Studio 2022

Credits

ScriptHoookVDotNet and all of its contributors for the amazing work on the scripting API

License & disclaimer

The C++ core and the AOT-specific runtime are written from scratch, while most parts of the scripting API are from ScriptHookVDotNet. For simplicity, all codes are under the same license.

Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net7.0

    • No dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on ScriptHookVDotNetCore:

Package Downloads
NexusKrop.LemonUI.SHVDNC

UI system fork that adds SHVDNCore support.

LemonUI.SHVDNC

UI system for Grand Theft Auto V. This package is for ScriptHookVDotNetCore.

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on ScriptHookVDotNetCore:

Repository Stars
LemonUIbyLemon/LemonUI
LemonUI for .NET (FiveM, RageMP, RagePluginHook and ScriptHookVDotNet 3)
Version Downloads Last updated
1.2.1 745 3/12/2023
1.2.0 208 3/11/2023
1.1.2 238 2/27/2023
1.1.1 239 2/19/2023
1.1.0 251 2/8/2023
1.0.0 260 12/21/2022