Compare commits
8 Commits
master
...
graphql-ui
Author | SHA1 | Date | |
---|---|---|---|
5d71a1b19b | |||
c17bb904af | |||
f982af16c2 | |||
7568e38575 | |||
3aedc4a8ff | |||
bb5e57e8b2 | |||
6bc31f3079 | |||
4cae521faf |
10
.drone.yml
Normal file
10
.drone.yml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
kind: pipeline
|
||||||
|
name: default
|
||||||
|
steps:
|
||||||
|
- name: test
|
||||||
|
image: crystallang/crystal:latest-alpine
|
||||||
|
environment:
|
||||||
|
commands:
|
||||||
|
- make deps
|
||||||
|
- make build
|
||||||
|
- make test
|
22
README.md
22
README.md
|
@ -1,6 +1,6 @@
|
||||||
# TETU Core
|
# TETU Core
|
||||||
|
|
||||||
A strategy & simulation game in space, inspired by Stellaris PDX
|
A strategy & simulation game in space, inspired by Stellaris PDX.
|
||||||
|
|
||||||
[![Build Status](https://drone.sceptique.eu/api/badges/TETU/Core/status.svg)](https://drone.sceptique.eu/TETU/Core)
|
[![Build Status](https://drone.sceptique.eu/api/badges/TETU/Core/status.svg)](https://drone.sceptique.eu/TETU/Core)
|
||||||
|
|
||||||
|
@ -11,24 +11,20 @@ Install `git`, `sfml`, `crystal`, `make`, `imgui` (`imgui-sfml` with archlinux).
|
||||||
# install dependencies first
|
# install dependencies first
|
||||||
make deps
|
make deps
|
||||||
|
|
||||||
# make with imgui static linking (I think, I don't remember)
|
# make an optimised build so it's fasteeer
|
||||||
export LD_LIBRARY_PATH="$(pwd)/cimgui"
|
|
||||||
make release
|
make release
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
# run the
|
./core # run the server (high performance for data)
|
||||||
export LD_LIBRARY_PATH="$(pwd)/lib/imgui-sfml"
|
xdg-open https://localhost:3000 # open the game UI (browser UI for simplicity)
|
||||||
./core
|
|
||||||
|
|
||||||
# there is also a make rule that handle the libraries
|
|
||||||
make run
|
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
* See the wiki <https://git.sceptique.eu/TETU/Core/wiki>.
|
* See the wiki for documentation: <https://git.sceptique.eu/TETU/Core/wiki>.
|
||||||
* See the current kanban: <https://git.sceptique.eu/TETU/Core/projects>
|
* See the current kanban for current WIP: <https://git.sceptique.eu/TETU/Core/projects>.
|
||||||
* Come talk on IRC **irc://irc.sceptique.eu#TETU**
|
* Come talk on IRC: **irc://irc.sceptique.eu:6697#TETU**.
|
||||||
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
@ -40,7 +36,7 @@ Install `git`, `sfml`, `crystal`, `make`, `imgui` (`imgui-sfml` with archlinux).
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
- [Arthur Poulet](https://git.sceptique.eu/Sceptique) - creator and maintainer
|
- [Arthur Poulet](https://git.sceptique.eu/Sceptique) - creator and maintainer.
|
||||||
|
|
||||||
## Particular mentions
|
## Particular mentions
|
||||||
|
|
||||||
|
|
19
adr/0001-record-architecture-decisions.md
Normal file
19
adr/0001-record-architecture-decisions.md
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# 1. Record architecture decisions
|
||||||
|
|
||||||
|
Date: 2022-08-07
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
We need to record the architectural decisions made on this project.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
We will use Architecture Decision Records, as [described by Michael Nygard](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions).
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
See Michael Nygard's article, linked above. For a lightweight ADR toolset, see Nat Pryce's [adr-tools](https://github.com/npryce/adr-tools).
|
23
adr/0002-use-a-ecs.md
Normal file
23
adr/0002-use-a-ecs.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# 2. Use a ECS
|
||||||
|
|
||||||
|
Date: 2022-08-07
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
One of the target of the game is to be able to run 10.000 planets galaxy on a standard computer. This may require a very careful approch of the architecture. Naive implementation will very likely ends up with non-scalable galaxy size and limited planet amount.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
An ECS pattern will be used to handle most of the code. In particular the economic system that handle the planets.
|
||||||
|
|
||||||
|
The ECS is entitas.cr (see the shards.yml file).
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
Developer(s) need to know this unusual pattern.
|
||||||
|
Performance are expected very high and scalable with threads.
|
||||||
|
The architecture of most of the code will be defined and limited by the ECS pattern.
|
5
graphql/base.graphql
Normal file
5
graphql/base.graphql
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
type Query {
|
||||||
|
empires(name: String!): String!
|
||||||
|
|
||||||
|
day(): Int!
|
||||||
|
}
|
26
shard.lock
26
shard.lock
|
@ -1,20 +1,28 @@
|
||||||
version: 2.0
|
version: 2.0
|
||||||
shards:
|
shards:
|
||||||
crsfml:
|
backtracer:
|
||||||
git: https://github.com/oprypin/crsfml.git
|
git: https://github.com/sija/backtracer.cr.git
|
||||||
version: 2.5.2
|
version: 1.2.1
|
||||||
|
|
||||||
entitas:
|
entitas:
|
||||||
git: https://github.com/spoved/entitas.cr.git
|
git: https://github.com/spoved/entitas.cr.git
|
||||||
version: 1.4.5
|
version: 1.4.5
|
||||||
|
|
||||||
imgui:
|
exception_page:
|
||||||
git: https://github.com/oprypin/crystal-imgui.git
|
git: https://github.com/crystal-loot/exception_page.git
|
||||||
version: 1.87
|
version: 0.2.2
|
||||||
|
|
||||||
imgui-sfml:
|
graphql:
|
||||||
git: https://github.com/oprypin/crystal-imgui-sfml.git
|
git: https://github.com/graphql-crystal/graphql.git
|
||||||
version: 1.87
|
version: 0.4.0
|
||||||
|
|
||||||
|
kemal:
|
||||||
|
git: https://github.com/kemalcr/kemal.git
|
||||||
|
version: 1.2.0
|
||||||
|
|
||||||
|
radix:
|
||||||
|
git: https://github.com/luislavena/radix.git
|
||||||
|
version: 0.4.1
|
||||||
|
|
||||||
spoved:
|
spoved:
|
||||||
git: https://github.com/spoved/spoved.cr.git
|
git: https://github.com/spoved/spoved.cr.git
|
||||||
|
|
10
shard.yml
10
shard.yml
|
@ -15,9 +15,7 @@ license: GPLv3
|
||||||
dependencies:
|
dependencies:
|
||||||
entitas:
|
entitas:
|
||||||
github: spoved/entitas.cr
|
github: spoved/entitas.cr
|
||||||
crsfml:
|
graphql:
|
||||||
github: oprypin/crsfml
|
github: graphql-crystal/graphql
|
||||||
imgui:
|
kemal:
|
||||||
github: oprypin/crystal-imgui
|
github: kemalcr/kemal
|
||||||
imgui-sfml:
|
|
||||||
github: oprypin/crystal-imgui-sfml
|
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
require "./spec_helper"
|
require "./spec_helper"
|
||||||
|
|
||||||
describe Core do
|
describe TETU do
|
||||||
# TODO: Write tests
|
|
||||||
|
|
||||||
it "works" do
|
it "works" do
|
||||||
false.should eq(true)
|
true.should eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
4
src/api.cr
Normal file
4
src/api.cr
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
module TETU::API
|
||||||
|
end
|
||||||
|
|
||||||
|
require "./api/*"
|
21
src/api/game_query.cr
Normal file
21
src/api/game_query.cr
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
require "./objects"
|
||||||
|
|
||||||
|
module TETU::API::Definitions
|
||||||
|
@[GraphQL::Object]
|
||||||
|
class GameQuery < GraphQL::BaseQuery
|
||||||
|
@[GraphQL::Field]
|
||||||
|
def hello(name : String) : String
|
||||||
|
"Hello, #{name}!"
|
||||||
|
end
|
||||||
|
|
||||||
|
@[GraphQL::Field]
|
||||||
|
def empire : Empire
|
||||||
|
Empire.new
|
||||||
|
end
|
||||||
|
|
||||||
|
@[GraphQL::Field]
|
||||||
|
def planet(id : ID? = nil) : Planet
|
||||||
|
Planet.new(id: id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
50
src/api/http_server.cr
Normal file
50
src/api/http_server.cr
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
class TETU::API::HttpServer
|
||||||
|
def self.start
|
||||||
|
spawn do
|
||||||
|
Kemal.run do |config|
|
||||||
|
server = config.server.not_nil!
|
||||||
|
server.bind_tcp(
|
||||||
|
host: ENV.fetch("HOST", "127.0.0.1"),
|
||||||
|
port: ENV.fetch("PORT", "3000").to_i,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
require "./game_query"
|
||||||
|
|
||||||
|
schema = GraphQL::Schema.new(TETU::API::Definitions::GameQuery.new)
|
||||||
|
|
||||||
|
|
||||||
|
# class CustomHandler < Kemal::Handler
|
||||||
|
# only ["/graphql"], "POST"
|
||||||
|
|
||||||
|
# def call(context)
|
||||||
|
# puts "Doing some custom stuff here"
|
||||||
|
# spawn do
|
||||||
|
# puts "Async stuff finished now"
|
||||||
|
# call_next context
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# add_handler CustomHandler.new
|
||||||
|
|
||||||
|
module TETU::API
|
||||||
|
PLAYER_CHANNEL = Channel(Tuple(String, Channel(String))).new
|
||||||
|
RESPONSE_CHANNEL = Channel(String).new
|
||||||
|
end
|
||||||
|
|
||||||
|
post "/graphql" do |env|
|
||||||
|
env.response.content_type = "application/json"
|
||||||
|
|
||||||
|
query = env.params.json["query"].as(String)
|
||||||
|
variables = env.params.json["variables"]?.as(Hash(String, JSON::Any)?)
|
||||||
|
operation_name = env.params.json["operationName"]?.as(String?)
|
||||||
|
context = TETU::API::Definitions::PlayerContext.new(TETU::API::PLAYER_CHANNEL)
|
||||||
|
schema.execute(query, variables, operation_name, context)
|
||||||
|
end
|
||||||
|
|
||||||
|
get "/" do |env|
|
||||||
|
"<html></html>"
|
||||||
|
end
|
3
src/api/objects.cr
Normal file
3
src/api/objects.cr
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
require "./objects/base"
|
||||||
|
require "./objects/planet"
|
||||||
|
require "./objects/all"
|
48
src/api/objects/all.cr
Normal file
48
src/api/objects/all.cr
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
require "./base"
|
||||||
|
require "./planet"
|
||||||
|
|
||||||
|
module TETU::API::Definitions
|
||||||
|
@[GraphQL::Object]
|
||||||
|
class Star < GraphQL::BaseObject
|
||||||
|
@@i : ID = 0
|
||||||
|
|
||||||
|
def initialize(id : Int32? = nil)
|
||||||
|
if id.nil?
|
||||||
|
@id = @@i
|
||||||
|
@@i += 1
|
||||||
|
else
|
||||||
|
@id = id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@[GraphQL::Field]
|
||||||
|
getter id : ID
|
||||||
|
|
||||||
|
@[GraphQL::Field]
|
||||||
|
def name : String
|
||||||
|
"my #{@id}th star name"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module TETU::API::Definitions
|
||||||
|
@[GraphQL::Object]
|
||||||
|
class Empire < GraphQL::BaseObject
|
||||||
|
@[GraphQL::Field]
|
||||||
|
def name : String
|
||||||
|
"Player"
|
||||||
|
end
|
||||||
|
|
||||||
|
@[GraphQL::Field]
|
||||||
|
def stars(context) : Array(Star)
|
||||||
|
context.player_channel.send({ "stars", TETU::API::RESPONSE_CHANNEL })
|
||||||
|
answer = TETU::API::RESPONSE_CHANNEL.receive
|
||||||
|
answer.split(",").map { |name| Star.new }
|
||||||
|
end
|
||||||
|
|
||||||
|
@[GraphQL::Field]
|
||||||
|
def planets : Array(Planet)
|
||||||
|
[] of Planet
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
8
src/api/objects/base.cr
Normal file
8
src/api/objects/base.cr
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
module TETU::API::Definitions
|
||||||
|
alias ID = Int32
|
||||||
|
|
||||||
|
class PlayerContext < GraphQL::Context
|
||||||
|
def initialize(@player_channel : Channel(Tuple(String, Channel(String))))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
23
src/api/objects/planet.cr
Normal file
23
src/api/objects/planet.cr
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
module TETU::API::Definitions
|
||||||
|
@[GraphQL::Object]
|
||||||
|
class Planet < GraphQL::BaseObject
|
||||||
|
@@i : ID = 0
|
||||||
|
|
||||||
|
def initialize(id : Int32? = nil)
|
||||||
|
if id.nil?
|
||||||
|
@id = @@i
|
||||||
|
@@i += 1
|
||||||
|
else
|
||||||
|
@id = id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@[GraphQL::Field]
|
||||||
|
getter id : ID
|
||||||
|
|
||||||
|
@[GraphQL::Field]
|
||||||
|
def name : String
|
||||||
|
"my #{@id}th planet name"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
33
src/core.cr
33
src/core.cr
|
@ -1,24 +1,20 @@
|
||||||
# require "log"
|
|
||||||
require "yaml"
|
require "yaml"
|
||||||
|
|
||||||
require "entitas"
|
require "entitas"
|
||||||
require "crsfml"
|
require "graphql"
|
||||||
require "imgui"
|
|
||||||
require "imgui-sfml"
|
|
||||||
require "spoved/logger"
|
require "spoved/logger"
|
||||||
|
require "kemal"
|
||||||
|
|
||||||
module TETU
|
module TETU
|
||||||
spoved_logger level: :info, io: STDOUT, bind: true
|
spoved_logger level: :info, io: STDOUT, bind: true
|
||||||
|
|
||||||
# TO BE USED
|
# TODO: TO BE USED
|
||||||
module Systems
|
module Systems
|
||||||
# Log = TETU::Log.for(self)
|
|
||||||
spoved_logger level: :info, io: STDOUT, bind: true
|
spoved_logger level: :info, io: STDOUT, bind: true
|
||||||
end
|
end
|
||||||
|
|
||||||
# TO BE USED
|
# TODO: TO BE USED
|
||||||
module Components
|
module Components
|
||||||
# Log = TETU::Log.for(self)
|
|
||||||
spoved_logger level: :info, io: STDOUT, bind: true
|
spoved_logger level: :info, io: STDOUT, bind: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -28,9 +24,9 @@ end
|
||||||
|
|
||||||
require "./helpers/*"
|
require "./helpers/*"
|
||||||
require "./core/*"
|
require "./core/*"
|
||||||
require "./ui_service"
|
|
||||||
require "./components"
|
require "./components"
|
||||||
require "./systems"
|
require "./systems"
|
||||||
|
require "./api"
|
||||||
|
|
||||||
class TETU::EconomicSystems < Entitas::Feature
|
class TETU::EconomicSystems < Entitas::Feature
|
||||||
def initialize(contexts : Contexts)
|
def initialize(contexts : Contexts)
|
||||||
|
@ -42,22 +38,16 @@ class TETU::EconomicSystems < Entitas::Feature
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class TETU::UiSystems < Entitas::Feature
|
class TETU::PlayerSystems < Entitas::Feature
|
||||||
def initialize(contexts : Contexts)
|
def initialize(contexts : Contexts)
|
||||||
@name = "UI Systems"
|
@name = "Player Systems"
|
||||||
|
add RequestHandlerSystem.new(contexts, player_channel)
|
||||||
add UiInitSystem.new(contexts)
|
|
||||||
add UiBackgroundSystem.new(contexts)
|
|
||||||
add UiEmpireSystem.new(contexts)
|
|
||||||
add UiPlanetSystem.new(contexts)
|
|
||||||
add UiDrawSystem.new(contexts) # keep at the end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class TETU::TimeSystems < Entitas::Feature
|
class TETU::TimeSystems < Entitas::Feature
|
||||||
def initialize(contexts : Contexts)
|
def initialize(contexts : Contexts)
|
||||||
@name = "Time Systems"
|
@name = "Time Systems"
|
||||||
|
|
||||||
add TimeSystem.new(contexts)
|
add TimeSystem.new(contexts)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -68,12 +58,12 @@ class TETU::MainWorld
|
||||||
def start
|
def start
|
||||||
# get a reference to the contexts
|
# get a reference to the contexts
|
||||||
contexts = Contexts.shared_instance
|
contexts = Contexts.shared_instance
|
||||||
|
|
||||||
# create the systems by creating individual features
|
# create the systems by creating individual features
|
||||||
@systems = Entitas::Feature.new("systems")
|
@systems = Entitas::Feature.new("systems")
|
||||||
.add(TimeSystems.new(contexts))
|
.add(TimeSystems.new(contexts))
|
||||||
.add(EconomicSystems.new(contexts))
|
.add(EconomicSystems.new(contexts))
|
||||||
.add(UiSystems.new(contexts))
|
.add(PlayerSystems.new(contexts))
|
||||||
|
# .add(UiSystems.new(contexts))
|
||||||
@systems.init
|
@systems.init
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -81,7 +71,6 @@ class TETU::MainWorld
|
||||||
# call execute on all the ExecuteSystems and
|
# call execute on all the ExecuteSystems and
|
||||||
# ReactiveSystems that were triggered last frame
|
# ReactiveSystems that were triggered last frame
|
||||||
@systems.execute
|
@systems.execute
|
||||||
|
|
||||||
# call cleanup on all the CleanupSystems
|
# call cleanup on all the CleanupSystems
|
||||||
@systems.cleanup
|
@systems.cleanup
|
||||||
end
|
end
|
||||||
|
@ -115,9 +104,11 @@ module TETU
|
||||||
t2 = Time.local
|
t2 = Time.local
|
||||||
logger.debug { "Duration: #{t2 - t1}" }
|
logger.debug { "Duration: #{t2 - t1}" }
|
||||||
logger.debug { "" }
|
logger.debug { "" }
|
||||||
|
sleep 0.1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
TETU::API::HttpServer.start
|
||||||
TETU.main_loop
|
TETU.main_loop
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
require "./configuration"
|
require "./configuration"
|
||||||
|
|
||||||
class TETU::Window
|
# class TETU::Window
|
||||||
@@instance = Window.new
|
# @@instance = Window.new
|
||||||
|
|
||||||
def self.instance
|
# def self.instance
|
||||||
@@instance
|
# @@instance
|
||||||
end
|
# end
|
||||||
|
|
||||||
GALAXY_WIDTH = TETU::MAX_X
|
# GALAXY_WIDTH = TETU::MAX_X
|
||||||
GALAXY_HEIGHT = TETU::MAX_Y
|
# GALAXY_HEIGHT = TETU::MAX_Y
|
||||||
UI_WIDTH = GALAXY_WIDTH + TETU::UI_CONF["right_sidebar"].as_i64
|
# UI_WIDTH = GALAXY_WIDTH + TETU::UI_CONF["right_sidebar"].as_i64
|
||||||
UI_HEIGHT = GALAXY_HEIGHT
|
# UI_HEIGHT = GALAXY_HEIGHT
|
||||||
SQUARE_SIZE = TETU::UI_CONF["square_size"].as_i64
|
# SQUARE_SIZE = TETU::UI_CONF["square_size"].as_i64
|
||||||
|
|
||||||
GALAXY = SF::Texture.from_file("assets/#{GALAXY_WIDTH}x#{GALAXY_HEIGHT}/galaxy.jpg")
|
# GALAXY = SF::Texture.from_file("assets/#{GALAXY_WIDTH}x#{GALAXY_HEIGHT}/galaxy.jpg")
|
||||||
|
|
||||||
getter window : SF::RenderWindow
|
# getter window : SF::RenderWindow
|
||||||
getter delta_clock : SF::Clock
|
# getter delta_clock : SF::Clock
|
||||||
property planet_menu_selected : GameEntity? = nil
|
# property planet_menu_selected : GameEntity? = nil
|
||||||
|
|
||||||
def initialize
|
# def initialize
|
||||||
@window = SF::RenderWindow.new(
|
# @window = SF::RenderWindow.new(
|
||||||
SF::VideoMode.new(UI_WIDTH, UI_HEIGHT),
|
# SF::VideoMode.new(UI_WIDTH, UI_HEIGHT),
|
||||||
"To the End of The Universe",
|
# "To the End of The Universe",
|
||||||
)
|
# )
|
||||||
@delta_clock = SF::Clock.new
|
# @delta_clock = SF::Clock.new
|
||||||
end
|
# end
|
||||||
|
|
||||||
def [](k)
|
# def [](k)
|
||||||
@data[k]
|
# @data[k]
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
require "./systems/*"
|
require "./systems/*"
|
||||||
require "./systems/ui/*"
|
require "./systems/player/*"
|
||||||
|
|
20
src/systems/player/request_handler.cr
Normal file
20
src/systems/player/request_handler.cr
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
class TETU::RequestHandlerSystem
|
||||||
|
include Entitas::Systems::ExecuteSystem
|
||||||
|
spoved_logger level: :info, io: STDOUT, bind: true
|
||||||
|
|
||||||
|
getter player_channel : Channel(Tuple(String, Channel(String)))
|
||||||
|
@contexts : Contexts
|
||||||
|
|
||||||
|
def initialize(@contexts, @player_channel)
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute
|
||||||
|
message, responder = player_channel.receive
|
||||||
|
if message == "stars"
|
||||||
|
stars = @contexts.game.get_group Entitas::Matcher.all_of(Named, Position, CelestialBody, PlayerOwned).none_of(StellarPosition)
|
||||||
|
responder.send stars.entities.map { |entity| entity.named.name }.join(",")
|
||||||
|
else
|
||||||
|
responder.send ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user