There's a thing known as the server-client boundary in Roblox. Whatever the server changes in the game affects all players (clients) but the reverse is not true, this was created to help reduce the number of exploiters/hackers in games. Now, sometimes it is necessary to use stuff only available from the client (mouse input, keyboard input are both good examples) and make changes to the server.
For example, you press the shift-button and you want a fireball to shoot out of your arms. Now, if you scripted one using localscripts, no one would be able to see you shooting it; but the server doesn't have a physical keyboard so there's no way it can fire anything. The solution is to use RemoteEvents and RemoteFunctions.
RemoteEvents allow you to either send information to/from the server/client. RemoteFunctions allow you to send information AND get information back (this is called returning) from the server/client.
Here's an example usage of a remote event:
2 | workspace.RemoteEvent.OnServerEvent:Connect( function (player, key) |
3 | print (player.Name.. " pressed " ..key) |
7 | game.UserInputService.InputBegan:Connect( function (input) |
8 | workspace.RemoteEvent:FireServer(input.KeyCode) |
And of a remote function:
2 | workspace.RemoteFunction.OnServerInvoke = function (player, number) |
7 | local add 52 ToThis = workspace.RemoteFunction:InvokeServer( 203 ) |
Of course, these aren't the only ways to use both. There's an unlimited amount, and you will only be able to understand through lots of practice.