SDK расширения — RC11, API 0.1
Это совместимые дополнения к существующему API, не совместимость со скриптами
Ech0 и не автоматическая поддержка новых игр. Новые права доступа не добавлены.
Callbacks по-прежнему выполняются последовательно в отдельном worker.
Имена vec2, vec3, matrix4, memory_buffer, array, пространстваprojection, buffer, math теперь заняты SDK. Если старый скрипт сам объявлял
совпадающий тип/функцию, его нужно переименовать. Существующие вызовы API сохранены,
но это не гарантия отсутствия конфликтов имён в произвольном пользовательском коде.
Стандартный array<T> AngelScript теперь зарегистрирован: поддерживаются
списки инициализации, length/resize, insertLast/removeLast, индексирование,
сортировка числовых значений. Неверный индекс вызывает исключение; данные
ограничены общей памятью worker, отдельной квоты каждого массива пока нет.
Массивы могут содержать vec3 и memory_buffer handles.
В namespace math зарегистрирован официальный generic scriptmath addon с
дополнительными собственными portable double/IEEE/finite helpers:
float/double sin/cos/tan/atan2, sqrt/pow, log/log10, abs/floor/ceil, closeTo,
fpFromIEEE/fpToIEEE и другие стандартные функции. math::is_finite(float/double)
проверяет NaN/Infinity; closeTo использует абсолютный конечный epsilon >=0.
Некорректные математические
области могут дать NaN/Infinity; для чисел из источника нужна проверка адаптера.
1. Векторы и матрицы
vec2() / vec3() создают нулевой вектор. Конструкторы с двумя/тремя float
задают компоненты. x, y, z доступны для чтения и записи.
Общие методы: add, subtract, multiply(float), length, length_squared,normalize, distance, dot, lerp(other, factor). У vec3 есть cross.
Методы возвращают новые значения, не изменяя исходный вектор. Нормализация
нулевого вектора даёт нулевой вектор. Lerp принимает только factor 0..1.
Не конечные компоненты и компоненты по модулю больше 10^7 отклоняются при
операциях; конструктор/присваивание само по себе не валидирует компоненты.
Недопустимые операции завершают callback диагностируемым исключением.
vec3 a(1,0,0), b(0,1,0);
vec3 normal = a.cross(b); // (0,0,1)
vec3 halfway = a.lerp(b,0.5f);
matrix4 view; // единичная матрица, row-major
view.set(0,3,0.5f); // строка, столбец, значение
float value = view.get(0,3);
matrix4 result = view.multiply(view.transpose());
Индексы matrix4: 0..3. Методы set/get проверяют границы. Матрицы хранят
float, 16 значений, row-major; умножение выполняет обычное A×B.
2. Проекция
vec2 screen_point;
bool okay = projection::project(view,world,screen::width(),screen::height(),screen_point);
Используется row-major матрица, умноженная на column-vector (x,y,z,1).
Проверяются clip W и экранные X/Y. Clip Z / near-far диапазон не проверяется.
Точки вне экрана или за камерой возвращают false; out обнуляется.
Если источник хранит column-major значения, явно используйте transpose().
Viewport задаётся в логических единицах; допускаются размеры 1..16384.
projection::from_bytes(bytes, matrix_out) принимает ровно 64 байта:
16 little-endian float32. Это декодирование уже имеющихся данных, не чтение
процесса. При неправильном размере/невалидных числах матрица обнуляется.
Вариант без view-matrix:
bool okay = projection::perspective(world,camera,forward,right,up,
horizontal_fov_degrees,screen::width(),screen::height(),screen_point);
Forward/right/up должны быть ортонормированными направлениями камеры в той
же системе координат, что world/camera. Горизонтальный FOV — 1..179 градусов.
Длины базисных векторов и их взаимная перпендикулярность проверяются с допуском
0.01. Преобразование Euler-углов конкретного движка делает автор адаптера.
Функция не определяет движок, его единицы и тип FOV автоматически.
3. Неизменяемые буферы
memory_buffer@ snapshot = process::read_buffer(address,64);
if(snapshot !is null) {
uint health=0;
float position=0;
snapshot.read_u32(0,health);
snapshot.read_float(4,position);
}
Read_buffer читает один непрерывный участок через существующий read-only
handle. Нужны process_read в manifest и явное согласие пользователя на PID.
Размер — 1..65536; частичное/неудачное чтение возвращает null. Один успешный
вызов расходует одну операцию и свой размер из бюджета существующего Process API.
Буфер хранит собственную неизменяемую копию, а не указатель на удалённую
память. Чтение его полей не делает новых системных чтений и не расходует
Process budget. Это снимок одного чтения, не гарантия атомарности данных
изменяющегося процесса. Для свежих данных получите новый снимок.
Старый снимок может оставаться у скрипта после изменения/завершения источника.
Методы: size(), read_u8, read_u16, read_u32, read_i32, read_u64,read_float, read_double. Все read-методы принимают offset и out, возвращают
bool и обнуляют out при неверных границах. Не выровненные смещения допускаются;
числа little-endian. Сырые float/double могут содержать NaN/Infinity — это
данные источника, которые должен валидировать адаптер.slice(offset,count,string_out) копирует байты; при ошибке out пустой.buffer::from_bytes(string) создаёт буфер из собственных сырых байтов,
без process-grant; максимум 64 КиБ. Пустой собственный буфер разрешён.
Handles удерживают буфер до освобождения последней ссылки; доступных методов
изменения/записи памяти нет. Общая память ограничена существующим worker Job.
Process API также дополнен read_u8, read_u16, read_i32, read_double;
проверки согласия, квоты и обнуление результатов такие же, как у read_u32.
4. Управление параметрами и графика
float radius=30;
uint mode=0;
void on_frame() {
radius=ui::slider("radius","Radius",radius,10,100,1,20,60,260,48);
mode=ui::cycle("mode","Mode",mode,3,20,120,260,32);
render::rect(20,180,100,40,0xff994d80,true);
render::filled_circle(160,200,20,0xff994d80);
}
Slider аргументы: id, label, value, min, max, step, x, y, width, height.
Значение возвращается скрипту; хранить его между кадрами нужно самостоятельно.
Min < max; step > 0 и <= max-min. Границы по модулю <=10^6, step >=10^-12.
Входное значение ограничивается диапазоном. При мышином обновлении округление
выполняется относительно min к ближайшему step, затем ограничивается min/max.
Поэтому максимум может быть конечной точкой неполного шага. Для ползунка
рекомендуется высота 48; минимальная ширина 24 и высота 24 как у остальных UI.
Перетаскивание использует захват мыши только собственного preview-окна.
Cycle — компактный циклический выбор, не выпадающий combobox. Аргументы:
id, label, current_index, choice_count, x, y, width, height. Choice_count 1..64,
индекс 0..count-1; клик переходит к следующему с возвратом к первому.
Подписи режимов может формировать скрипт. Checkbox/button остаются совместимыми.
Идентификаторы всех видов UI должны быть уникальны в одном кадре. Последний
отрисованный элемент получает клик при пересечении областей. Повторные события
слайдера сливаются; focus/capture loss отменяет ожидающее действие. Обновления
приходят через следующий host snapshot, не исполняя script callback в UI thread.
Старые/неизвестные и невалидные значения не переходят в будущие кадры.
Новый widget API не отправляет клавиши/мышь в другую программу. Click-through
overlay остаётся click-through, интерактивные виджеты тестируются в preview.
render::rect(x,y,width,height,color,filled=false) — outline или заливка;
размер 1..4096. filled_circle(x,y,radius,color) — заливка круга; радиус
0.5..2048. Alpha и цвет 0xRRGGBBAA, прежние 256 команд на кадр сохранены.
Пробный пакет
В клиенте выберите SDK workbench · math / buffers / UI → Load script.
Он работает на синтетических данных без PID, сети и storage-разрешения.
Пример показывает slider, cycle, checkbox, проекцию и залитые фигуры.
Доступ к реальной игре и совместимость её актуальных структур этим не проверяются.
Сетевые HTTP/WS интерфейсы, пользовательские параллельные потоки, полноценный
combobox, изображения и Zydis/Unicorn не входят в RC11. API версионируется как
0.1; существующие вызовы сохраняются. Готовые Ech0-скрипты требуют адаптации.