Hi Chris,
before I commit to a prototype, I'd love your judgement on an architecture. I'm aware AC isn't intended for multiplayer — I'm not asking you to support it, just to point out where my plan collides with AC's internals.
The goal: a 2–4 player co-op point-and-click that is also fully playable solo. The game is designed around N player characters: solo players switch between them (classic Zak McKracken style, using AC's native player-switching), while in co-op each character is controlled by a friend over the network (FishNet).
The planned architecture — AC only ever runs "fully" on the host:
The host runs AC normally and is the single source of truth.
A bridge layer subscribes to EventManager events (OnVariableChange, OnInventoryAdd/Remove, OnObjectiveUpdate, OnBeginActionList, OnHotspotInteract) and mirrors state into networked containers (SyncVars/SyncLists).
Remote clients never execute interactions themselves — they send "player X wants to use hotspot Y" intents; the host runs the interaction via Hotspot.RunInteraction, and resulting state replicates back.
On clients, replicated values are written back via the public APIs (GlobalVariables.Set*, inventory scripting) so local UI stays consistent.
Remote players are represented as inactive Players/NPC-like characters (the 1.71 "inactive Players behave like NPCs" behaviour), position-synced externally.
Cutscenes: gameplay-blocking cutscenes only trigger at "gather points" where all players are present, so everyone sees them simultaneously; small dialogues stay local to the triggering player.
My specific questions:
Cutscenes/GameState: When a cutscene or Conversation runs, AC changes the global game state (pausing gameplay, camera control). On a client, I'd want to suppress that entirely and only mirror the visible result. Is there a supported way to run a "headless" AC instance that never enters cutscene state — or would you rather recommend clients not running ActionLists at all and being pure presentation?
Hotspot gating: OnHotspotInteract appears to fire before the ActionList runs, but there's no cancel API. Is the intended pattern to disable AC's default interaction handling and re-trigger via Hotspot.RunInteraction from script, so I can insert a network round-trip in between?
Player-switching as remote representation: Any known pitfalls in driving inactive Players' positions/animations externally every frame (they're puppets of a network sync, not AC pathfinding)?
Save/late-join: Would you consider PlayerData + OnBeforeSaving/OnFinishLoading a sane basis for syncing a late-joining client to the host's current state, or is a full custom snapshot the safer route?
Any "this specific subsystem will fight you" warnings are exactly what I'm hoping for. Thanks for the fantastic asset — and for reading this far!
It looks like you're new here. If you want to get involved, click one of these buttons!
Comments
Interesting stuff!
You can shut down AC entirely with the TurnOffAC function, but otherwise the StateHandler will always enter the Cutscene state if gameplay-blocking ActionLists are running. However, if the Client avoids ActionLists leaving the Host to run them, it is possible to manually enter the Cutscene state with EnforceCutsceneMode.
OnHotspotInteract runs before both the Interaction ActionList (which has its own event as well) and the movement of the Player to the Hotspot. The StopMovingToHotspot function can be used to cancel a pending movement / interaction sequence.
I'd expect that's probably the most reliable way to do it. If you set the character's Motion control to Manual then AC won't fight for control over their Transform values. For animation, you may need to similarly use a custom/empty animation engine and update the sprite manually.
Probably a good middle ground to have a custom Remember script that lets you save custom class data. If the game is only ever showing the Host player's scene, you can attach it to the Host player prefab.
thank you, that helped alot.