Рубрика развивается при поддержке
Gamedev
Andrey Apanasik
1945

ECSY — легковесный ECS фреймворк для JavaScript

Команда, работающая над A-Frame Mixed Reality, опубликовала ECSY - легковесный экспериментальный Entity Component System фреймворк для JavaScript.

В закладки

Особенности:

  • Не завязан на конкретный фреймворк.
  • Ориентирован на предоставление простого, но эффективного API.
  • Разработан с идеей сократить нагрузку на сборщик мусора.
  • Системы, сущности и компоненты находятся в инстансе world.
  • Несколько запросов на систему.
  • Реактивный.
  • Предсказуемость:
  • - Системы работают в порядке регистрации или на основе заданного при регистрации приоритета.
  • - Реактивные события не будут генерировать случайные колбеки при вызове, но будут поставлены в очередь и будут обрабатываться по порядку.
  • Современный Javascript: ES6, классы, модули, ...
  • Пул для компонентов и сущностей.

Распространяется по MIT лицензии, весь код на гитхабе.

Примеры:

Более подробно можно почитать в анонсе Mozilla.

Материал опубликован пользователем.
Нажмите кнопку «Написать», чтобы поделиться мнением или рассказать о своём проекте.

Написать
{ "author_name": "Andrey Apanasik", "author_type": "self", "tags": ["js","javascript","entitycomponentsystem","ecs"], "comments": 34, "likes": 22, "favorites": 53, "is_advertisement": false, "subsite_label": "gamedev", "id": 73909, "is_wide": false, "is_ugc": true, "date": "Mon, 07 Oct 2019 05:48:34 +0300", "is_special": false }
0
{ "id": 73909, "author_id": 1922, "diff_limit": 1000, "urls": {"diff":"\/comments\/73909\/get","add":"\/comments\/73909\/add","edit":"\/comments\/edit","remove":"\/admin\/comments\/remove","pin":"\/admin\/comments\/pin","get4edit":"\/comments\/get4edit","complain":"\/comments\/complain","load_more":"\/comments\/loading\/73909"}, "attach_limit": 2, "max_comment_text_length": 5000, "subsite_id": 64954, "last_count_and_date": null }
34 комментария
Популярные
По порядку
Написать комментарий...
5

Идея вызывает серьезный скепсис. С виду половина технических идей ECS - по оптимизации кеша процессора и минимизаций обращении к памяти для объектов на js выглядит малореализуемой.
Наверное подход сможет что-то улучшить, но банально - без низкоуровневых операций нет возможностей оптимизировать систему обслуживания компонентов. Оверхед самой компонентной системы может быть больше, чем если просто писать минимальный js код, оптимизированный под конкретные нужные вам алгоритмы.
Web Assembly видится более подходящей платформой под такие штуки.
Хотя авторы наверняка потестировали свой подход, но выглядит похожим на hype driven development

Ответить
1

И так понятно ,что никаким DoD тут и не пахнет. Языки интерпретируемые или те у которых творится с памятью то же, что в C# могут только в ECS подход на уровне шаблона. Да, это может быть удобно и читабельно, но никак не в десятки раз производительнее.

По факту DOD\ECS возможен только на С и С++.

Ответить
0

1. Что не так с C#?
2. В js в том же V8 есть jit компиляция и т.п.

Ответить
1

В языках, которые не дают напрямую работать с памятью, а тем более тех, которые позиционируют себя как ООП, вы не можете быть уверены ( и они вам этого не гарантируют), что ваши даные будут сохранять принцип локальности. Это значит, что в любой момент исполнения вы не можете гарантировать ,что у вас нет кешмисов, болеее того, машина\компилятор\виртуалка, вообще не важно кто или что, никогда не смогут вам ничего гарантировать, у них там свои тараканы. За "удобство" в таких высокоуровневых языках приходится платить.

Ответить
2

В С# последовательные массивы структур не менее последовательные, чем в С++.
Почему кеш-миссы там должны случаться по другим правилам?

Ответить
0

Этого недостаточно, понятно что есть аналоги вектора, но у вас нет никакого контроля над памяью т к. Обращения к памяти закрыты от вас полностью. Ну и группы и пулы как в том же entt не выйдет сделать так ж из-за отсутствия контроля памяти. Про войны с GC вообще опустим, Unity пришлось практически заново из C# делать C++. Ну дурость же.

Ответить
0

Про кеш и вот этот вот всё они, к слову, писали в оригинальной статье:
You may notice that ECSY is not focused on data-locality or memory layout as much as many native ECS engines. This has not been a priority in ECSY because in Javascript we have far less control over the way things are laid out in memory and how our code gets executed on the CPU. We get far bigger wins by focusing on preventing unnecessary garbage cоllection and optimizing for JIT. This story will change quite a bit with WASM, so it is certainly something we want to explore for ECSY in the future.

Ответить
0

Так о чем и речь. Они делают именно шаблон, а не следуют какой-то конкретной парадигме... Что-то среднее выходит. А что там творится при исполнении с указателями, которые ОЧЕНЬ сильно снижают производительность черт его знает. Плюсом у них сущности, как я понял, не SoA, а это тоже важно.

Ответить
0

Меня эта тема с кешем и CPU в js тоже весьма смутила. Но я пока особо не вчитывался. Чуть позже может про кишки их ECS отдельную статью напишу.

Ответить
4

Разработан с идеей сократить нагрузку на сборщик мусора.
> Системы, объекты и компоненты находятся в инстансе world.

Довольно противоречиво

Ответить
0

Про "объекты" мой косяк. В оригинале там "entities".

Ответить
0

Сущности. В любом случае, странная там херня творится, под капотом-то

Ответить
0

Я позже может переведу оригинальный пост. Там много подробностей.

Ответить
0

Да с этим ок, компоненты хранятся в сторах, которые хранится в самом компоненте мира, и ещё как поинтеры в сущностях, это стандартный ECS. Просто для сборщика мусора тут никакой оптимизации нету, разве что сторы будут оптимизированы под удаление объектов из них и движок под капотом будет удалять ненужные компоненты. Хотя все равно это для создания прототипов каких-то максимум

Ответить
1

Что за ECS с которым все носятся? В контексте юнити очень часто слышу, а я в танке (вебе).

Ответить
1

Последняя ссылка на пример: https://ecsy.io/examples/systemstatecomponents/

Ответить
0

Ненавижу JS, но я попробую фреймворк, спасибо за наводку.

Ответить
2

После JS любой язык кажется паскалем.
Кодишь и думаешь, как люди вообще без спреад-оператора живут :)

Ответить
0

Это в плюс или в минус JS ?
Так то и паскаль хороший язык, и без спреда нормально живут, вестимо) (спасибо, прочитал про такой забавный оператор)

Ответить
0

Ну, про мертвых либо хорошо, либо никак, согласен)

Ответить
0

Мне когда то нравился, и на делфи писал.
Хороший язык.
Но что есть, то есть, с жизнью у него не заладилось)

Ответить
0

Попробуй хаскель или го, и поймешь что js не так уж плох

Ответить
0

По поводу ГО х3, его очень даже в моих кругах хайпят и говорят что оч крутой язык.

Ответить
1

Да его много хайпят, и основной косяк этого языка выдают за его достоинство. Сеньор и Джун на этом языке пишут одинаковый год. 

Казалось бы круто, когда джун сразу пишет код как сеньор. Но на практике ситуация скорее обратная, код дерьмовый и скорее сеньор пишет как Джун. Потому что язык не дает возможности писать по другому. 

В итоге мы имеем кодовую базу которую всякий раз проще переписать заново, чем развить и доработать. Для микро сервисов пойдет, но для большого проекта выбор этой технологии как основного backend языка - выстрел в ногу. 

Ответить
0

Про код джуна и сеньора не очень понял. Даже неважно какой язык, всякие паттерны, переиспользуемость и поддерживаемость кода сеньор применит/сделает лучше все равно.
И какой основной косяк в js?

Ответить
0

У JS с этим все хорошо, есть классы, прототипы, наследование, я про GoLang выше писал. Там код одинаково плох (лапша), кто бы его не писал. 

А разница между Джоном и Сеньором в понимании того как работает го под капотом и в архитектуре проекта. 

У JS проблемы мелкие, из разряда итерация объектов передает первым аргументом значение, а вторым ключ, а не наоборот как у всех. Присвоение объектов через = по умолчанию по ссылке, а не по значению. 

Со временем привыкаешь, но по началу бесит жутко. 

Ответить
1

Даже не знаю, в моем понимании выразительности go хватает для создания удобных объектов.
Да, он минималистичен, в нем ограниченные средства и есть обычно только один способ сделать все правильно. Но ограниченный дизайн и ставился целью.
Код сениора будет отличаться только декомпозицией, именованием и архитектурой решения, то есть самыми важными вещами в структуре программы. А детали да, одинаковые.
js в этом смысле мощный метаязык, который можно использовать кучей способов, но какая разница, если там мало средств для защиты кода - ни типизации, ни сокрытия, ни самодокументирования.
В моем понимании мощный сахар и хитрые варианты синтаксиса js - не плюс, а единообразие кода на go - не минус языка.

Ответить
0

самодокументирования - Нет никаких проблем с этим, пишишь анноации к функциям и тебе IDE будет ошибки показывать, когда ты будешь не те данные передавать в функцию как аргументы. А линтер может запретить пушить при наличие таких ошибок.

Аннотации собираются через swagger и делает страничку с API.
Типизацию да - можно решить через typescript, или через теже аннотации, в них можно указывать типы.
Насчёт сокрытия - не очень понимаю о чём речь, есть приватные и публичные свойства классов - объектов. С этим тоже нет проблемы.

 Синтаксис JS не хитрый, он свободный - не имеет жестких ограничений. Если бы код на go был бы единообразным с хорошим синтаксисом, как у JS, Dart - вопросов бы не было. Но то единообразие которое есть - увы многих разрабов которые привыкли писать красивый DRY код - не радует.

Ответить
0

Да понятно, что жить можно. Собственно аннотации и их поддержка в IDE, как и ts - это попытка решить связанные с обычной работой неудобства.
Но мне кажется единообразие и понятность go - скорее вопрос привычки.
Ну то есть обычная декомпозиция такая же, нет проблем с DRY. Есть проблемы с объемностью некоторых типичных конструкций, которые в других языках имеют более компактное решение.
Впрочем Я не писал на go больших вещей, может реально проблема есть.
На js впрочем тоже, но тут Я даже не представляю, как это сделать. Осторожно наверное, аннотации, организационно как то решать.

Ответить
0

Ну я сам пишу на PHP & JS, и сейчас например руковожу тремя командами где языки Java, Ruby, Elixir до этого был в составе команды где BackEnd был на Go.

Хотя на Java я не пишу - у него типичный C подобный понятный синтаксис и я даже могу участвовать в код Review давая замечания по увиденной реализации.

С Ruby & Elixir сложнее, синтаксис специфичен, но и его можно освоить и привыкнуть, по крайней мере, я понимаю что ребята пишут, в основном и даже могу внести какие-то критичные хот фиксы.

Но проект с Go, а он у нас был большой, был для меня болью. Так как на коротких кусочках кода вроде понятно что написано, но если мы будем брать целый контроллер какой нибудь - то уже глаза кровоточить начинают.

Другой критерий оценки - насколько легко разобраться в легаси. Скажем проект в середине пути, я нанимаю в команду нового разраба уровня middle +. Со всеми языками кроме Go новый разраб относительно быстро въезжает в кодовую базу и начинает активно закрывать задачи.

С Go так было, только когда это был очень типичный код, скажем интеграции которые получали одинаковые данные от разных поставщиков. Или когда кодовая база маленькая. Микросервис которые предоставляет REST к одной сущности из одной таблицы в бд. Когда мы нанимали Go разрабов посередине готового проекта, вникали в проект они реально долго.

Ответить
0

Ок, вам определенно есть с чем сравнить

Ответить
–1

по мне так typescript решает 90% проблем чистого JS, очень приятно на нем работать, что на фронте, что на бэке.

Ответить
0

Да, собственно он и сделан, чтобы их решать))
Мне тоже нравится ts, но веб и js  в принципе не мой профиль.
Ну разве что иногда пострадать, но в этом случае ванильный js как то интереснее.

https://mefist0fel.github.io/

Конечно есть снисходительные комментарии в стиле "для тех, кто не смог в динамическую типизацию" или "мне и так норм, никаких проблем" или "для калек из c#, которые не смогли в js"

Справедливости ради, похожие претензии к питону. Я все же поборник статической типизации.

Ответить

Прямой эфир

[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox_method": "createAdaptive", "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fizc" } } }, { "id": 4, "label": "Article Branding", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "p1": "cfovz", "p2": "glug" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfk" } } }, { "id": 6, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjog" } } }, { "id": 10, "disable": true, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "disable": true, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "createAdaptive", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-250597-0", "render_to": "inpage_VI-250597-0-1134314964", "adfox_url": "//ads.adfox.ru/228129/getCode?pp=h&ps=clmf&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid10=&puid21=&puid22=&puid31=&puid32=&puid33=&fmt=1&dl={REFERER}&pr=" } }, { "id": 15, "label": "Баннер в ленте на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byudo", "p2": "ftjf" } } }, { "id": 17, "label": "Stratum Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fzvb" } } }, { "id": 18, "label": "Stratum Mobile", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fzvc" } } }, { "id": 20, "label": "Кнопка в сайдбаре", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "p1": "chfbl", "p2": "gnwc" } } } ]