Cleanup repository

This commit is contained in:
Ukendio 2024-11-23 04:42:54 +01:00
parent dacec22efa
commit b7a5785dbb
24 changed files with 157 additions and 237 deletions

View file

@ -1,8 +1,8 @@
{
"aliases": {
"jecs": "src",
"testkit": "testkit",
"jecs": "jecs",
"testkit": "test/testkit",
"mirror": "mirror"
},
"languageMode": "strict"
}
}

129
README.md
View file

@ -1,65 +1,64 @@
<p align="center">
<img src="image-5.png" width=35%/>
</p>
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=for-the-badge)](LICENSE) [![Wally](https://img.shields.io/github/v/tag/ukendio/jecs?&style=for-the-badge)](https://wally.run/package/ukendio/jecs)
Just a stupidly fast Entity Component System
* [Entity Relationships](https://ajmmertens.medium.com/building-games-in-ecs-with-entity-relationships-657275ba2c6c) as first class citizens
* Iterate 800,000 entities at 60 frames per second
* Type-safe [Luau](https://luau-lang.org/) API
* Zero-dependency package
* Optimized for column-major operations
* Cache friendly [archetype/SoA](https://ajmmertens.medium.com/building-an-ecs-2-archetypes-and-vectorization-fe21690805f9) storage
* Rigorously [unit tested](https://github.com/Ukendio/jecs/actions/workflows/ci.yaml) for stability
### Example
```lua
local world = jecs.World.new()
local pair = jecs.pair
-- These components and functions are actually already builtin
-- but have been illustrated for demonstration purposes
local ChildOf = world:component()
local Name = world:component()
local function parent(entity)
return world:target(entity, ChildOf)
end
local function getName(entity)
return world:get(entity, Name)
end
local alice = world:entity()
world:set(alice, Name, "alice")
local bob = world:entity()
world:add(bob, pair(ChildOf, alice))
world:set(bob, Name, "bob")
local sara = world:entity()
world:add(sara, pair(ChildOf, alice))
world:set(sara, Name, "sara")
print(getName(parent(sara)))
for e in world:query(pair(ChildOf, alice)) do
print(getName(e), "is the child of alice")
end
-- Output
-- "alice"
-- bob is the child of alice
-- sara is the child of alice
```
21,000 entities 125 archetypes 4 random components queried.
![Queries](image-3.png)
Can be found under /benches/visual/query.luau
Inserting 8 components to an entity and updating them over 50 times.
![Insertions](image-4.png)
Can be found under /benches/visual/insertions.luau
<p align="center">
<img src="assets/image-5.png" width=35%/>
</p>
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=for-the-badge)](LICENSE) [![Wally](https://img.shields.io/github/v/tag/ukendio/jecs?&style=for-the-badge)](https://wally.run/package/ukendio/jecs)
Just a stupidly fast Entity Component System
- [Entity Relationships](https://ajmmertens.medium.com/building-games-in-ecs-with-entity-relationships-657275ba2c6c) as first class citizens
- Iterate 800,000 entities at 60 frames per second
- Type-safe [Luau](https://luau-lang.org/) API
- Zero-dependency package
- Optimized for column-major operations
- Cache friendly [archetype/SoA](https://ajmmertens.medium.com/building-an-ecs-2-archetypes-and-vectorization-fe21690805f9) storage
- Rigorously [unit tested](https://github.com/Ukendio/jecs/actions/workflows/ci.yaml) for stability
### Example
```lua
local world = jecs.World.new()
local pair = jecs.pair
-- These components and functions are actually already builtin
-- but have been illustrated for demonstration purposes
local ChildOf = world:component()
local Name = world:component()
local function parent(entity)
return world:target(entity, ChildOf)
end
local function getName(entity)
return world:get(entity, Name)
end
local alice = world:entity()
world:set(alice, Name, "alice")
local bob = world:entity()
world:add(bob, pair(ChildOf, alice))
world:set(bob, Name, "bob")
local sara = world:entity()
world:add(sara, pair(ChildOf, alice))
world:set(sara, Name, "sara")
print(getName(parent(sara)))
for e in world:query(pair(ChildOf, alice)) do
print(getName(e), "is the child of alice")
end
-- Output
-- "alice"
-- bob is the child of alice
-- sara is the child of alice
```
21,000 entities 125 archetypes 4 random components queried.
![Queries](assets/image-3.png)
Can be found under /benches/visual/query.luau
Inserting 8 components to an entity and updating them over 50 times.
![Insertions](assets/image-4.png)
Can be found under /benches/visual/insertions.luau

View file

Before

Width:  |  Height:  |  Size: 392 KiB

After

Width:  |  Height:  |  Size: 392 KiB

View file

Before

Width:  |  Height:  |  Size: 391 KiB

After

Width:  |  Height:  |  Size: 391 KiB

View file

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View file

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 103 KiB

View file

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View file

@ -1,6 +1,6 @@
<svg width="47" height="18" viewBox="0 0 47 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 14C5.8 14 6 13.3333 6 13V4H0V0H6H10V13C10 17 6.66667 18 5 18H0V14H5Z" fill="white"/>
<path d="M46.5 4V0H39C37.1667 0 33.5 1.1 33.5 5.5C33.5 9.9 36.8333 11 38.5 11H41C41.5 11 42.5 11.3 42.5 12.5C42.5 13.7 41.5 14 41 14H33.5V18H41.5C43.1667 18 46.5 16.9 46.5 12.5C46.5 8.1 43.1667 7 41.5 7H39C38.5 7 37.5 6.7 37.5 5.5C37.5 4.3 38.5 4 39 4H46.5Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.5 0V4H30.5C28.5 4 24.5 5 24.5 9C24.5 11.0835 25.5853 12.3531 26.9078 13.0914L22.4606 14.661C21.2893 13.3156 20.5 11.4775 20.5 9C20.5 1.8 27.1667 0 30.5 0H32.5ZM24.4656 16.3357C26.5037 17.5803 28.8905 18 30.5 18H32.5V14H31.0833L24.4656 16.3357Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.3793 0C24.766 0.241156 24.1568 0.53354 23.571 0.885014C22.1712 1.72492 20.9038 2.91123 20.0606 4.5H11V0H25.3793ZM25.5 4.39421C25.445 4.42876 25.3906 4.46402 25.3368 4.5H25.5V4.39421ZM20.0606 13.5C20.9038 15.0888 22.1712 16.2751 23.571 17.115C24.1568 17.4665 24.766 17.7588 25.3793 18H11V13.5H20.0606ZM19.1854 7C19.0649 7.62348 19 8.28956 19 9C19 9.71044 19.0649 10.3765 19.1854 11H11V7H19.1854Z" fill="white"/>
</svg>
<svg width="47" height="18" viewBox="0 0 47 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 14C5.8 14 6 13.3333 6 13V4H0V0H6H10V13C10 17 6.66667 18 5 18H0V14H5Z" fill="white"/>
<path d="M46.5 4V0H39C37.1667 0 33.5 1.1 33.5 5.5C33.5 9.9 36.8333 11 38.5 11H41C41.5 11 42.5 11.3 42.5 12.5C42.5 13.7 41.5 14 41 14H33.5V18H41.5C43.1667 18 46.5 16.9 46.5 12.5C46.5 8.1 43.1667 7 41.5 7H39C38.5 7 37.5 6.7 37.5 5.5C37.5 4.3 38.5 4 39 4H46.5Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.5 0V4H30.5C28.5 4 24.5 5 24.5 9C24.5 11.0835 25.5853 12.3531 26.9078 13.0914L22.4606 14.661C21.2893 13.3156 20.5 11.4775 20.5 9C20.5 1.8 27.1667 0 30.5 0H32.5ZM24.4656 16.3357C26.5037 17.5803 28.8905 18 30.5 18H32.5V14H31.0833L24.4656 16.3357Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.3793 0C24.766 0.241156 24.1568 0.53354 23.571 0.885014C22.1712 1.72492 20.9038 2.91123 20.0606 4.5H11V0H25.3793ZM25.5 4.39421C25.445 4.42876 25.3906 4.46402 25.3368 4.5H25.5V4.39421ZM20.0606 13.5C20.9038 15.0888 22.1712 16.2751 23.571 17.115C24.1568 17.4665 24.766 17.7588 25.3793 18H11V13.5H20.0606ZM19.1854 7C19.0649 7.62348 19 8.28956 19 9C19 9.71044 19.0649 10.3765 19.1854 11H11V7H19.1854Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -1,6 +1,6 @@
<svg width="47" height="18" viewBox="0 0 47 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 14C5.8 14 6 13.3333 6 13V4H0V0H6H10V13C10 17 6.66667 18 5 18H0V14H5Z" fill="black"/>
<path d="M46.5 4V0H39C37.1667 0 33.5 1.1 33.5 5.5C33.5 9.9 36.8333 11 38.5 11H41C41.5 11 42.5 11.3 42.5 12.5C42.5 13.7 41.5 14 41 14H33.5V18H41.5C43.1667 18 46.5 16.9 46.5 12.5C46.5 8.1 43.1667 7 41.5 7H39C38.5 7 37.5 6.7 37.5 5.5C37.5 4.3 38.5 4 39 4H46.5Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.5 0V4H30.5C28.5 4 24.5 5 24.5 9C24.5 11.0835 25.5853 12.3531 26.9078 13.0914L22.4606 14.661C21.2893 13.3156 20.5 11.4775 20.5 9C20.5 1.8 27.1667 0 30.5 0H32.5ZM24.4656 16.3357C26.5037 17.5803 28.8905 18 30.5 18H32.5V14H31.0833L24.4656 16.3357Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.3793 0C24.766 0.241156 24.1568 0.53354 23.571 0.885014C22.1712 1.72492 20.9038 2.91123 20.0606 4.5H11V0H25.3793ZM25.5 4.39421C25.445 4.42876 25.3906 4.46402 25.3368 4.5H25.5V4.39421ZM20.0606 13.5C20.9038 15.0888 22.1712 16.2751 23.571 17.115C24.1568 17.4665 24.766 17.7588 25.3793 18H11V13.5H20.0606ZM19.1854 7C19.0649 7.62348 19 8.28956 19 9C19 9.71044 19.0649 10.3765 19.1854 11H11V7H19.1854Z" fill="black"/>
</svg>
<svg width="47" height="18" viewBox="0 0 47 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 14C5.8 14 6 13.3333 6 13V4H0V0H6H10V13C10 17 6.66667 18 5 18H0V14H5Z" fill="black"/>
<path d="M46.5 4V0H39C37.1667 0 33.5 1.1 33.5 5.5C33.5 9.9 36.8333 11 38.5 11H41C41.5 11 42.5 11.3 42.5 12.5C42.5 13.7 41.5 14 41 14H33.5V18H41.5C43.1667 18 46.5 16.9 46.5 12.5C46.5 8.1 43.1667 7 41.5 7H39C38.5 7 37.5 6.7 37.5 5.5C37.5 4.3 38.5 4 39 4H46.5Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.5 0V4H30.5C28.5 4 24.5 5 24.5 9C24.5 11.0835 25.5853 12.3531 26.9078 13.0914L22.4606 14.661C21.2893 13.3156 20.5 11.4775 20.5 9C20.5 1.8 27.1667 0 30.5 0H32.5ZM24.4656 16.3357C26.5037 17.5803 28.8905 18 30.5 18H32.5V14H31.0833L24.4656 16.3357Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.3793 0C24.766 0.241156 24.1568 0.53354 23.571 0.885014C22.1712 1.72492 20.9038 2.91123 20.0606 4.5H11V0H25.3793ZM25.5 4.39421C25.445 4.42876 25.3906 4.46402 25.3368 4.5H25.5V4.39421ZM20.0606 13.5C20.9038 15.0888 22.1712 16.2751 23.571 17.115C24.1568 17.4665 24.766 17.7588 25.3793 18H11V13.5H20.0606ZM19.1854 7C19.0649 7.62348 19 8.28956 19 9C19 9.71044 19.0649 10.3765 19.1854 11H11V7H19.1854Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

View file

@ -1,31 +1,28 @@
{
"name": "jecs-test",
"tree": {
"$className": "DataModel",
"StarterPlayer": {
"$className": "StarterPlayer",
"StarterPlayerScripts": {
"$className": "StarterPlayerScripts",
"$path": "tests"
}
},
"ReplicatedStorage": {
"$className": "ReplicatedStorage",
"Lib": {
"$path": "src"
},
"rgb": {
"$path": "rgb.luau"
},
"benches": {
"$path": "benches"
},
"mirror": {
"$path": "mirror"
},
"DevPackages": {
"$path": "benches/visual/DevPackages"
}
}
}
"name": "jecs-test",
"tree": {
"$className": "DataModel",
"StarterPlayer": {
"$className": "StarterPlayer",
"StarterPlayerScripts": {
"$className": "StarterPlayerScripts",
"$path": "tests"
}
},
"ReplicatedStorage": {
"$className": "ReplicatedStorage",
"Lib": {
"$path": "src"
},
"benches": {
"$path": "benches"
},
"mirror": {
"$path": "mirror"
},
"DevPackages": {
"$path": "benches/visual/DevPackages"
}
}
}
}

View file

@ -5,7 +5,6 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Matter = require(ReplicatedStorage.DevPackages.Matter)
local ecr = require(ReplicatedStorage.DevPackages.ecr)
local jecs = require(ReplicatedStorage.Lib)
local rgb = require(ReplicatedStorage.rgb)
local newWorld = Matter.World.new()
local ecs = jecs.World.new()

View file

@ -4,7 +4,6 @@
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Matter = require(ReplicatedStorage.DevPackages["_Index"]["matter-ecs_matter@0.8.1"].matter)
local ecr = require(ReplicatedStorage.DevPackages["_Index"]["centau_ecr@0.8.0"].ecr)
local rgb = require(ReplicatedStorage.rgb)
local newWorld = Matter.World.new()
local jecs = require(ReplicatedStorage.Lib)
@ -133,13 +132,6 @@ for i = 1, N do
end
print("TEST", hm)
local white = rgb.white
local yellow = rgb.yellow
local gray = rgb.gray
local green = rgb.green
local WALL = gray(" │ ")
local count = 0
for _, archetype in ecs:query(D2, D4, D6, D8):archetypes() do

View file

@ -5,7 +5,6 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Matter = require(ReplicatedStorage.DevPackages.Matter)
local ecr = require(ReplicatedStorage.DevPackages.ecr)
local jecs = require(ReplicatedStorage.Lib)
local rgb = require(ReplicatedStorage.rgb)
local newWorld = Matter.World.new()
local ecs = jecs.World.new()

View file

@ -1,6 +1,6 @@
{
"name": "jecs",
"tree": {
"$path": "src"
}
}
"name": "jecs",
"tree": {
"$path": "jecs.luau"
}
}

View file

View file

@ -1,46 +1,46 @@
{
"name": "@rbxts/jecs",
"version": "0.4.0-rc.0",
"description": "Stupidly fast Entity Component System",
"main": "src",
"repository": {
"type": "git",
"url": "https://github.com/ukendio/jecs.git"
},
"keywords": [],
"author": "Ukendio",
"contributors": [
"Ukendio",
"EncodedVenom"
],
"homepage": "https://github.com/ukendio/jecs",
"license": "MIT",
"types": "src/index.d.ts",
"files": [
"src",
"LICENSE.md",
"README.md"
],
"publishConfig": {
"access": "public"
},
"devDependencies": {
"@rbxts/compiler-types": "^2.3.0-types.1",
"@rbxts/types": "^1.0.781",
"@typescript-eslint/eslint-plugin": "^5.8.0",
"@typescript-eslint/parser": "^5.8.0",
"eslint": "^8.5.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-roblox-ts": "^0.0.32",
"prettier": "^2.5.1",
"roblox-ts": "^3.0.0",
"typescript": "^5.4.2",
"vitepress": "^1.3.0"
},
"scripts": {
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
}
}
{
"name": "@rbxts/jecs",
"version": "0.4.0",
"description": "Stupidly fast Entity Component System",
"main": "jecs.luau",
"repository": {
"type": "git",
"url": "git+https://github.com/ukendio/jecs.git"
},
"keywords": [],
"author": "Ukendio",
"contributors": [
"Ukendio",
"EncodedVenom"
],
"homepage": "https://github.com/ukendio/jecs",
"license": "MIT",
"types": "jecs.d.ts",
"files": [
"jecs.luau",
"LICENSE.md",
"README.md"
],
"publishConfig": {
"access": "public"
},
"devDependencies": {
"@rbxts/compiler-types": "^2.3.0-types.1",
"@rbxts/types": "^1.0.781",
"@typescript-eslint/eslint-plugin": "^5.8.0",
"@typescript-eslint/parser": "^5.8.0",
"eslint": "^8.5.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-roblox-ts": "^0.0.32",
"prettier": "^2.5.1",
"roblox-ts": "^3.0.0",
"typescript": "^5.4.2",
"vitepress": "^1.3.0"
},
"scripts": {
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
}
}

View file

@ -1,33 +0,0 @@
return {
white_underline = function(s: any)
return `\27[1;4m{s}\27[0m`
end,
white = function(s: any)
return `\27[37;1m{s}\27[0m`
end,
green = function(s: any)
return `\27[32;1m{s}\27[0m`
end,
red = function(s: any)
return `\27[31;1m{s}\27[0m`
end,
yellow = function(s: any)
return `\27[33;1m{s}\27[0m`
end,
red_highlight = function(s: any)
return `\27[41;1;30m{s}\27[0m`
end,
green_highlight = function(s: any)
return `\27[42;1;30m{s}\27[0m`
end,
gray = function(s: any)
return `\27[30;1m{s}\27[0m`
end,
}

View file

@ -1,29 +0,0 @@
{
"name": "jecs-test",
"tree": {
"$className": "DataModel",
"StarterPlayer": {
"$className": "StarterPlayer",
"StarterPlayerScripts": {
"$className": "StarterPlayerScripts",
"$path": "tests"
}
},
"ReplicatedStorage": {
"$className": "ReplicatedStorage",
"Lib": {
"$path": "lib"
},
"rgb": {
"$path": "rgb.lua"
},
"benches": {
"$path": "benches"
},
"mirror": {
"$path": "mirror"
}
}
}
}

View file

@ -1,3 +0,0 @@
roots = ["ServerStorage"]
[extraOptions]

View file

@ -6,8 +6,7 @@ realm = "shared"
license = "MIT"
include = [
"default.project.json",
"src/**",
"src",
"jecs.luau",
"wally.toml",
"README.md",
"CHANGELOG.md",