aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kennel/config.py4
-rw-r--r--kennel/engine/components/controllable.py3
-rw-r--r--kennel/engine/entities/entity.py10
-rw-r--r--kennel/engine/systems/network.py1
-rw-r--r--kennel/engine/systems/system.py1
-rw-r--r--kennel/engine/systems/world.py24
-rw-r--r--kennel/kennel.py7
-rw-r--r--kennel/main.py20
-rw-r--r--templates/index.html2
9 files changed, 59 insertions, 13 deletions
diff --git a/kennel/config.py b/kennel/config.py
index 8cec699..4452044 100644
--- a/kennel/config.py
+++ b/kennel/config.py
@@ -5,8 +5,8 @@ load_dotenv()
class Config:
- SIMULATION_WIDTH = int(os.getenv("SIMULATION_WIDTH", 1000))
- SIMULATION_HEIGHT = int(os.getenv("SIMULATION_HEIGHT", 1000))
+ WORLD_WIDTH = int(os.getenv("WORLD_WIDTH", 1000))
+ WORLD_HEIGHT = int(os.getenv("WORLD_HEIGHT", 1000))
HATECOMPUTERS_ENDPOINT = os.getenv(
"HATECOMPUTERS_ENDPOINT", "https://hatecomputers.club"
diff --git a/kennel/engine/components/controllable.py b/kennel/engine/components/controllable.py
index 49b0557..25ec835 100644
--- a/kennel/engine/components/controllable.py
+++ b/kennel/engine/components/controllable.py
@@ -10,4 +10,5 @@ class Controllable(Component):
return f"Controllable(by={self.by})"
def dict(self) -> dict:
- return {"by": self.by}
+ # don't serialize who owns this
+ return {}
diff --git a/kennel/engine/entities/entity.py b/kennel/engine/entities/entity.py
index 0ca8666..b72e996 100644
--- a/kennel/engine/entities/entity.py
+++ b/kennel/engine/entities/entity.py
@@ -23,6 +23,13 @@ class Entity:
def add_component(self, component: Component) -> None:
self.components[component.component_type] = component
+ def to_dict(self) -> dict:
+ return {
+ "entity_type": self.entity_type,
+ "id": self.id,
+ "components": {k: v.dict() for k, v in self.components.items()},
+ }
+
class EntityManager:
def __init__(self):
@@ -58,3 +65,6 @@ class EntityManager:
def get_entity(self, entity_id: str) -> Optional[Entity]:
return self.entities.get(entity_id)
+
+ def to_dict(self) -> dict:
+ return {k: v.to_dict() for k, v in self.entities.items()}
diff --git a/kennel/engine/systems/network.py b/kennel/engine/systems/network.py
index 7df8088..c9696c8 100644
--- a/kennel/engine/systems/network.py
+++ b/kennel/engine/systems/network.py
@@ -6,6 +6,7 @@ import asyncio
class EventType(str, Enum):
+ INITIAL_STATE = "INITIAL_STATE"
ENTITY_BORN = "ENTITY_BORN"
ENTITY_POSITION_UPDATE = "ENTITY_POSITION_UPDATE"
ENTITY_DEATH = "ENTITY_DEATH"
diff --git a/kennel/engine/systems/system.py b/kennel/engine/systems/system.py
index 0e51f3a..78bda58 100644
--- a/kennel/engine/systems/system.py
+++ b/kennel/engine/systems/system.py
@@ -5,6 +5,7 @@ from abc import abstractmethod
class SystemType(str, Enum):
NETWORK = "NETWORK"
+ WORLD = "WORLD"
class System:
diff --git a/kennel/engine/systems/world.py b/kennel/engine/systems/world.py
new file mode 100644
index 0000000..396e7cb
--- /dev/null
+++ b/kennel/engine/systems/world.py
@@ -0,0 +1,24 @@
+from kennel.engine.systems.system import System, SystemType
+from kennel.engine.entities.entity import EntityManager
+from kennel.engine.components.component import ComponentType
+from kennel.app import logger
+
+
+class WorldSystem(System):
+ def __init__(self, width: int, height: int):
+ super().__init__(SystemType.WORLD)
+ self.width = width
+ self.height = height
+
+ async def update(self, entity_manager: EntityManager, delta_time: float):
+ entities = entity_manager.get_entities_with_component(ComponentType.POSITION)
+ for entity in entities:
+ position = entity.get_component(ComponentType.POSITION)
+ if position is None:
+ logger.error(f"Entity {entity} has no position component")
+ continue
+
+ position.x = max(0, min(self.width, position.x))
+ position.y = max(0, min(self.height, position.y))
+
+ entity.add_component(position)
diff --git a/kennel/kennel.py b/kennel/kennel.py
index 0b38261..61847a5 100644
--- a/kennel/kennel.py
+++ b/kennel/kennel.py
@@ -10,6 +10,7 @@ from kennel.engine.systems.network import (
Event,
EventType,
)
+from kennel.engine.systems.world import WorldSystem
from kennel.config import config
from .app import logger
from typing import List
@@ -59,9 +60,6 @@ class KennelClientEventTransformer(ClientEventTransformer):
logger.error(f"Entity {id} does not exist")
return event
for component_type in entity.components:
- if component_type == ComponentType.CONTROLLABLE:
- # Do not send controllable components to clients
- continue
component = entity.get_component(component_type)
if component is not None:
event.data[component_type] = component.dict()
@@ -69,8 +67,9 @@ class KennelClientEventTransformer(ClientEventTransformer):
return event
+system_manager.add_system(WorldSystem(config.WORLD_WIDTH, config.WORLD_HEIGHT))
system_manager.add_system(
- NetworkSystem(EventProcessor(), KennelClientEventTransformer())
+ NetworkSystem(EventProcessor(), KennelClientEventTransformer()),
)
kennel = Game(entity_manager, system_manager, config.MIN_TIME_STEP)
diff --git a/kennel/main.py b/kennel/main.py
index 122e40a..17a143b 100644
--- a/kennel/main.py
+++ b/kennel/main.py
@@ -12,16 +12,16 @@ from fastapi.staticfiles import StaticFiles
from kennel.engine.systems.system import SystemType
from kennel.engine.systems.network import Event, Publishable, EventType
from typing import Annotated, Optional
-from .kennel import (
+from kennel.kennel import (
kennel,
system_manager,
entity_manager,
create_session_controllable_entities,
)
-from .app import app, templates, logger
-from .kennelcats import KennelCatService
-from .middleware import logger_middleware
-from .config import config
+from kennel.app import app, templates, logger
+from kennel.kennelcats import KennelCatService
+from kennel.middleware import logger_middleware
+from kennel.config import config
import asyncio
import uuid
@@ -85,6 +85,16 @@ async def websocket_endpoint(
await websocket.accept()
logger.info(f"Websocket connection established for session {session}")
+ await websocket.send_json(
+ {
+ "event_type": EventType.INITIAL_STATE,
+ "data": {
+ "world": {"width": config.WORLD_WIDTH, "height": config.WORLD_HEIGHT},
+ "entities": kennel.entity_manager.to_dict(),
+ },
+ }
+ )
+
session_entities = create_session_controllable_entities(session)
try:
network_system = system_manager.get_system(SystemType.NETWORK)
diff --git a/templates/index.html b/templates/index.html
index 1bb53e8..07acb30 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -5,10 +5,10 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Kennel Club</title>
+ <script src='https://unpkg.com/panzoom@9.4.0/dist/panzoom.min.js'></script>
</head>
<body>
<div id="kennel-window"></div>
<script src="{{ url_for('static', path='/index.js') }}"></script>
</body>
</html>
-