The Minecraft code can be divided into two “sides” – Client
and Server.
- The Server side is responsible for maintaining the master copy of the world - updating the blocks and entities based on packets received from the client, and sending updated information to all the clients.
- The Client side is primarily responsible for reading input from the player and for rendering the screen.
There is one server, and a number of clients which connect to it. Even in single player mode, the server and client code are running simultaneously (in separate threads).
Some parts of the code are used by both Client and Server code, for example Block methods. If you are writing code which might be called by either Client or Server, how can you tell which side has called the code?
First preference: if your method has been passed a World object, or the Class you are extending has a World field (typically called worldObj):
If your code has been passed a NetHandler:
As a last resort:
Some parts of the code are used by both Client and Server code, for example Block methods. If you are writing code which might be called by either Client or Server, how can you tell which side has called the code?
First preference: if your method has been passed a World object, or the Class you are extending has a World field (typically called worldObj):
- if World.isRemote is true, this is Client side
- if World.isRemote is false, this is Server side.
- NetHandler.isServerHandler() returns true if Server side.
- FMLcommonHandler.instance().getEffectiveSide() returns Side.SERVER or Side.CLIENT.
Client and Server run in parallel
Communication between the Client and Server sides takes
place through Packets, which are sent back and forth using NetClientHandler and
NetServerHandler. The basic steps are
shown in the diagram below. There are a
large number of different packets used:
* Packets from Server to Client
Some guidelines on the Client<-->Server communication here.
Communication from Client to Server |
Communication from Server to Client |
If you need to send packets in your mod code, Forge has
thoughtfully provided PacketDispatcher to send packets to the client or the
server without having to retrieve a NetServerHandler or NetClientHandler.
·
.sendPacketToServer()
·
.sendPacketToPlayer()
·
.sendPacketToAllAround()
·
.sendPacketToAllInDimension()
·
.sendPacketToAllPlayers()
If the existing packets don’t meet your needs, you can
create a custom packet Packet250CustomPayload.
More details here.
In many cases, you won’t need to create custom packets to
keep your client and server code synchronised.
The vanilla code and Forge code do this in a number of ways already:
- Creation, Removal, Movement, health, actions etc for Entities. This is accomplished for new Entities by Forge packet EntitySpawnPacket. You can define a custom handler for this using EntityRegistration.setCustomSpawning().
- Removal or placement of Blocks
- Adding DataWatcher variables to your Entity (see here)
- Containers (Inventory, furnace, etc)