Game Programming and other stuff
Tags: websockets, javascript, games, multiplayergames
Published: 2020-02-07 08:34:59

---
title: Game Programming and other stuff
published: true
description: How Strummulu was born
tags: websockets,javascript,games,multiplayergames
---


> How the fuck are you able to maintain 80 github repos?

I don't, simple as that.

Each one of those [repos](https://github.com/vikkio88) was something I started one day out if boredom, to solve a problem or test out something. And once the problem was solved or my attention ended up somewhere else, the repo just got abandoned forever.

Sometimes I feel bad about those repos, but I found them interesting to look at when I want to remember what I was interested in at some point in my life.

![meme](https://img.devrant.com/devrant/rant/r_660180_ndNCC.jpg)

One thing that has always interested me, since I was a kid, was **GAMES**.

I love computer games, and whenever I want to learn a new technology I always try to make a game with it, it does not matter if is a programming language or hardware programming.

Out of all the computer games, multiplayer games have always interested me more than everything else, the idea of kicking someone's ass while said ass is thousands of kilometres away is an amazing concept, especially if you suck at games as much as I do.

I am one of those who rages quit.

A game that I used to play a lot during University was [WarRock](https://warrock.papayaplay.com/warrock.do), a disgusting low budget, free to play clone of Battlefield.

I have never been amazing a competitive games, but I had my good days, where I would be able to get loads of kills and wins, but then after a while, what happens to **free to play** games happened to **WarRock**.

It became _Pay to win_.

Everyone started to buy more powerful guns and gear, with real money, and the game, for some cheapskate like me, became unplayable.

I did, I must confess, spent **25€** once, to have a month premium access to all the best weapon, and once I realised how stupid it was, and how stupidly easy was for me to destroy everyone's ass, I got bored and stop playing. games. for good. because I started to study. and. got. a degree. few years after.

That weird experience made me leave a bit the world of games, and as time went on I did not play anything else multiplayer, because I did not want to be destroyed by people who had a "premium" account.

Multiplayer Games were dead to me.

Then I discovered [CS:GO](https://store.steampowered.com/app/730/CounterStrike_Global_Offensive/). A game where you and your abilities where the only thing that made you win, no premium guns and gear, the only thing people buy there are gun skins, just an aesthetic addition, but not real in game advantage.

I got back into multiplayer gaming, and loved it.

I discovered that there are some games where you don't need to spend money to become good at, and that is the thing I like the most.

In the real world, instead, I have played a fair amount of hours with [Magic: The Gathering](https://magic.wizards.com/en), and I loved (as every nerd in the world) the game mechanics, the skills, and the combos.

But even that game has the same problem, in a way it is a **pay to win**, if you buy 700 boosters you will have better cards and for sure a better deck.

Lame and annoying.

In 2014 I found randomly a nice card game that reminded me of **Magic**, but somehow it took away the **pay to win** and it was way easier to play even though it gave you some of the typical in game mechanics.

[EarthCore: Shattered Elements](https://levelskip.com/mobile/Earthcore-Shattered-Elements-Review).

Beautiful game, just on mobile, and easy to pick up.

Loved it.

But then, like everything I love, it died. Apparently they did have some internal problems and the company, a polish software house, went out of business, and the game got abandoned, leaving thousands of fans, like me, sad and lonely.

That is why, almost 2 years ago, March 2018, I decided to recreate the game myself, as a side project.

Introducing [Elime](https://github.com/NomeTemporaneo/elime).

In few weeks I managed to create the UI prototype, that is still playable [here](https://elime.surge.sh/).

It is a bit clunky, and "not polished", but I am definitely not a game designer, nor a UX guru.

Nevertheless, it works and it is playable.

The only thing that I had to do back then was making it playable online by different people.

Aaaand it was too hard to do, so fuck it, project died. In May 2018.

**END OF THE STORY**


Actually no, few months ago, I had the brilliant idea to get back into it, and finally to get some time to work with **websockets**.

As always, _before writing a single line of code, check that someone else hasn't done it_ (is the second time I say it in 2 posts, maybe I should standardise this rule one day). So I stumbled upon [Colyseus](https://colyseus.io/).

**AMAZING!**, but too advanced for what I wanted to do, so fuck the rule #1, and let's code something ourselves.

Is the 29th of December 2019, and I decided to spend some hours of a lazy Sunday, to test my abilities of making my life more complex than it should be. Succeeding.

[Strummulu](https://github.com/vikkio88/strummulu) was born.

I coded it in around 10-15 days, and tested it with a silly other game that I had done before with a silly randomized ai, [Revorbaro](http://revorbaro.surge.sh/) (Source code [Revorbaro-source](https://github.com/vikkio88/revorbaro)).

The game is easy, a bit like **Elime**, is sort of _Rock_, _Paper_, _Scissor_.

Only with extra steps.

You and an enemy have a gun each, and 3 possible actions in every turn.

- Reload
- Defend
- Shoot

You can't **shoot** if you haven't reloaded, you can dodge a bullet using **defend**, and if you **reload** while the enemy is shooting you are dead.

Nice and easy.

The only things I needed from a multiplayer game library were:

- Matchmaking: Creating, sharing rooms
- Game State Sharing: a way of the two players to have always a fresh and valid game state supplied.
- Action Validation: To move the logic of validation of the action and mutations of the state to the server side, to prevent data tampering.

I am sure that *Colyseus* does all those things, but I couldn't be bothered reading the docs.

I managed to make everything in a way I would like a lib to behave. Leave me freedom to hack it, but making most of the things for me, so I only have to write the **Game Logic**.

[Source Code](https://github.com/vikkio88/strummulu/tree/master/examples/revorbaroReact) - [RevorbaroWS](https://revorbaro-ws.surge.sh/)

### frontend
On the frontend, you only need few lines of code, to integrate with the backend game service.

```javascript
// we create the client feeding it the url of the backend 
const client = strummulu(REACT_APP_GAME_BACKEND_URL);

// we initialise it, on componentDidMount (specifically for react)
client.init({
    [client.EVENTS.MESSAGE]: msg => this.messageHandler(msg),
    [client.EVENTS.ERROR]: msg => this.messageHandler(msg),
    [client.EVENTS.STATE_UPDATE]: data => this.gameStateUpdate(data)
});
```

Then whenever needed, to communicate actions you need to call 3 different methods:

```javascript
// a client can create e room
client.createRoom();

// it can join a room (given the right room id)
client.joinRoom(roomId);

// it can leave the room
client.leaveRoom(roomId);

// and can trigger game actions, those will be handled by the game logic class on the server
client.sendAction(type, joinedRoomId);
```

(mode info on the FE implementation and full code in [here](https://github.com/vikkio88/strummulu/tree/master/examples/revorbaroReact/frontend))

### backend
The code in the backend is even smaller and easier.

```javascript
const gameServer = new Server({
    roomFactory: (client, data) => gameRoomFactory(GAME_TYPES.TWO_PLAYERS_TURN_BASED, new RevorbaroGameLogic(), client)
});

const server = strummuluServerFactory(gameServer);


server.listen(port);
```

- You create a **game server**, feeding it a **gameRoomFactory** that will take care of creating a new Game Room, if the client requires one.
- You create a **server** instance (socketIo server) wrapping the **gameServer**
- You put the server to listen on a given port.

The only thing the backend of a Game needs to do, as said before, is implement the `GameLogic`.

Which in this case is literally extending a blueprint class (no interfaces in plain javascript :sadface:).

```javascript
class GameLogicInterface {
    startingGameState(creatorId, gameState) { }
    player2Joined(joinerId, gameState) { }
    forfait(leaverId, gameState) { }
    getMutationFromAction(playerId, action, gameState) { }
    passTurn(passingId, gameState) { }
    needsResolving(gameState) { }
    resolve(player, gameState) { }
}
```

Easy enough to understand what each method does (apart from having spelled forfeit wrongly).

You have a game state, if a player does an action, a mutation will change the state, creating a new one that will be broadcast to the players in the game room.

In the case of the game **Revorbaro**, the game logic is in [here](https://github.com/vikkio88/strummulu/blob/master/examples/revorbaroReact/backend/GameLogic/RevorbaroGameLogic.js).

### What now?

My plan was, once I had this done and dusted, to polish the lib, add some tests, better docs, and use it on a new version of **Elime**.

But of course, apart from life getting in the way, this blog engine project got in the way too, so I thought, maybe, if I write about it, it will do a comeback?

Too soon to say.

If you are interested in this project, on the lib, just let me know, on the repo itself opening an issue, or via [tweet](https://twitter.com/vikkio88).

It is all for today.

bye

[posted on my blog (another side project)](https://vikkio.me/cipudda/#/post/game-programming-and-other-stuff-b7vxo)