You could create your game where there are two types of game data on the client end. The first is the stock static game content that ships with the game itself. This often includes terrain-specific data, often data to help aid in physics client-side determinations, placement of world static geometry like bridges, trees, etc along with area trigger definitions, music associations, and the actual music and visual binary files. This is the content that in a client/server approach, shouldn't be modified and if a modification is detected, the server & client will handshake and exchange the right file from the server's repository to avoid clients from changing the expected behavior of the game based on the server side simulation. The second type of static content is your addons/mods which the server doesn't care about. These simply use some exposed API by the client to provide either enhanced UI options or extend the UI well beyond the shipped version for the player's experience.
In the case of where you can create your own maps and play with your friends over a network, usually the map has to be installed on both ends by players before they can join a game together. Usually this is done by some lobbying mechanic that makes sure both clients agree on simulation details before starting the match.
but if I was to use client-side prediction, I'd still like to be able to get everything synced up. As well, the server may have added entities that the client may not have on its computer, so the problem of downloading the content still stands.
What you describe above is often referred to as game state data and not necessarily "content". In networked games, the server's simulation will need to be synchronized with the client's simulation. There isn't much in the way of a standard practice here other than the notion that you want to minimize your bandwidth footprint, transmit multiple packets of data in one delivery if possible and with client-predication in place, carefully being able to interpolate between latency differences of state transmission to avoid the rubber-band effect so game play is relatively smooth.
In the simplest of terms, a client when connected to the server has an Area of Interest (AOI) that controls what level of state data gets transmitted by the server. There are various ways you can define an AOI, whether it be using physics collisions or some spacial index queries. In either way, objects that are of interest to a client simply have their state replicated to all interested clients as it changes per game loop. Keep in mind though what gets sent is typically some form of numerical values that the server and client both understand. The client has a local database cache of Dictionary lookups that it uses to convert the streamed data from the server to actual visual representations that can be shown to you. For example, server may send that my avatar is race 2. On the client side, race 2 is in some table that represents an Orc mesh. Another transmitted value could be 16 that represents to use the brown Orc skin rather than maybe the green skin because of my selections during creation.
Edited by crancran, 20 December 2012 - 12:32 PM.
As frob said it depends on the nature of your game.