Um. I don't see why you wouldn't be able to control four characters at the same time from a single keyboard. Yes, they all come from the same single command queue, but you're pressing different keys for different characters so it's not really an issue. Heck, even several keyboards would work, as long as you set up different keys for different players. Adding controller support for this would also not be difficult.
The main hurdle with having four people on the same keyboard, though, is that most keyboard seem to have a hardware limitation where you can only press 4 to 5 keys at the same time. If you press more keys than that, they're just not sent to the system at all (so this is a problem for any software, any OS, etc). Having multiple keyboards or gamepads could solve this, easy.
For those who are experienced it's not too bad, but I don't know if a newbie can so easily do it. It's not an out-of-the-box thing for Sphere, like single player movement is.
Hmm, a good start I guess:
function Move(name, inputs) {
if (!IsCommandQueueEmpty(name)) return;
if (IsKeyPressed(inputs.up)) QueuePersonCommand(name, COMMAND_MOVE_NORTH, false);
else if (IsKeyPressed(inputs.down)) QueuePersonCommand(name, COMMAND_MOVE_SOUTH, false);
else if (IsKeyPressed(inputs.left)) QueuePersonCommand(name, COMMAND_MOVE_WEST, false);
else if (IsKeyPressed(inputs.right)) QueuePersonCommand(name, COMMAND_MOVE_EAST, false);
}
var inputs = [];
inputs[0] = { up: KEY_UP, down: KEY_DOWN, left: KEY_LEFT, right: KEY_RIGHT };
inputs[1] = { up: KEY_W, down: KEY_S, left: KEY_A, right: KEY_D };
inputs[2] = { up: KEY_U, down: KEY_J, left: KEY_H, right: KEY_K };
inputs[3] = { up: KEY_NUM_8, down: KEY_NUM_2, left: KEY_NUM_4, right: KEY_NUM_6 };
var players = ["player1", "player2", "player3", "player4"];
function Update() {
for (var i = 0; i < players.length; ++i) {
Move(players[i], inputs[i]);
}
}
function game() {
CreatePerson("player1", "player.rss", false);
CreatePerson("player2", "player.rss", false);
CreatePerson("player3", "player.rss", false);
CreatePerson("player4", "player.rss", false);
SetUpdateScript("Update()");
MapEngine("map.rmp", 60);
}
I guess that's the minimum. You'll have to set the people in different places, otherwise they'll be on top of each other. Notice I didn't use AttachInput(), that means triggers won't fire, and NPC's can't be talked to. But there are ways around that. The above is a good start tho.