https://github.com/netgusto/ecs-typescript
Port of bytearena/ecs from Golang to TypeScript
https://github.com/netgusto/ecs-typescript
Last synced: 6 months ago
JSON representation
Port of bytearena/ecs from Golang to TypeScript
- Host: GitHub
- URL: https://github.com/netgusto/ecs-typescript
- Owner: netgusto
- Created: 2018-05-28T16:10:12.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2023-01-25T23:32:24.000Z (almost 3 years ago)
- Last Synced: 2025-04-13T00:36:59.142Z (9 months ago)
- Language: TypeScript
- Size: 1.53 MB
- Stars: 11
- Watchers: 1
- Forks: 2
- Open Issues: 24
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# ecs-typescript
Port of https://github.com/bytearena/ecs from Golang
```
$ yarn install
$ yarn start
```
## Example
```typescript
import * as ecs from './ecs';
// The components data; always design components as simple containers without logic
// interface is perfect for this (except for getters/setters if useful)
interface IWalkProps {
Direction: "east"|"west"|"south"|"north";
Distance: number;
}
interface ITalkProps {
Message: string;
}
// Initialize the ECS manager
const manager = new ecs.Manager();
// Declare the components
const walk = manager.newComponent();
const talk = manager.newComponent();
// Create 3 entities, and provide their components
// This one only walks
manager.newEntity().addComponent(walk, { Direction: "east", Distance: 3.14 });
// This one only talks
manager.newEntity().addComponent(talk, { Message: "Wassup?" });
// This one does both
manager.newEntity().
addComponent(walk, { Direction: "north", Distance: 12.4 }).
addComponent(talk, { Message: "Fluctuat nec mergitur" });
// Tags are masks that help identify entities that match the required components
const walkers = ecs.buildTag(walk);
const talkers = ecs.buildTag(talk);
const walkertalkers = ecs.buildTag(walkers, talkers);
// Process the walkers
console.log("\n# All the walkers walk :")
for (const result of manager.query(walkers)) {
const walkAspect = result.get(walk);
console.log(result.entity.id + " > I'm walking", walkAspect.Distance, "km towards", walkAspect.Direction)
}
// Process the talkers
console.log("\n# All the talkers talk (and be mutated) :");
for (const result of manager.query(talkers)) {
const talkAspect = result.get(talk);
console.log(result.entity.id + " > I'm talking and I say \"" + talkAspect.Message + '"');
// Here we mutate the component for this entity
talkAspect.Message = talkAspect.Message.toUpperCase() + "!!!!";
}
// Process the talkers/walkers
console.log("\n# All the talkers & walkers do their thing :")
for (const result of manager.query(walkertalkers)) {
const walkAspect = result.get(walk);
const talkAspect = result.get(talk);
console.log(result.entity.id + " > I'm walking", walkAspect.Distance, "km towards", walkAspect.Direction, "while saying \"" + talkAspect.Message + "\"")
}
///////////////////////////////////////////////////////////////////////////
// Demonstrating views
// To increase speed for repetitive queries, you can create cached views
// for entities matching a given tag
///////////////////////////////////////////////////////////////////////////
console.log("\n# Demonstrating views");
const talkersView = manager.createView(talkers);
manager.newEntity().
addComponent(talk, {
Message: "Ceci n'est pas une pipe",
});
console.log("\n# There are 3 talkers in the talkersView at this point:")
for (const result of talkersView.get()) {
const talkAspect = result.get(talk)
console.log(result.entity.id + " > says \"" + talkAspect.Message + "\"")
}
manager.disposeEntities(talkers);
console.log("\n# Talkers have been disposed; the view has been updated, and we should not print any message below:")
for(const result of talkersView.get()) {
const talkAspect = result.get(talk);
console.log(result.entity.id, "says", talkAspect.Message)
}
```