Skip to content

bigomega/catan

Repository files navigation

Catan

Free to play multiplayer Catan board game

Links

Play Game: catan-qvig.onrender.com

The onrender server goes to sleep on inactivity, if you open the link it might take a few minutes to get the server up

Open the Browser Console to have control over all the game configs, including mapkey

Shuffler & Board builder: bharathraja.in/catan


Local Installation & Running

npm i
npm start

The server will be reachable at localhost:3000. You're now ready to play the game…

I have an .nvmrc pointing to node version v20.10. Please use at least v18 and above…

Game Features

  • Design your own map
  • 2/3/4 Players
  • Build Houses, Roads, and Cities
  • Robber Mechanics
  • Trade Requests
  • Buy and Use Development Cards
  • Sounds
  • Animations
  • Keyboard Shortcuts
  • Clear Notification History
  • Smart Map Shuffler
  • Optional Timer

Future Ideas

  • Browser Notifications
  • Optimization (memory1, speed, colors)
    • Further modularisation (as of Dec 2024 model/game.js is :700 and public/js/game.js is :470)
  • Join random games
    • Private & public games
  • Watch games
  • Custom map builder
  • Rethink ports
    • multiple in single Sea tile
    • disallow connected edges of land being added as ports
  • Introducing 8-player maps
  • Social login (w pic and/or just a name/id)
  • Discord help (for talking)
  • Seafarers expansion (fairly easy one)
  • Trade negotiations

Frameworks

Major

Minor Libraries

MapKey DSL Explanation

The map is decoded from left-to-right and top-to-bottom. There can by any amount of space \s and newline \n inbetween the rows and tiles. They are ignored by .trim().

Board

The board consists of <Rows> separated by a - (bottom-left) or + (bottom-right) representing its tile-relationship to the previous row.

<Row> ([+|-] <Row>)*

Row

A <Row> consists of one or more <Tile> separated by dot ..

<Tile> (. <Tile>)*

There are two types of Tiles - Resource and Sea.

Resource Tile

A Resource tile is represented by its key <TileKey> and a number <Number> next to it.

<TileKey><Number>
// Accepted values:
const TileKey = { G: 'Grassland', J: 'Jungle', C: 'Clay Pit', M: 'Mountain', F: 'Fields', S: 'Sea', D: 'Desert' }
const Number = [2, 3, 4, 5, 6, 8, 9, 10, 11, 12]

Sea Tile

A Sea tile is represented by S and can optionally have one trade.

S<Trade>?

Trade

A Trade is represented by its edge of the Sea tile it's on <tEdge>, type <tType> and a number <tRatio> covered by round braces () and split by underscore _.

(<tEdge>_<tType><tRatio>)
// Accepted values:
const tEdge = {
  tl: 'top_left',     tr: 'top_right',
  l: 'left',                                        r: 'right',
              bl: 'bottom_left',  br: 'bottom_right',
}

const tType = { '*': 'All', S: 'Sheep', L: 'Lumber', B: 'Brick', O: 'Ore', W: 'Wheat' }

const tRatio = [2, 3]

// Example: (tr_W3)

General Note

  • Surrounding your land with the sea is not necessary, but recommended to get the beautiful sea shores.
  • The robber will be placed in the last desert found during decoding.

Example

This configuration…

const config = {
  mapkey: `
                        S  .S(bl_O2)    .S(br_O2)    .S
                      -S .M8         .D          .M8   .S
                    -S .G9    .S           .S       .G9  .S
                  -S .F10 .S         .S          .S    .F10.S
                -S  .S .C11   .S           .S       .C12 .S  .S
              -S  .S .S   .C2        .S          .C3   .S  .S  .S
        -S(r_L2).J6.J5 .J4    .S           .S       .J4  .J5 .J6 .S(l_L2)
              +S  .S .S   .S         .S          .S    .S  .S  .S
  `
}
// Same as writing…
config.mapkey = `S.S(bl_O2).S(br_O2).S-S.M8.D.M8.S-S.G9.S.S.G9.S-S.F10.S.S.S.F10.S-S.S.C11.S.S.C12.S.S-S.S.S.C2.S.C3.S.S.S-S(r_L2).J6.J5.J4.S.S.J4.J5.J6.S(l_L2)+S.S.S.S.S.S.S.S.S`

Renders the map… Screenshot 2024-02-04 at 11 46 20 copy

Status

In Progress

Jan '25
  • z
Feb '24
  • Alert history
  • Quit game
  • Login & waiting room UI rework
  • End Game
Jan '24
  • Accessibility (Zoom, Fullscreen, Sound, Shortcuts)
  • Opponents UI
  • Shuffler
  • Longest Road & Largest Army
  • Animations (DC, Cost, Build, Dice, Hand)
  • Dev Card Actions
  • Trade
  • Keyboard Shortcuts
  • Client Refactor
  • Robber
  • Basic Turn Actions
  • Refactor server-side Game.js
  • Page refresh state persistance
  • Render Hand
  • Distribute resource
  • Place second house & road
  • Place first house & road
Dec '23
  • Alert & Notification Messaging
  • Timer System
Nov '23
  • Sound Collection
  • Waiting Room
Jun '23
  • Socket IO setup
  • Render Corners and Edges
  • Render Board
  • Image and Sprite Collection & Edit
  • Login Page
  • Simple Server
  • Decoding the map from key

Bugs

  • Road into the Sea
  • Development card styling issue in Safari

Feedback

  • Initial build - show the built house
  • Resource animation after dice animation
  • Music reminder
  • Can play DevCard after dice, update text
  • Trade denied/accepted message
  • Remember player name
  • Timer focus when few seconds left
  • Game end, new game link
  • Login splash image quick load
  • larger screen number fix

Footnotes

  1. https://www.ditdot.hr/en/causes-of-memory-leaks-in-javascript-and-how-to-avoid-them

About

Free to play multiplayer catan style board game

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published