Как начать

Это руководство поможет создать ваш первый скрипт используя интерфейс скриптов OpenNox на языке Go.

Первые шаги

Заметка

Удостовертесь что у вас установлен OpenNox. Оригинальный Nox, Reloaded или иная версия не будут работать!

Чтобы создать ваш первый скрипт, скопируйте существующую папку одной из карт, либо создайте новую карту в редакторе. Если карта была скопирована, удостоверьтесь что файл карты внутри папки тоже был переименован.

Затем, создайте следующие файлы в папке карты:

script.go (любое имя с *.go будет работать):

package <mapname>
	
func init() {
	println("hello!")
}

go.mod:

module <mapname>

go 1.22

К примеру, оригинальная карта:

maps/
  estate/
    estate.map
    estate.nxz

И скопированная, включая новые файлы:

maps/
  example/
    example.map
    example.nxz
    script.go
    go.mod

В файле script.go:

package example

func init() {
	println("hello!")
}

В файле go.mod:

module example

go 1.22

Готово! Теперь запустите карту в OpenNox, откройте консоль и вы должны увидеть там сообщение hello!.

Информация

Вам не нужно устанавливать Go или какой-либо другой компилятор чтобы писать скрипты для OpenNox.

Тем не менее, правильная настройка Go поможет включить поддержку IDE, проверку типов в скриптах, автодополнение и т.д. По этому, мы крайне советуем это сделать.

Полная настройка

Для полной настройки нам понадобиться:

  1. Go 1.20+ (для проверки типов, работы с зависимостями)
  2. Git (для Windows)
  3. GoPls (для интеграции с VSCode)
  4. VSCode (сама IDE)
  5. Расширение Go для VSCode (включает документацию для gopls)

Когда все установлено, мы можем создать новый проект. Для это нужно:

  1. Скопировать существующую карту или создать новую через редактор карт.
  2. Открыть папку карты через VSCode.
  3. Открыть терминал (Terminal -> New Terminal в верхнем меню VSCode).
  4. go mod init <mapname> (например go mod init example). Это создаст готовый go.mod.
  5. Создать новый Go файл, например script.go с package <mapname> (например package example).
  6. Добавить какой-либо код в этот файл, например func init() { println("hello!") }.
  7. Сохранить все файлы, запустить OpenNox и проверить карту.

Скриптовые движки

Существует несколько доступных версий скриптовых движков (полный список здесь), к примеру:

Скриптовые движки работают следующим образом: обычно один из движков явлется остновным (NS4 в данном случае), который предоставляет весь функционал доступный в OpenNox. Остальные движки являются лишь слоем поверх него. Тем не менее эти слои важны! Они предоставляют уже знакомый интерфейс для разработчиков карт (например NS3 или EUD).

Благодаря этому, полность безопастно использовать несколько движков в одной карте. Если есть опыт в NS3 - лучше начать с него. Если вы только начинаете разбираться с Nox скриптами - выбирайте последний NS движек (NS4).

Ссылки выше ссылаются на документацию языка Go для каждого из движков - это основной источник документации
по функциям и классам доступным в каждом из движков. Это руководство даст лишь базовое знание про настройку скриптов.

Использование движков

Тогда, как использовать эти движки?

Если вы пропустили полную настройку, то для это нужно лишь добавить import в Go файл и использовать его:

package example

import (
    "fmt"
    
    "github.com/noxworld-dev/noxscript/ns/v4"
)

func OnFrame() {
	fmt.Println("players:", len(ns.Players()))
}

Несколько моментов которые стоит отметить:

  • Мы подключили стандартный пакет Go fmt используемы для вывода в консоль. Вы можете свободно использовать и другие стандартные Go пакеты.
  • Мы подключили NS через github.com/.../ns/v4, но мы ссылаемся на него как ns.* (например в ns.Players). Суффикс v4 является версией пакета.
  • Функция OnFrame будет вызываться OpenNox каждый кадр (или “тик сервера”). Так что мы должны увидеть множество сообщений в консоли!

Это все что нужно знать чтобы использовать один из движков. Но что если мы хотим использовать и NS3 и NS4, к примеру?

Подключение обоих пакетов не сработает - ведь у них одинаковое имя. Так что мы присвоим псевдоним для каждой версии:

package example

import (
    "fmt"
    
    ns3 "github.com/noxworld-dev/noxscript/ns/v3"
    ns4 "github.com/noxworld-dev/noxscript/ns/v4"
)

func OnFrame() {
	fmt.Println("players:", len(ns4.Players()))
	fmt.Println("talking:", ns3.IsTalking())
}

Если вы привыкли к NoxScript 3 и не хотите указывать ns. или ns3. повсюду, можно так же указать псевдоним как точку:

package example

import (
    "fmt"
    
    . "github.com/noxworld-dev/noxscript/ns/v3"
    ns4 "github.com/noxworld-dev/noxscript/ns/v4"
)

func OnFrame() {
	fmt.Println("players:", len(ns4.Players()))
	fmt.Println("talking:", IsTalking())
}

Можно заметить что мы вызываем IsTalking без префикса ns3. Это, тем не менее, не типично для Go, т.к. из кода не понятно объявлена ли функция IsTalking в карте или в другом пакете.

Теперь, возвращаясь к полной настройке IDE, вы могли заметить что импорты не были опознаны. Это происходит потому что нам нужно обновить зависимости проекта в go.mod. Мы можем сделать это двумя способами:

  • go mod tidy в терминале (требует Git).
  • Либо навести мышку на нераспознанное имя импорта, выбрать Quick fix..., и далее go get ....

В обоих случаях зависимости должны загрузиться (то есть тот NS движек который вы выбрали) и добавиться в go.mod.

Теперь автодополнение должно работать корректно для пакетов движка.

Обновление движков

Скриптовые движки периодически обновляются в OpenNox чтобы добавить новые возможности или исправить ошибки.

Это делаться автоматически, новый релиз OpenNox подключит новый движек без каких либо действий со стороны разработчика карт.

Тем не менее, IDE не будет распознавать новые функции движка до тех пор пока они не обновяться в проекте карты.

Самый простой способ обновить это открыть файл go.mod в папке карты и найти строку с движком который нужно обновить:

require (
    github.com/noxworld-dev/noxscript/ns/v4 v4.3.0
    // ... other lines
)

Просто обновите версию в нем, и запустите go mod tidy. Полный список версий доступен при нажатии на версию в документации пакета скриптов а так же на GitHub.

Пакеты

Теперь мы знаем как подключить движки скриптов и запускать скрипты. Как же лучше структурировать код?

В Go, единичным проектом является “пакет” (package): директория с одним или несколькими Go файлами. Имена самих Go файлов не имеют значения, единственное требование это то что все файлы в директории должны иметь одинаковую строку package в начале файла. OpenNox так же добавляет ещё одно ограничение: package должен совпадать с именем карты.

В остальном, организация кода полностью зависит от вас. Все функции и переменные обхявленные в одном файле доступны во всех других файлах в этой директории.

Как я могу …

Это руководство лишь поверхностно, в паре шагов показывает как работать со скриптами.

Если вы уже знакомы с оригинальным NoxScript 3, стоит просмотреть руководство по миграции для NS3.

Возможно вам так же интересно поближе познакомиться с языком Go. Язык очень простой, по этому это не должно составить труда. Интерактивный Go тур является хорошим местом чтобы начать.

Некоторые из вопросов могут быть уже покрыты в Q&A. Так же доступны примеры.

Если вопросы не нашли ответа, можно задать их здесь или в нашем Discord.