Followers 0

# Players states interaction on the same screen

## 11 posts in this topic

Posted (edited)

I am bogged down by this for a while and I can't figure out a proper way to do it.  In a multiplayer game, a player should be able to see other players' visible states on the same screen/ same zone.  For example, my player should see other players' state change when they change size or color or collide with some entities if these players are in my player's viewport. The same applies to other players, so they can see what my player is doing, seamlessly.

I have designed a architecture that if each player has some collection called "nearbyPlayers", each player can iterate through them one by one and get the state changes and then send them to the current player. But on the server because these players are at the same zone some state changes will be iterated many times. Assume A, B, C and D are on the same viewport, to get the environmental screen state changes for A, I need to iterate through collection = [A, B, C, D]. And for B, C and D I need to iterate through the same collection. I think this way my structure has repeatedly computed some states many times, which wasted a lot of CPU cycles. Maybe there is a term to describe the problem but I don't know.

I have also tried to design a pub-sub pattern, so that if players are on the same screen/same zone, each of them are subscribed to each other and if one player changes state the others should know the change. But still, the player need to tell all the subscribers the change. And in a simple implementation of this pattern I didn't find much performance improved.

In both ways I find it easy to make mistakes such as detecting collisions with the same entity multiple times. Is there a generic or standard way to solve this problem?

Edited by caymanbruce
0

##### Share on other sites

The problem is that you're polling for state changes instead of letting the subscription tell you about them, which is what pub/sub is for.

"to get the environmental screen state changes for A, I need to iterate through collection = [A, B, C, D]. "

What you should be doing is this:

"B changed, and A is subscribed, so queue an update about B for A."

"D changed, and A is subscribed, so queue an update about D for A."

... and a little later (e.g. milliseconds, not seconds or minutes)

"A has queued update messages about B and D - transmit them to A's client."

You're making the same mistake regarding detecting collisions. You shouldn't have every entity check for collisions against every other entity in isolation. Instead, you should run collision detection once across all entities, comparing each pair only once, and notify any pairs when collisions happen. (In a client/server game, that's probably a multi-step process, because you notify the server that a collision has happened, you resolve the collision, and then tell the clients what has happened as a result of that resolution).

0

##### Share on other sites

Posted (edited)

1 hour ago, Kylotan said:

The problem is that you're polling for state changes instead of letting the subscription tell you about them, which is what pub/sub is for.

"to get the environmental screen state changes for A, I need to iterate through collection = [A, B, C, D]. "

What you should be doing is this:

"B changed, and A is subscribed, so queue an update about B for A."

"D changed, and A is subscribed, so queue an update about D for A."

... and a little later (e.g. milliseconds, not seconds or minutes)

"A has queued update messages about B and D - transmit them to A's client."

You're making the same mistake regarding detecting collisions. You shouldn't have every entity check for collisions against every other entity in isolation. Instead, you should run collision detection once across all entities, comparing each pair only once, and notify any pairs when collisions happen. (In a client/server game, that's probably a multi-step process, because you notify the server that a collision has happened, you resolve the collision, and then tell the clients what has happened as a result of that resolution).

Thanks I try to understand how this works. But one thing I don't understand is that when B changes, how does B know who subscribes to itself? If B wants to queue an update for someone, it needs to iterate through a subscribers list to find that particular player right? If it works like this I still need to check each player in this list. And if A is subscribed for B and B is also subscribed for A, do I need to queue messages both ways?

Or maybe I totally misunderstood the way how pub/sub works. Is it more like a messaging system? So I will put every update message in a global queue and every player looks up this queue and find the message that he is interested in. I am using javascript so maybe that'll be easy to implement.

Edited by caymanbruce
0

##### Share on other sites

It's not really about "B knowing who is subscribed to itself", nor does B "want to queue an update" for anyone specific. It's about your server knowing which clients are subscribed to which entities. When your server changes entity B, it should have a list of clients interested in B, and can send or queue messages for those clients accordingly. Yes, it involves iterating through the list, but only a list of subscribers - i.e. clients you know need an update - not a list of everyone on the server, many of whom will not need this update.

Pub/sub is literally just where the subscriber says, "put me on the list, so when you publish something, I get a copy". In this case, the publisher is B, and it 'publishes' a state change, and all subscribers get sent this change.

0

##### Share on other sites

Posted (edited)

@Kylotan Even though this looks easy, I am still confused with monitoring the updates. For example, on the server, at some interval, I iterate though the player list, and in each loop step I get update changes for current player and queue updates for its subscribers, and then I send out the updates to that client / current player. The updates I send to current player which is B in this case may not contain the updates other players that B subscribes to, if I iterate B at the beginning of the player list, because other players are not checked at the time. Then B may get the update info it subscribes to in next loop after some interval. The problem is, I can't keep this update info forever because a few frames later B may be in different position and see different players states on B's screen. So when should I clear the old update info and use the new update info? If I do this before I loop through the player list it may delete the update info that B may need to use in next loop.

Pseudo Code example:

if (currentTime >= nextUpdateTime) {

// When to clear the update info for subscribers?

for (const player of playerList) {

Bstates = getPlayerStates(player);

someChanges = EventQueue[player.id].pop();

// Bstates doesn't contain player info B subscribes to if I iterate B before testing other players

sendUpdateTo(player, Bstates);
}

nextUpdateTime += interval;

}

Edited by caymanbruce
0

##### Share on other sites

I don't understand your code because I don't know what those variables represent. I'll explain the basic model that works for me and hopefully you can make sense of it.

When sending updates to B, what you want to send is any relevant messages that have been accumulated since last time you sent messages to B. Nothing more complicated than that.

If you're worried about messages not being sent quickly enough because entity C gets updated later in the loop than entity B, then just do all the updates in one loop and the sends in another loop. e.g.

for entity in world:
change_message = entity.update()
for each client in entity.subscribers:
client.queue_outgoing_message(change_message)

for client in connected_clients:
if client.queued_outgoing_messages.length() > 0:
client.transmit(client.queued_outgoing_messages)
client.queued_outgoing_messages.empty()

There's no rule saying you have to handle everything in one single loop.

Also, in the general case, it is not correct to talk about entities and players and clients as if they're the same thing. In many games, you can talk this way because each player controls one client and that client controls one entity - but that doesn't hold true when you talk about NPCs (1 entity, no client, no player) or admin/spectator clients (1 player, 1 client, 0 entities), etc.

With this in mind, it makes even more sense to separate out your entity updates from your network sending loop. You could even run them at different rates if you liked. If you find that a client ends up with 2 updates for the same entity, you could drop the oldest one, but that's an optimisation, not an essential part of the logic. As long as the messages are transmitted in the right order then everything will be consistent.

0

##### Share on other sites
48 minutes ago, Kylotan said:

I don't understand your code because I don't know what those variables represent. I'll explain the basic model that works for me and hopefully you can make sense of it.

When sending updates to B, what you want to send is any relevant messages that have been accumulated since last time you sent messages to B. Nothing more complicated than that.

If you're worried about messages not being sent quickly enough because entity C gets updated later in the loop than entity B, then just do all the updates in one loop and the sends in another loop. e.g.


for entity in world:
change_message = entity.update()
for each client in entity.subscribers:
client.queue_outgoing_message(change_message)

for client in connected_clients:
if client.queued_outgoing_messages.length() > 0:
client.transmit(client.queued_outgoing_messages)
client.queued_outgoing_messages.empty()

There's no rule saying you have to handle everything in one single loop.

Also, in the general case, it is not correct to talk about entities and players and clients as if they're the same thing. In many games, you can talk this way because each player controls one client and that client controls one entity - but that doesn't hold true when you talk about NPCs (1 entity, no client, no player) or admin/spectator clients (1 player, 1 client, 0 entities), etc.

With this in mind, it makes even more sense to separate out your entity updates from your network sending loop. You could even run them at different rates if you liked. If you find that a client ends up with 2 updates for the same entity, you could drop the oldest one, but that's an optimisation, not an essential part of the logic. As long as the messages are transmitted in the right order then everything will be consistent.

Thanks now this finally makes sense for me.

0

##### Share on other sites

In general, though, "players seeing players" is a n-squared problem. If all players are within view range of each other, then all players need to see all players, which requires N players state updates generated for N players.

In general, you'll want to cache what the actual state is on the server, rather than compute it when anyone wants to observe it. The simulation updates the actual values of each player -- this is just once per player. Then, the network-view iterates through each player, and sends the state for each player that player can see. There's no re-computation at that point, just packing a bunch of states into a packet, and then sending it.

For interest management (which is the formal name for the mechanism of "who can see what") you'll often end up needing a spatial index (quad tree, hash grid, etc) to efficiently figure out who can see what. Otherwise, each time any player moves, that player has to check ALL other players for which players are nearby or not. It's better to scan only a subset of players when you need to.

0

##### Share on other sites
4 hours ago, hplus0603 said:

In general, though, "players seeing players" is a n-squared problem. If all players are within view range of each other, then all players need to see all players, which requires N players state updates generated for N players.

In general, you'll want to cache what the actual state is on the server, rather than compute it when anyone wants to observe it. The simulation updates the actual values of each player -- this is just once per player. Then, the network-view iterates through each player, and sends the state for each player that player can see. There's no re-computation at that point, just packing a bunch of states into a packet, and then sending it.

For interest management (which is the formal name for the mechanism of "who can see what") you'll often end up needing a spatial index (quad tree, hash grid, etc) to efficiently figure out who can see what. Otherwise, each time any player moves, that player has to check ALL other players for which players are nearby or not. It's better to scan only a subset of players when you need to.

0

##### Share on other sites

As an additional addendum ... It looks like you are doing good.

12 hours ago, caymanbruce said:

Even though this looks easy, I am still confused with...

Trying to manage this type of relationship is complex, it has difficulty, and it is one of the more computer-sciency topics in game development.

Interest management is a tricky balancing act. There are many different factors that are competing, and each game makes different tradeoffs.  Exactly what to scan, what to process, what to transmit, when to scan, when to process, when to transmit, what to retain, what to prevent, ... balancing all the details make an enormous difference for online games.

Many games make it look easy, the best games make it completely invisible to the player, but the developers either got extremely lucky or they invested enormous amounts of efforts to make the game work so well.

I think all of us with network game experience have been there and felt the pain. I don't have much more to add other than both commiseration and praise. It is hard work, and it takes effort to do well.  Find a good balance between immediate work, deferred work, and avoidable work, that's often a good starting point to help break down the problems.  Otherwise, high five or fist-bump or whatever kids are doing these days, because any progress in a networking project is good.

0

##### Share on other sites
9 minutes ago, frob said:

As an additional addendum ... It looks like you are doing good.

Trying to manage this type of relationship is complex, it has difficulty, and it is one of the more computer-sciency topics in game development.

Interest management is a tricky balancing act. There are many different factors that are competing, and each game makes different tradeoffs.  Exactly what to scan, what to process, what to transmit, when to scan, when to process, when to transmit, what to retain, what to prevent, ... balancing all the details make an enormous difference for online games.

Many games make it look easy, the best games make it completely invisible to the player, but the developers either got extremely lucky or they invested enormous amounts of efforts to make the game work so well.

I think all of us with network game experience have been there and felt the pain. I don't have much more to add other than both commiseration and praise. It is hard work, and it takes effort to do well.  Find a good balance between immediate work, deferred work, and avoidable work, that's often a good starting point to help break down the problems.  Otherwise, high five or fist-bump or whatever kids are doing these days, because any progress in a networking project is good.

Thanks I have fixed the problem in my game. So far so good. I've spent days fixing it here and there before I ask the question. But I will do more testing to make it better.

0

## Create an account

Register a new account

Followers 0

• ### Similar Content

• Hey. Just finished low poly pistol.  What do you think about it?
3700 tr  ready for unreal , unity or any other engine

•
Hey guys I'm a newbie here and interested in game development. A little background, I went to college for a while and learnt C++ and Java, however due to personal reasons at that time I was not able to get most out of my classes. You can say that I'm a little proficient in C++ like I know how to use loops, functions and abit of pointers. I'd like to do game development in my free time and build my portfolio at the same time. So how do I go about this?
I understand that there are many things in game dev such as cameras, math, AI and the engine. I do not know where to start. should I go back and brush up on my C++ or can I dive into something that is less intensive and learn and build from there? I'm currently reading the book by Jason Gregory of Naughty Dog, Game engine architecture. I'm pretty sure most of the technical stuff would fly over my head but the concepts are very interesting. One of my goals would be to build an engine in the far future.
Can you guys fill me in on what to do and how to approach this?

Khairul
• By ghonchi
I want to learn game development/modding/make games . But my pc is very old. I don't to where to start & software that will work on this pc.  I don't have money to buy a new pc so this is what I am stuck with. I don't want latest hd graphics type games. I am more than ok with Quake, Half-life, Counter Strike, NOLF, type games or 2d games. Most of the software I see have high system requirements like Unity or Unreal. Please guide me & don't tell me to buy a new pc I cant afford. Also don't tell me that its not possible to develop on these specs. Because these games run smoothly.  Sorry for my English. Thanks

old Pentium 4 1.70 Ghz, 1gb + 512 MB RAM, Windows XP.

Please don't ignore its a matter of life & death for me
In my previous post, I took a look at the various level designs lessons gleaned from Super Mario Bros. 3’s first world. A lot of them naturally dealt with introductory tutorials, but I wanted to take a slightly different approach with this article.

The elegant introduction of new mechanics is still present throughout SMB 3. In this example, the first appearance of a Chain Chomp is marked by two columns that indicate its range and allow the player to safely observe its behaviour.

SMB 3 is filled with great levels, so I decided to pick out a bunch of clever, fun or simply unique moments from the game that originated with its architecture. I skipped over a lot of possible examples trying to keep the list down to 30, but I think I came up with a good collection that complements the original post.

1) World 2 Fortress

It’s a common technique to place falling obstacles side by side on the ceiling so that the player can “narrowly” dodge them while running underneath. Of course once the first hazard is avoided, it’s easy to figure out that the others won’t pose any threat.
In order to sustain tension, the above Thwomps are positioned at different heights, each one closer to the ground than the last. Although it’s still possible run underneath them, the player can’t be sure he’ll make it until he’s all the way through.
It’s also worth noting that the other fortress levels often work to build a similar feeling of suspense (even when they’re actually not any more difficult than the regular stages).

2) World 2-3

The end-level pipe is covered with a mound of Brick Blocks patrolled by a couple of Koopa Troopas. It’s unlikely that the player will choose — or be able — to dispatch the enemies without stomping on them and sending a stray shell rocketing into the bricks. This causes a chain reaction where the shell destroys many of the blocks, but this is far from a randomized event.
Some of the bricks are deliberately turned into Used Blocks when hit, penning the shell inside and ensuring that it clears a path to the exit pipe. The lone brick that survives the destruction also proves to be a Coin Block, rewarding the players that risk activating it.

3) World 2 Quicksand

The Angry Sun doesn’t scroll with the rest of the background, immediately making this level feel unique.
When the player gets past the Tweester, the sun detaches from its static position and begins swooping down on Mario. The entire level is designed with this dodging gameplay in mind as its layout is fairly flat and it doesn’t contain many enemies.

4) World 2-4

The top-left corner of the level’s starting position shows a narrow gap plugged up with a bunch of Brick Blocks. This draw the players attention and guides him to discover that he can fly and smash through the entire column without losing any elevation.
Once at the top of the platform — which contains a neat-looking enclosed pool — the player is given a chance to discover another fun continuous-flight mechanic: bumping a horizontal line of Brick Blocks that all dispense coins.

5) World 2 Pyramid

These tight tunnels are filled with one-off brick walls. Although it’s possible to destroy them with Raccoon Mario’s spin-attack, the plethora of Buzzy Beetles ensures that the player has many chances to use the enemies in order to carve a path through the level.

6) World 3-2

This is an example of an interesting Starman mechanic: the Wooden Block dispenses the invincibility powerup, and if Mario is invincible while bumping certain other “?” Blocks, they will also release Starmen instead of coins.
Although quite challenging to time, this allows the player to blaze through the level instead of following the more exploratory route.

7) World 3-3

In addition to changing Brick Blocks into collectible coins, the P-Switch can also be used to make level traversal much easier. In this case, rows of coins are turned into platforms that allow Mario to avoid various hazards lurking below. These makeshift bridges carry on to the end-level pipe and provide a much safer route if the player is quick enough to take advantage of them.
The end-level pipe is also interesting as it’s not located on the very right edge of the map, but instead roughly 2 screens to its left. If the player travels past the pipe, he’ll discover a secret 1-Up Mushroom.
This is a great example of making something feel novel by enforcing a certain pattern (end-level pipes are always on the right side of the map) and then simply breaking it (the end-level pipe is now closer to the middle).

8) World 3 Fortress 1

This hallway with numerous doorways introduces large-scale branching and looping design. Most doors drop Mario into a pool of water, but two have unique destinations: a bonus coin room, and the actual path to the level’s end.
Since working out which doors lead to where is a matter of trial and error, it’s easy for the player to start feeling a little tense as the timer continues to tick down.

9) World 3-4

Perhaps the greatest slide in all of SMB 3; not only does it let Mario barrel through a bunch of Goombas, but it can also launch him over a lake and onto higher ground. It’s almost like a Sonic the Hedgehog segment, albeit not quite as thrilling.
If the player misses the jump, there are also a couple of invisible “?” Blocks over the lake that create an alternative path to the top.

10) World 3-8

In this level Mario is constantly harassed by Boss Basses while the whole map dips in and out of water. Thankfully the stage also contains a few Beanstalks that allow the player to climb up and “ride out the storm.”
This is notable as these elements were all encountered in previous levels, but an entirely new dynamic was introduced by putting them together.

11) World 4-1

Probably the most beloved of SMB 3’s worlds, Giant Land features unusually large enemies and objects. Despite their size, most of them behave the same way as their smaller counterparts (although there are a few differences such as not being able to destroy giant Brick Blocks with a spin-attack).
Giant Land levels actually mix large objects and enemies with the regular-sized versions, but it’s the behemoths that are the ones remembered. The sense of wonder they evoke is similar to the “Honey, I Shrunk the Kids” effect, and it works so well because the player had 3 previous worlds (and perhaps other Mario games as well) to get used to the standardized dimensions. When most everything is suddenly blown up — regardless of actual impact on gameplay — it leaves quite an impression.

12) World 4-3

This is a small but notable example of difficulty ramping and an alternative use of objects.
Wooden Blocks are usually a boon to Mario as they stop enemies and occasionally dispense powerups. However, in this case they make navigating the triangular platforms much more difficult. Instead of providing a reward, the blocks stop Mario’s jump and actually push him back, sending him skidding towards a bottomless pit.

13) World 4-4

Air bubbles emanating from the pipe indicate a water current that’s impossible to pass without the somewhat rare Frog Suit. This is actually one of the few areas a Raccoon Mario can’t reach, and its end-point is a neat bonus room with two P-Switches.
This is unusual as P-Switches are typically limited to 1 per level, but there there are 2 of them here (side by side, no less). This is possible as the 2 P-Switches actually serve 2 different functions: one changes a wall of bricks into coins, while the other summons a wall of previously invisible/non-collidable Silver Coins.

14) World 4-6

This level is actually split into 2 nearly identical maps, with a single door joining them together. The main difference between the 2 areas is that the first contains large enemies, while the second contains regular enemies.
The effect makes the door feel like a gateway to the “normal” part of the game, in turn accentuating the surreal, alternate-universe nature of Giant Land. All this is also achieved with no extra art resources, and it comes across as quite unique since it’s never repeated in any other levels.

15) World 5-2

Mario enters this level by falling down a narrow, walled-off tunnel. While descending, the player is shown a pipe and some blocks that inform him of an area he can’t yet reach.
As the tunnel ends, a couple of platforms pop into view that — if the player is fast enough — can be used to break Mario’s fall. The platforms are Jump Blocks and their bounciness makes this a somewhat tense exercise, but successfully landing on them allows the player to get up to the pipe Mario just passed.
If the player misses the platforms, though, he won’t lose a life. Instead, he’ll continue falling while collecting a few extra coins, and eventually take a slightly harder, alternative route to the level’s end.

16) World 5-3

The only level in the game where Mario can get a hold of the famous Kuribo’s Shoe. Although the powerup is fairly easy to miss — it disappears if the Goomba riding it is stomped or shot with a fireball — a helpful row of blocks allows Mario to bump it from below. This catapults the Goomba out of the shoe and lets the player take it for himself.
Further on in the level Mario encounters a variety of enemies and obstacles that are usually harmful to touch. However, if he’s riding the shoe, Mario will be able to perform various hazardous tasks such as walking across Munchers and stomping Piranha Plants! This extremely satisfying twist stems from flipping a bunch of rules on their heads, and in the process it greatly empowers the player.
It also feels all the more special as the shoe is only encountered in this one stage.

17) World 6-1

The first ice level contains a secret door in the sky that can only be reached by a flying Mario. The door leads to an icy room filled with Brick Blocks clogging a corridor, and a small passage just above them.
Although Mario can use the spin-attack to get past the bricks, the upper path contains a P-Switch that can turn all the blocks into coins. Since only a super version of Mario can fly up to this room, the player must use a running slide to get through the narrow passage and reach the P-Switch.
Once the P-Switch is hit, the cramped quarters make backtracking to the coins somewhat difficult (especially since the game always slides Mario to the right if he gets stuck under a block). However, the newly encountered ice provides less friction, which in turn makes sliding much easier. This relatively small difference is elegantly used to create a layout that would be frustrating (if not impossible) in other worlds.

18) World 6-5

This is perhaps the most puzzle-ish level in the entire game, and it requires very specific knowledge to properly traverse.
Here’s how the level is completed:
Mario must first turn into Raccoon Mario if he’s not already capable of flight. This is made fairly easy by a small room that can be entered from a pipe at the beginning or end of the map. This room contains a powerup-dispensing “?” Block that respawns every time it’s visited. Once Mario has the ability to fly, he must clear the ground of Buster Beetles and Ice Blocks to create a runway. However, he must not kill the Koopa Troopa while doing this. Next, Mario must stomp the Koopa Troopa, pick up its shell, and quickly fly to the upper-right corner of the map before the turtle wakes up. Finally, the player must toss the shell into some blocks and Nipper Plants. This is the only way to take out the Nipper Plants and open up a path to the end-level pipe. The reason for all these steps is that the Nipper Plants cannot be stomped, and their surroundings prevent Mario from spin-attacking them. It’s also impossible to get up to this part of the map with a Fire Mario, or to bring along an Ice Block as Raccoon Mario cannot carry them while flying. Finally, even if the player decides to “sacrifice” a hit to the Nipper Plants, he’ll instantly shrink and be unable to break the Brick Blocks that wall off the end-level pipe.
The only way to reach the exit is to use a turtle shell, and this whole chain of events shows how a group of relatively simple objects and enemies can be combined to create a very complex obstacle.

19) World 6-6

Cheep-Cheeps are usually encountered in large bodies of water, but in this level they can also be found in small, one-tile-wide cavities. It’s a unique occurrence, but executed very well.
The Cheep-Cheeps never miss their jumps — even when their starting and ending points are placed at different elevations — and their aerial acrobatics are fun to interact with and observe.

20) World 6-7

This autoscrolling level is filled with Donut Lifts that crumble and fall under Mario’s weight. The player can actually risk riding them as they fall to collect columns of coins and still jump off before it’s too late. In fact, this very technique is required to exit the level.
Midway through the stage, the player can also obtain a Fire Flower. The level is easier to traverse with Raccoon Mario’s glide ability, but the Fire Flower allows Mario to melt a bunch of frozen coins at the end of the stage (a similar mechanic is later used with frozen Munchers).

21) World 6-8

The plethora of Ice Blocks and rows of enemies found in this level allow the player to set off numerous chain reactions that take out his foes in a single move.
The cascading effect of tossing shells/blocks is always fun, and it provides extra points/1-Ups while clearing the path ahead.

22) World 6 Fortress 3

When Mario enters the penultimate room in this fortress, he finds himself dropping past a door near the ceiling. As Mario falls, multiple Boos surround him and the background begins to scroll down.
This creates a unique and pretty tense situation as the player is forced to dodge the incoming Boos while waiting for the exit to descend.

23) World 7-1

The ability to loop around the edges of the screen was a staple of the original Mario Bros., and it’s also used at various points in SMB 3. In this case, it teases the player with a coin-filled room.
Although it’s possible to get close to the room’s entry-pipe by looping around the screen, Mario cannot jump into it. Instead, he must drop to the thin horizontal pipe below, build up his P meter, and finally soar up and fly into the entry-pipe from below.

24) World 7-2

If the player falls into the above ditch, he’ll quickly discover that it’s impossible to jump back out. Consequently, this will lead him to enter the pipe at its bottom. It’s a preferable choice to simply falling into a bottomless pit, but there’s a catch: like with so many later levels, this seemingly innocuous mechanic (entering a pipe) results in a hazardous situation.
When Mario emerges on the other side, he’ll find himself floating underwater above a bottomless pit. To make matters worse, the pipe itself will spew out air bubbles that will push him ever closer to his death. It’s not too difficult to escape the current, but it’s a somewhat unexpected challenge that requires quick reflexes.

25) World 7-5

Although the above jump is possible, it’s quite tricky. Most players will not reach the ledge, and when they try to jump back up, they’ll bump into a bunch of invisible “?” Blocks (the blocks are only collidable when hit from the bottom).
This technique is used in numerous levels, and although it slows down the player and forces him to backtrack, the unveiled “?” Blocks serve as helpful bridges the second time around.

26) World 7 Fortress 1

This unique fortress lacks any enemies and is another great example of a puzzle-oriented level.
Its first room is constructed almost entirely out of Brick Blocks, with a single door on the far right. The door leads to an empty hallway (which is a little creepy due to the absence of Hot Foot, Stretch and Roto-Disc enemies despite the presence of objects they’re usually attached to), and another door that deposits the player in a lava room.
The lava room contains a “?” Block that spawns a powerup and is bordered by a wall. The wall is mostly there to prevent a Mushroom (if that’s what the “?” releases) from escaping Mario’s reach. This is vital as the room is a dead-end and the player needs a super version of Mario to complete the level.
Once the powerup is collected, the player has to backtrack to the beginning of the stage and smash some of the Brick Blocks positioned above his head. One of these Brick Blocks will turn out to contain a P-Switch, and when the switch is pressed, all of the bricks in the room will turn into coins.
It’s easy to let Mario’s momentum slide him off of the P-Switch, or simply to jump and grab at the plethora of coins, but restraint is required to make progress; if the player falls through the newly materialized coins, he’ll simply find another door that leads back to the empty hallway.
Instead, when the P-Switch is hit, an invisible door will appear close to it (so even if the player misses it, he’ll know about it’s presence). The hidden door leads to a secret room and a Tanooki Suit, and eventually back to the empty hallway. The lack of enemies in the level makes it easy to do all this backtracking without losing the suit, and its flight ability needs to be used in this section in order to reach the hidden exit pipe on the ceiling.

27) World 7-7

This is a unique implementation of the Starman powerup as the player is actually forced to use it in order to complete the level.
The invincibility afforded by the Starman allows Mario to run across the flat row of Munchers, periodically hitting “?” Blocks in order to snag another Starman. Of course the distance between the “?” Blocks keeps increasing as the level goes on, and this creates a sense of tension as Mario is forced to continuously rush forward while recharging the temporary powerup.

28) World 8 Tank Brigade, World 8 Navy, and World 8 Airforce

The auto-scrolling “military” levels are one of the defining features of SMB 3, and they do a good job of making the player feel like he’s plowing through an entire army.
They also play off of each other quite well:
The tanks in the first wave have animating treads that — when combined with the auto-scrolling nature of the level — make it seem like they’re slowly approaching Mario. The tanks are completely stationary, but the constant forward-push of the scrolling is a neat trick that makes ’em appear mobile. The second wave consists of battleships and a “rising tide” mechanic that has the whole map continuously dipping up and down. It’s another simple trick, but it does a great job of making the level feel as if it were a battle taking place on the open seas. Finally, the airship wave drastically increases the auto-scrolling speed, jarring the player from the ponderous pace of the previous waves and throwing him into a hectic chase atop floating platforms.
29) World 8 Hand Trap 1

Although the Hand Trap levels are somewhat random and optional, the first one is notable for its gauntlet of mini-bosses. It contains no regular enemies, just the numerous variants of the Hammer Bros., and ends with a single chest instead of a Goal Panel/boss fight.

30) World 8 Bowser's Castle

The treacherous last level contains various hazards, but it’s main notable point is the final confrontation with Bowser.
Although it’s possible to dispatch him with the Hammer Suit, the traditional approach is to let Bowser stomp through the the bricked floor. It’s a very intuitive mechanic as it’s demonstrated for the player throughout the fight, but what really makes it interesting is how it contrasts Mario’s own abilities.
Throughout the entire game, Mario destroys bricks by hitting them from below. Bowser, on the other hand, is capable of exactly the opposite maneuver: smashing blocks by stomping down on them.

Despite this list being a top 30, it is not thorough (for example, a cool concept never mentioned is the P-Switch in World 4 Fortress 2 that outlines an invisible door with a bunch of silver coin). Taking what’s here, though, it becomes quite evident that much of SMB 3’s uniqueness comes from conditioning the player, and then pulling the rug out from underneath him. This isn’t as bad as it sounds as these “twists” are often optional and give the player time to adjust.
They’re also part of a larger design choice that seems to be SMB 3’s main focus: variety.
Beyond the clever architecture, one-time mechanics/dynamics, unique art assets, etc., the overall flow of the levels shows the importance of this goal. Even when the Worlds are themed — such as Ice Land — each of their consecutive stages use different tilesets and gameplay. The standard level is accompanied by multi-directional auto-scrollers, tense fortresses, sluggish underwater stages, battle arenas, one-off themed levels, labyrinth maps, bonus shops, airships, minigames, etc. Simply put, SMB 3 pulls out all the stops in trying to create a constantly stimulating experience that never feels repetitive.
I’d like to take a closer look at how all this variety is stitched together, so for my final post I’ll focus on SMB 3’s “meta” aspects and how they tie-into the overall level design.

Note: This article was originally published on the author's blog, and is reproduced here with kind permission.

• Hello,
Currently I am working on a game design document for a Text Based Gangster MMORPG. This will be Web Based similar to torn.com, mafiareturns.com, mafiamatrix.com.
Basically, the players will choose between a Crime, Law, or Business role. They then progress with their characters, ranking up and trying to reach the top. Players can get together and form crews or groups as well. Players must be smart though, because death in the game is permanent and they will have to create a new character if they die.
I'm looking for someone (or a small team) to help develop the game. I will handle design, production, and even business administration. I need someone else to handle the backend and possibly front end of the coding. I envision the game being done in PHP, MySQL, HTML, CSS, AJAX, etc. I'm open to suggestions by the coders as well.
I may also need an artist who can draw a clean UI for us.
At the moment, this is a rev-share position with contractual pay options later.

• 12
• 28
• 14
• 11
• 34