ASKA
You are viewing a potentially older version of this package. View Latest Version
Install

Details

Date Uploaded
3 months ago
Downloads
419
Size
189KB
Dependency string
OrdinaryJoe-CartPort-1.0.0

CartPort

BepInEx 6 IL2CPP plugin for ASKA that lists all loaded carts and sleds and teleports the selected one to a spot in front of your camera — including carts that have bugged out (e.g. floating in the sky over the ocean) where normal Fusion state authority won't let you move them.

Works in single-player, player-hosted co-op, and dedicated-server co-op (Fusion Shared mode).

Install

  1. Install BepInEx 6 IL2CPP into your ASKA install, launch the game once so BepInEx\interop\ contains a populated Assembly-CSharp.dll (tens of MB, not 0 bytes).
  2. Drop CartPort.dll into ASKA\BepInEx\plugins\.
  3. For dedicated-server co-op, drop the same DLL into ASKA Dedicated Server\BepInEx\plugins\.
  4. Launch the game once to generate the config at BepInEx\config\com.cartport.aska.cfg.

Usage

  • F9 — toggle cart/sled list (rebindable in config).
  • Summon here — teleport the selected cart/sled to ~4m in front of the camera.
  • Force Mode (toolbar toggle) — persistently re-applies the teleport every frame for ~10s. Use for orphaned carts where Fusion sync keeps snapping the cart back.
  • Esc — close menu.

The list shows [Auth] / [No Auth] per cart based on local Fusion state authority, and [Forcing...] while Force Mode is active on that cart.

How it works

The interesting problem is Fusion networking in Shared mode: each NetworkObject (cart) has its own state-authority holder, and that holder is not necessarily the dedicated server process — in Shared mode a peer (often the Shared Master Client) holds authority. A naïve SendReliableDataToServer call routes to the Shared Master Client, which may not be the peer Fusion elected for this specific cart.

Summon path (in order)

  1. Local-authority shortcut — if netObj.HasStateAuthority is already true on this peer, apply the teleport directly (no relay).
  2. Local peer is server/Shared-master relay — apply via ApplySummonOnAuthority immediately.
  3. Targeted authority relay — query netObj.StateAuthority for the actual PlayerRef holding authority, and SendReliableDataToPlayer(stateAuthorityPlayer, payload) directly to that peer. This is the fix that retrieves "orphaned" carts.
  4. Server/host relay fallback — if targeted send fails, fall back to SendReliableDataToServer + local prediction.

The receiving peer parses the CPRT payload (4-byte magic + NetworkId + pos + rot = 37 bytes), looks up the NetworkObject, and calls CartSummon.ApplySummonOnAuthorityImmediate. A dedup set prevents double-apply when multiple reliable hooks fire for the same frame.

Inbound reception (multiple hooks, best-effort)

Different game builds deliver Fusion ReliableData through different paths, so CartPort hooks several:

  • NetworkRunner.Fusion_Simulation_ICallbacks_OnReliableData (Harmony postfix — OFF by default, IL2CPP+Harmony+Fusion can hard-crash on some builds).
  • Simulation.Fusion_Sockets_INetPeerGroupCallbacks_OnReliableData (Harmony postfix on dedicated).
  • Assembly-CSharp game OnReliableDataReceived overloads (Harmony postfix — only when PatchAssemblyCSharpReliableCallbacks=true).
  • INetworkRunnerCallbacks registered via NetworkRunner.AddCallbacks (injected or subclass path, works even when Harmony hooks don't).

Bugged-cart recovery (CartPortServerSummonQueue + CartPortPersistentSummonOverride)

When running on a host that doesn't currently hold state authority for a cart:

  1. RequestStateAuthority() (+ AllowStateAuthorityOverride = true) is called and retried every N frames.
  2. If authority arrives before ServerSummonAuthorityWaitFrames (~10s), the summon applies through the normal path.
  3. Otherwise, a Unity-physics fallback (BruteForceApplyTransform) writes both the Fusion pose and raw Transform + wakes rigidbodies.
  4. Because Fusion sync from the real authority holder keeps overwriting the position, CartPortPersistentSummonOverride re-applies the transform every frame for ForceSummonPersistDurationFrames (600 ≈ 10s @ 60fps) until the cart is within ~3m of the target (arrival), then auto-cancels.

Other components

  • CartRegistry — finds CartStructure + any Structure whose IL2CPP type name contains Sled.
  • CartSummon — raycast-to-ground placement, authority-aware move application.
  • CartPortGameplayInputSuspend — disables Unity Input System Player/Look/Move maps while the menu is open so the mouse doesn't rotate the camera.
  • CartPortInboundFusionCallbacks(Injected|Subclass) — IL2CPP-registered INetworkRunnerCallbacks wrapper. Inject path is tried first; subclass path used when ClassInjector reports the interface is exposed as an IL2CPP class.

Build

dotnet restore
dotnet build -c Release

The post-build step auto-copies CartPort.dll to ASKA\BepInEx\plugins\ and ASKA Dedicated Server\BepInEx\plugins\ if the paths resolve. Close the game and server process first to avoid file locks.

The project finds game assemblies in this order:

  1. CartPort\GamePaths.props next to CartPort.csproj (copy from GamePaths.props.example for manual override).
  2. Environment variable ASKA_BEPINEX pointing to the BepInEx folder containing interop and unity-libs:
    setx ASKA_BEPINEX "D:\SteamLibrary\steamapps\common\ASKA\BepInEx"
    
  3. Relative paths when the repo sits under ASKA\BepInEx\CartPort\.
  4. Steam auto-discovery via tools\Discover-AskaBepInEx.ps1 (reads libraryfolders.vdf + appmanifest_1898300.acf). Disable with MSBuild property CartPortSkipSteamDiscovery=true.

After major ASKA updates, delete BepInEx\interop and launch the game once so interop regenerates before rebuilding.

Config reference (com.cartport.aska.cfg)

Key settings (most defaults are fine):

  • General.ToggleMenuKey — menu toggle key (default F9).
  • General.SuspendGameplayInputWhileMenuOpen — disable Player/Look/Move while menu open.
  • Summon.ForwardDistance — horizontal offset in front of camera (default 4m).
  • Summon.GroundRaycastStartHeight — raycast start height (default 120m).
  • Summon.SummonVerticalOffset — extra lift off ground hit (default 0.35m).
  • Summon.DeferSummonApply — defer one frame to dodge villager-equipment cleanup races.
  • Network.ServerAuthoritativeSummon — relay summons to the authority holder (recommended for multiplayer).
  • Network.RequestFusionStateAuthority / SummonWithoutAuthorityFallback — authority request + fallback behavior.
  • Network.ForceSummonPersistDurationFrames — Force Mode / server-queue fallback persistence (default 600).
  • Network.ForceSummonServerQueueFallbackPersist — keep re-applying after server queue authority-wait timeout.
  • Network.EnableHarmonyFusionReliablePatches — NetworkRunner reliable-data postfix. OFF by default (can hard-crash IL2CPP on some builds — enable only after verifying the game starts cleanly).
  • Network.EnableHarmonySimulationSocketPatch — Simulation socket postfix for dedicated. OFF by default; enable NetworkRunner hook first.
  • Network.PatchAssemblyCSharpReliableCallbacks — Harmony-patch game-side Fusion callbacks. Sometimes required on dedicated; set false if startup crashes.
  • Network.RegisterFusionInboundRunnerCallbacks — register INetworkRunnerCallbacks via AddCallbacks.
  • Debug.VerboseLogging — extra BepInEx log lines. Default false.

License / credits

Plugin for the game ASKA by Sand Sailor Studio. Not affiliated with the developer. Uses BepInEx, HarmonyX, Il2CppInterop, and Fusion (Photon).

Thunderstore development is made possible with ads. Please consider making an exception to your adblock.