• Stars
    star
    283
  • Rank 146,066 (Top 3 %)
  • Language
    C
  • License
    MIT License
  • Created over 3 years ago
  • Updated 9 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Lua ECS

A simple Entity-Componet library for Lua.

-- Create a world
local w = ecs.world()

-- Register a new type "vector( x:float, y:float )" into world.
-- It's a C component (The data is in C memory).
w:register {
	name = "vector",
	"x:float",
	"y:float",
}

-- Register a new type "name" into world.
-- It's a Lua component (The value can be any lua object)
w:register {
	name = "name",
	type = "lua",
}

-- Create a new entity with components vector and name.
local eid = w:new {
	vector = { 1.0, 2.0 },
	name = "point",
}

-- Iterate every entity with component vector and name
for v in w:select "vector:in name:in" do
	-- v is the iterator, we can read compionent from it.
	-- DO NOT store v outside of the iteration
	print(v.name)	-- output : point
	print(v.vector.x, v.vector.y)	-- output: 1.0, 2.0
end

Component Types

C Component

The component is stored in C side, it's compat and can be accessed from C side easily. The supported buildin types are:

  • int (32bits)
  • float
  • bool (8bits)
  • int64
  • dword (unsigned 32bits)
  • word (unsigned 16bits)
  • byte (unsigned 8bits)
  • double
  • userdata (void *)
w:register {
	name = "vector",
	"x:float",
	"y:float",
}

The equivalent C struct is

struct vector {
	float x;
	float y;
};

A single buildin C type can be register as

w:register {
	name = "visible",
	type = "bool",
}

Lua component

The component is stored in Lua side , and can be any lua types, such as string, table, userdata, etc.

w:register {
	name = "name",
	type = "lua",
}

Tag

The tag is a special component , it can be read as a boolean type, and the value must be true. It used for selection.

w:register {
	name = "visible"
}

Entity ID

Each entity has a build-in readonly component eid , it's a 64bits unique monotonic ID. The newest entity always has the biggest eid.

Select Pattern

Use for v in world:select(pattern) to manage components. It iterate all the entities in the world and filter out the entities matching the pattern. The order of iteration is the creation order of the entities.

-- print all the entities' eid
for v in w:select "eid:in" do
	print(v.eid)
end

The pattern is a space-separated combination of componentname[:?]action, and the action can be

  • in : read the component
  • out : write the component
  • update : read / write
  • absent : check if the component is not exist
  • exist (default) : check if the component is exist
  • new : create the component
  • ? means it's an optional action if the component is not exist
-- clear temp component from all entities
w:clear "temp"

-- Iterate the entity with visible/value/output components and without readonly component
-- Create temp component for each.
for v in w:select "visible readonly:absent value:in output:out temp:new" do
	v.output = v.value + 1
	v.temp = v.value
end

NOTICE: If you use action new , you must guarantee the component is clear (None entity has this component) before iteration.

Create Entity

-- create an empty entity
local eid = w:new()
-- Import component "name" into entity (eid)
w:import(eid, { name = "foobar" })
-- Or you can use
local eid = w:new { name = "foobar" }

You can also create an entity from a template :

-- Create a template first
local t = w:template {
	name = "foobar"
}
-- instance the template into an entity, and add visible tag.
-- The additional components ( { visible = true } ) is optional.
local eid = w:template_instance(w:new(), t, { visible = true })

You can offer init / marshal / unmarshal functions for the component type in w:register().

marshal and unmarshal is for lua component of template, and init is the constructor of the component, the common use is for C component initialization.

NOTICE: C component can be initialize by a lua string, you can use string.pack() to generate the C structure data.

Remove Entity

-- Remove an entity with eid
w:remove(eid)
-- Or remove an entity with an iterator
for v in w:select "value:in" do
	if v.value == 42 then
		w:remove(v)
	end
end

for v in w:select "REMOVED value:in do
	assert(v.value == 42)
end

-- delete all the entities removed
w:update()

The entities removed are not going to disppear immediately, they are tagged with REMOVED only, and deleted after you call w:update().

Group

You can add an entity into a group after creation. Each entity can belongs one or more groups (or no group).

-- Add entity (eid) into a group with groupid (32bit integer)
w:group_add(groupid, eid)

You can tags entities in groups with w:group_enable(groupid1, groupid2,...)

Persistance

Only C components can be persistance.

-- Save
-- Create a writer to file "saves.bin"
local writer = ecs.writer "saves.bin"
writer:write(w, w:component_id "eid") -- write component eid
writer:write(w, w:component_id "value") -- write component value
writer:write(w, w:component_id "tag") -- write component tag
local meta = writer:close()
local function print_section(s)
	print("offset =", s.offset)
	print("stride =", s.stride)
	print("n = ", s.n)
end
print_section(meta[1])	-- meta information of eid
print_section(meta[2])	-- meta information of value
print_section(meta[3])	-- meta information of tag
-- Load
local reader = ecs.reader "saves.bin"
local maxid = w:read_component(reader, "eid", meta[1].offset, meta[1].stride, meta[1].n)
local value_n = w:read_component(reader, "value", meta[2].offset, meta[2].stride, meta[2].n)
local tag_n = w:read_component(reader, "tag", meta[3].offset, meta[3].stride, meta[3].n)
reader:close()

You can also use w:generate_eid() instead of reading eid from file

Other APIs

w:exist(eid) -- Check if the entity with eid exist

w:clear(typename) -- delete component (typename) from all the entities

w:clearall() -- delete all the entities

w:component_id(typename) -- returns the component id of the component (typename) . It's for C systems.

w:type(typename) -- returns "tag", "lua" or "c"

w:first(pattern) -- Read the first component with the pattern.

w:filter(tagname, pattern) -- Enable tags marching the pattern

Access Components from C side

  1. Create a context by w:context { component1, component2, ... } for C. Export the components C concerned.
  2. Define C structs of components in C.
  3. Use APIs in luaecs.h

void * entity_iter(struct ecs_context *ctx, cid_t cid, int index) void * entity_sibling(struct ecs_context *ctx, cid_t cid, int index, cid_t sibling_id)

struct component *v;
int i;
// iterate all the components with COMPONENT_ID. COMPONENT_ID is the index of context (base 0) or component id from lua MAKE_COMPONENT_ID(cid)
for (i = 0; (v = (struct component *)entity_iter(ctx, COMPONENT_ID, i)); i++) {
	// Read the component2 associate with component (the same entity)
	struct component2 * c2 = (struct component2 *)entity_sibling(ctx, COMPONENT_ID, i, COMPONENT_ID2);
}

int entity_sibling_id(struct ecs_context *ctx, cid_t cid, int index, cid_t sibling_id)

The same with entity_sibling, but returns an id (base 1). 0 : not exist.

void * entity_add_sibling(struct ecs_context *ctx, cid_t cid, int index, cid_t sibling_id, const void *buffer)

int entity_new(struct ecs_context *ctx, cid_t cid, const void *buffer)

Create an entity with one component

void entity_remove(struct ecs_context *ctx, cid_t cid, int index)

void entity_enable_tag(struct ecs_context *ctx, cid_t cid, int index, cid_t tag_id)

void entity_disable_tag(struct ecs_context *ctx, cid_t cid, int index, cid_t tag_id)

int entity_get_lua(struct ecs_context *ctx, cid_t cid, int index, void *L) int entity_sibling_lua(struct ecs_context *ctx, cid_t cid, int index, cid_t sibling_id, void *L)

void entity_group_enable(struct ecs_context *ctx, int tagid, int n, int groupid[])

More Repositories

1

skynet

A lightweight online game framework
C
12,707
star
2

coroutine

A asymmetric coroutine library for C.
C
2,381
star
3

pbc

A protocol buffers library for C
C
1,607
star
4

mptun

Multi-path Tunnel
C
1,243
star
5

lua53doc

The Chinese Translation of Lua 5.3 document
HTML
916
star
6

sproto

Yet another protocol library like google protocol buffers , but simple and fast.
C
912
star
7

lua-snapshot

Make a snapshot for lua state to detect memory leaks.
C
497
star
8

rudp

Reliable UDP
C
395
star
9

stellaris_cn

Stellaris 群星 汉化 Mod
Lua
386
star
10

cstring

A simple C string lib
C
351
star
11

buddy

Buddy memory allocation
C
316
star
12

aoi

Area of Interest Library
C
293
star
13

ltask

C
257
star
14

neuralnet

Toy neural network
C
223
star
15

skynet_sample

A sample for skynet
Lua
219
star
16

lua-bgfx

Yet another bgfx lua binding
Lua
215
star
17

socket-server

C
209
star
18

hive

Parallel lua states
C
202
star
19

mread

Multi-Read from one bind port
C
195
star
20

windsoul

An open source 3d engine
C
160
star
21

luareload

reload a lua module
Lua
147
star
22

lua-serialize

Serialize lua objects into a binary block
C
140
star
23

lua-trace

Trace for debug lua
Lua
135
star
24

stable-connection

C
122
star
25

luadebug

A lua debugger in independent lua VM
C
118
star
26

tpp_feedback

《程序员修炼之道》第二版中译反馈
112
star
27

lua-int64

A int64 lib for lua with lightuserdata in 64bit architecture
C
109
star
28

sharplua

Embed lua 5.3 into mono
C
108
star
29

math3d

A lua math lib for linear algebra (matrix and vector)
C
102
star
30

lua-bson

A BSON library for lua
C
102
star
31

ldebug

A Lua Remote Debugger
Lua
94
star
32

battlearena

A experimental project for moba like game server
Lua
87
star
33

luaprofiler

simple lua profiler
C
86
star
34

xlsx2txt

Convert xlsx file to txt for grep text
C
81
star
35

datalist

A simple list data sheet
C
79
star
36

lua-mongo

A simple lua mongo driver
C
76
star
37

remotepvrtool

C
71
star
38

ameba

multithread for lua 5.2
67
star
39

bpa

A bump pointer allocator
C
66
star
40

lua-db

A database shared data among multi-states .
C
62
star
41

lsocket

lsocket from http://tset.de/lsocket/
C
59
star
42

skynet_package

C
58
star
43

luabind

simple and robust lua binding lib
C
56
star
44

lua-stable

Share table among lua states
C
55
star
45

ejoy3d

Just a toy
C
55
star
46

efkbgfx

A bgfx renderer for effekseer runtime
Scala
50
star
47

luawinfile

Replacement lfs and lua original api to support utf-8 filename
C
50
star
48

luacc

LUACC allows you write C code in lua
Lua
47
star
49

lua-conf

Convert a lua table to a C object , and share it among many lua states .
C
46
star
50

xenonauts

xenonauts chinese translation
Lua
45
star
51

rogue

A simple rogue lib for lua
C
44
star
52

dfont

Manage texture for Chinese character rendering.
C
44
star
53

lua-array

lua sparse array
C
43
star
54

handlemap

Map object pointer to an unique id
C
42
star
55

atomdict

A data structure for data exchange between multi lua states.
C
38
star
56

skynet-reload

Reload skynet lua service
C
37
star
57

simplethread

A simple thread library base on pthread and win thread
C
36
star
58

iupmingw

IUP all in one
Lua
36
star
59

vla

Variable length array
C
35
star
60

skynet_group

示范如何让多组游戏服务器运行在同一个 skynet 进程内
Lua
35
star
61

backtrace-mingw

Automatically exported from code.google.com/p/backtrace-mingw
C
33
star
62

syncmodel

一个根据时间戳同步的模型
Lua
31
star
63

tracedoc

Lua
30
star
64

roguestale_cn

A Chinese translation mod of Rogue's Tale
C
30
star
65

bgfxidl

An IDL for bgfx
Lua
28
star
66

attrib

Expression calculate machine
C
28
star
67

luaxlsx

C
27
star
68

pathfinding

A simple A star path-finding module for Lua
C
26
star
69

lalloc

A allocator for lua
C
26
star
70

eaccodec

A simple Ericsson Texture EAC codec
C
25
star
71

lua-crypt

simple crypt lib
C
24
star
72

aura

C
24
star
73

skynet2

单独放一些临时代码, 之后会合并到 skynet 的 2.0 分支中
C
23
star
74

lthread

lua thread (step execute a lua function)
C
21
star
75

skynet_transaction

A example of transaction
Lua
20
star
76

caccessor

Let lua access C types
C
20
star
77

lmonitor

monitor lua calls
C
19
star
78

font16xaa

16xAA font rendering using coverage masks
C
19
star
79

stringid

C
18
star
80

luatypesystem

A simple type system for lua
Lua
17
star
81

manualgc

Automatically exported from code.google.com/p/manualgc
C
17
star
82

ctable

Dump a lua table into a block of memory, and use it as a lua table later.
Lua
17
star
83

syncobj

Lua
15
star
84

tablepointer

Convert lua table to pointer, and iterate it.
C
15
star
85

lua_typecheck

Lua
14
star
86

datatree

C
13
star
87

netout

Redirect stdout to a tcp socket
C
13
star
88

textcell

ImGui style table cell, but for text mode
C
13
star
89

skynet-demo

A demo for skynet (WIP)
Lua
12
star
90

bgfxlshaderc

A lua version of bgfx shaderc
Lua
12
star
91

pdxparser

Paradox Game data file parser
Lua
10
star
92

etccompose

compose ETC2_EAC without encode
C
10
star
93

kdtree

C
9
star
94

freeabc

给自己用的 ABC 输入法
Lua
9
star
95

stylecache

C
9
star
96

luaproto

dump lua prototype constants
C
7
star
97

routemap

C
6
star
98

treeclone

Clone a tree by blueprint
C
5
star
99

cmod

A simple C modules manager
C
5
star
100

extable

Put data into external lua state
C
5
star