Installing Nevermore
Installing Nevermore is easy. Once you have Nevermore set up for your project, it's easy to install new packages that are compatible with Nevermore. Generally installing Nevermore can be daunting since it involves a few new pieces of technology. However, this technology is here for a reason, and in general, this installation can be streamlined.
Nevermore should be installable within 2-3 minutes if you follow this guide.
Available installation methods
Fast track: Installing via NPM and the Nevermore CLI (recommended)
If you want to just try out Nevermore, making a new templated game can be the easiest way to do this. For this reason, there is now a Nevermore CLI that can be used. A CLI stands for command line interface.
We can then use the npm command line to generate a working directory.
- Open a terminal, like Command Prompt, PowerShell, or Windows Terminal (recommended).
- Change directory to the location you would like to initialize and create files. You can do this by typing
mkdir MyGame
and thencd MyGame
. You can usedir
orls
to list out the current directory. - Run the command
npx nevermore init
to generate a new game. - Run the command
npm install @quenty/maid
or whatever package you want.
You can globally install the nevermore CLI by running the following command in the terminal.
npm install -g @quenty/nevermore-cli
This will install the current version of Maid and all dependencies into the node_modules
folder. To upgrade you will want to run npm upgrade
You should ignore the node_modules
folder in your source control system.
What is NPM and why are we using it?
npm is a package manager. Nevermore uses npm to manage package versions and install transient dependencies. A transient dependency is a dependency of a dependency (for example, Blend depends upon Maid.
How do I install additional packages?
The default installation comes with very few packages. This is normal. You can see which packages are installed by looking at the package.json
file in a text editor. To install additional packages, simply run the following command in a terminal:
npm install @quenty/servicebag
This will install the packages into the node_modules
folder.
What is package-lock.json?
When you run npm install
you end up with a package-lock.json
. You should commit this to source control. See NPM's documentation for details.
Installing via NPM into an existing game via Rojo
Nevermore is designed to work with games with existing architecture. If you're using Knit, a multi-script architecture, a custom framework or a single-script architecture, Nevermore provides a lot of utility modules that are useful in any of these scenarios. Nevermore's latest version also supports multiple copies of Nevermore running at once as long as bootstrapping is carefully managed. This can allow you to develop your game in an isolated way, or introduce Nevermore dependencies slowly as you need them.
If you want to install this into an existing game follow these instructions:
Ensure that you have Node.js v14+ installed on your computer.
Ensure that you have rojo v7+ installed on your computer.
- Run
npm init
to create apackage.json
- Install
npm install @quenty/loader
- Sync in the
node_modules
folder using Rojo. A common file format is something like this:
This is an example of a Rojo project.json
file that is generated by the Nevermore CLI:
{
"name": "MyGame",
"globIgnorePaths": [ "**/.package-lock.json" ],
"tree": {
"$className": "DataModel",
"ServerScriptService": {
"MyGame": {
"$className": "Folder",
"game": {
"$path": "src/modules"
},
"node_modules": {
"$path": "node_modules"
}
},
"GameNameScripts": {
"$path": "src/scripts/Server"
}
},
"StarterPlayer": {
"StarterPlayerScripts": {
"GameNameScripts": {
"$path": "src/scripts/Client"
}
}
}
}
}
You can put the MyGame
folder wherever you want, but the recommended location is ServerScriptService
.
In your main script you will need to "bootstrap" the components such that script.Parent.loader
is defined. To do this the following snippet will work, and is generated by the Nevermore CLI as ServerMain.server.lua
:
local ServerScriptService = game:GetService("ServerScriptService")
local loader = ServerScriptService.MyGame:FindFirstChild("LoaderUtils", true).Parent
local require = require(loader).bootstrapGame(ServerScriptService.MyGame)
This will create the following folders in ReplicatedStorage when the game loads:
- MyGame
- game
- Client
- Shared
- Server
- node_modules
- game
You might notice that the Server folder is also cloned to the game
folder in ReplicatedStorage. This is an intentional optimization that only happens in Studio.
From here, every exported package will exist in the node_modules
folder, populated only by modules that need to be replicated to that context.
To access the exported packages on the client, you perform the same bootstrap operation on the new replicated location (also generated, as ClientMain.client.lua
):
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local loader = ReplicatedStorage:WaitForChild("MyGame"):WaitForChild("loader")
local require = require(loader).bootstrapGame(loader.Parent)
Assuming you've changed nothing, the path to the replicated modules should be the same as the one used on the server, just indexed under ReplicatedStorage instead.
Manually installing via NPM for a stand-alone module.
If you want to use Nevermore for more stand-alone or reusable scenarios (where you can't assume that a packages folder will be reused, you can manually bootstrap the components using the loader system.
Ensure that you have Node.js v14+ installed on your computer.
Ensure that you have rojo v7+ installed on your computer.
- Run
npm init
- Run
npm install @quenty/loader
and whatever packages you want.
In your bootstrapping code you can write something like this for your server code.
Notice we manually transform and parent our returned loader components. this allows us to bootstrap the components. We then parent the client component into ReplicatedFirst with dependencies.
--[[
@class ServerMain
]]
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local client, server, shared = require(script:FindFirstChild("LoaderUtils", true)).toWallyFormat(script.src, false)
server.Name = "_SoftShutdownServerPackages"
server.Parent = script
client.Name = "_SoftShutdownClientPackages"
client.Parent = ReplicatedFirst
shared.Name = "_SoftShutdownSharedPackages"
shared.Parent = ReplicatedFirst
local clientScript = script.ClientScript
clientScript.Name = "QuentySoftShutdownClientScript"
clientScript:Clone().Parent = ReplicatedFirst
local serviceBag = require(server.ServiceBag).new()
serviceBag:GetService(require(server.SoftShutdownService))
serviceBag:Init()
serviceBag:Start()
The client code is as follows.
--[[
@class ClientMain
]]
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local packages = ReplicatedFirst:WaitForChild("_SoftShutdownClientPackages")
local SoftShutdownServiceClient = require(packages.SoftShutdownServiceClient)
local serviceBag = require(packages.ServiceBag).new()
serviceBag:GetService(SoftShutdownServiceClient)
serviceBag:Init()
serviceBag:Start()
Manually installing with NPM for Plugins
You can use the Nevermore CLI to generate a project structure for a new plugin.
Ensure that you have Node.js v14+ installed on your computer.
Ensure that you have rojo v7+ installed on your computer.
npx nevermore init-plugin