socket.io-games
v1.0.109
Published
A package you can use to create your own game platform using with an implemented match- and user-system with default games like TicTacToe socket.io
Downloads
214
Readme
Game Package
A package you can use to create your own game platform with an implemented match- and user-system with default games like TicTacToe using socket.io
Documentation
Typical Configuration
const express = require('express');
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const socketGames = require('socket.io-games');
socketGames.config.config(app, {
file: "./db.json",
usernameCharacterLength: {
minimum: 2, // default => 0 (no minimum)
maximum: 15 // default => 0 (no maximum)
}, // optional
pluginURL: "https://myPluginURL.com" // default => official plugin site
}).then(() => {
socketGames.config.clearDatabaseSync();
});
app.use(express.static("pages"));
app.use(express.static("public"));
io.on('connection', (socket, name) => {});
app.all('/', (req, res) => {
res.sendFile("pages/home/index.html");
});
http.listen(3000, () => {
console.log("Server is ready");
});
Configuration
Setup
socketGames.config.config(app, {
file: "./db.json" // database
});
Read Database
socketGames.config.readDatabase().then((result) => {
console.log(result.data);
});
Clear Database
socketGames.config.clearDatabase().then((result) => {
console.log("Cleared the database");
});
Matches
Create Match
socket.on("createMatch", (options) => {
socketGames.matches.createMatch(socket.id, options).then((result) => {
if (!result.err) {
io.of("/").sockets.get(result.playerId).emit("newMatch", result);
}
});
});
Accept Match
socket.on("acceptMatch", (options) => {
socketGames.matches.acceptMatch(socket.id, options).then((result) => {
if (!result.err) {
socket.emit("acceptMatch", result);
}
});
});
Reject Match
socket.on("rejectMatch", (options) => {
if (socketGames.config.readDatabaseSync().data.matches[options.matchId]?.status === "pending") {
socketGames.matches.rejectMatch(socket.id, options).then((result) => {
if (!result.err) {
socket.emit("rejectMatch", result);
}
});
}
});
Open Match
socket.on("openMatch", (options) => {
try {
socketGames.config.readDatabaseSync().data?.matches?.[options.matchId]?.players.forEach((player) => {
io.of("/").sockets.get(player).emit("openMatch", {
matchId: options.matchId,
turn: socketGames.config.readDatabaseSync().data?.matches?.[options.matchId]?.data.turn,
players: socketGames.config.readDatabaseSync().data?.matches?.[options.matchId]?.data?.players,
users: socketGames.users.allUsersSync().users
});
});
} catch (err) {}
});
Users
Create User
socket.on("createUser", (options) => {
socketGames.users.createUser(socket.id, options).then(() => {
socketGames.users.allUsers().then(({ users }) => {
io.emit("userUpdate", { users });
});
});
});
Edit User
socket.on("editUser", (options) => {
socketGames.users.editUser(socket.id, options).then(() => {
socketGames.users.allUsers().then(({ users }) => {
io.emit("userUpdate", { users });
})
});
})
Delete User
socket.on("disconnect", () => {
socketGames.users.deleteUser(socket.id, io).then((deletedUser) => {
if (!deletedUser.err) {
socketGames.users.allUsers().then(({ users }) => {
io.emit("userUpdate", { users });
deletedUser.matches.forEach((match) => {
match[1].players.filter((player) => player !== socket.id).forEach((player) => {
io.of("/").sockets.get(player).emit("roomLeave", {
username: result.users[player].username
});
});
});
});
}
});
});
Games
Create Match of TicTacToe
socket.on("createMatch", (options) => {
socketGames.games.tictactoe.createMatch(socket.id, options).then((result) => {
if (!result.err) {
io.of("/").sockets.get(result.playerId).emit("newMatch", result);
}
});
});
Create Match of Connect Four
socket.on("createMatch", (options) => {
socketGames.games.connectfour.createMatch(socket.id, options).then((result) => {
if (!result.err) {
io.of("/").sockets.get(result.playerId).emit("newMatch", result);
}
});
});
Place Field of TicTacToe
socket.on("placeField", (options) => {
try {
socketGames.games.tictactoe.placeField(socket.id, options).then((result) => {
if (!result.err) {
Object.keys(result.players).forEach((player) => {
io.of("/").sockets.get(player).emit("placeField", {
...result,
...{
users: socketGames.users.allUsersSync().users
}
});
});
}
});
} catch (err) {}
});
Place Field of Connect Four
socket.on("placeField", (options) => {
try {
socketGames.games.connectfour.placeField(socket.id, options).then((result) => {
if (!result.err) {
Object.keys(result.players).forEach((player) => {
io.of("/").sockets.get(player).emit("placeField", {
...result,
...{
users: socketGames.users.allUsersSync().users
}
});
});
}
});
} catch (err) {}
});
Game Registry
Register File
socketGames.gameRegistry.registerGames({
games: [
{
type: "file", // set type to file
game: "./game.js" // path to your game
}
]
});
Register URL
socketGames.gameRegistry.registerGames({
games: [
{
type: "url", // set type to url
game: "https://raw.githubusercontent.com/username/repository/root/file" // url to your game
}
]
});
Register Plugin
socketGames.gameRegistry.registerGames({
games: [
{
type: "plugin", // set type to plugin
game: "My Plugin Id" // plugin id
}
]
});
Unregister File
socketGames.gameRegistry.unregisterGames({
games: [
{
type: "file", // set type to file
game: "./game.js" // path to your game
}
]
});
Unregister URL
socketGames.gameRegistry.unregisterGames({
games: [
{
type: "url", // set type to url
game: "https://raw.githubusercontent.com/username/repository/root/file" // url to your game
}
]
});
Unregister Plugin
socketGames.gameRegistry.unregisterGames({
games: [
{
type: "plugin", // set type to plugin
game: "My Plugin Id" // plugin id
}
]
});
Example
const express = require('express');
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const socketGames = require('socket.io-games');
socketGames.config.config(app, {
file: "./db.json"
}).then(() => {
socketGames.config.clearDatabaseSync();
});
app.use(express.static("pages"));
app.use(express.static("public"));
io.on('connection', (socket, name) => {
socket.on("createUser", (options) => {
socketGames.users.createUser(socket.id, options).then(() => {
socketGames.users.allUsers().then((result) => {
io.emit("userUpdate", result.users);
});
});
});
socket.on("createMatch", (options) => {
socketGames.games.tictactoe.createMatch(socket.id, options).then((result) => {
if (!result.err) {
io.of("/").sockets.get(result.playerId).emit("newMatch", result);
}
});
});
socket.on("acceptMatch", (options) => {
socketGames.matches.acceptMatch(socket.id, options).then((result) => {
if (!result.err) {
socket.emit("acceptMatch", result);
}
});
});
socket.on("rejectMatch", (options) => {
if (socketGames.config.readDatabaseSync().data.matches[options.matchId]?.status === "pending") {
socketGames.matches.rejectMatch(socket.id, options).then((result) => {
if (!result.err) {
socket.emit("rejectMatch", result);
}
});
}
});
socket.on("openMatch", (options) => {
try {
socketGames.config.readDatabaseSync().data?.matches?.[options.matchId]?.players.forEach((player) => {
io.of("/").sockets.get(player).emit("openMatch", {
matchId: options.matchId,
turn: socketGames.config.readDatabaseSync().data?.matches?.[options.matchId]?.data.turn,
players: socketGames.config.readDatabaseSync().data?.matches?.[options.matchId]?.data?.players,
users: socketGames.users.allUsersSync().users
});
});
} catch (err) {}
});
socket.on("placeField", (options) => {
try {
socketGames.games.tictactoe.placeField(socket.id, options).then((result) => {
if (!result.err) {
Object.keys(result.players).forEach((player) => {
io.of("/").sockets.get(player).emit("placeField", {
...result,
...{
users: socketGames.users.allUsersSync().users
}
});
});
}
});
} catch (err) {}
});
socket.on("disconnect", () => {
socketGames.users.deleteUser(socket.id, io).then((deletedUser) => {
if (!deletedUser.err) {
socketGames.users.allUsers().then((result) => {
io.emit("userUpdate", result.users);
deletedUser.matches.forEach((match) => {
match[1].players.filter((player) => player !== socket.id).forEach((player) => {
io.of("/").sockets.get(player).emit("roomLeave", {
username: result.users[player].username
});
});
});
});
}
});
});
});
app.all('/', (req, res) => {
res.sendFile("pages/home/index.html");
});
http.listen(3000, () => {
console.log("Server is ready");
});
Client Side Documentation
Configuration
Setup
<script src="/socket.io/socket.io.js">
const socket = io();
Actions
Users
Create User
socket.emit("createUser", {
username: "My Username"
});
Matches
Create Match
socket.emit("createMatch", {
playerId: "player id"
});
Accept Match
socket.emit("acceptMatch", {
matchId: "match id"
});
Reject Match
socket.emit("rejectMatch", {
matchId: "match id"
});
Open Match
socket.emit("openMatch", {
matchId: "match id"
});
Games
Place Field
socket.emit("placeField", {
matchId: "match id",
field: "1" // number from 1 to 9
})
Events
Users
User Update
socket.on("userUpdate", (options) => {
console.log(options.users); // do some stuff with the users
});
Matches
New Match
socket.on("newMatch", (options) => {
console.log(options.username, options.matchId); // do some stuff with the match request
});
Accept Match
socket.on("acceptMatch", (options) => {
console.log(options.matchId); // do some stuff with the accepted match
socket.emit("openMatch", { matchId: options.matchId }); // open the accepted match
});
Reject Match
socket.on("rejectMatch", (options) => {
console.log(options.matchId); // do some stuff with the rejected match
});
Open Match
socket.on("openMatch", (options) => {
console.log(options.users[socket.id], options.users[Object.entries(options.players).filter((item) => item[0] !== socket.id)[0][0]].username, options.turn); // do some stuff with the opened match
});
Games
Place Field
socket.on("placeField", (options) => {
console.log(options.field); // do some stuff with the placed field
});
Rooms
Room Leave
socket.on("roomLeave", (options) => {
console.log(options.username); // do some stuff with the user who left
});
Changelog
1.0.0 - Basic Version
Basic version of configuration, matches and users with TicTacToe and Connect Four as games
1.0.1 to 1.10 - Bug Fixes
Some bug fixes and updates for a better interface
1.11 to 1.20 - Game Updates
Updated games and security updates
1.21 - Templates (Client)
Templates (also called Client) added. Requires a http server or express app in config function
1.22 to 1.30 - Basic Updates
Some basic updates
1.31 - Leaderboard
Automatic leaderboard sorting for wins in all or specific games
1.32 - Game Engine (renamed to Game Registry)
Script to make adding custom games easy for beginners with file, urls and plugins (including plugin platform)
1.33 - Added data object to users and matches
Allow storing custom data in users and matches
1.34 to 1.42 - Bug fixes
Including fixing overwriting old fields
1.43 to 1.58 - Rock paper scissors
Added rock paper scissors as default game
1.59 - Added default options
Added default options which constains data about default changeable
1.60 to 1.72 - Bug fixes
Some bug fixes
1.73 to 1.80 - Memory
Added memory as default game
1.81 to 1.84 - Added shortcuts
Added shourtcuts with basically the same function as the game registry
1.85 - Added util functions
Added some util function
1.86 to 1.88 - Bug fixes
Some bug fixes
1.89 - Added random number generator
Added new util function called random number generator
1.90 to 1.94 - Bug fixes
Some bug fixes
1.95 to 1.96 - Added get quantity of each item
Added new util function called get quantity of each item
1.97 - Renamed read file
Renamed the read file function in config to read database
1.98 to 1.101 - Updated documentation
Updated the documentation in the readme file
1.102 to 1.104 - Added rounds
Added rounds to the default games
1.105 - Added changelog
Added changelog to the readme file
1.106 - Note and bugs
Added note and bugs to the readme file
1.107 to 1.109 - Bug fixes
Some bug fixes
Note
This package is based on promises, but every single function also contains a same synchronous function.
Bugs
Please report bugs in the following github repository: https://github.com/DinoscapeProgramming/Game-Package
Known issues
- Fetch URL sync not working. Getting data from other web servers (also third party services) cannot be done synchronously. Use the asynchronous function instead.
Example Site
https://tictactoe.dinoscape.tk