Headless Client/Server
Headless Clients are versions of Neos that lack a graphical user interface, allowing them to run efficiently in scenarios where rendering is not needed (such as when used as a server). Neos Pro users and all Patrons at the level Gunter and up have access to Headless Client builds. Check the pins in the #headless-client channel in the Neos Discord server, or contact a Neos administrator to get your access code.
Installation
Method 1
If using Steam:
- Go to Steam, open Neos Properties, and go to the Betas tab
- Use your code to activate the beta branch
- Switch to the headless-client branch
Method 2
If using SteamCMD:
- Paste the following command into SteamCMD:
app_update 740250 -beta headless-client -betapassword your_code
Configuration
After Steam finishes the update, open the installation folder. You can find the headless client in the "Headless Client" subfolder. You can use the Config/DefaultConfig.json file to configure a startup world or to have the server login into an account (please don't use your main Neos account). Here's a sample configuration you can use and modify:
{ "comment": "", "tickRate": 60.0, "maxConcurrentAssetTransfers": 4, "usernameOverride": null, "loginCredential": null, "loginPassword": null, "startWorlds": [ { "isEnabled": true, "sessionName": "", "customSessionId": null, "description": null, "maxUsers": 12, "accessLevel": "Anyone", "hideFromPublicListing": false, "tags": [ "test1", ], "mobileFriendly": false, "loadWorldURL": "", "saveAsOwner": null, "loadWorldPresetName": null, "forcePort": null, "keepOriginalRoles": false, "defaultUserRoles": { "User": "Admin" }, "autoInviteUsernames": null, "parentSessionIds": [ "" ], "autoInviteMessage": null, "autoRecover": true, "idleRestartInterval": -1.0, "forcedRestartInterval": -1.0, "saveOnExit": false, "autosaveInterval": -1.0, "awayKickMinutes": -1.0, "autoSleep": true } ], "dataFolder": null, "cacheFolder": null, "allowedUrlHosts": null, "autoSpawnItems": null, "metamovieRoles": null }
- The
loadWorldPresetName
attribute loads a world based on Neos world templates. The available templates are "SpaceWorld", "Basic Empty", "GridSpace", "Microworld", "Testing Scaling", "ScratchSpace", "ScratchSpace (mobile)", "Instancing Test", "Physical Locomotion Test" and "UIX Test". - The
accessLevel
names in the headless differ slightly from the in game selections.- "Private": Private (Invite Only)
- "LAN": LAN Connections Only
- "Friends": Contacts
- "FriendsOfFriends": Contacts+
- "RegisteredUsers": Registered Users
- "Anyone": Anyone
- The
"defaultUserRoles"
attribute defines the user and access level for the world. The format is "USERNAME": "ROLE". The roles are "Admin", "Builder", "Moderator", "Guest", and "Spectator".
- The
"loginCredential"
attribute defines the Neos account to run the server with. It is recommended to create a separate account to run the server as if you wish to join your own server - it is not possible to join a server running with the same account on the client and server.
- The
"customSessionId"
attribute accepts the following formatting:S-[userID]:[anything]
where[UserID]
is the userID of the account running the headless session, and[anything]
is whatever you want to put
- Utilized for nested sessions,
"parentSessionIds"
is recommended to manually configure a custom session ID for parent worlds using the note above as without this, session IDs are dynamic. This allows for nested sessions that do not appear in the public headless server listing.
- Run the executable to start the client.
Configuration for a Local or Cloud World Save
To configure a Headless client to act as a local storage server, set your world to "saveAsOwner" : "LocalMachine"
(will be replaced after first execution with it's unique startWorldURL
) as well as "saveOnExit" : true
and your desired autoSaveInterval
.
If you want the world data saved to the cloud (a valid dedicated Neos account will be needed), set "saveAsOwner" : "CloudUser"
.
Please use the shutdown
command to allow the server to save any unsaved changes on shutdown.
Config file example:
{ "tickRate": 60.0, "usernameOverride": null, "loginCredential": null, "loginPassword": null, "startWorlds": [ { "sessionName": "My World 1", "description": null, "maxUsers": 32, "accessLevel": "LAN", "tags": null, "mobileFriendly": false, "loadWorldPresetName": "BasicEmpty", "saveAsOwner" : "LocalMachine", "autoRecover": true, "saveOnExit" : true, "autoSaveInterval" : 240, "forcedRestartInterval": -1.0 } ], "dataFolder": null, "cacheFolder": null }
Configration using Cloud Variables
For more details for Cloud Variables, see Cloud Variables.
- The
roleCloudVariable
allows auto-assigning a role based on a cloud variable.- This lets you define a cloud variable and assign value to users to determine their role in given world.
- The variable needs to be of type string. The value you assign equals the name of the role you want to grant to given user.
- It is STRONGLY recommended to make sure you're using cloud variable that you can write into on behalf of other users (
definition_owner
), otherwise users might be able to assign themselves a high permission role. - If no value is set for given user, the usual method to determine default role is used
- The
allowUserCloudVariable
allows using cloud variable to always allow user into a session.- The cloud variable needs to be of type bool and set to true for given user.
- This is equivalent of the user being sent an invite - they can join regardless of MaxUsers limit and even if the session is set to Private (they need to obtain).
- Same recommendations as above apply, please make sure you use the right cloud variables that you have proper control over.
- The
denyUserCloudVariable
allows denying join access to users via a cloud variable.- This functions similarly to
allowUserCloudVariable
, except when the value for given user is true, they will be denied access - This always takes precedence over other variables
- This functions similarly to
- The
requiredUserJoinCloudVariable
to world startup configuration, which requires a cloud variable to be set to true for given user so they can join- You can set a custom deny message via requiredUserJoinCloudVariableDenyMessage
- If the variable isn't set to true for given user, they won't be allowed access
- Setting the variable to true won't automatically grant access (unlike
allowUserCloudVariable
) and will still need to pass other rules - public access, session user limit and so on allowUserCloudVariable
takes precedence over this one, allowing to always allow given user access- This variable is useful for controlling access to a session, without bypassing the session max user limit and providing a custom message
Commands
See Headless Client Commands for a list of commands.