Contents
Games Demystified: Portal
 
 
Printer-Friendly VersionPrinter-Friendly Version
 
Latest News
spacer View All spacer
 
November 21, 2009
 
Video Game Watchdog National Institute On Media And The Family Shutting Down [10]
 
Modern Warfare 2 Infinity Ward's 'Most Successful PC Version' Yet [12]
 
New Tech, Design Details Of Project Natal To Emerge At Gamefest In February
spacer
Latest Jobs
spacer View All     Post a Job     RSS spacer
 
November 21, 2009
 
Sucker Punch Productions
Character Artist
 
Sucker Punch Productions
3D Environment Artist
 
Sucker Punch Productions
Network Programmer
 
Sucker Punch Productions
Texture Artist
 
Sony Online Entertainment
Brand Manager
 
Monolith Productions
Sr. Software Engineer, Engine - Monolith Productions - #113767
 
Crystal Dynamics
Sr. Level Designer
 
Gargantuan Studios
Lead World Designer
spacer
Latest Features
spacer View All spacer
 
November 21, 2009
 
arrow Upping The Craft: Susan O'Connor On Games Writing [6]
 
arrow Small Developers: Minimizing Risks in Large Productions - Part II [6]
 
arrow iPhone Piracy: The Inside Story [48]
 
arrow And Yet It Grows: Analyzing the Size and Growth of the European Game Market [5]
 
arrow NPD: Behind the Numbers, October 2009 [13]
 
arrow Reflecting On Uncharted 2: How They Did It [5]
 
arrow Sponsored Feature: Rasterization on Larrabee -- Adaptive Rasterization Helps Boost Efficiency
 
arrow Postmortem: Wadjet Eye's The Blackwell Convergence [2]
spacer
Latest Blogs
spacer View All     Post     RSS spacer
 
November 21, 2009
 
Accepting the Inherent Value of Games
 
Planckogenesis, Part II: Song Structure & Gravy Train [1]
 
Designing Games Is About Matching Personalities [1]
spacer
About
spacer News Director:
Leigh Alexander
Features Director:
Christian Nutt
Editor At Large:
Chris Remo
Advertising:
John 'Malik' Watson
Recruitment/Education:
Gina Gross
 
Features
  Games Demystified: Portal
by Jeremy Alessi
10 comments
Share RSS
 
 
August 26, 2008 Article Start Previous Page 2 of 3 Next
 

In order to break this down we will visit our old friend velocity, which is a vector. A vector is a magnitude coupled with a direction. Velocity is a vector whose magnitude is representative of speed. When the player collides with a portal we can extract the speed component of our velocity and redirect it to form a new velocity vector.

Now what term from the last column do we remember most of all? Those who remembered "surface normal" get a pat on the back along with a cookie. When a portal is applied to a wall, floor, or ramp in the game, the surface normal of the surface is communicated to the portal inhabiting it.

Advertisement

We then take the velocity we entered a portal with, and break it down into components. To do this we multiply by the surface normals of the exit portal.

In the end, Portal uses the traditional teleportation mechanic with a velocity and orientation change. Here's a simple code snippet, again written in Blitz3D, which is an excellent tool for quick prototyping like this.

;====== UPDATE PLAYER PHYSICS ======

Function updatePlayerPhysics()

player.playerClass = Object.playerClass( localPlayer )

AlignToVector( player\skeleton, 0, 1, 0, 2, 0.05 )

portalCollision = EntityCollided( player\skeleton, PORTALSTATIC )
If ( portalCollision <> 0 And portalOpen() )

EntityType( player\skeleton, STATIC )

For portal.portalClass = Each portalClass
If portal\entrance <> portalCollision Then Exit
Next

PositionEntity( player\skeleton, EntityX( portal\entrance ), EntityY( portal\entrance ), EntityZ( portal\entrance ) )

velocity# = Sqr( player\vX# ^ 2 + player\vY# ^ 2 + player\vZ# ^ 2 )

player\vX# = portal\nX# * velocity# * 1.2
player\vY# = portal\nY# * velocity# * 1.2
player\vZ# = portal\nZ# * velocity# * 1.2

RotateEntity( player\skeleton, VectorPitch( portal\nX#, portal\nY#, portal\nZ# ), EntityYaw( portal\entrance ) + 180 - ( EntityYaw( portalCollision ) - EntityYaw( player\skeleton ) ), 0 )
TranslateEntity( player\skeleton, 10 * portal\nX#, 10 * portal\nY#, 10 * portal\nZ# )

EntityType( player\skeleton, DYNAMIC )

CaptureWorld()
UpdateWorld()
RenderWorld( 1 )

Else

If ( EntityCollided( player\skeleton, STATIC ) )
player\vX# = 0
player\vZ# = 0
If ( CollisionNY( player\skeleton, 1 ) > 0.5 )
player\vY# = 0
MoveEntity( player\skeleton, player\mX#, 0, player\mZ# )
player\jumpTimer = MilliSecs()
EndIf
Else
player\vX# = player\vX#
player\vY# = player\vY# - 1
player\vZ# = player\vZ#
TranslateEntity( player\skeleton, player\vX#, player\vY#, player\vZ# )
MoveEntity( player\skeleton, player\mX#, 0, player\mZ# )
EndIf

If player\jumpTimer + 250 > MilliSecs() Then player\vY# = player\vY# + player\mY#

EndIf

End Function

;======

 
Article Start Previous Page 2 of 3 Next
 
Comments

Haig James Toutikian
profile image
Coming from a science background, I can really appreciate articles like this. Very refreshing!


Eric Diepeveen
profile image
Awesome article. You keep picking the most innovative & jawdropping gameplay features from games and turn them into understandable lines of code. Your fascination with physics makes for some awesome reads. Keep up the good work.

Milosz Derezynski
profile image
Haig: Not coming from a science background (well, CS..) i appreciate this article too ;)

Bart Stewart
profile image
Love it. It's like going back to the heady days when Byte magazine still printed code listings.

Knowing how stuff really works is glorious.

Thanks for choosing to publish this, Gamasutra editors!

Stone Bytes
profile image
If portals are nothing really new, Portal itself has been a gem for genuinely focusing on a main, say single positive gimmick which is key to the gameplay. Just proof that you don't need games that do all, just be sure that the one core idea or function that supports the whole product is solid and rich enough.
I also honestly hope that people won't start to say that anyone could have made Portal, notably because it's not that hard to "find" the code behind the rule. This is something recurrent you hear from jaleous mouths, but the point is that one guy did it, you others didn't, and too bad for you.

Dario Hardmeier
profile image
Another great article with very inspiring insights.

I suggest one slight modification to the transformation of the player velocity : instead of changing the velocity direction to the normal of the exit portal, thus changing any movement at a right angle to the portal normal into forward motion, i propose projecting the velocity vector onto the basis vectors of the entrance portal. This gives back the players velocity relative to the entrance portal's orientation. This new velocity can then be multiplied with the basis vectors of the exit portal, resulting in the "correct" transition.

Might be a few more lines of code (and a bit more of a hassle with setting up the basis vectors), but allows far more possibilities when playing around with portals.

Things could even be taken further when using different sizes of portals (ie differing, non-normalized basis vectors for the entrance and exit portals), in combination with scaling of objects passing through a portal. For a very nice example of this, see Peter Molyneux's GDC 2005 "Room" demo ( http://www.youtube.com/watch?v=vGiPUx9Zgi0 ).

PS: Very looking forward to you next article!

Anonymous
profile image
I would've liked to hear about the rendering of the portals as well, which it seems to me is the more technically challenging part. There was a commentary node about it in the game: as I recall, they iterated through several methods, each of which had its own performance issues, and eventually arrived at rendering inside a stencil buffer using a different camera. I would expect this to put particular pressure on the vertex unit of the GPU, which may explain why they chose very clean-looking environments that are low on vertices. It's also only done to two levels of recursion, after which further portals are cheaply faked by only rendering the fiery oval instead of the actual scene. Very clever to use a stencil buffer for such an unusual trick.

Anonymous
profile image
You're absolutely right. The rendering part is so much more interesting. I think everybody with a bit of understanding on vectors knows how to do this. Probably anybody who can code in Blitz3D. :)

The Room from GDC 2005 is really interesting. I did not get whether they included this mechanic in BW2???

Shay Pierce
profile image
I'm with everyone else on wanting to see some practical implementations of the portal rendering. But since the author was apparently writing this on the eve of his wedding, I certainly forgive him for only analyzing ONE fascinating piece of code. :)

Maybe the next installment of the column could come back to Portal and analyze that part as well.

If not, I'd like to see the next one be about Braid's time rewinding mechanics! Seems like Jon Blow has described how he did it enough times that it would be easy to reverse-engineer. But even when you know you could do it yourself if you had to, there's something about seeing someone else actually implement it and share the code - even if it's a non-refined implementation - that gets the creative juices flowing. Thanks for the articles Jeremy!

Anonymous
profile image
The rendering of the portals is not quite right. The portals are obviously rendered with a set camera position, but should be rendered using the direction of the player to give a correct perspective on the 2D plane. For instance if you walk up to one of the portal entrances and look diagonally in it, it does not look correct.


none
 
Comment:
 


Submit Comment