Skip to content

Commit

Permalink
remove import path and fixes for travis
Browse files Browse the repository at this point in the history
  • Loading branch information
Noofbiz committed Apr 6, 2019
1 parent 93415f8 commit 3706c5f
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ branch:
only:
- "master"
language: go
go_import_path: engo.io/ecs
go_import_path: github.com/EngoEngine/ecs
go:
- 1.6.2
44 changes: 22 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@

[![Build Status](https://travis-ci.org/EngoEngine/ecs.svg?branch=master)](https://travis-ci.org/EngoEngine/ecs)

This is our implementation of the "Entity Component System" model in Go. It was designed to be used in `engo`, however
This is our implementation of the "Entity Component System" model in Go. It was designed to be used in `engo`, however
it is not dependent on any other packages so is able to be used wherever!

## Basics
In the Entity Component System paradigm, you have three elements;

* Entities
* Components
* Systems.
* Systems.

In our implementation, we use the type `World` to work with those `System`s. Each `System` can have references to any number (including 0) of entities. And each `Entity` can have as many `Component`s as desired.
In our implementation, we use the type `World` to work with those `System`s. Each `System` can have references to any number (including 0) of entities. And each `Entity` can have as many `Component`s as desired.

An example of creating a `World`, adding a `System` to it, and update all systems
```go
// Declare the world - you can also use "var world ecs.World"
// Declare the world - you can also use "var world ecs.World"
world := ecs.World{}

// You can add as many Systems here as you like. The RenderSystem provided by `engo` is just an example.
// You can add as many Systems here as you like. The RenderSystem provided by `engo` is just an example.
world.AddSystem(&engo.RenderSystem{})

// This will usually be called within the game-loop, in order to update all Systems on every frame.
Expand All @@ -39,10 +39,10 @@ type System interface {
}
```

What does this say? It needs to have an `Update` method (which is called from `world.Update`), and it needs to have a `Remove(ecs.BasicEntity)` method. Why require a Remove method, but not an Add method? Because there's no 'generic' `Add` method (the parameters may change), while in order to remove something, all you need it the unique identifier (as provided by the `BasicEntity`).
What does this say? It needs to have an `Update` method (which is called from `world.Update`), and it needs to have a `Remove(ecs.BasicEntity)` method. Why require a Remove method, but not an Add method? Because there's no 'generic' `Add` method (the parameters may change), while in order to remove something, all you need it the unique identifier (as provided by the `BasicEntity`).

### Initialization
Optionally, your `System` may implement the `Initializer` interface, which allows you to do initialization for the given `World`. Basically, it allows you to initialize values, without having to call the function manually before adding it to the `World`. Whenever you add a `System` (one that implements the `Initializer` interface) to the world, the `New` method will be called.
Optionally, your `System` may implement the `Initializer` interface, which allows you to do initialization for the given `World`. Basically, it allows you to initialize values, without having to call the function manually before adding it to the `World`. Whenever you add a `System` (one that implements the `Initializer` interface) to the world, the `New` method will be called.

```go
type Initializer interface {
Expand All @@ -53,7 +53,7 @@ type Initializer interface {
```

### Priority
Optionally, your `System` may implement the `Prioritizer` interface, which allows the `World` to sort the `System`s based on that priority. If omitted, a value of `0` is assumed.
Optionally, your `System` may implement the `Prioritizer` interface, which allows the `World` to sort the `System`s based on that priority. If omitted, a value of `0` is assumed.

```go
type Prioritizer interface {
Expand All @@ -65,7 +65,7 @@ type Prioritizer interface {
## Entities and Components
Where do the entities come in? All game-logic has to be done within `System`s (the `Update` method, to be precise)). `Component`s store data (which is used by those `System`s). An `Entity` is no more than a wrapper which combines multiple `Component`s and adds a unique identifier to the whole. This unique identifier is nothing magic: simply an incrementing integer value - nothing to worry about.

> Because the precise definition of those `Component`s can vary, this `ecs` package provides no `Component`s -- we only provide examples here. The `engo.io/engo/common` package offers lots of `Component`s and `System`s to work with, out of the box.
> Because the precise definition of those `Component`s can vary, this `ecs` package provides no `Component`s -- we only provide examples here. The `github.com/EngoEngine/engo/common` package offers lots of `Component`s and `System`s to work with, out of the box.
Let's view an example:

Expand All @@ -87,7 +87,7 @@ type Player struct {
}
```

Here, the type `Player` is made out of three elements: the unique identifier (`ecs.BasicEntity`) and two `Component`s. A `System` may make use of one or more of those `Component`s. Which are required, is defined by the `Add` method on that `System`.
Here, the type `Player` is made out of three elements: the unique identifier (`ecs.BasicEntity`) and two `Component`s. A `System` may make use of one or more of those `Component`s. Which are required, is defined by the `Add` method on that `System`.

Let's view a few examples:

Expand All @@ -111,7 +111,7 @@ for _, system := range world.Systems() {

// Use a type-switch to figure out which System is which
switch sys := system.(type) {

// Create a case for each System you want to use
case *MySystem1:
sys.Add(&player.BasicEntity, &player.SpaceComponent)
Expand All @@ -121,13 +121,13 @@ for _, system := range world.Systems() {
}
```

That is all there is to it.
That is all there is to it.

## Custom Systems - How to save Entities?

You more than likely will want to create `System`s yourself. We will now go in depth on what you should do when defining your own `Add` method for your `System`. As seen above, you can create any number (and type of) parameters you want.
You more than likely will want to create `System`s yourself. We will now go in depth on what you should do when defining your own `Add` method for your `System`. As seen above, you can create any number (and type of) parameters you want.

> We do ask you to let *the first argument* be of type `*ecs.BasicEntity` - as a general rule.
> We do ask you to let *the first argument* be of type `*ecs.BasicEntity` - as a general rule.
Your `System` should include an array, slice or map in which to store those entities. Now it is important to note that you're not receiving entities per se -- you are receiving references to the `Component`s you need. The actual `Entity` (type `Player` in our example) may contain way more `Component`s. You will most-likely want to create a struct for you to store those pointers in. An example:

Expand All @@ -147,10 +147,10 @@ func (m *MyAwesomeSystem) Add(basic *ecs.BasicEntity, space *SpaceComponent) {
```

> ### NOTE
> As a convention, please include "System" in the name of your `System` -- at the end. When you define a struct (which contains pointers, as opposed to the `Player` struct we created earlier), please replace that `System` part with `Entity`. You should **only** use this newly-created struct in your similarly-named `System`. You will usually *never* want to export that `Entity` definition, as it is only being used in that `System`. If your system would be called `BallMovementSystem`, then your struct would be called `ballMovementEntity`.
> As a convention, please include "System" in the name of your `System` -- at the end. When you define a struct (which contains pointers, as opposed to the `Player` struct we created earlier), please replace that `System` part with `Entity`. You should **only** use this newly-created struct in your similarly-named `System`. You will usually *never* want to export that `Entity` definition, as it is only being used in that `System`. If your system would be called `BallMovementSystem`, then your struct would be called `ballMovementEntity`.
### Removing Entities from your System
Your `System` must implement the `Remove` method as specified by the `System` interface. Whenever you start storing entities, you should define this method in such a way, that it removes the custom-created non-exported `Entity`-struct from the array, slice or map. An `ecs.BasicEntity` is given for you to figure out which element in the array, slice or map it is.
Your `System` must implement the `Remove` method as specified by the `System` interface. Whenever you start storing entities, you should define this method in such a way, that it removes the custom-created non-exported `Entity`-struct from the array, slice or map. An `ecs.BasicEntity` is given for you to figure out which element in the array, slice or map it is.

```go
// Remove removes the Entity from the System. This is what most Remove methods will look like
Expand All @@ -160,7 +160,7 @@ func (m *MyAwesomeSystem) Remove(basic ecs.BasicEntity) {
if entity.ID() == basic.ID() {
delete = index
break
}
}
}
if delete >= 0 {
m.entities = append(m.entities[:delete], m.entities[delete+1:]...)
Expand All @@ -169,18 +169,18 @@ func (m *MyAwesomeSystem) Remove(basic ecs.BasicEntity) {

// OR, if you were using a `map` instead of a `slice`:

// Remove removes the Entity from the System. As you see, removing becomes easier when using a `map`.
// Remove removes the Entity from the System. As you see, removing becomes easier when using a `map`.
func (m *MyAwesomeSystem) Remove(basic ecs.BasicEntity) {
delete(m.entities, basic.ID())
}
//
```

> #### NOTE
> Even though that a `map` looks easier, if you want to loop over that `map` each frame, writing those additional lines to use a `slice` instead, is definitely worth it in terms of runtime performance. Iterating over a `map` is a lot slower.
> Even though that a `map` looks easier, if you want to loop over that `map` each frame, writing those additional lines to use a `slice` instead, is definitely worth it in terms of runtime performance. Iterating over a `map` is a lot slower.
## Custom Systems - The Update method
Whatever your `System` does on the `Update` method, is up to you. Each `System` is unique in that sense. If you're storing entities, then you might want to loop over them each frame. Again, this depends on your use-case.
Whatever your `System` does on the `Update` method, is up to you. Each `System` is unique in that sense. If you're storing entities, then you might want to loop over them each frame. Again, this depends on your use-case.

```go
func (m *MyAwesomeSystem) Update(dt float32) {
Expand Down Expand Up @@ -249,14 +249,14 @@ func (m *MySystem) AddByInterface(o ecs.Identifier) {
}
```

To use the system, instead of `w.AddSystem()` use
To use the system, instead of `w.AddSystem()` use

```go
var myable *Myable
w.AddSystemInterface(&MySystem{}, myable, nil)
```

### Note
### Note
This takes **a pointer to** the interface that the system needs implemented to use AddByInterface.

Finally, to add an entity, rather than looping through all the systems, you can just
Expand Down
2 changes: 1 addition & 1 deletion doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@
//
// For instance, an animation system may render entities possessing animation
// components.
package ecs // import "engo.io/ecs"
package ecs

0 comments on commit 3706c5f

Please sign in to comment.