DEV Community

Vincenzo
Vincenzo

Posted on

Game Programming and other stuff

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

I don't, simple as that.

Each one of those repos 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

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, 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. 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, 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.

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.

In few weeks I managed to create the UI prototype, that is still playable here.

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.

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 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 (Source code Revorbaro-source).

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 - RevorbaroWS

frontend

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

// 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)
});
Enter fullscreen mode Exit fullscreen mode

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

// 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);
Enter fullscreen mode Exit fullscreen mode

(mode info on the FE implementation and full code in here)

backend

The code in the backend is even smaller and easier.

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

const server = strummuluServerFactory(gameServer);


server.listen(port);
Enter fullscreen mode Exit fullscreen mode
  • 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:).

class GameLogicInterface {
    startingGameState(creatorId, gameState) { }
    player2Joined(joinerId, gameState) { }
    forfait(leaverId, gameState) { }
    getMutationFromAction(playerId, action, gameState) { }
    passTurn(passingId, gameState) { }
    needsResolving(gameState) { }
    resolve(player, gameState) { }
}
Enter fullscreen mode Exit fullscreen mode

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.

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.

It is all for today.

bye

posted on my blog (another side project)

Top comments (0)