Skip to content

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:

  1. Insert a Script into ServerScriptService.
  2. Rename it HelloNova.
  3. 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)
  1. 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

  • Script runs on the server. It owns the authoritative state.
  • LocalScript runs on the client. It sees replicated state and the local player's GUI.
  • Use RemoteEvent to 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

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.