| NIMP: Getting started
A journal of building an awful social media based MMO.
Oct

Motivation

I’ve been hooked on MMOs since I played MUDs as a kid, but it was Ultima Online (UO) that really opened up what was possible for me. There’s something special about building and maintaining a world with thousands of other people, most of who will happily stab you to death the minute you leave a safe area. It’s as if we’ve taken the complex systems of the real world and distilled them down to their purest forms, from the economies to the social contructs.

Ultima Online

Ultima Online, a classic 90s MMO still being played today. Source

Recently, I’ve been toying with the idea of building something MMO-like, though avoiding the graphics side of things, which is a time sink, and focusing on the economic and social side of things. A sort of lofi MMO that centers on exploration as a means to build resources which allow communication via text and images. It’s an idea that has been bouncing around my head for awhile, and despite my apprehension, I think it’s time.


Overview

If you’ve ever played an MMO, you know a lot of it is about turning the grind into entertainment. People who play MMOs appreciate a good grind. If you’re not familiar with grinding, it’s usually some repetitious action done to achieve a self-imposed goal. That goal could be fighting mobs until they drop a particular item, or harvesting enough wood to level up your woodcutting skill. In a game like New World, it might take someone 5-10 hours to level up their logging skill to max level, though this a minor grind compared to some.

New World logging

20,000 clicks on trees, and counting. Source

The important part about these games is there is no real final destination. Goals are set by the player, and everyone can have their own.The game I’m planning will be similar, but I want to mix the grind with social media.

It will be Twitter without the drama, Facebook without the politics, and TikTok without the videos. Where social media sites put everything up front and streamline the process of posting, I also want it, at least initially, to be nearly unusable as normal social media site. Users will need to explore, harvest, level up and craft in order to establish themselves as members of the community.

I’m planning this as a series of posts done together, with whoever is reading. Consider these documents as living. They’ll change and be updated over time. In fact, this very sentence is being written in what I’d called the second draft.


Getting started

These posts will be light on code, and heavy on planning and design. There will, of course, be plenty of codings, but code included in these documents will used to explain the motivation behind what is done. For the code, you’ll be referred to the repo and the branches that I will add.

For now, we’ll be painting the broad strokes of our grand design, and later zoom in on each. We’ll lay out goals for what we’re calling our minimum viable project (MVP). Not product, because in our MMO utopia nothing is for sale.

Here are the basics of what we hope to achieve:

  1. An infinite multiplayer world
  2. A resource-based economy
  3. Real-time interaction
  4. Game elements
  5. Posting of text and low-res images

It’s important to note that we’re sketching out the big picture at this stage, not the technical nitty-gritty. We’ll consider how our design choices might shape the final creation, but we’re not getting into the weeds with our tech stack or code architecture just yet.


An infinite world

If you’ve played with Figma, you’ve experienced an infinite canvas, albeit constrained by memory, storage, and the finite universe. Maybe we can name our social media site NIMP, or the Nearly Infinite Message Project?

NIMP

Thanks Stable Diffusion!

To start thinking about our infinite world we’ll look at two things:

  1. How we’ll render it.
  2. How we’ll break it into different pieces.

First, we’ll look at rendering.

Rendering

The current vision I have for the site is an expansive canvas where users are able to excavate space for text and images. These messages can be linked to others, allowing users to follow chains of conversation through the world. Resources are accrued through the establishing of spaces to build and through interaction with existing messages.

Building an infinite canvas is relatively easy for a single user space, but for building out a real-time infinite canvas with potentially hundreds or thousands of people simultanously exploring and manipulating it, the complexity increases significantly. The complexity comes primarily from how we display world elements to the users (players). With collaborative tools, like shared whiteboard spaces or apps such as Figma, there is complexity in ordering the operations performed by users (see CRDT), but all the elements of the spaces are loaded in at once. With Figma, all uses have all text fields loaded into memory, for example.

For our application we may have millions of messages stored, and can’t allow each user to load and update those as they change. We’ll need limit what send to the user based on what they’re viewing.

In 2D and 3D games, only things which can be seen are rendered (drawn), saving precious resources. In 2D games this might be done via a quadtree which stores information about objects to draw at points on a 2D plane, while in 3D you’d use a frustum and clipping plane.

Frustum

Frustum in action

Thankfully, we won’t have to employ anything like quadtrees or make use of frustum culling, but that doesn’t mean this will be easy. For now, let’s think of our world as broken into regions, each of which will contain a number of potential messages. We’ll take the naive approach and break our world into equally-size regions which will be further broken down into broken into equally-sized spaces. The center of our world will be at (0, 0).

Plain plane

The plain plane

Regions

Since screens are typically wider than tall, we’ll use rectangles of size 3200x2048 pixels, which is larger than most desktop resolutions. Now, instead of transferring the whole world, we’ll only transfer the chunks that the user is currently viewing, which given the size would mean at most four grid regions are transferred to a user at time, and then only if the user is viewing a section where the four corners touch.

Sized grid

Sizing our up our regions to be 3200x2048

Keep in mind that each of these regions will contain multiple messages and images, and that we’ll be transferring them in chunks. We could, theoretically, let the database grab all messages within a particular view frame, but I have a suspicion that will create a bottleneck at some point. By breaking it into regions we can query directly on primary keys connected to the region’s location, something we’ll see later on.

Messages

Each region will be composed of many messages, with the space for those messages to be explored by users. We want messages to be of varying size, but we still need some sort of tiling on which to construct the world. These tiles will be what users harvest or mine in order to expose spaces to place messages. We’re going to make our tiles be 64x64 with something padding. Individual posts and images will be constrained to 5x5 cells in size, making the largest size possible 320x320, which should fit well on most cell phones, where the lowest resolution is around 360px.

Filled grid

Each color represents either message of different size.

We’ll make it such that images can only be square, but still remain 28x28 resolution, and be stretched over this space, spanning multiple 64x64 blocks. The same will happen with messages, but we’ll constrain them to being wider than they are high.


Resource-based economy

The beating heart of any captivating MMO is the economy that fuels it. These digital economies usually mirror the real world, grounded in resource acquisition and utilization. The activities in many games center around mining, lumberjacking, and crafting. For the world we’re envisioning, though, let’s simplify without sacrificing the ambition. If we seek to be ambitious, this could easily be the most complex aspect of the world, but as with the infinite canvas aspect, I want to keep things relatively simple.

To start, players will gather resources by opening new areas for posting content. The mechanics of this will be explored in more detail later, but for the moment, let’s say that various activities and achievements yield resources. As we flesh out the concept, these may evolve, but initially, players can harvest things like:

  • Dirt
  • Stone
  • Wood
  • Water
  • Iron
  • Gold
  • Gems
  • Special items

Personally, I’d like to change this to be a bit more interesting, but I haven’t quite thought of what. For now, think of these as placeholders for what’s to come.

Resources will drop when a player uncovers a new section on the grid. Let’s say someone opens a 64x64 pixel section at coordinates (5600, 1345). They might find themselves richer by 12 units of dirt, 3 of stone, and a piece of iron. I say semi-randomly because I’d like to make there be areas which end up being richer than others, defined at the time of first exploration.

Resources are the currency for actions and creation in our world. With them we’ll allow people to perform actions like:

  • Crafting posts and images
  • Unlocking colors for image creation
  • Buying emojis
  • Creating new tools for exploration
  • Bypassing a curse to reenable explicit language in posts
  • Making posts permanent (otherwise they degrade and can be reused)
  • Highlighting posts with neon borders
  • Fast travel of sorts
  • A fleeting spot on a leaderboard for bragging rights
  • Performing actions on other people’s posts

While there’s no cap on resources a player can possess, we’ll make item inventory somewhat finite.

I’d also like to have a sort of secondary market which centers around food and animals, which will include different emojis that you might receive. You’ll have a stock of emojis that you can add to another person’s posts. While these are not a currency, they are a resource of sorts, as different emojis and combinations of emojis, when applied to a particular post, can give that post’s owner, or the post itself, abilities, as well as receiving something for themselves.

For example, as one is expanding territory through mining they are rewarded with dirt and gold, but maybet they also find a watermelon emoji. If they like a particular person’s post they can add that emoji to it. If a post has been gifted that emoji, it now has a green and pink border.

We’ll also have a marketplace where players can offload surplus resources and crafted items to a bank, which in turn offers higher-level resources. How this marketplace operates is still up in the air. It’s an integral, yet complex feature we’ll let simmer on the back burner for now. Initially, the bank’s exchange rates will flex to match the in-game economy.

In summary:

  • Territory exploration yields resources.
  • Resources are spent to enhance capabilities and create items.
  • Emojis are separate rewards that can be used on other’s posts.
  • Excess resources and items can be traded with the bank at fluctuating rates.
  • A direct player-to-player market is tabled for future development.

Real-time interactivity

Real-time interactivity cranks up the complexity, especially when we’re talking about potentially thousands of simultaneous users. I’ll admit, I haven’t built something at this scale before, and I expect to thoroughly screw it up the first time. Nothing more hardware won’t be able to initially fix, I’m sure.

More memory

These days it’s more GPUs, but close enough

We have a few options for allowing interactivity: polling, server-sent events, or websockets. In this situation there is really no other choice than websockets.

More memory

I have no idea how legit this is, but a few searches provide plenty of similar examples [Source].

The world being divided into regions simplifies the messaging as updates are only sent to users viewing the relevant region. User join a channel by entering a region, connecting to others in the same area. Desktop users, with their wider view, or users looking at the intersection of regions, might connect to multiple regions at once, but nobody should be in more than four channels simultaneously.

Maybe there’s a sleeker solution. I’ve pondered alternatives, like hexagonal regions that might limit necessary connections to three.

Hex region

Could have worked, but seems like more effort than it’s worth.

You may know a better way to do this, and if you do, please email me. In the end I figured I’d keep this version simple, and if a bottleneck is reached at some point, then a restructuring could be in order.


Game elements

There are going to be a few types of games, and I use that term in the sense of there being puzzles and other interactive elements within the world. The games will come as follows:

  • Games used to unlock territory
  • Based on using items
  • Easter eggs users unlock

Unlocking territories

The mini-games included to accomplish certain tasks will be simple enough any person can beat them, but difficult enough to confuse bots. Games might include doing things like:

  • Flying a space ship though obstacles.
  • Stacking blocks within a time limit.
  • Clicking exactly 19 times on the yellow square.
  • Whac-a-mole

Games should be short and silly.

Whac-a-mole

Whac-a-mole? Source

I’m thinking most games will take 5-20 seconds to complete and appear randomly when exploring, mining or doing other actions. To do this there will need to be some sort of framework in which they can be made, and I’m not entirely sure what to use as of yet. Perhaps p5js or straight HTML5 and canvas. This is something to be investigated further once we start looking at this part.

Using items

The games elements which come from items will be different, as they’re not games in the sense of mini-games, but between players and with themselves. Items will either unlock abilities or allow users to perform specific one-off or time-restricted actions. Some ideas were mentioned in the previous section, but I’d like to expand a bit further here.

What I see is a way for users to affect others, though perhaps not directly. I don’t want items to allow people to delete others' posts, but instead do things like claim a region for themselves for a period of time, make the background a specific color, or force all users in a region to listen to 80s midi video game music. Maybe it gives them the ability to put temporary birthday hats on N number of posts or create glowing neon edging. The possibilities for this are endless, and over time I see adding and removing them as need be.

Easter eggs

I actually want this to be a significant part of the game, as I see these unlocks bringing the community together to search out ways of gaining new abilities and effects. These are to be discovered through any number of actions. The first users to discover them will be added to an Adventurer’s Log for all of history. For example, users might discover they can make their posts have a special background by typing specific phrases, or unlock a permanent ability by drawing a specific image.

Pinball

Windows used you have cool Easter eggs like pinball in Word.

Maybe creating a post in a specific region will unlock the ability to post in a similar region, or maybe they’ll find they can’t post in a region if they’ve posted in another. We could exclude the color orange in all images, for example, until a user mentions pumpkins in one of their posts. When they do that they’ll be recorded in the Adventurer’s Log and everyone now can use orange. It’s even possible to have abilities which are one-off, meaning that only one person can have it at a time, and perhaps they only have it for a specified period of time before losing it and it needing to be found again.

Again, this is not directly a game, but it is a game in the sense of the community working to discover things which affect the world. I don’t want to plan any of these at this point, but instead define them as a class of game that will be included as we go forward. Later, we’ll create a system to add in each of these types of games such that they can be easily modified, added and removed.


Posting text and low-fidelity images

As mentioned, this site will be built around text and image messages, but opening the floodgates to allow users to post things on your site invites a whole spectrum of moderation challenges – from porn and spam to the darker corners of doxing and threats. We’ll aim to curb the porn issue by taking our site back to the early days of 8-bit graphics, allowing only user-drawn, pixelated images at a quaint resolution of something like 28x28 pixels. Enlarged, these become charming pixel art pieces.

Pixel art

Make it small. Source

The first image on the site will invariably be a dick, but it’ll be an 8-bit one and hardly distinguishable from other elongated objects.

Aubergine

Close enough. Source

Managing text is somewhat simpler. We’ll cap the length and restrict the input to non-HTML or very basic HTML content. Legalities, like what defines a direct threat, will need attention, with mechanisms for flagging content on each post. I’m against heavy-handed censorship; instead, I favor fostering positive interaction over filtering words and users, except where necessary for legal reasons. We will look more at how to do this when we research and discuss moderation in a later post.


Recap

This is a long post, and it’s something I see myself coming back to again to update with new ideas. In the next post we’re going to look at how we’ll organize our data, with our primary focus being on the regions.