// Nightscript | How to NOT make your programming language

POST INFO

Author: Lazzzycat

Date: Oct 29, 2025


RATING

★ 5.0/5

(1 ratings)

← BACK TO BLOG


Nightscript | How to NOT make your programming language featured image

What is NightScript

Nightscript is a dynamically typed programing language made by me, for a game engine named “Nightforge. It was supposed to be a language that would just host-call C++ functions to make game development easier but it ended up developing into a fully fledged language.

How do I use it?

Go to my repo on github and follow the instructions there.

What’s the syntax?

It’s a Lua-inspired syntax with modern conveniences and built-in game development functions.


Basic Syntax

Comments

# This is a single-line comment
# Comments start with # and continue to end of line

Case Sensitivity

  • Keywords are case-insensitive
  • Variable names are case-sensitive
  • Function names are converted to lowercase internally

Statement Terminators

  • Newlines act as statement terminators
  • No semicolons required

Data Types

Nil

Represents absence of a value.

x = nil

Boolean

flag = true
done = false

Integer

48-bit signed integers (range: -(2^47) to 2^47-1)

count = 42
negative = -100

Float

64-bit IEEE-754 floating point numbers

pi = 3.14159
temp = -273.15

String

Immutable text enclosed in single or double quotes

name = "Alice"
message = 'Hello, world!'

# Escape sequences
text = "Line 1\nLine 2\tTabbed"

Supported escape sequences: \n \t \r \\ \" \'

Array

Ordered collection of values (0-indexed)

# Array literal syntax
numbers = {1, 2, 3, 4, 5}
mixed = {42, "hello", true, nil}
empty = {}

# Access elements
first = numbers[0]
last = numbers[4]

# Negative indexing
last_item = numbers[-1]

Table (Dictionary)

Key-value pairs with support for string, number, and boolean keys

# Table literal syntax
person = {
    name: "Alice",
    age: 25,
    active: true
}

# Access values
name = person.name
age = person["age"]

# Mixed key types
data = {
    "string_key": 100,
    42: "number key",
    true: "bool key"
}

Buffer

Mutable string builder for efficient string concatenation

# Created automatically during string concatenation
result = "Hello" + " " + "World"  # Creates buffer internally

Variables

Global Variables

x = 10
name = "Bob"

Local Variables

Declared with local keyword, scoped to function or block

local x = 5
local y, z  # Multiple declarations

function test()
    local result = x + 10
    return result
end

Assignment

x = 42
name = "Alice"

# Table field assignment
person.age = 26
data["key"] = "value"

# Array element assignment
numbers[0] = 100
numbers[-1] = 999  # Last element

Operators

Arithmetic Operators

a + b   # Addition
a - b   # Subtraction
a * b   # Multiplication
a / b   # Division
a % b   # Modulo (remainder)
-a      # Unary negation

Comparison Operators

a == b   # Equal (also: a is b)
a != b   # Not equal
a < b    # Less than
a > b    # Greater than
a <= b   # Less than or equal
a >= b   # Greater than or equal

Logical Operators

a and b  # Logical AND
a or b   # Logical OR
not a    # Logical NOT

String Concatenation

result = "Hello" + " " + "World"
text = "Count: " + 42  # Automatic conversion

Operator Precedence (highest to lowest)

  1. * / %
  2. + -
  3. == != < > <= >=
  4. and
  5. or

Control Flow

If Statements

if condition then
    # code
end

if x > 10 then
    print "Large"
elseif x > 5 then
    print "Medium"
else
    print "Small"
end

While Loops

while condition do
    # code
end

# Example
i = 0
while i < 5 do
    print i
    i = i + 1
end

For Loops

Numeric for loops with inclusive range

for i = start, end do
    # code
end

# Example: prints 1 through 5
for i = 1, 5 do
    print i
end

Break and Continue

for i = 1, 10 do
    if i == 3 then
        continue  # Skip to next iteration
    end
    if i == 7 then
        break  # Exit loop
    end
    print i
end

Functions

Function Declaration

function name(param1, param2)
    # function body
    return result
end

# Example
function add(a, b)
    return a + b
end

result = add(5, 3)  # result = 8

Function Calls

# With parentheses
result = add(5, 3)

# Without parentheses (single argument)
print "Hello"
wait 1

# Multiple arguments without parentheses
wait_ms 1000

Return Statement

function check(x)
    if x < 0 then
        return false
    end
    return true
end

# Implicit nil return if no return statement
function no_return()
    print "Done"
end  # Returns nil

Local Variables in Functions

function calculate(x, y)
    local temp = x * 2
    local result = temp + y
    return result
end

Collections

Array Operations

Creating Arrays

# Literal syntax
arr = {1, 2, 3}

# Using array() function
arr = array()

Array Functions

# Add element to end
add(value, arr)
# Sugar syntax: add value to arr

# Remove element at index
removed = remove(arr, index)
# Sugar syntax: remove arr[index]

# Clear all elements
clear(arr)
# Sugar syntax: clear arr

# Get length
len = length(arr)
# Sugar syntax: length of arr

# Get size (same as length)
sz = size(arr)

Array Indexing

arr = {10, 20, 30, 40}

# Get elements
first = arr[0]
second = arr[1]
last = arr[-1]  # Negative indexing from end

# Set elements
arr[0] = 100
arr[-1] = 999

Table Operations

Creating Tables

# Literal syntax
tbl = {name: "Alice", age: 25}

# Using table() function
tbl = table()

Table Functions

# Set value
tbl.key = value
tbl["key"] = value

# Get value
val = tbl.key
val = tbl["key"]

# Check if key exists
exists = has(tbl, key)
exists = has_key(tbl, key)

# Get all keys
keys = keys(tbl)  # Returns array

# Get all values
vals = values(tbl)  # Returns array

# Get table size
sz = size(tbl)

Field Access

person = {name: "Bob", age: 30}

# Dot notation
name = person.name
person.age = 31

# Bracket notation
name = person["name"]
person["age"] = 31

Standard Library

String Functions

# Split string by delimiter
parts = split(str, delimiter)

# Join array elements with separator
result = join(array, separator)

# Replace occurrences
new_str = replace(str, old, new)

# Get substring
sub = substring(str, start)
sub = substring(str, start, end)

# Case conversion
upper = uppercase(str)
lower = lowercase(str)

# Trim whitespace
trimmed = trim(str)

# String checks
starts = starts_with(str, prefix)
ends = ends_with(str, suffix)
contains = contains(str, substring)

# Find substring position (-1 if not found)
pos = find(str, substring)

# Get character at index
char = char_at(str, index)

# Repeat string
repeated = repeat(str, count)

Type Conversion

# Convert to integer
num = to_int(value)

# Convert to float
num = to_float(value)

# Convert to string
str = to_string(value)

# Convert to boolean
bool = to_bool(value)

# Get type name
type_name = type(value)  # Returns: "nil", "bool", "int", "float", "string", "buffer", "table", "array"

Math Functions

# Basic operations
abs_val = abs(x)
floor_val = floor(x)
ceil_val = ceil(x)
rounded = round(x)

# Powers and roots
result = power(base, exponent)
root = sqrt(x)
root = nroot(value, degree)  # nth root

# Trigonometry (radians)
sin_val = sin(x)
cos_val = cos(x)
tan_val = tan(x)

# Logarithms
ln = log(x)        # Natural log
log_10 = log10(x)  # Base 10 log
log_n = log_n(value, base)  # Custom base

# Random numbers
rand = random()  # 0.0 to 1.0
rand_int = random_int(min, max)  # Inclusive range

# Min/Max
minimum = min(a, b)
maximum = max(a, b)
clamped = clamp(value, min, max)

# Constants
pi_val = pi  # 3.14159...
e_val = e    # 2.71828...

File I/O

# Check if file exists
exists = file_exists(path)

# Read entire file
content = file_read(path)

# Write file (overwrites)
success = file_write(path, content)

# Append to file
success = file_append(path, content)

# Read file as array of lines
lines = file_lines(path)

# Delete file
success = file_delete(path)

# Directory operations
exists = dir_exists(path)
success = dir_create(path)
files = dir_list(path)  # Returns array of filenames

Utility Functions

# Get current time (seconds since epoch)
time = now()

# Wait (blocks execution)
wait(seconds)      # Float seconds
wait_ms(milliseconds)  # Integer milliseconds

# User input
value = input()           # Read line from stdin
value = input("Prompt: ") # With prompt

# Get length/size
len = length(value)  # Works with arrays, strings, buffers
sz = size(value)     # Works with tables, arrays

Example Programs

Hello World

print "Hello, World!"

FizzBuzz

for i = 1, 100 do
    if i % 15 == 0 then
        print "FizzBuzz"
    elseif i % 3 == 0 then
        print "Fizz"
    elseif i % 5 == 0 then
        print "Buzz"
    else
        print i
    end
end

Simple Game Loop

function update_game()
    local health = get_variable("health")
    
    if health <= 0 then
        show_text("Game Over!")
        return false
    end
    
    return true
end

# Main loop
local running = true
while running do
    running = update_game()
    wait(0.016)  # ~60 FPS
end

Data Processing

function process_scores(scores)
    local total = 0
    local count = length(scores)
    
    for i = 0, count - 1 do
        total = total + scores[i]
    end
    
    local average = total / count
    return average
end

scores = {85, 92, 78, 95, 88}
avg = process_scores(scores)
print "Average score:", avg

Appendix: Reserved Keywords

and       array     boolean   break     call
character choice    continue  dialogue  do
else      elseif    end       false     for
function  if        is        local     nil
not       on_enter  or        return    scene
set       then      true      while     table

Note: Keywords are case-insensitive but shown in lowercase by convention.

RATE THIS POST


Login to rate

COMMENTS (0)


Login to comment