question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Since v3.7.0 is coming soon, which contains various performance improvements, compatibility fixes for earlier game versions and a lot of features, it’s definitely a good idea we should start thinking how we should design the v4 API. We could provide more organized/polished APIs before I start thinking about how to create another runtime variant of SHVDN built against .NET 7+ with the use of features only available in .NET Core environment, such as Span.

More ideas will be suggested periodically, so it would be great if you could leave your own idea/feedback below.

Separate AppDomain per script

Since you can share variables between scripts without using dedicated ways in v2 and v3, we can’t use separate AppDomains for scripts built agains v2 or v3 in favor of compatibility (See #1162 for the details).

Struct InputArgument

One of our biggest design mistakes IMO. No need to use class for a single 8 byte value that can be exposed in the public without having too much of issues. For OutputArgument, we could define a implicit operator to convert to InputArgument. We don’t want to push the GC pressure for native calls in future APIs.

Weapon Classes Restructure

We could make brand new weapon or ped inventory classes such as PedInventory, PedWeaponInventory, PedWeaponInventoryItem, PedAmmoInventory, and PedAmmoInventoryItem. There is CWeapon, which manages weapon states such as the current ammo count in clip (not a subclass of CObject btw), so we should not reserve Weapon class for the class for weapon inventory item of a ped IMO.

Remove Auto Model Loading from Methods For Entity Creation

Looks like the not a few script developers casually create entities just with World.Create* (not applies to CreateRandom variants as they use one of loaded ambient models), while you cannot control how you load models by those methods and it is not guaranteed you can create multiple entities with different models at the same frame. Not a few script developers don’t bother to mark models they requested as no longer needed so the game can free the resource for the models, either.

Script developers will care about model resource handling as you would need to in ysc or C++ scripts in the v4 API. More code to write in your scripts, but you may fail to create multiple entities with different models otherwise. SHVDN will return null if fails to create due to the model absent (CREATE_* natives won’t crash even if the model is not loaded like equivalent opcodes do crash the game in that case in 3D Era games, will return zero instead in that case).

Separate TextStyle class

We should separate text drawing or measureing class and text style class just like how RAGENativeUI handles the current text style. Separating them would increase performance as we can avoid redundant native calls for applying text style (you can’t avoid END_TEXT_COMMAND_DISPLAY_TEXT setting the font style values to default ones however).

Dedicated Static Control Class

Simple, the Game class is kinda bloated for control methods. Since the exe has the dedicated class CControl, making a dedicated class for Control would make sense.

Await support for custom Task-ish class (but not for built-in Task in favor of performance)

It would be great if you can use the await syntax, correct? Looks like we shouldn’t use the classic Tasks in SHVDN built against .NET Framework, because Task/Task<T> that are used for the default .NET scheduler suffers way more overhead than in .NET Core/NET 5+. FiveM suffered the slow Tasks and they are introducing the custom Task-ish classes Coroutine/Coroutine<T>. Looks like we should not introduce our custom task scheduler for built-in Task in SHVDN that runs on .NET Framework, either. Maybe it won’t suffer too much of overhead if we use our custom task scheduler for built-in Task in a new SHVDN equivalent runtime built against .NET 7+ though.

For your information, the built-in Tasks allocates less resources such as ExecutionContext in .NET Core 2.1, and there are more improvements for async jobs in .NET 6.

Don’t use more than 1 thread for all .NET scripts (if possible)

I believe there’s no need to use more than one dedicated thread for .NET scripts as long as we can stop executing them when an unhandled exception is thrown or they takes too much time in one loop without a debugger attached. We might need one dedicated thread for more stack space, though. If we use a task scheduler (that execute in a single thread) to process scripts, we’ll end up in losing the ability to abort scripts that takes too long time in one loop without letting them execute one loop, but I wouldn’t care that ability too much since The docs of .NET doesn’t recommend to use Thread.Abort very much and it’s not supported in .NET 5+. RAGE Plugin Hook doesn’t abort plugin execution during a loop for long execution time and instead it terminates the plugin after the loop ends FYI.

The compatibility may break too much if we reduce the number threads to one, but we could do this without worrying about the compatibility for the v4 API before the first official version with v4 API is published.

Misc

  • Don’t force script developers to create duplicate native calls Vehicle.CreatePedOnSeat and Vehicle.CreateRandomPedOnSeat throw ArgumentException is the seat is occupied, but that forces Vehicle.IsSeatFree to be called twice to guarantee the methods will not throw ArgumentException for the seat being occupied.
  • Make ISpatial only have Position Having rotation prevent the NavMeshBlockingObject from having ISpatial. The same case may happen in other classes that represents the game classes or structs.
  • Rename the Enum Bone to PedBoneTag

Tasks

  • Provide separate AppDomain per script
  • Made InputArgument struct instead of class for v4 API
  • Restructure weapon classes for v4 API
  • Remove Auto Model Loading from Methods For Entity Creation for v4 API
  • Create Dedicated Control class for v4 API
  • Support async/await for custom Task-ish classes (no support for built-in Task in favor of performance)

Issue Analytics

  • State:open
  • Created 4 months ago
  • Reactions:6
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
kagikncommented, Jun 30, 2023

Enabled GitHub Discussions for more potential engagement in discussions. crosire wouldn’t have enabled this, but I’m giving it a try. Maybe we can spot design flaws more easily. Discord server for SHVDN? I’ll need more time to set up for that.

0reactions
kagikncommented, Jun 27, 2023

I thought of nuget packages providing interfaces for abstraction for API layers, but I am speculating you’ll end up dealing with versioning issues on interface implementation (such as old and new version resolution). However, maybe we shouldn’t create many custom interfaces in API itself in the first place, since you would think of mocking typically when you use third party libraries IMO. I haven’t used mocks much due to the nature of game modding where you can’t exactly predict how functions embedded in the game works without people with good reverse engineering skill, but using your own mocks is a generally better option to me. I remember when I mocked my own sockets where a Web API is used in production in a tiny web app of mine a year ago, but don’t remember when I used some mocks provided by libraries themselves (not talking about libraries such as Jest).

As for PlayerProvider you provided, it doesn’t seem to me mock does a job for properties too good, since none of them doesn’t execute complex logics afaik. Game.Player.Character only fetches local player index (always zero in SP) and gets the player ped handle (will have to register script entity index, but still not too complex). Player.CanControlCharacter basically reads/writes a value from/to a 4-byte value and that’s it. Player.IsDead will only check if the player ped is not lower than the fatal injury threshold.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Ideas for v4 API · Issue #1227 · scripthookvdotnet ...
Tasks · Provide separate AppDomain per script · Made InputArgument struct instead of class for v4 API · Restructure weapon classes for v4...
Read more >
13 Fun and Powerful APIs and Project Ideas to Try Them With
Table of Contents NASA OpenWeather Prismic Try Prismic for yourself! COVID-19 Cloudmersive Image Recognition aviationstack
Read more >
How To Create An API: Interesting 5 API Ideas - 2023
5 API Ideas to Make Money · 1. Form Submission API (Static Websites) · 2. Meme API · 3. Notes API · 4....
Read more >
API v4: Introduction & Structure
API v4 uses more resource-based routes compared to API v3, which allows a flexible creation and management of the different resources, and an...
Read more >
Hello Analytics Reporting API v4; Java quickstart for ...
This tutorial walks through the steps required to access the Analytics Reporting API v4. Note: The purpose of these quickstart guides is to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found