You are viewing a potentially older version of this package. View all versions.
Cray-ForeverGolfCart-0.3.2 icon

ForeverGolfCart

Hold Q to spawn a pastel-tinted golf cart you immediately drive. Empties after exit, so you can summon a fresh cart whenever you need one.

By Cray
Date uploaded 3 months ago
Version 0.3.2
Download link Cray-ForeverGolfCart-0.3.2.zip
Downloads 194
Dependency string Cray-ForeverGolfCart-0.3.2

This mod requires the following mods to function

BepInEx-BepInExPack-5.4.2305 icon
BepInEx-BepInExPack

BepInEx pack for Mono Unity games. Preconfigured and ready to use.

Preferred version: 5.4.2305

README

ForeverGolfCart

Hold Q to summon a golf cart — every player with the mod can do this on demand instead of hunting for the rare cart pickup. The cart appears at your feet, you're seated as the driver automatically, and the moment you step out of an empty cart it despawns so the world doesn't fill up with abandoned carts.

The summoned cart is tinted with a random pastel hue so you can tell it's not a vanilla spawn at a glance.

Configuration

BepInEx/config/sbg.forevergolfcart.cfg:

  • Spawn.HotkeyHoldDuration — seconds you have to hold the hotkey before the cart spawns (default 0.4).
  • Spawn.SummonKeyKeyCode for the summon button (default Q).
  • Visuals.PastelTintEnabled — toggle the tint (default true).

Limitations / known gaps in v0.1

  • True rebinding through the in-game controls menu isn't wired in — KeyCode config only.
  • Pastel tint is computed locally at spawn time; modded clients will see slightly different hues unless someone wires up a synced color message.

Build / deploy / release

dotnet build -c Release
pwsh tools/package.ps1
gh release create vX.Y.Z artifacts/Cray-ForeverGolfCart-<ver>.zip --notes-file CHANGELOG.md

CHANGELOG

Changelog

v0.3.2

  • Fix joining clients getting kicked because of a stale driver-seat reservation on summoned carts. 0.3.0/0.3.1 called ServerReserveDriverSeatPreNetworkSpawn(target) to set the cart's driverSeatReserver SyncVar before NetworkServer.Spawn. Vanilla normally clears that reservation through CmdInformDrivingSeatReservationReceived once the player walks up to the placed cart and enters; our ServerEnter shortcut bypassed the Cmd, so the reserver stayed permanently set on every summoned cart. When a fresh player joined the lobby, initial-state sync of the cart fired OnDriverSeatReserverChanged(null, hostPlayer) before their own GameManager.LocalPlayerInfo was available. The hook compares previousReserver == GameManager.LocalPlayerInfo (null == null → true), enters the branch, and NREs on LocalPlayerInventory.ItemUseCancelled. Mirror catches the exception but the read pointer is now off → "GolfCartInfo OnDeserialize size mismatch" → client gets disconnected on rejoin. Skipping the reservation flow entirely (the cart goes straight from InstantiateNetworkServer.SpawnServerEnter) keeps the SyncVar at null so joining clients never see a non-default value, and ServerTryAssignPassengerToSeat already handles authority assignment when the player takes seat 0.

v0.3.1

  • Fix the host crashing to lobby on summon. v0.3.0 hooked NetworkClient.OnConnectedEvent += OnClientConnected in Plugin.Awake to register the custom ForeverGolfCartTintMsg handler. But Mirror's NetworkManager.Awake runs after plugin Awake and assigns the same delegate (OnConnectedEvent = OnClientConnectInternal), silently wiping the subscription. So when the host's tint broadcast looped back through its own local-loopback connection, the client side had no handler for the message id → Mirror logged "Unknown message id: 14576" → "NetworkClient: failed to unpack and invoke message. Disconnecting." → the player got bounced to main menu. v0.3.1 polls in Update instead and re-registers handlers whenever NetworkServer/NetworkClient becomes active.
  • Actually install the OnStartClient postfix. Same Harmony placement bug we hit in InAirItems / DrivingRangeItems: [HarmonyPatch] was on the postfix method instead of a type, so PatchAll() skipped it. The late-arrival tint path that fires when the tint message lands before the cart spawn replicates was dead code in 0.3.0. Wrapped in a nested class so it actually runs.

v0.3.0

  • Fix the pastel tint not actually applying. v0.2.0 gated the OnStartClient hook behind ServerTrackedCarts, which the host populated AFTER NetworkServer.Spawn already triggered the host's own client init — so the gate's first run always missed. Now the server applies the tint directly post-spawn (with a 6-frame re-apply to defeat cosmetic overlays), then broadcasts a ForeverGolfCartTintMsg{netId} to every client. Clients add the netId to a local set and apply on receipt or when OnStartClient first sees the cart, whichever lands first.
  • Switched tint application from MaterialPropertyBlock to direct material-instance edits (r.materials[i].color *= tint). MaterialPropertyBlock was being overwritten by the game's cosmetic overlays on seat-entry; instance edits stick.

v0.2.0

  • Fix the cart not actually appearing when Q is held. The 0.1.0 server flow only reserved the driver seat and never asked the player to enter, so vanilla's ServerReserveDriverSeatPreNetworkSpawn 5 s "unused cart destroy" timer cleaned the cart up before it spawned visibly. Now invokes GolfCartInfo.ServerEnter(target) directly via reflection right after NetworkServer.Spawn, so the requesting player is seated as the driver immediately.
  • Add Diagnostics.VerboseLogging (default false) for remote diagnosis of summon failures.

v0.1.0

  • Initial release. Hold Q (configurable) to summon a pastel-tinted cart with auto driver entry. Empty carts despawn on exit.