Giter Site home page Giter Site logo

wurwolves's Introduction

Wurwolves

A simple web app to play Werewolves (AKA Mafia) online. Live now at wurwolves.com.

Deployment

This repository can be used to build docker containers for the frontend and backend, using nix, or can be run using nix directly.

  1. Configure .env

then either:

  1. Run nix run .#frontend in one window
  2. ...and nix run .#backend in another

or:

  1. nix run to build docker images and store them in the local registry
  2. docker compose up

Local development

For local development, install nix and direnv then use::

  1. direnv allow
  2. npm i
  3. npm run dev

Outline

The backend runs a FastAPI REST interface in python. The frontend is React.js served by its built-in server.

wurwolves's People

Contributors

charlesbaynham avatar dependabot[bot] avatar pre-commit-ci[bot] avatar

Stargazers

Alvise Vianello avatar  avatar

Watchers

 avatar  avatar

wurwolves's Issues

Plague carrier

Dies on the nth night of plague. If attacked by a wolf before that, takes the wolf with them.

Crash on game end when spectators kicked

See

$ heroku logs --tail
2020-07-06T20:30:26.292575+00:00 app[web.1]: [1] (Background on this error at: http://sqlalche.me/e/gkpj)
2020-07-06T20:30:26.292658+00:00 app[web.1]: [1] INFO:     User 411530e5-e9cd-4c41-8072-9161ecba121f joining now
2020-07-06T20:30:26.292703+00:00 heroku[router]: at=info method=GET path="/api/cottage-grove-is-late/state_hash?known_hash=0" host=wurwolves.herokuapp.com request_id=cef9a691-2452-48d7-9de3-3dd564d76cd4 fwd="81.101.135.226" dyno=web.1 connect=0ms service=401ms status=500 bytes=216 protocol=https  
2020-07-06T20:30:26.293483+00:00 heroku[router]: at=info method=POST path="/api/cottage-grove-is-late/join" host=wurwolves.herokuapp.com request_id=68cbb527-c390-49d0-99c0-b3c63f587dce fwd="81.101.135.226" dyno=web.1 connect=0ms service=402ms status=200 bytes=170 protocol=https
2020-07-06T20:30:26.299251+00:00 heroku[router]: at=info method=GET path="/cottage-grove-is-late" host=wurwolves.herokuapp.com request_id=5d841fa6-6c31-4e35-95f8-fa910716adf9 fwd="84.68.75.136" dyno=web.1 connect=0ms service=2ms status=304 bytes=237 protocol=https
2020-07-06T20:30:26.301589+00:00 heroku[router]: at=info method=GET path="/images/bike.png" host=wurwolves.herokuapp.com request_id=c697343e-b7df-4a28-bc6b-eb4f63e24eb7 fwd="3.9.5.152" dyno=web.1 connect=0ms service=7ms status=304 bytes=238 protocol=https
2020-07-06T20:30:26.310856+00:00 app[web.1]: [1] INFO:     3.9.5.152:0 - "POST /api/cottage-grove-is-late/join HTTP/1.1" 200 OK
2020-07-06T20:30:26.312351+00:00 heroku[router]: at=info method=POST path="/api/cottage-grove-is-late/join" host=wurwolves.herokuapp.com request_id=0b4bfbe7-2e7d-4899-affb-36e2892689b6 fwd="3.9.5.152" dyno=web.1 connect=1ms service=29ms status=200 bytes=170 protocol=https
2020-07-06T20:30:26.343180+00:00 heroku[router]: at=info method=GET path="/images/logo.svg" host=wurwolves.herokuapp.com request_id=79f29782-b03e-4703-ab6d-dbfc55e425d9 fwd="82.21.239.77" dyno=web.1 connect=0ms service=1ms status=304 bytes=238 protocol=https
2020-07-06T20:30:26.351617+00:00 app[web.1]: [1] INFO:     Remove player JD for inactivity (p.user.last_seen=2020-07-06 20:29:24.625747, threshold=2020-07-06 20:29:46.335551
2020-07-06T20:30:26.357092+00:00 heroku[router]: at=info method=GET path="/images/logo.svg" host=wurwolves.herokuapp.com request_id=e3324aa4-de76-443f-b248-524382eb0720 fwd="86.148.4.18" dyno=web.1 connect=0ms service=5ms status=304 bytes=238 protocol=https
2020-07-06T20:30:26.376865+00:00 app[web.1]: [1] INFO:     Triggering updates for game 8032217
2020-07-06T20:30:26.377112+00:00 app[web.1]: [1] INFO:     3.9.5.152:0 - "GET /api/cottage-grove-is-late/state_hash?known_hash=0 HTTP/1.1" 500 Internal Server Error
2020-07-06T20:30:26.378722+00:00 app[web.1]: [1] ERROR:    Exception in ASGI application
2020-07-06T20:30:26.378723+00:00 app[web.1]: [1] Traceback (most recent call last):
2020-07-06T20:30:26.378723+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py", line 385, in run_asgi
2020-07-06T20:30:26.378724+00:00 app[web.1]: [1]     result = await app(self.scope, self.receive, self.send)
2020-07-06T20:30:26.378724+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
2020-07-06T20:30:26.378725+00:00 app[web.1]: [1]     return await self.app(scope, receive, send)
2020-07-06T20:30:26.378725+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/fastapi/applications.py", line 146, in __call__
2020-07-06T20:30:26.378726+00:00 app[web.1]: [1]     await super().__call__(scope, receive, send)
2020-07-06T20:30:26.378726+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/applications.py", line 102, in __call__
2020-07-06T20:30:26.378726+00:00 app[web.1]: [1]     await self.middleware_stack(scope, receive, send)
2020-07-06T20:30:26.378727+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/middleware/errors.py", line 181, in __call__
2020-07-06T20:30:26.378728+00:00 app[web.1]: [1]     raise exc from None
2020-07-06T20:30:26.378728+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/middleware/errors.py", line 159, in __call__
2020-07-06T20:30:26.378729+00:00 app[web.1]: [1]     await self.app(scope, receive, _send)
2020-07-06T20:30:26.378729+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/exceptions.py", line 82, in __call__
2020-07-06T20:30:26.378730+00:00 app[web.1]: [1]     raise exc from None
2020-07-06T20:30:26.378730+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/exceptions.py", line 71, in __call__
2020-07-06T20:30:26.378730+00:00 app[web.1]: [1]     await self.app(scope, receive, sender)
2020-07-06T20:30:26.378731+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/routing.py", line 550, in __call__2020-07-06T20:30:26.378731+00:00 app[web.1]: [1]     await route.handle(scope, receive, send)
2020-07-06T20:30:26.378731+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/routing.py", line 227, in handle  
2020-07-06T20:30:26.378732+00:00 app[web.1]: [1]     await self.app(scope, receive, send)
2020-07-06T20:30:26.378732+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/routing.py", line 41, in app
2020-07-06T20:30:26.378733+00:00 app[web.1]: [1]     response = await func(request)
2020-07-06T20:30:26.378733+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/fastapi/routing.py", line 197, in app       
2020-07-06T20:30:26.378733+00:00 app[web.1]: [1]     dependant=dependant, values=values, is_coroutine=is_coroutine
2020-07-06T20:30:26.378734+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/fastapi/routing.py", line 148, in run_endpoint_function
2020-07-06T20:30:26.378734+00:00 app[web.1]: [1]     return await dependant.call(**values)
2020-07-06T20:30:26.378735+00:00 app[web.1]: [1]   File "./backend/main.py", line 55, in get_state_hash
2020-07-06T20:30:26.378735+00:00 app[web.1]: [1]     game.player_keepalive(user_id)
2020-07-06T20:30:26.378735+00:00 app[web.1]: [1]   File "./backend/game.py", line 108, in f
2020-07-06T20:30:26.378736+00:00 app[web.1]: [1]     raise e
2020-07-06T20:30:26.378737+00:00 app[web.1]: [1]   File "./backend/game.py", line 98, in f
2020-07-06T20:30:26.378737+00:00 app[web.1]: [1]     out = func(self, *args, **kwargs)
2020-07-06T20:30:26.378737+00:00 app[web.1]: [1]   File "./backend/game.py", line 383, in player_keepalive
2020-07-06T20:30:26.378738+00:00 app[web.1]: [1]     self.kick(p)
2020-07-06T20:30:26.378738+00:00 app[web.1]: [1]   File "./backend/game.py", line 108, in f
2020-07-06T20:30:26.378738+00:00 app[web.1]: [1]     raise e
2020-07-06T20:30:26.378739+00:00 app[web.1]: [1]   File "./backend/game.py", line 104, in f
2020-07-06T20:30:26.378739+00:00 app[web.1]: [1]     self._session.commit()
2020-07-06T20:30:26.378739+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 1042, in commit
2020-07-06T20:30:26.378740+00:00 app[web.1]: [1]     self.transaction.commit()
2020-07-06T20:30:26.378740+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 504, in commit
2020-07-06T20:30:26.378741+00:00 app[web.1]: [1]     self._prepare_impl()
2020-07-06T20:30:26.378741+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 483, in _prepare_impl
2020-07-06T20:30:26.378741+00:00 app[web.1]: [1]     self.session.flush()
2020-07-06T20:30:26.378742+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 2523, in flush
2020-07-06T20:30:26.378742+00:00 app[web.1]: [1]     self._flush(objects)
2020-07-06T20:30:26.378743+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 2664, in _flush
2020-07-06T20:30:26.378743+00:00 app[web.1]: [1]     transaction.rollback(_capture_exception=True)
2020-07-06T20:30:26.378743+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py", line 69, in __exit__
2020-07-06T20:30:26.378744+00:00 app[web.1]: [1]     exc_value, with_traceback=exc_tb,
2020-07-06T20:30:26.378744+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/util/compat.py", line 178, in raise_
2020-07-06T20:30:26.378745+00:00 app[web.1]: [1]     raise exception
2020-07-06T20:30:26.378745+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 2624, in _flush
2020-07-06T20:30:26.378745+00:00 app[web.1]: [1]     flush_context.execute()
2020-07-06T20:30:26.378746+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/unitofwork.py", line 422, in 
execute
2020-07-06T20:30:26.378749+00:00 app[web.1]: [1]     rec.execute(self)
2020-07-06T20:30:26.378750+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/unitofwork.py", line 624, in 
execute
2020-07-06T20:30:26.378750+00:00 app[web.1]: [1]     uow,
2020-07-06T20:30:26.378756+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/persistence.py", line 348, in delete_obj
2020-07-06T20:30:26.378757+00:00 app[web.1]: [1]     delete,
2020-07-06T20:30:26.378758+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/persistence.py", line 1340, in _emit_delete_statements
2020-07-06T20:30:26.378758+00:00 app[web.1]: [1]     c = connection.execute(statement, del_objects)
2020-07-06T20:30:26.378758+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1020, in execute
2020-07-06T20:30:26.378759+00:00 app[web.1]: [1]     return meth(self, multiparams, params)
2020-07-06T20:30:26.378759+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/sql/elements.py", line 298, in _execute_on_connection
2020-07-06T20:30:26.378760+00:00 app[web.1]: [1]     return connection._execute_clauseelement(self, multiparams, params)
2020-07-06T20:30:26.378760+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1139, in _execute_clauseelement
2020-07-06T20:30:26.378760+00:00 app[web.1]: [1]     distilled_params,
2020-07-06T20:30:26.378761+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1324, in _execute_context
2020-07-06T20:30:26.378761+00:00 app[web.1]: [1]     e, statement, parameters, cursor, context
2020-07-06T20:30:26.378761+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1518, in _handle_dbapi_exception
2020-07-06T20:30:26.378762+00:00 app[web.1]: [1]     sqlalchemy_exception, with_traceback=exc_info[2], from_=e
2020-07-06T20:30:26.378762+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/util/compat.py", line 178, in raise_
2020-07-06T20:30:26.378763+00:00 app[web.1]: [1]     raise exception
2020-07-06T20:30:26.378763+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1284, in _execute_context
2020-07-06T20:30:26.378763+00:00 app[web.1]: [1]     cursor, statement, parameters, context
2020-07-06T20:30:26.378764+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 590, in 
do_execute
2020-07-06T20:30:26.378764+00:00 app[web.1]: [1]     cursor.execute(statement, parameters)
2020-07-06T20:30:26.378765+00:00 app[web.1]: [1] sqlalchemy.exc.IntegrityError: (psycopg2.errors.ForeignKeyViolation) update or delete on table "players" violates foreign key constraint "actions_selected_player_id_fkey" on table "actions"
2020-07-06T20:30:26.378765+00:00 app[web.1]: [1] DETAIL:  Key (id)=(17) is still referenced from table "actions".
2020-07-06T20:30:26.378765+00:00 app[web.1]: [1]
2020-07-06T20:30:26.378766+00:00 app[web.1]: [1] [SQL: DELETE FROM players WHERE players.id = %(id)s]
2020-07-06T20:30:26.378766+00:00 app[web.1]: [1] [parameters: {'id': 17}]
2020-07-06T20:30:26.378767+00:00 app[web.1]: [1] (Background on this error at: http://sqlalche.me/e/gkpj)
2020-07-06T20:30:26.399854+00:00 heroku[router]: at=info method=GET path="/icons/site.webmanifest" host=wurwolves.herokuapp.com request_id=31dc7bfa-05d7-4964-b8ef-c755ca9a0c14 fwd="3.9.5.152" dyno=web.1 connect=0ms service=1ms status=304 bytes=237 protocol=https
2020-07-06T20:30:26.488862+00:00 heroku[router]: at=info method=GET path="/cottage-grove-is-late" host=wurwolves.herokuapp.com request_id=5f45eab6-0756-4c28-b374-0bfb949012a6 fwd="3.9.5.152" dyno=web.1 connect=1ms service=4ms status=304 bytes=237 protocol=https
2020-07-06T20:30:26.425928+00:00 heroku[router]: at=info method=GET path="/static/css/2.829c9cb5.chunk.css" host=wurwolves.herokuapp.com request_id=e0523986-ff9d-4d64-9d7f-e7feb37d1ef9 fwd="84.68.75.136" dyno=web.1 connect=0ms service=2ms status=304 bytes=239 protocol=https
2020-07-06T20:30:26.452477+00:00 heroku[router]: at=info method=GET path="/static/css/main.9277d78a.chunk.css" host=wurwolves.herokuapp.com request_id=e9ad1608-3072-46f5-8859-30b5d74e82f3 fwd="81.101.135.226" dyno=web.1 connect=0ms service=1ms status=304 bytes=237 protocol=https
2020-07-06T20:30:26.427685+00:00 heroku[router]: at=info method=GET path="/static/js/main.f85e60f7.chunk.js" host=wurwolves.herokuapp.com request_id=7ca0df56-6e68-4355-89b3-4cfe29057690 fwd="84.68.75.136" dyno=web.1 connect=1ms service=2ms status=304 bytes=238 protocol=https
2020-07-06T20:30:26.548048+00:00 heroku[router]: at=info method=GET path="/api/cottage-grove-is-late/state_hash?known_hash=0" host=wurwolves.herokuapp.com request_id=16cae53a-e9a2-4fdb-b1cd-c2ab6c4eacb2 fwd="82.21.239.77" dyno=web.1 connect=0ms service=157ms status=500 bytes=216 protocol=https    
2020-07-06T20:30:26.483233+00:00 heroku[router]: at=info method=GET path="/icons/site.webmanifest" host=wurwolves.herokuapp.com request_id=636bc752-1885-44f3-9ef8-1e99f3e00daf fwd="86.148.4.18" dyno=web.1 connect=1ms service=2ms status=304 bytes=237 protocol=https
2020-07-06T20:30:26.438771+00:00 heroku[router]: at=info method=GET path="/cottage-grove-is-late" host=wurwolves.herokuapp.com request_id=b24b35ea-2f21-4b8a-9e57-0af205e45b50 fwd="92.6.152.125" dyno=web.1 connect=1ms service=2ms status=304 bytes=237 protocol=https
2020-07-06T20:30:26.471908+00:00 heroku[router]: at=info method=GET path="/cottage-grove-is-late" host=wurwolves.herokuapp.com request_id=5283d9f2-259a-4af7-a339-9f3efbc8ebb0 fwd="81.101.135.226" dyno=web.1 connect=1ms service=9ms status=200 bytes=2939 protocol=https
2020-07-06T20:30:26.416843+00:00 app[web.1]: [1] INFO:     Remove player JD for inactivity (p.user.last_seen=2020-07-06 20:29:24.625747, threshold=2020-07-06 20:29:46.401017
2020-07-06T20:30:26.442956+00:00 app[web.1]: [1] INFO:     Triggering updates for game 8032217
2020-07-06T20:30:26.443283+00:00 app[web.1]: [1] INFO:     86.148.4.18:0 - "GET /api/cottage-grove-is-late/state_hash?known_hash=0 HTTP/1.1" 500 Internal Server Error
2020-07-06T20:30:26.444118+00:00 app[web.1]: [1] ERROR:    Exception in ASGI application
2020-07-06T20:30:26.444119+00:00 app[web.1]: [1] Traceback (most recent call last):
2020-07-06T20:30:26.444120+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py", line 385, in run_asgi
2020-07-06T20:30:26.444120+00:00 app[web.1]: [1]     result = await app(self.scope, self.receive, self.send)
2020-07-06T20:30:26.444121+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
2020-07-06T20:30:26.444121+00:00 app[web.1]: [1]     return await self.app(scope, receive, send)
2020-07-06T20:30:26.444122+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/fastapi/applications.py", line 146, in __call__
2020-07-06T20:30:26.444122+00:00 app[web.1]: [1]     await super().__call__(scope, receive, send)
2020-07-06T20:30:26.444123+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/applications.py", line 102, in __call__
2020-07-06T20:30:26.444123+00:00 app[web.1]: [1]     await self.middleware_stack(scope, receive, send)
2020-07-06T20:30:26.444124+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/middleware/errors.py", line 181, in __call__
2020-07-06T20:30:26.444124+00:00 app[web.1]: [1]     raise exc from None
2020-07-06T20:30:26.444125+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/middleware/errors.py", line 159, in __call__
2020-07-06T20:30:26.444125+00:00 app[web.1]: [1]     await self.app(scope, receive, _send)
2020-07-06T20:30:26.444125+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/exceptions.py", line 82, in __call__
2020-07-06T20:30:26.444126+00:00 app[web.1]: [1]     raise exc from None
2020-07-06T20:30:26.444126+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/exceptions.py", line 71, in __call__
2020-07-06T20:30:26.444127+00:00 app[web.1]: [1]     await self.app(scope, receive, sender)
2020-07-06T20:30:26.444127+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/routing.py", line 550, in __call__2020-07-06T20:30:26.444128+00:00 app[web.1]: [1]     await route.handle(scope, receive, send)
2020-07-06T20:30:26.444128+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/routing.py", line 227, in handle
2020-07-06T20:30:26.444128+00:00 app[web.1]: [1]     await self.app(scope, receive, send)
2020-07-06T20:30:26.444129+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/starlette/routing.py", line 41, in app
2020-07-06T20:30:26.444129+00:00 app[web.1]: [1]     response = await func(request)
2020-07-06T20:30:26.444130+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/fastapi/routing.py", line 197, in app
2020-07-06T20:30:26.444130+00:00 app[web.1]: [1]     dependant=dependant, values=values, is_coroutine=is_coroutine
2020-07-06T20:30:26.444131+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/fastapi/routing.py", line 148, in run_endpoint_function
2020-07-06T20:30:26.444131+00:00 app[web.1]: [1]     return await dependant.call(**values)
2020-07-06T20:30:26.444132+00:00 app[web.1]: [1]   File "./backend/main.py", line 55, in get_state_hash
2020-07-06T20:30:26.444132+00:00 app[web.1]: [1]     game.player_keepalive(user_id)
2020-07-06T20:30:26.444132+00:00 app[web.1]: [1]   File "./backend/game.py", line 108, in f
2020-07-06T20:30:26.444133+00:00 app[web.1]: [1]     raise e
2020-07-06T20:30:26.444133+00:00 app[web.1]: [1]   File "./backend/game.py", line 98, in f
2020-07-06T20:30:26.444134+00:00 app[web.1]: [1]     out = func(self, *args, **kwargs)
2020-07-06T20:30:26.444134+00:00 app[web.1]: [1]   File "./backend/game.py", line 383, in player_keepalive
2020-07-06T20:30:26.444134+00:00 app[web.1]: [1]     self.kick(p)
2020-07-06T20:30:26.444135+00:00 app[web.1]: [1]   File "./backend/game.py", line 108, in f
2020-07-06T20:30:26.444135+00:00 app[web.1]: [1]     raise e
2020-07-06T20:30:26.444136+00:00 app[web.1]: [1]   File "./backend/game.py", line 104, in f
2020-07-06T20:30:26.444136+00:00 app[web.1]: [1]     self._session.commit()
2020-07-06T20:30:26.444137+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 1042, in commit
2020-07-06T20:30:26.444137+00:00 app[web.1]: [1]     self.transaction.commit()
2020-07-06T20:30:26.444137+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 504, in commit
2020-07-06T20:30:26.444138+00:00 app[web.1]: [1]     self._prepare_impl()
2020-07-06T20:30:26.444138+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 483, in _prepare_impl
2020-07-06T20:30:26.444139+00:00 app[web.1]: [1]     self.session.flush()
2020-07-06T20:30:26.444139+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 2523, in flush
2020-07-06T20:30:26.444139+00:00 app[web.1]: [1]     self._flush(objects)
2020-07-06T20:30:26.444140+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 2664, in _flush
2020-07-06T20:30:26.444140+00:00 app[web.1]: [1]     transaction.rollback(_capture_exception=True)
2020-07-06T20:30:26.444141+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py", line 69, in __exit__
2020-07-06T20:30:26.444141+00:00 app[web.1]: [1]     exc_value, with_traceback=exc_tb,
2020-07-06T20:30:26.444142+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/util/compat.py", line 178, in raise_
2020-07-06T20:30:26.444143+00:00 app[web.1]: [1]     raise exception
2020-07-06T20:30:26.444144+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 2624, in _flush
2020-07-06T20:30:26.444144+00:00 app[web.1]: [1]     flush_context.execute()
2020-07-06T20:30:26.444144+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/unitofwork.py", line 422, in 
execute
2020-07-06T20:30:26.444145+00:00 app[web.1]: [1]     rec.execute(self)
2020-07-06T20:30:26.444145+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/unitofwork.py", line 624, in 
execute
2020-07-06T20:30:26.444145+00:00 app[web.1]: [1]     uow,
2020-07-06T20:30:26.444149+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/persistence.py", line 348, in delete_obj
2020-07-06T20:30:26.444150+00:00 app[web.1]: [1]     delete,
2020-07-06T20:30:26.444150+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/orm/persistence.py", line 1340, in _emit_delete_statements
2020-07-06T20:30:26.444151+00:00 app[web.1]: [1]     c = connection.execute(statement, del_objects)
2020-07-06T20:30:26.444151+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1020, in execute
2020-07-06T20:30:26.444151+00:00 app[web.1]: [1]     return meth(self, multiparams, params)
2020-07-06T20:30:26.444151+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/sql/elements.py", line 298, in _execute_on_connection
2020-07-06T20:30:26.444152+00:00 app[web.1]: [1]     return connection._execute_clauseelement(self, multiparams, params)
2020-07-06T20:30:26.444152+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1139, in _execute_clauseelement
2020-07-06T20:30:26.444152+00:00 app[web.1]: [1]     distilled_params,
2020-07-06T20:30:26.444153+00:00 app[web.1]: [1]   File "/app/.heroku/python/lib/python3.7/site-packages/sqlalchemy/engine/base.py", line 1324, in _execute_context
2020-07-06T20:30:26.444153+00:00 app[web.1]: [1]     e, statement, parameters, cursor, context
^CTerminate batch job (Y/N)? ^C

Don't delete actions: keep for stats

It's a shame to throw away such a rich source of statistics! Actions should be kept in the database, but just filtered by a UUID associated with each game. To start a new game, you just change the UUID.

Role resolution is a disaster

The mixin-based, action modifying resolver network is a real headache and quite counter-intuitive.

This all comes about because it relies on altering actions rather than altering players. It would be much easier to understand if the do_modifier() steps all just altered players instead of actions. I didn't do this at first because I don't like having attributes on objects which aren't declared, so I preferred to keep action modifiers as mixins. I could mitigate this by having new role classes declare their intentions by adding fields to the definition of GamePlayer. GamePlayer could become a pydantic model, and new fields would have defaults. That way all GamePlayers would have all fields defined, and you'd have a definitive list of the fields that exist.

Each role would still be responsible for implementing the results appropriately, but that's how it currently is. I'd keep the triggering do_modifiers() system but it would alter GamePlayers instead of actions. I'd lose the ability to set prevented and have it respected in the do_modifiers round, but again, that's how it already is.

Priest

Once per game, can check the role (not alignment) of the person who was just lynched

Acolyte

Villager with no powers or knowledge, but wins with the wolves

Button text confusing

Hanscombe says:

From my one ‘Click someone's icon and click the button.’ looks like it should say ‘Click someone’s icon to select them’

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.