Your first Nova script¶
This is a five-minute script. It assumes you can open a place in the editor on https://www.novalabs.top. If you cannot open the editor, check Create on Nova first.
1. Open a place¶
Create an empty place or open a small test place. You do not need a full game for this; a baseplate is enough.
2. Add a server script¶
In the Explorer:
- Insert a
ScriptintoServerScriptService. - Rename it
HelloNova. - Paste this:
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
print("joined:", player.Name, player.UserId)
player.CharacterAdded:Connect(function(character)
local humanoid = character:WaitForChild("Humanoid")
humanoid.WalkSpeed = 20
humanoid.JumpPower = 60
humanoid.Died:Connect(function()
print("died:", player.Name)
end)
end)
end)
- Press Play. The Output window should show the player joining, and the character should move a little faster.
This is the same script you would write on Roblox. Nothing Nova-specific is happening yet.
3. Add a client script¶
Insert a LocalScript into StarterPlayerScripts and paste:
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local screen = Instance.new("ScreenGui")
screen.Name = "HelloGui"
screen.ResetOnSpawn = false
screen.Parent = player:WaitForChild("PlayerGui")
local label = Instance.new("TextLabel")
label.Size = UDim2.new(0, 260, 0, 48)
label.Position = UDim2.new(0, 24, 0, 24)
label.BackgroundColor3 = Color3.fromRGB(15, 23, 42)
label.BackgroundTransparency = 0.15
label.TextColor3 = Color3.fromRGB(230, 240, 255)
label.Font = Enum.Font.SourceSansBold
label.TextSize = 20
label.Text = "Hello, " .. player.Name
label.Parent = screen
Press Play again. The label should appear in the corner. This is a normal client-side GUI; no layout classes are involved.
4. Understand the boundary¶
Scriptruns on the server. It owns the authoritative state.LocalScriptruns on the client. It sees replicated state and the local player's GUI.- Use
RemoteEventto send a request from the client to the server. - Validate everything on the server.
A minimal remote:
-- ReplicatedStorage/Remotes/SayHello (RemoteEvent)
local remote = game:GetService("ReplicatedStorage")
:WaitForChild("Remotes")
:WaitForChild("SayHello")
-- Server
remote.OnServerEvent:Connect(function(player, message)
if typeof(message) ~= "string" or #message > 80 then
return
end
print(player.Name, "says", message)
end)
-- Client
remote:FireServer("hello from the client")
5. Where to go next¶
- Nova for Roblox developers — what changed and what did not.
- Port a script — rewrite a modern script that uses raycasting.
- Build a UI without UIListLayout — the most common porting task.
- API reference — look up a class before you use it.
Common first-script errors¶
| Error | Cause |
|---|---|
X is not a valid member of Y |
The member is missing in Nova. Check the class page. |
Insufficient permissions |
You called a plugin/CoreScript-only API. |
Attempt to index nil |
The instance has not replicated yet; use WaitForChild. |
| Nothing appears | The script is a LocalScript in a server-only container, or the GUI parent is wrong. |
More: FAQ.