Turning a game developed for singleplayer into a multiplayer game when it was not designed for that from the start can be extremely difficult, both regarding software architecture and regarding game design.
But there are some things you can do which make it much easier to add multiplayer later while not hampering your development progress too much while you are still single-player.
The most important is having a clear separation of concerns from the start. Strongly encapsulate the input, game mechanics, game state, graphic engine and UI of your game. Have them communicate with each other using clearly defined, loosely coupled functions which assume nothing about the inner workings of the other modules.
This allows you to later replace these local modules with remote modules which then communicate with the remaining local modules using the same functions you already have.
- When a second local player joins the game, you simply create a new instance of the input module which listens to different keys and assign it to a new instance of the player entity.
- When a new remote player joins the game, then a network input module takes the role of the local input module.
- When you move game mechanics to a server, then the server networking module takes the role of a local gameplay module.
- To send local events to the server, you could either add a second consumer to your input module or use the same functions which are used by the UI module to monitor changes in the game state.
You might also go a step further and develop your singleplayer game as if it were a multiplayer game. Assume every game entity is remote-controlled, but "fake" that remote control with a local controller. That way most of your game architecture won't know and won't care if a game entity is an enemy controlled by a local AI controller or another player controlled by a network controller.
And besides, proper encapsulation and separation of concerns is always a good guideline for a clear and easily maintainable and extensible software architecture.
But besides the architectural concerns, there are also game design concerns. Multiplayer games are often far harder to design than single player games for a couple reasons:
- Game balance is more important. When you accidentally have a feature in your game which is so overpowered that it breaks the game, then single-players will often be able to show at least some restraint from abusing it until it stops the game from being fun. You might also see players trying to finish the game without using that overpowered feature as a self-imposed challenge. In multiplayer, however, players will have far less quarrels. Competitive multiplayers will usually do everything it takes to win, even if it makes the game boring to play for everyone including themselves.
- Counter play becomes an important consideration. When you give the player a new ability in a single-player game, you just have to wonder "How does this make the game more fun for the user?". But in a multiplayer game you also have to wonder "How does this make the game more fun for the one it is used against?". For example, freezing an enemy in a block of ice for a couple minutes might be fun in single-player, but in multi-player it is extremely annoying for the one being frozen and unable to play. Extra Credits made a good video about this topic.
- Time skipping becomes impossible. In a single player game you can skip boring sequences by either speeding up time (common in strategy and puzzle games) or by simply omitting them (fast-travel systems are a common example). However, when multiple players share the same game world, they also share the same game time. You can usually not speed up the game for some players who are currently in a boring phase but not for those who are currently in a more complex game phase.
Again, the best way to address these problems early is to design your single-player game as if it were a multiplayer game. To address balance and counter-play, consider to follow a general rule that whatever the player can do can also be done by the AI opponents. And if you notice that parts of your game are boring and tedious, don't take the easy way out by simply using time-skipping. Try to find a proper solution to make those phases as interesting as the rest of the game or to speed them up in a way which is plausible within the fiction of the game and does not break game balance in multiplayer.
There are also narrative differences between single player and multiplayer. In single player, the player-character (PC) can be someone special. There is no issue with making the PC the chosen Mary Sue character the whole world turns around. But the more players you add, the more limited you become regarding the role of the PC in your game's narration. In a multiplayer game, the PCs have to share the spotlight with each other. Not everyone can be "the chosen one".
In a massive multiplayer game where you have thousands of PCs, it becomes almost impossible to add any convincing narrative which makes the PC and their experience seem unique. Some MMO games try by having those quests of the game designed to be played alone make the PC somehow special, hoping that the player ignores the fact that all the people around them currently experience the exact same story they do. But the illusion falls apart as soon as you enter the cooperative content.
But in exchange for that, you get a completely different narrative angle. You can give the player the feeling of being part of something greater and making a useful contribution to a coordinated group effort. This is challenging (but not impossible) to pull off in a single-player game due to the lack of empathy for the NPC characters, but it can be a very satisfying experience in a massive multiplayer game where the player knows that all those people they fight alongside are in fact real humans.