unix1 / nuk Goto Github PK
View Code? Open in Web Editor NEWGeneric turn based game server in Erlang/OTP
License: GNU General Public License v2.0
Generic turn based game server in Erlang/OTP
License: GNU General Public License v2.0
Add following documentation:
System must be able to:
nuk_game_engine
behavior defined in #5gen_fsm
might be better suited for nuk_game_server
since it relies on small number of states. These states could be:
After a successful login server keeps a nuk_user_server
process for each user. However, after an unsuccessful login that process should stop normally.
Steps to repro:
> nuk_users:put(nuk_user:new("User1", "")).
ok
> supervisor:which_children(nuk_user_sup).
[]
> nuk_users:login("BadUser", "").
{error,user_not_found,"BadUser"}
> supervisor:which_children(nuk_user_sup).
[{undefined,<0.53.0>,worker,[nuk_user_server]}]
Currently with nuk_game_engine
behavior callbacks game engines get their own arbitrary state that they themselves had previously set. However, nuk tracks general game state which game engines will find useful; so game engines should also be able to access it also.
Currently, when players want to get an update for the game they've joined they must call nuk_games:get_game_session
. This gives them a current snapshot of:
nuk
stateFrom this information they have to make decisions.
I'd like to investigate whether it's more useful to provide incremental updates, such as queuing messages for individual player clients, in addition to having this functionality.
%% create/modify, get and delete user
ok = nuk_users:put(nuk_user:new("User1", "Pass1")).
ok = nuk_users:delete("User1").
{ok, User} = nuk_users:get("User1").
%% login/logout
{ok, SessionId} = nuk_users:login(Username, Password).
ok = nuk_user_sessions:delete(SessionId).
%% get an active session
nuk_user_sessions:get(SessionId).
%% list all active users and sessions
[User1|OtherUsers] = nuk_users:list().
[Session1|OtherSessions] = nuk_user_sessions:list().
Currently all game tests are run against the nuk_game_coinflip
sample game, which is limited to 1 player. In order to more fully test multilayer conditions (e.g. successful join
with another player), implement a 2+ player game and write corresponding tests.
Currently to register a game the nuk_game:game()
data type must be created which takes min_players
and max_players
arguments.
Instead of specifying those hardcoded options there, would it make more sense to have a behavior callback where the game module gives the default general and arbitrary options which may (or may not) be overridden during nuk_game_engine:initialize/2
callback?
Currently nuk provides following behaviors and their corresponding default implementations:
nuk_user_storage
: implemented by nuk_user_store_server
nuk_user_session_storage
: implemented by nuk_user_session_store_server
nuk_game_storage
: implemented by nuk_game_store_server
nuk_game_session_storage
: implemented by nuk_game_session_store_server
The implementing modules are hardcoded in nuk. They should be configurable and the configured module should be called instead.
nuk_users
, nuk_user_sessions
, nuk_games
, nuk_game_sessions
appication:set_env
to override defaultsapplication:get_env
and call the configured moduleSimilar to user sessions, we need to have an implementation that maps game session IDs to game servers. This would allow:
nuk_game_server
pid on the serverPer dialyzer:
nuk_user_session.erl:30: Invalid type specification for function nuk_user_session:new/0. The success typing is () -> #{'user':=#{}, 'username':='anonymous'}
Indeed, the opaque session()
type defines username => string()
, and we are setting an atom.
In a multiplayer environment it is necessary for game engines to keep the following 3 buckets of data:
Currently, there's only one public bucket described as term()
type. This needs to be split in 3, allowing:
nuk_game_engine
behavior to return them separately as callback resultsnuk_game_server
to return the appropriate data to each player, and keep private datanuk_game_session
to extract themIn nuk_game_server:handle_info/2
when we receive the finish
message we invoke the game engine for final cleanup and stop the game server process. We should also clean up the game session storage - i.e. delete the pid to session mapping by invoking the nuk_game_sessions
deletion, which in turn invokes the nuk_game_session_storage:delete/1
behavior call.
Also look at nuk_user_sessions:delete/1
calling nuk_user_session_store_server:delete/1
which should probably have a similar solution.
Create different tests suites for user tests and game tests.
Exported functions in modules such as nuk_games
, nuk_users
, nuk_game_sessions
, etc. must have reference documentation that is automatically generated with make
.
%% returns list of available games (game engines)
[Game1|OtherGames] = nuk_games:list().
%% returns list of active games
[GameSession2|OtherGameSessions] = nuk_game_sessions:list().
%% start a new game
{ok, GameSession1} = nuk_games:start(Session, Game1).
%% join an existing game
nuk_games:join(Session, GameSession2).
nuk_games:get_state(Session, GameSession1).
nuk_games:move(Session, GameSession1, Move).
nuk_games:leave(Session, GameSession1).
nuk_games:end(Session, GameSession1).
nuk_games:initialize ------> nuk_game_engine:initialize ------> {ok, GameState}
nuk_games:join ------> nuk_game_engine:join ------> {ok, GameState}
nuk_games:start ------> nuk_game_engine:start ------> {ok, GameState}
nuk_games:move ------> nuk_game_engine:move ------> {ok, GameState}
#{
status => Status, % see above
players => [User1, User2, User3, User4],
waiting_turn => [User2, User4],
state => #{
%% other internal state specific to game engine
}
}
There should be a way for users to log out which would also delete their session. This would also be helpful for #2.
Currently prior to starting a game nuk checks that the user and game sessions are valid and that user is a member of the game session. nuk should also check that the minimum number of players has been met, per game registration.
Before (or after) each test case, delete all logged in user sessions so they don't affect tests that haven't run yet.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.