Search the Community

Showing results for tags 'Optimization'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Categories

  • Audio
    • Music and Sound FX
  • Business
    • Business and Law
    • Career Development
    • Production and Management
  • Game Design
    • Game Design and Theory
    • Writing for Games
    • UX for Games
  • Industry
    • Interviews
    • Event Coverage
  • Programming
    • Artificial Intelligence
    • General and Gameplay Programming
    • Graphics and GPU Programming
    • Engines and Middleware
    • Math and Physics
    • Networking and Multiplayer
  • Visual Arts
  • Archive

Categories

  • News

Categories

  • Audio
  • Visual Arts
  • Programming
  • Writing

Categories

  • Audio Jobs
  • Business Jobs
  • Game Design Jobs
  • Programming Jobs
  • Visual Arts Jobs

Categories

  • GameDev Unboxed

Forums

  • Audio
    • Music and Sound FX
  • Business
    • Games Career Development
    • Production and Management
    • Games Business and Law
  • Game Design
    • Game Design and Theory
    • Writing for Games
  • Programming
    • Artificial Intelligence
    • Engines and Middleware
    • General and Gameplay Programming
    • Graphics and GPU Programming
    • Math and Physics
    • Networking and Multiplayer
  • Visual Arts
    • 2D and 3D Art
    • Critique and Feedback
  • Topical
    • Virtual and Augmented Reality
    • News
  • Community
    • GameDev Challenges
    • For Beginners
    • GDNet+ Member Forum
    • GDNet Lounge
    • GDNet Comments, Suggestions, and Ideas
    • Coding Horrors
    • Your Announcements
    • Hobby Project Classifieds
    • Indie Showcase
    • Article Writing
  • Affiliates
    • NeHe Productions
    • AngelCode
  • Workshops
    • C# Workshop
    • CPP Workshop
    • Freehand Drawing Workshop
    • Hands-On Interactive Game Development
    • SICP Workshop
    • XNA 4.0 Workshop
  • Archive
    • Topical
    • Affiliates
    • Contests
    • Technical

Calendars

  • Community Calendar
  • Games Industry Events
  • Game Jams

Blogs

  • Michael Tanczos.. Gamedev.net code monkey
  • So much for Creativity
  • The nearsighted one cometh
  • Kylotan's Developer Journal
  • Rabbit Droppings
  • The Code Zone Bargain Basement Blog
  • Author, Programmer, Bag of Wind(TM)
  • Journal of Sneftel
  • Strife's Most Excellent Journal
  • Readme.txt
  • Journal of Null and Void
  • Dirty Hacks and Stupid Tricks
  • This is not a blog
  • Continuous Refinement
  • 23yrold3yrold's excessively awesome journal
  • Journal of Tiffany_Smith
  • Journal of The God
  • Journal of void*
  • Journal of UknowsI
  • The Mothership Connection
  • Journal of Sandman
  • Gaiiden's Scroll
  • Journal of LessBread
  • mittentacular
  • Journal of adventuredesign
  • Journal of WitchLord
  • Journal of cone3d
  • Ian's Blog Rants
  • Is this thing on?
  • There is no escape from the Washu
  • /* Why you crying? */
  • Journal #259850
  • Journal of Yann L
  • Fortress of Solitude
  • Insignificant Corner on the Wild Wild Web
  • T. Wade Murphy - Sketchbook
  • Journal of Woodsman
  • Journal of kevmo
  • Not dead...
  • Working late past midnight...
  • Journal of pi_equals_3
  • Adventures in Game Production
  • Journal of Drewish
  • Development, OSS, and pie at work
  • Rarely Spoken
  • evolutional.co.uk
  • Welcome to the bowels of hell
  • Journal of danbrown
  • Journal of __Daedalus__
  • Journal of a Magical Badger
  • The Mad World Of Me
  • Perpetual Alpha
  • Journal of Buzzy
  • The Storytelling Ape
  • Untitled
  • Reminiscence
  • Big Sassy's Ramblings
  • Journal of dthorp
  • Journal of benstr
  • Journal of Prairie
  • The Simplest Thing That Could Possibly Work
  • Journal of eklypse
  • Journal of falkone
  • Let
  • Journal of DarkZoulz
  • 0_o
  • Adagio for GameDev
  • MEY - Archive
  • Journal of Ysaneya
  • A constant battle with time
  • Journal of CoffeeMug
  • Journal of Clash
  • My personal space of thoughts...
  • Journal of Void
  • Journal of xEricx
  • Jorgander's journal
  • Journal of mohaps
  • Journal of SEHenley
  • Journal of EricMeyer
  • A view from the trenches
  • Journal of LorenTapia
  • Incoherent Ramblings of a Madman
  • Journal of _zombie
  • FRIZZLEFRY!
  • Journal of IronWolf
  • Designing: The Game and Its Content
  • Fuzzlr
  • Journal of Deltah
  • Game Development of the Graphics Type
  • Journal of IndyHood
  • Raptor's Den
  • Journal of Scott
  • Journal of NafdahliX
  • Journal of Stoffel
  • Journal of the Digital Hobos
  • J3's Joint
  • The NoMonkey Experience
  • Codex of the Modemancer
  • Journal of Blivvy
  • My Thoughts and Progress
  • Journal of Mulligan
  • Boring banter of a programmer.
  • The mighty journal of Raymondo
  • Journal of Nurgle
  • Journal of Bossk
  • Journal of DJHoy
  • One bastard's rants
  • Reprogramming my brain
  • Building the Sphere, one vertex at a time.
  • Journal of Kraiklyn
  • Journal of MonkeyChuff
  • Journal of jakem3s90
  • Journal of Shred
  • Journal of Erluk
  • Ramblings of a Red Dwarf addict
  • Beginnings of the Wayward Programmer
  • Journal of mattnewport
  • Journal of iNsAn1tY
  • MMO Indie? Can't Be Done
  • Journal of CGameProgrammer
  • Journal of scarmiglion
  • Mmm...soylent green...
  • _luridcortex
  • Journal of SeanHowe
  • Journal of Zophar
  • Journal of glincoln
  • Daedalus Development
  • World of Sshado
  • My GameDev Journal
  • Shell extensions, code design and fluff
  • Deux
  • Eh
  • A Keyboard and the Truth
  • The Unofficial 'Empyrean Gate' Journal
  • Journal of whaleyboy
  • Journal of RobertC
  • Journal of James Trotter
  • The Barracks
  • Untitled
  • Don't Click Here
  • Stupid .NET Tricks
  • Journal of JimboC
  • iosys Research and Development Journal
  • ... And on the 8th day, God created Pouya ...
  • Angry Cuttlefish's Fishtank
  • SteelGolem
  • Journal of onehundred
  • Drakkcon's journal
  • Alexmoura's Journal
  • Journal of thesadjester
  • zdlr's game development journal
  • Destructive Design
  • You are all weirdos.
  • Train of Thought
  • Andy Pandy's Magical Journal of DOOM
  • Any Colour You Like
  • Inane Ravings of a Mad Engineer
  • Adventures In Managed World
  • Compiling...executing...recompiling
  • Journal of codemonster
  • Journalgasm
  • Journal of digisoap
  • So long, Gamedev.
  • Journal of hothead
  • For The Storm! a Tribute to Netstorm :)
  • Journal of Magmai Kai Holmlor
  • Journal of JoeDorson
  • Amazing Journal
  • Journal of John Swidorski
  • Journal of benutne
  • Journal of caffeineaddict
  • Journal of Antonie_Bouman
  • Journal of Thygrrr
  • In Which Christopher Robin Buys Some Cheese
  • The Monkey Digest
  • Jinxed
  • Rixter by Rixter by Rixter by Rixter
  • Journal of Cold_Steel
  • NanoTera
  • Journal of MagicScript
  • Journal of a struggling Student
  • MyJournal.lnk
  • Journal of doomhunk
  • Sir Code Alot's Codex
  • Unbreakable
  • Journal of lethalhamster
  • Brain Drain
  • Journal of uto314
  • Not your journal.
  • Computer food
  • Journal of The Frugal Gourmet
  • Digital Scrawl
  • Journal of ToohrVyk
  • Journal of graveyard filla
  • A look into the mind of TheNobleOne
  • Journal of BioMors
  • "That wasn't dirty dancing, it was Salsa"
  • Brandon N's Journal
  • Journal of HughG
  • DogCity Adventures
  • Programmology
  • Journal of Bluehair_fr
  • Graham's Incessant Ramblings (gwihlidal)
  • noaktree leaves
  • ElJournalo
  • Booleans spiffy development journal
  • Journal of Pants
  • coldacid.dev.journal
  • Simple Foolishness :: Just What I Like
  • Journal of Raduprv
  • Journal of Prozak
  • Dave, The Mystical Workings Of...
  • Journal of kentcb
  • Rhaal's Journal
  • Journal of evillive2
  • mobile chronicles
  • Proverbial Max
  • Codename: Karma Online
  • krez's Amazingly Entertaining and Informative Journal
  • The Re-education of Maik Vidales
  • Ols (Away)
  • Yar
  • Writing Web Games
  • What's going on at TDLGames or TDLSoftware
  • DruinkJournal
  • The Meaning of Nahrix
  • Journal of Obscure
  • Drawing Lightning
  • Metaphorical Journeys of Happenstance
  • Journal of Eddie Hicks
  • Ubertainment
  • DavidRM's GDC Coverage
  • Sande's GDC Blog
  • Journal of KellyM
  • joanusdmentia::journal
  • Stompy's Gamedev Journal
  • How to finish a game in less than ten years
  • The Long Road to Making Games
  • Journal
  • Unhandled Exception
  • Journal of cm2
  • Journal of SanityAssassin
  • The sleeper must awaken... and code some.
  • Devnull's Log o' Geekery
  • markr's complete waste of time
  • Ahhh! I think I'm melting!
  • Journal of MrP
  • rhummer's Journal
  • Journal of CyberSlag5k
  • Journal of scubabbl
  • Journal of BlueDev
  • Journal of chadmeyers
  • Journal of Raisor
  • Journal of Undergamer
  • Journal of Hedos
  • Journal of robpers2003
  • Journal of NeHe
  • Nothing much of interest...
  • The Realm of Trial
  • Starving Programmer - Will code for food!
  • Journal of iduchesne
  • Journal of Kippesoep
  • On the path with a ramblin' man
  • You Gotta Squeeze Every Pixel
  • Lame? Where?!
  • Journey into a 3D World
  • Child of GDNet
  • Journal of finch
  • Journal of Hakiko
  • Journal of Lenox
  • Journal of LastUnicron
  • MrEvil's Journal
  • Journal of evelyn
  • Journal de S'Greth
  • donjonsons thoughts
  • Journal of dotnetted
  • The Tub of Awesome
  • Journal of EnemyBoss
  • Triangular Pixels
  • Radioactive-Software
  • Ubik
  • Journal of wasted_druid
  • Level-Grind Online
  • Journal of adam17
  • Sir Sapo... The Man ... The Legend
  • An Artist's Ramblings
  • Journal of LiyonDR
  • Thoughts from a Wanna Be Producer
  • Independent thoughts of PaulECoyote
  • Journal of Lab-Rat
  • Journal of Revelations
  • Gauntlets of Recursion (+3)
  • Journey to the Ancient Galaxy
  • Random things uavfun thinks are cool
  • NickGeorgia's GameDev Journal
  • Journal of jonpolly99
  • Brutally honest game dev stories
  • Journal of Lacutis
  • Clever Title
  • Beals Software
  • Journal of TheArtifex
  • Journal of Ranger Meldon
  • Journal of Pestilence64
  • Journal of jyk
  • Kudu's GameDev Blog
  • Tech: Arena
  • Journal of skittleo
  • Shiny Journal of Programmingness
  • Journal of LamerGamer
  • Programming. Academics. Life
  • Journal of unazona
  • Journal of CalvinCoder
  • Adventures in 3D
  • Journal of tstrimp
  • Journal of Xiachunyi
  • Journal of QuadMV
  • Neutrally Buoyant in a Sea of Productivity
  • Cypher's Journal
  • Journal of Nomad010
  • Journal of a freak
  • Journal of dcosborn
  • Journal of Nagashi
  • The XNA Struggle
  • Journal of Mrs Kensington
  • Journal of heavygearz
  • J of K
  • Journal of MikeWW
  • Distilled Brilliance
  • Journal of EvDaedalus
  • Journal of WillC
  • Necron00bicon
  • Jemgine
  • Big Trouble In Little Chairtown
  • Satisfaction Guaranteed*
  • Journal of munKiecs
  • NetSim: A Hacking Simulator
  • Almost Lackadasical Gamedev
  • Journal of cppgirl
  • Journal of PennstateLion
  • Journal of sathenzar
  • Journal of Trading Route
  • Journal of RingTek
  • Journal of Aiursrage2k
  • Journal of Kalidor
  • The Bag of Holding
  • Journal of Sages
  • Journal of fur (p2pmud project)
  • Journal of Landsknecht
  • Joshua Pilkington's Journal
  • Journal of JoriathLionfort
  • Maddox's Best Friend
  • Primal Damage
  • The Rambloring of Beldamir
  • #ifdef TRAPPER_ZOID
  • Journal of IronGryphon
  • 1000 Monkeys
  • Horror Stories of RanBlade
  • UberFantasticoSuperJournalRahr!
  • Ascending the Lift Hill of Life
  • shilblog
  • "Another genius foiled by an incapable assistant."
  • Exploring infinity
  • Journal of meix
  • Journal of Impeller Head Games
  • The scriblings of Samsonite 2007 AD.
  • Kazade's GDNet Life
  • SteevR's Deadly Development Mistakes
  • IBTL
  • The Moonpod Insider
  • Journal
  • I update. You read. Ok?
  • Journal of pink_daisy
  • In The Beginning
  • We stumble at noonday as in the dark.
  • Journal of Zipster
  • Journal of fearghaill
  • Evolve Games
  • No ninjas here, no really they are over there.
  • Journal of Caitlin
  • Journal of _winterdyne_
  • Journal of PreditorX0789
  • Journal of TyroWorks
  • Journal of AfroFire
  • The Whine Cellar
  • Journal of bargasteh
  • Journal of LilBudyWizer
  • Journal of CTar
  • Journal of furin121
  • Journal of Khaos Dragon
  • Untitled
  • Sheridan's adventures in random nonsense.
  • Nitrous Butterfly Developer Journal
  • Journal of Mephs
  • Journal of Nuget5555
  • Journal of xaver
  • Journal of Fahrenheit451
  • Captaiz Z
  • Journal of nts
  • Journal of rodgaskins
  • Chronicles of the Hieroglyph
  • Journal of Kuro
  • The Life of Corman
  • Journal of Kria Krabbit
  • Abwood's Coding Notes
  • extralongjournal
  • A love story: Me and my 2D engine.
  • Journal of sBibi
  • Journal of necreia
  • Dzz's Journal
  • Journal of Jervin
  • The journal of rpg_code_master
  • 2D Game Development with a splash of Mumbo Jumbo
  • Journal of Mordt
  • Journal of paradoxnj
  • The Wayward Druid
  • Journal of Tera_Dragon
  • darkpanda's awakening
  • Journal of Downer
  • Journal of RageHard
  • Journal of TommyA
  • Journal of kylecrass
  • Destination: Failure
  • Ye Olde Ramblings
  • Journal of Johnny Casil
  • Journal of C J W
  • Krizo
  • Journal of Zao
  • Journal of socrates200X
  • Journal of chapmast
  • Journal of rjhcomputers
  • The Broken Mind
  • Journal of ebner-wilson
  • Journal of SKREAMZ
  • Journal of astralvoid
  • Graphics is gooder and stuff
  • Journal of Talonius
  • Explicity undeclared yet implicitly defined ramble
  • UofU Team Journal
  • Journal of thedott
  • I am a duck
  • Delusions of Grandeur
  • Journal of kirkd
  • Exploration of pie and caek
  • Journal of slowpid
  • It's a hobby.
  • Subverting C++
  • Journal of Dreddnafious Maelstrom
  • Journal of marmin
  • Monkey Land
  • Dev. Blog of Empire Productions
  • Wiiiiiiiiiiiiiiiiiiiiiiiii!!
  • Slow progress
  • Journal of trailervoice
  • Illusive Studios
  • Journal of MindWipe
  • Journal of kmccusker
  • Ramblings of a partialy sane programmer
  • My Game programming journey
  • Adventures in Text-mode
  • Better Together
  • Journal of Kyle N
  • Journal of Genesis : Origins
  • NO
  • Project Kingstone
  • Brainfold
  • Journal of darkzim
  • Journal of jkielpinski
  • Dovyman's Journal
  • Journal of Goober King
  • Adventure Owns You
  • Journal of Sentientv2
  • Journal of mistermecha
  • Journal of sipickles
  • Prodigious
  • Bradley Sward - Small Game Projects
  • El Nino Games
  • Journal of Trefall
  • Tesseract's Game Development Journal
  • Mark the Artist Fights the Future
  • PumpkinPieman's Journal.
  • Get back to work!
  • Journal of Kevinator
  • Journal of Charles Thomas
  • Journal of erwincoumans
  • Journal of Michael Nischt
  • Journal of ukdm
  • Journal of Andrew Fults
  • Level editor in the works
  • Good Enough?.... Never!
  • Wijnand's Game Journal
  • Odorless Entertainment
  • Journal of blimey
  • Milkshake's Dev Diary
  • Journal of dist0rted
  • Journal of -JetSirus-
  • Bandit Revolvers: Championship Edition!
  • Journal of the enemy
  • Journal of soconne
  • Journal of valles
  • Journal of Aardvajk
  • Frog Blog
  • Journal of GreenGiant
  • Journal of ArNy
  • Developing Firebox
  • Journal of John_23
  • Journal of Luminous
  • Journal of CloudNine
  • The Enigma Code
  • bricklayer developers: Fountaindale
  • Journal of The_Neverending_Loop
  • Abort Button Software
  • Journal of Xrystal
  • Journal of Stuart Y
  • Journal of Jesse_P
  • H3O + U-235
  • Journal of a Shaven Ape
  • metaverses
  • Journal of C0D3Name
  • Journal of binaryguy
  • Journal of a wannabe game programmer
  • Journal of Fortia
  • Journal of dracan
  • Journal of boto
  • iLiNX
  • Journal of a undecided
  • Journal of cwestbrook20
  • Yet Another Game Maker
  • Journal of smc
  • The Journal of Thraed, Shadow of Fahrenguard
  • Journal of webjeff
  • Journal of phantom-soft
  • The Wild West of Programming
  • Journal of tribalKris
  • shadowcomplex's stuffs
  • Journal of IceSynth
  • Journal of Tesl
  • Surreal Sensations
  • Journal of AlexLoren
  • Journal of Ronnie Howell
  • Indisputable Tales of Interest
  • Journal of KGodwin - Newbie Game Dev
  • Wills' Wishes
  • Journal of miminawewe
  • Journal of DavidNeal
  • soggyfries
  • Journal of Tallitus
  • Promit's Ventspace
  • Journal of FunLogic
  • Journal of cheops2007
  • Journal of Sensei Maku
  • A Developer's Dream
  • Journal of VanillaSnake21
  • The ballad of a n00b
  • Journal of mattdev
  • Your company name here
  • The Richest Beggar in the World
  • Synbios128's Journal
  • Journal of AnthonyN1974
  • Journal of acappella
  • Journal of deerslyr1
  • Journal of Dragoro
  • Journal of Damon501
  • This Is My Story
  • Evil Stick Man in Evil Stick Land
  • Journal of noNchaoTic
  • Journal of Journaling
  • Phyletic gradualism
  • Fallen, oh dear :
  • The Byproduct of Facts and Fiction
  • Journal of Adam Hamilton
  • WISP
  • The Lion amongst the code
  • Abliss Gamedev
  • Once a Bird
  • Yeah
  • Journal of ShaneHeres
  • Orbital Fan's game development journal
  • Journal of VikingDK
  • Journal of zedz
  • Kiryn's Development
  • Defeating procrastination one post at a time!
  • Journal of HeftiSchlumpf
  • Journal of Scint
  • Journal of MattWhite06
  • Journal of Funkymunky
  • Under a ShadowyTree
  • Frogames adventures
  • Journal of Treesong
  • Brandogon's Journal
  • Alaklin's workshop
  • The never-ending story...
  • Journal of GreenToad
  • Journal of TiredofSleep
  • CAN Games Development Journal
  • What is Interactive Art?
  • Verg-o-nomics
  • Excursions into the Unknown
  • My Epiphany
  • Brain spasm
  • Brian Hoffer's Journal
  • BrokenThorn Entertainment
  • Journal of terry_burns85
  • Old code never dies, it just fades away
  • Journal of ChrisE
  • Journal of ShadowRancher
  • Journal of Dark Matter
  • Journal of mikalar
  • Journal of Moss
  • The Mystic work of Chad
  • Jason's journal
  • UserJP's Journal of Doom +4 ( Imbued with Fire )
  • Quanta's Journal
  • Journal of InnocuousFox
  • JasonP Works It
  • Every Semicolon
  • Data Spire
  • Blue stain
  • Journal of hashin
  • Journal of s3r1n
  • IndieZen Developers Journal
  • OddGames development journal
  • Journal of rvdwerf
  • Memoirs of a Graphics Engine
  • Journal of DraconisRavenix
  • Journal of dbaumgart
  • Journal of Nytegard
  • Archipelago
  • The truth between the lies
  • Journal of kornman00
  • Journal of EvanWeeks
  • Journal of _ArmuT_
  • Journal of stenol26
  • Journal of Besome Games
  • Journal of Palish
  • Journal of binchawpz
  • Magpie
  • MJP's Last Stand
  • Journal of theOneAwaited
  • Journal of EliteCoder
  • Journal of Pluvious
  • Journal of Veslefrikk
  • Journal of Vyper_uk
  • Journal of ExcessNeo
  • Mammal Games
  • Journal of Rascal
  • Laura's Game Journal
  • Robot, Ninja, Pirate, Monkey
  • Journal of Synthros
  • Journal of PsychoPumpkin
  • Rex of the Arx
  • Leandro's endeavours on managed code land
  • Journal of Moore452
  • Chronic Procrastination
  • Journal of Lode
  • Z Axis Games
  • Frisson
  • Journal of +1Games
  • Journal of kapilkapre
  • Journal of Taharez
  • Journal of xtBones
  • Journal of tinac2008
  • Life in the cereal box....
  • Journal of SilentSiren
  • Omegaice's Dev Journal
  • MMORPG Development
  • Journal of NowSayPillow
  • Pixelante
  • nerd_boy's journal
  • Journal of Remus Turcuman
  • The Log: Cloud Ocean
  • Journal of Jaap1978
  • Journal of Mak
  • Journal of lucius
  • Don't forget, it's supposed to be fun!
  • Journal of DarkPsychosis
  • Journal of rolkA
  • Journal of Sastrugi
  • Journal of 4fingers
  • Journal of nsmadsen
  • Just Glad to Be Here
  • Journal of MS Larsen
  • Ep's tool-dev diary
  • lightassassin.log
  • Journal of 2disbetter
  • Crawling with ideas
  • Journal of nightwreath
  • IfThen Software
  • Academia
  • Journal of ID Merlin
  • Journal of digitalerr0r
  • Journal of Hi Speed
  • Journal of Anexa85
  • Journal of ZootSuitGames
  • Journal of jrmcv
  • Journal of Earthania
  • Journal of Lethargic Programmers
  • The Adventures of a Universal Traveller
  • Merry Prankster Games
  • Journal of caldiar
  • Journal of Darkrider0318
  • Journal of davepermen
  • Journal of Encicra
  • Software Renderer in 28 days
  • Journal of DrSizzla
  • Journal of brainstyler
  • Journal of linternet
  • Journal of matt_j
  • Untitled
  • Journal of m3sh
  • My Newbie GD Journal
  • Journal of smr
  • Drew_Benton
  • Journal of FeverGames
  • Windows [Phone | 8] musings
  • Journal of popcorn
  • Journal of gytha
  • Isolate Development
  • Journal of MrCpaw
  • The Pixel Ocean
  • Journal of Zubski
  • Journal of inferno82
  • Journal of mikeman
  • Starting Thoughts
  • Journal of stimarco
  • dwn
  • Tachyon Wars
  • Journal of AndrewA
  • Journal of rip-off
  • Treehouse Gaming
  • Journal of Tom
  • Journal of rohde
  • Journal of wicked357
  • Journal of Roo Avery
  • Journal of Tower City
  • Journal of geekster
  • Graphics Engine Development
  • Journal of hGonzalez
  • Journal of Caste
  • Skipping a D
  • Journal of Matt328
  • Elucidation
  • Battlefield simulation engine
  • Journal of AEdmonds
  • DudeMiester Speaks!
  • Technical Artistry
  • Journal of Exide
  • Mason's Journal
  • istar's Game Life
  • The Greatest Development Journal Ever Written
  • A Traveller's Tale
  • Journal of foursticksj
  • Robot University -- a 2D DirectX Puzzle
  • Journal of KnivesAldren
  • Journal of jerrywilkins
  • Tales from the Veggie Patch
  • Journal of jnbutler
  • Lonely Hearts Club
  • Journal of Rakshasa
  • Journal of OmegaDog
  • Journal of Machaira
  • Journal of damix911
  • Journal of Richard Geslot
  • Dark Horse Software
  • Digital adventures through the third dimension
  • Gnoblins - Development journal of an indie game
  • Journal of ThomasBelgium
  • Wavesonics Pseudo-Random Journal Generator
  • Yckx's GameDev Journal
  • Tales of Ozak
  • Journal of nes8bit
  • Journal of bgund001
  • tinyrocket
  • Think Small
  • The YAR Project
  • Journal of Christopher Loyd
  • Journal of Vanderry
  • Journal of Ariste
  • Journal of namar777
  • Feathers and Code
  • Journal of Mussi
  • Dans Journal
  • Journal of Drakonite
  • Wilhelm's Journal
  • Journal of Laval B
  • Journal of Sybalos
  • Journal of dx elliot
  • True, False, Maybe
  • Journal of dragongame
  • Journal of ManuelMarino
  • Journal of wpalmer
  • Journal of KezraPlanes
  • ProgrammerMattC's Journal
  • Journal of reversinguy
  • Rants Etc.
  • Journal of daveodonoghue
  • Journal of Lunarjax
  • Journal of ShabbaStoney
  • Journal of Dwarf King
  • Journal of Lee Stripp
  • Rendering Systems
  • My C++ Journey
  • Journal of LarryWP
  • Journal of Daivuk
  • Journal of spacemoses
  • Journal of Sam Hagelund
  • #!/Bin/Bash-ObsidianBlk
  • etodd makes games
  • liger13's Blog
  • zer0wolf's Blog
  • davepermen's Blog
  • SageKri's Blog
  • Neutrix's Blog
  • speciesUnknown's Blog
  • FAR Colony's Blog
  • megamoscha's Blog
  • In the year 4016...
  • Lightning Engine
  • kiwibonga's Blog
  • Revenge of a Buzz Saw
  • InvalidPointer's Internets Rambling
  • KulSeran's Blog
  • Drilian's House of Game Development
  • alfith's
  • Ravyne's Blog of Blogs
  • cowsarenotevil's Blog
  • AndrewBC's Blog
  • JoeDev
  • Uncertanities, pitfalls and lesssons
  • martin_bfg10k's Blog
  • ScottsCreations' Blog
  • The Journal Of Luckless
  • Pixel ? Tile ? World
  • Fastcall's Development Blog
  • Blog 3.0
  • owl's Blog
  • dwarfsoft [GPA]
  • Seaßourne's Blog
  • mytre's Blog
  • Kevin's Blog
  • Gaetano Lenoci GameDev Blog
  • chench's Blog
  • fcoelho's Blog
  • Shozan's Quest
  • A Zombie Wedding
  • TheHinch
  • Dev Notes
  • kseh's blog
  • MichaelT's Blog
  • Mastrgamr's Blog
  • Life in Code
  • Mental(FrameRate)
  • The Animal Farm GameDev Blog
  • brslocum's Blog
  • Lost in the Catacombs of Game Development
  • LambdaRogue Development Blog
  • In the Shade
  • Moe's Blog
  • (O_o)
  • Blog
  • Scourage's Blog
  • Tocs' Blog
  • Ezbez's Blog
  • Liheike's Blog
  • Blendium's Blog
  • Madhed's Blog
  • Out Of The Ashes
  • stonemetal's Blog
  • Lords of Midnight Development
  • MarcotteR's Adventures in Research and Development
  • Coding in the Fast Lane
  • Lavinski's Blog
  • Leadwerks Developer Blog
  • MaskedAvenger's Blog
  • XXChester's Blog
  • Just Let It Trickle
  • assainator's Blog
  • Okiedoke!
  • HzerDown's Blog
  • Random Rantings
  • diablos_blade's Blog
  • Airy's Blog
  • HydroxicAcid
  • Igroman's Blog
  • Imgelling's Blog
  • px's cleverly named blog
  • JamesPenny's Blog
  • LogicalError's Blog
  • Splinter of Chaos' Blog
  • The Game Prodigy - GameDev.net Edition
  • Retronator
  • Rulers of the Known Universe
  • Exiled Dimension
  • Katerina's Blog
  • kasonerap's Blog
  • Crage Games' Blog
  • Mastering MMORPG3
  • Emotion Rays DevBlog
  • Adam Omega
  • The duckpond
  • Cross Mobile Gaming
  • Henry Prescott's Portfolio
  • 15 minutes of fame and an eternity of shame
  • Kristof's Game Dev Blog
  • wakahana's Blog
  • sdaq overflow
  • Kimmi's developer blog
  • Lightning Bolt Games
  • Tutorials By Andy Esser
  • BulletOtaku Games Journal
  • Eclision Programming Team
  • New Old Things
  • They don't teach this stuff in school
  • Glow engine Journal
  • Drennen's Journal
  • Jake's Journal
  • A non-programmer's programs
  • Hexagon's Journal
  • Mobeen's Journal
  • EndersGames' Journal
  • Minastas Games
  • Ali Akbar's Journal
  • Butabee's Journal
  • Dragon's Nest
  • Stop playing, start coding!
  • G-Truc Creation
  • Ninja GD
  • Slav2's Journal
  • NickyB's Journal
  • Jastiv's Journal
  • PARPG development blog
  • Romnia007's Journal
  • rachoac's Journal
  • Product Review Blog
  • developing gordebak
  • AciDGraphit3's Journal
  • SFAgent24 Developer Journal
  • Milcho's Journal
  • MikeTacular's Journal
  • The Start and Journey of Sound Creation
  • GDC 2011
  • Hypnotron's Saga
  • glaeken's Journal
  • Robot Ramblings
  • vicviper's Journal
  • jMonkey Business
  • Project Simplicity
  • alphablackzer0's Journal
  • gasto's Journal
  • InfectiousGames Brand NEW journal!!
  • GuardStar's Journal
  • MysteryMeat's Journal
  • deks' Journal
  • T-JAM Studios Journal
  • sk84z's Journal
  • Dace's Journal
  • Adrenaline's First Huge Project
  • Digivance Game Studios
  • Tomasz Dabrowski's Journal
  • Jacobean's Journal
  • Quiet Ponderation
  • Peter Vaughn's Journal
  • J-Snake's Journal
  • nomura's Journal
  • Opt7ons' Journal
  • gharen2's Journal
  • SymphonyOfDream's Journal
  • standingguy's Journal
  • ArtyjayStudios: A fistful of fail.
  • 3D BYTE Technology Blog
  • Aeroflot's Journal
  • Michael J Pierce
  • Datahammer dev blog
  • Bullet Points
  • Sappharos' Journal
  • Pendragon274's Journal
  • Daniel E's Journal
  • From Nothing to Everything
  • ballerplaya's Game Dev Blog
  • Twisted Shield Interactive
  • Menopia's Journal
  • The Legends of racoiaws
  • Andrew Kabakwu's Journal
  • BlueGlutton's Journal
  • StudioZx Journal
  • Lucas Daltro's Journal
  • zerothrillz's Journal
  • GameDev.net Staff Journal Old
  • Matthew Wood's Journal
  • RedPin's Game Jorunal
  • DeeMOONger's Journal
  • Locke's Game Dev
  • Lloyent's Journal
  • Wildlander's development blog
  • AmzBee's Journal
  • Kaushik's Journal
  • Shawn Hargreaves' Blog
  • Xerron's Journal
  • Mario Cavett's Journal
  • BauAir Studios
  • Jacob Gardner's Journal
  • TiagoCosta's Journal
  • Cypharr's Journal
  • loveworld99's Journal
  • Songbird's Journal
  • Oddbird Games
  • IsNe's Programming Journal
  • Firework Factory Development Journal
  • TheLogster's Journal
  • Little Coding Fox's Journal Of Exotic Adventures
  • Hexagon2D
  • TKE Super Dave's Journal
  • andi's Journal
  • Tim Sarbin's Open Wars Journal
  • Jaye's Journal
  • Vermaelen's Journal
  • The 'Massive' Project
  • Marek A. Krzeminski, MASc
  • The Road Less Traveled
  • Inclemency Studios Log
  • Short-Story about Meteora(My dev team)
  • Fox89's Journal
  • Trivigy's Journal
  • FetDaniel's Journal
  • Browser based RTS in the making
  • MortenB's Journal
  • LastContract
  • Developer Quest: Journey of Hope
  • Mayatrone's Journal
  • Vaguely In Focus
  • Starting up as a new company
  • __Homer__'s Journal
  • Sketching the Surface
  • Fubar the game - Developers Journal
  • StephanieRct's Journal
  • daver64's Journal
  • Mozly's Journal
  • Venfer's Riddle RPG/Puzzle game devjour
  • The AdaptivElite Developer's Journal
  • resell4's Journal
  • 2pacfarrar's Journal
  • Karim Kenawy's Journal
  • bandicootzcrib's Journal
  • grandiz3r's final gaming assault
  • ElementCy's Journal
  • Shadows, instruments and ohh my
  • Rattrap's Journal
  • XDaWNeDX's Journal
  • Eliad Moshe's Journal
  • ChugginWindex's Journal
  • Slyxsith's Journal
  • MutedVision
  • r1ckparker's Journal
  • ashkan_203's Journal
  • Project: CharWars
  • luckeytree's Journal
  • Journal of Suspense
  • PREDATOR_UK's Journal
  • Walking Towards The Sun
  • Trucking on
  • Zeypher Rise to Power
  • Keeping up with yesterday
  • vibrunazo's Journal
  • tangentstar's Journal
  • Accountability Journal
  • carlosx's Journal
  • EtherFields' Journal
  • mobilus' Journal
  • AnotherGS' Blog
  • Web by Day, Games by Night.
  • void* journal
  • N.O.W.
  • sosa's Journal
  • Cam's DevLog
  • Disciple of Jonato
  • StarDust DevLog
  • Paradigma11's Journal
  • GSoC '11 - Mono Runtime
  • D Bits
  • The Design Conundrum
  • DrTorte's Journal
  • Mobile RPG
  • 5MinuteGaming's Journal
  • KingofSwing94's Journal
  • Arc Fusion Games' Journal
  • ebontide's Journal
  • Yang G's Journal
  • Arcade Zombies
  • Xaviarrob's Journal
  • Stepping into demons lair
  • Rodimus and Unity
  • Linkfan88's block world journal
  • MeowMeow's Journal
  • A shooter game for all ages
  • The Failure Epiphany
  • Bregma's Persistent World
  • Nik02's Journal
  • lask1's Journal
  • Vic's Journal
  • sketckasketch's Journal
  • Last Engine
  • nife
  • Booniverse
  • Muzz5's Insane Witterings
  • Joe Storm's Journal
  • Switchblade_77's Journal
  • Eiffel's Journal
  • Graphics & Games... or the other way around
  • phara0h's Journal
  • IggyT's Journal
  • ElusiveCoder's Journal
  • Thoughts and Opinions
  • scout113's Journal
  • notyourbuddy's Journal
  • MERKB's Journal
  • Mr Moose's Journal
  • AAKN's Journal
  • TheEvilMuffinator's Epic Adventure
  • Cat Scratchings
  • FreeStejler's Journal
  • Gerónimo Garcia, a game developer
  • zacaj.devlog
  • TC's Journal
  • Luc the Whiny Wind Boy's Journal
  • Tactical Recon Dev Journal
  • OmensDev's Journal
  • OMG NUB!
  • Irvin's Journal
  • ZSG Development Journal
  • MrCodeSushi - Raw and Tasty Code!
  • bls61793's Journal
  • 3D Models for Games
  • T e c h l o r d's Journal
  • Santisan's Journal
  • ZenithSal's Journal
  • Reflections of a Mindless Individual
  • Polar's Journal
  • RetLee's Journal
  • Journey To Hammerdale Devlogs
  • BigDaveDev's Journal
  • bugbuster77's Journal
  • Survivor Game Journal
  • GoofProg.F's Journal
  • gash's Journal
  • Ghavami
  • blltdgr's Journal
  • marcelomp's Journal
  • ZARS Dev Journal
  • Joe P's Journal
  • Discouraged Programmer
  • Real Time RayTracing and implicit modeling
  • Space Exploration/Action RPG hybrid reliant on UGC
  • Random Developments
  • The Newbie Chronicles
  • Mark's Journal
  • DeXmas' Journal
  • Betable's Journal
  • parowoz's Journal
  • Topblast_'s Journal
  • CopperpotQ's Journal
  • japro's journal
  • Merlin3D Development Journal
  • SuperMaximo93's game development
  • Hect
  • Alberta online
  • DIEVOLUTION DevBlog
  • vodku's Journal
  • Codinguy's Journal
  • One man show
  • frang75's Journal
  • Calculemus's Journal
  • ConorJH's Journal
  • DaedalusK71's Journal
  • undead's programming corner
  • SubgateUniverseDevLog
  • Maciekp's Journal
  • Truxton's Journey into Game Development
  • -=cmaster.matso=-'s Journal
  • Not enought samples
  • Eigen's Journal
  • After Hours - and Then Some
  • Dylan's Journal
  • MelKay's Journal
  • Starpires - Space Strategy
  • StormJournal
  • QuestLore devblog
  • Journal of the Mini-Engine (ME)
  • Gl_Terminator's Journal
  • Terminal 0.1 Log 03
  • Odiee's Journal
  • Noisecrime's Journal
  • IMPACT Engine Development Blog
  • asm0day's Journal
  • YodamanJer's Journal
  • Learning Game Programming
  • The Beginning
  • GuardianResearch
  • Dumping Thoughts
  • lanemax's Journal
  • LaneMaxwell's Journal
  • IceFall Games
  • Ashnor's dev journal
  • moodywine's Journal
  • Thomas Amaranth's Journal
  • LoreHunter's Journal
  • VJ01's Journal
  • IronReaverGames Journal
  • OutlawZen's Journal
  • Xealgo's Tumblr Blog
  • Rich Markle's Journal
  • bigxow's Journal
  • Unity3D and AI Game Development
  • Project Updates
  • Lyost's Journal
  • AffenCode Blog
  • davispolk's Journal
  • LightSource Team's Journal
  • Midnight Thoughts
  • Subliminalman's Journal
  • AltairDali's Journal
  • NFL 2011 Talk
  • Valvatorezj's Development Journal
  • Silviu Andrei's Journal
  • Slaton's Journal
  • FlyingSpork's Journal
  • From AiGameDev's Secret Lab
  • FLeBlanc's Journal
  • sampad's Journal
  • Meh Entertainment
  • DeGod's Journal
  • dev.mind
  • ZEJOKER13's Journal
  • swiftcoding
  • paka3d's Journal
  • Lior Tal's Sandbox
  • The Forgotten Planet
  • Rav3nSt0rm's Journal
  • Litheon's Journal
  • ddn3 journal
  • Yacjys
  • I am a beginner and clueless.
  • Adventures in GameDev
  • Mallach's Dev Blog
  • mortalmarshy's Journal
  • Triax Bridge Command
  • EddyDownload's Journal
  • David Amador Journal
  • WorldAlpha.com DevBlog
  • DevDog82's Journal
  • Halley62373's Journal
  • pygame
  • Untitled zombie game
  • alwynd's Journal
  • Lucasnj's Journal
  • johnnycash's Journal
  • George Laskowsky's Journal
  • Eastfist Builds a Machine
  • Allar's Journal
  • irrationalistic's Journal
  • Bidimensional Dreams
  • Jeason's Journal
  • MikeDodgers' Journal
  • BrianTheProg's Journal
  • ZorgaGames Journal
  • Dreaming's Esoteric Teachings
  • compscialien's Journal
  • sythe's Journal
  • turbello's Journal
  • Xanthier's Journal
  • Flowers In Tears' Journal
  • Chris's Animation Blorg
  • Shaker25's Journal
  • SpeedRun's Journal
  • JetStone's Journal
  • sirkibble2's Journal
  • The Shadow Journals
  • Overm1nd's Journal
  • TommyForesd's Journal
  • LeonidValess' Journal
  • Black-Rook's Journal
  • My project blog
  • Mayley's Journal
  • Azure Acres
  • darc koder's Journal
  • Earthwalker's Journal
  • The Hitchhikers Guide to Video Game Production
  • LarryADaniel82's Journal
  • 2D Game Making, the Easy Way
  • DMFirmy's Development Blog
  • Giliam's Journal
  • Notes
  • The Curiously Recurring Gimlet Pattern
  • Zach's Development Journal
  • Dukandia
  • Under Development Law @ GDNet
  • #AltDevBlogADay
  • Digitalis Digoxin
  • Hedron Online Development
  • BlueStar03
  • Library of links to movies
  • SCForest's Journal
  • Heath's Journal
  • Malachor's Journal
  • Craftwork Games Blog
  • Behind the Scenes of Mirthwerx
  • omnomnom's RPG journal
  • Gaiiden's Journal
  • Overview Journal
  • Severed Infinity
  • Creating a Grand Strategy
  • Life at Demergo Studios
  • RADICAL HEROES: CRIMSON CITY CRISIS
  • Adam's Lair
  • Vilntus Entertainment
  • Lateral Creation's Journal
  • nodeg's learning journal
  • Eating The Elephant
  • Cbear's Dev Journal
  • The Siege Released
  • GDC 2012
  • ChezNoir
  • Journey Into Game Dev
  • Ya2's Journal
  • theNewb1e's Journal
  • Boreal's Dev Journal
  • www.Dubious-Games.co.uk
  • _Suezo_'s Journal
  • Lemon Treehouse
  • TechnoFlux
  • GrayMatters
  • Computational Contemplations
  • StarInc Android Development
  • Narf the Mouse's Journal
  • Antilia Development Journal
  • SpaceBeam development
  • Nocturnal Ferret
  • Tdawg30's Journal
  • Making the 'Rituals'
  • Timelines: Assault on America
  • Gunthera's Journal
  • Anthropocene: A Browser-Based Text RPG
  • AndreaTux's Journal
  • Rendering Is Fun
  • Emforce's Journal
  • _moagstar_'s Journal
  • Journey to Ironbane
  • Tipsy's Journal
  • Nick's Corner
  • Methods of A Madman
  • B O N E S' Journal
  • i-tech's Journal
  • Zul's Journal
  • kruncher's Journal
  • Misadventures in Game Making
  • WubWub Games
  • The Proverbial Bottom Rung
  • MidnightTangent's Journal
  • Bharath Raghavan's Journal
  • Stuff Games
  • From Pixel to Product
  • MissMarble's Journal
  • | dxCUDA | software development journal
  • Ralph McJournalstein
  • HorangiSoft
  • Flight of the Journal
  • Thekill473's Tinker Shop
  • Staring into the Moon
  • Mr Jones' Journal
  • BlackWingedGames' Journal
  • ChinaJoy CGDC 2012
  • A Weird Journal
  • necros devblog
  • CodeImp Game Developments
  • Face Punch Games Devblog
  • Sparked Studios Games
  • nighttime development
  • Coding In Transit
  • Journal
  • Kazuo5000's Journal
  • TMKCodes' Journal
  • miicchhii's Journal
  • Framework Philosophies
  • Journal of the Burning Hand
  • Warbringers - hotseat pvp game
  • Tyberthia Learning Experience
  • 2D MO Game
  • SIC Games' Journal
  • RATED-RKOFRANKLIN's Journal
  • Severin's Journal
  • lwm's Roa Journal
  • n00b0dy's Journal
  • uwi2k2 - Part Time Game Dev
  • Bluefirehawk's: "Path to World Domination"
  • Project Veritas - Working title
  • An Engine Through Time and Space
  • Epic Zombie's Journal
  • Bon Ink Creations' Journal
  • Aeronel's Journal
  • My Journey
  • vee's game development blog
  • The Long Road of Simulation
  • TestRoom
  • Amateuriffic
  • Alex Hopkins' Journal
  • Game Project #1
  • Project NN
  • Hostile Viking Studio Development
  • First game for Android
  • Jonathan's Journal
  • The Dwarfenheim Journal
  • codingnoobie's Journal
  • Will push pixels for food
  • Funstorm Dev Blog
  • Synchrex Studios Dev Blog
  • Tales of Allula: Crystal Spirits Development
  • Realm Chronicles developer's blog
  • dmdSpirit's Journal
  • Empyrios: Prophecy of Flame
  • Horizon Dev Journal
  • Corey Hoard's Journal
  • Freya's Journal
  • Hannah Wood's Producer Journal
  • Aurioch's Time Machine
  • achild's Journal
  • Retro Grade
  • Little Sticky Destroyer
  • C# Workshop - Some reedits.
  • creatures-of-gaia.com
  • Adventure Through Game Programming and Development
  • ellisvlad's MMORPG Development Journal
  • FantasyCraft's Game Engine Development
  • The life of a Unity Developer
  • My First Journal
  • Alex.SilR's Journal
  • Nathan's Blog
  • theartist493's Journal
  • Black's Tales
  • Fran Bow, a point & click adventure
  • Aaru's Journal
  • Drayan's TechBlog
  • Journal.Unknown
  • Josh Hartley's Journal
  • A long, frozen Path
  • Game Dev: P-13
  • Gianmarco Leone - Audio Director
  • slicer4ever's Journal
  • The Tribes Game Dev Journey
  • Like tears in the rain
  • Undead Castle Dev Journal
  • Welcome to Flying Cow Ink
  • Riphath's Journal
  • sgt_barnes' Journal
  • Voxel Game's
  • Xamusel's Gamedev Journal
  • Legends of Maelm
  • Crunch Magic
  • The Gameconomist
  • Kaptein's Journal
  • Morphex's Journal
  • Cafe Murder Dev Log
  • XNA 3D hexagon tile RPG testing
  • Modern Roguelike
  • Luis Krestos IOS
  • Gamieon's Journal
  • Koron
  • Sports Fiction ® New Sci-Fi Sports Game Project
  • cengizonkal's Journal
  • Minecraft/Survivalcraft Text Based Game
  • MrPhoenix's Dark Galaxy RPG
  • Vaerydian
  • j-jorge's Journal
  • Progress of 2D (?) Game
  • Orcus3D - The development of a modern game engine
  • Solo Game Developer Guy
  • Terrifying Secrets
  • Ground Up: A Journal Of An Engine
  • 1520:The Asylum
  • Electronic Meteor
  • Cthuga's Journal
  • ikam's Journal
  • Making a simple dungeon crawler
  • Digitopia's Journal
  • Ghostship Journal
  • Marc Mencher's Career Advice
  • Zombie Factory Dev Journal
  • Colony - Indiegame Dev Journal
  • Christian24's Journal
  • Joe's Games
  • MateiSoft's Journal
  • Tubocass' Journal
  • EWClay's Journal
  • And let there be light.
  • Starbase Citadel
  • arunDev's Journal
  • redw0lf's Journal
  • BGBTech: The Status Update
  • The Dawn Age - Development Journal
  • Fen's Journal
  • Jcam Engine 2 Development
  • More Than Cannons Announcement
  • chamomoe's Journal
  • Evolving as a programmer starting with Pong
  • scottrick49's Journal
  • Leadwerks Developer Blog
  • From idea to a game.
  • Game for kids
  • Azaral's Rants, Raves, and Lunatic Ideas
  • Krealit's Journal
  • Scarabus' Journal
  • Journey Into Functional Programming
  • The Beginner's Programmicon
  • Project Domini
  • fps games by mohammed 360
  • Infinity Elephant Development Journal
  • Making a Terrain Generator
  • Squared'D's Journal
  • Squire Studios: A Team of First-Timers!
  • AllEightUp's Journal
  • My attempt at making a platfo... no, a game
  • Spacetime Perpetuance
  • Multiplayer Project Journal
  • PokingWater's Journal
  • Creating A Game: My Journey
  • Konrad's Journal
  • Sam Jackson's World of Game Development
  • Miscellaneous Programming Notebook
  • Somewhere in space
  • Le Journal de Yahiko
  • TidBitCode
  • Nightmaare Shares
  • Dev notes from the Crypt!!!1eleven
  • Neometron's Journal
  • Snapey Code
  • Morikubo's Journal
  • Game A Week Self Challenge
  • DareDeveloper's Journal
  • Aura Games' Journal
  • Viadukt Dev-Journal
  • Arhim's Journal
  • DOT Space Hero's Journal
  • Building a browser game.
  • IcedCrow's Dev Journal
  • BigGiantHead's Journal
  • Richards Software Ramblings
  • Mikkel Staunsholm
  • The Wood under the Moon
  • Dialock's Journal
  • Meatsack's Workshop Journal
  • LouisMed's Journal
  • UncleVlad29's Journal
  • Hands On GameMaker:Studio
  • Project StickandCarrot
  • Casey Hardman's Journal
  • The SeaVax Journal
  • Howligan's Journal
  • Better Than Accounting
  • Death rays and scrapyards
  • Jsvcycling's Journal
  • Vilem Otte's Journal
  • Fight Club Games
  • TOT to Unity3D
  • LemCoop Development Journal
  • Dog Days Dev
  • The Journey of Taking Over Someone Else's Project
  • Gamedev info
  • Caveman
  • Project Z
  • A different way
  • Big Boss TV
  • Sunchasers development diary.
  • The Great Emoticon
  • Nothing Journal
  • Arkanong development blog
  • Building OllieBit
  • Kveitosphier -- Angelic Series (092113)
  • The Adventures of Mr. Fluffypants and Galaxy Lad
  • EraEngine
  • BallShooter Dev.
  • slayemin's Journal
  • Shane C's Journal
  • 2DFriends
  • PanPan's Journal
  • 2d Game Creation
  • #GameDevIsWayMoreFun
  • Grand Strategy: Space War
  • mabulous techblog
  • Mippy's Beehive
  • The development of Voxel
  • Return of Spy Ghost Raider
  • Wunderpong
  • Living and working in Russia
  • Dumont's Journal
  • reenigne's Journal
  • The coming Onslaught
  • Too dumb to make it, too dumb to quit.
  • The Development Blog of Neuton Mouse
  • Brass Watch Games Development
  • Sky Battles - Follow the evolution
  • Kornner Studios
  • The Dev Journal
  • N.I.B.'s Journal
  • jph's itreationGAMES development journal
  • csliva's Journal
  • Ilya Suzdalnitski's Journal
  • Project North Dev Journal.
  • Pete's Journal
  • A Youngster's Development Journal
  • [Theoretical] Games that evolve from player input
  • NerdSushi's Journal
  • Only if [Beta] - Surreal Puzzle Game
  • Never Miss: Dev Journal
  • My SDL Adventure
  • montify's Journal
  • Battle City
  • The Seven Tides
  • Latte Deconstruction - A classic 2D platform game deconstructible
  • SeaCraft! – game development journal
  • exOfde's Journal
  • Nyphoon's Thrilling Quest for Release and Everything In-Between
  • Tutorial Doctor's Journal
  • Path Tracing Adventures
  • ferrous' Journal
  • Alex's Journey Through Game Development
  • Exploring, learning and failing
  • arka80's Journal
  • J Fixby
  • GrinnTech's Notes
  • Spectra - First Game Creation
  • Fortification Hills Studios
  • QuickSilverCarpet's Journal
  • Flappy Assassin is now available
  • Animated Skinned Meshes
  • Undergroundies Projects
  • From End to Beginning
  • ShadowKind Games DevLog
  • Code Snippets
  • The Inner Circle
  • EveronWorlds Ew FPS Online
  • bradleycooper11's Journal
  • The Journeycat's Handbook
  • russelvedcse's Journal
  • MadRockGames
  • Sergioni's Journal
  • Pixel Perfect blog
  • MacAfeeje's Eludiant Time:Starlit
  • Smeagol's Journal
  • chel's Journal
  • Flared Development Journal
  • Malkavian Assembly's Journal
  • OLD Lactose!'s Journal
  • Alurik's Journal
  • Dreaming of adventure
  • Jsvcycling's Tower Defense DevBlog
  • Truerror's Journey Through Insanity
  • Jordan Bonser's Indie Dev Journal
  • afraidofdark's Journal
  • Journal Ov Azathotep
  • Fallen Shadows
  • GTRACE
  • deadstip's Journal
  • showtime
  • Edward's Journal
  • LOST ORBIT Development
  • Raven_rs Journal
  • PNGs and Things
  • Ding! Games
  • ZeroBeat's Journal
  • Coding with OpenGL
  • Joe Gilliver - Black Shuck Audio Journal
  • Giallanon's Journal
  • Project Root
  • delagames' Journal
  • Saint Retro's Journal
  • Arch1eN's GameDev Adventures
  • Return of the Dodo's
  • Riuthamus's Freelance
  • lalilulelost's Journal
  • newtechnology's Journal
  • normoyle1993's Journal
  • Kiritsu Games
  • LariGuilger's Journal
  • Creating Spacemasters
  • Hedeic's Journal
  • dustArtemis ECS Framework
  • IKazma: The Development & Experience
  • SelenaMiller's Journal
  • Project Anera
  • Daath Galaxy Devlog
  • Exploring Programming
  • Wombat Hole
  • GoCatGo's Development Journal
  • JumpSmash Legend a 3D Badminton Simulation Mobile Game
  • The Cuboid Zone
  • Avengers UTD Chronicles
  • Xylvan's Journal
  • Jean-François Fortin's Journal
  • Parallel Development Log
  • Gregory's Development Journal
  • SynchingFeeling's Journal
  • FinalXIIISora's Journal
  • The Big Procedural Game Journal
  • GiTS' Journal
  • Sporniket's log - Game programming while having a busy life
  • 2Play's Developer Journal
  • Garrett Hoofman's Journal
  • Island Troll Tribes
  • int main
  • cyberspace009's Journal
  • Impossibru is nothing!
  • NineheadGenesha's Journal
  • Inside a Wicked Lair
  • Final´s Game-Dev
  • Stett's Journal
  • Madolite's Journal
  • My Game"The Alien On The Planet"
  • How to make a clone of Futile Tiles
  • A Dreamer's Notebook
  • AfricanThunder's Journal
  • Arikin's Journal
  • Sinvas_K's Journal
  • Procedural Worlds
  • Binary Cats
  • Burnt Dragon's Journal
  • Washu's Journal
  • imoogiBG's Journal
  • Eck's Journal - Still Flying
  • Thaumaturge's Journal
  • ryan20fun's Journal of Rasterisation
  • Xaer0's Journal
  • The Week of Awesome II
  • The week of awesome II - shadowisadog
  • 0sok's Journal
  • Making of: Acclimate Engine
  • Misantes' Journal
  • The Week of Awesome II Herd of Nerd Star Participation
  • New Syntax blog for Week-of-Awesome-II
  • Captain Coffee's Journal
  • WoA II Journal
  • Jack & Francis's Week Of Awesome II
  • Erik Rufelt's Journal
  • Week of Awesome II
  • Xai's Awesome Living Toys
  • Week of Awesome II dev journal
  • WoA - My first gamejam
  • The Last Toy in the Toy Box
  • Extremely Usefull Bits
  • GeoffreyS' Journal
  • Jurassic Park Aftermath
  • Project PX
  • H.A.C.K. - Development Journal
  • ajm113's Journal
  • LV-341B
  • Archmage Rises
  • Stormynature's Miscellanea
  • Hierarchical subdivision
  • Radiant Engine Development
  • "Barricade"
  • New New Things
  • Librexus
  • mtlk's Journal
  • EmpiresInRuins' TD Journal
  • Collectible Card Game + Commercial Sim = Awesome
  • Legend of Grimrock 2 Review
  • Dr.John's Journal
  • Gorogorosama vs GameDev
  • Ironbane Devlog #1
  • Game News
  • PowerShell Games
  • ODMO - puzzle game - android release
  • Gaiiden's Journal^2
  • Gaiiden's Journal
  • Gaiiden's Journal
  • Debugging Diaries
  • General Thoughts
  • Captain's Log
  • Orangepixel's Journal
  • LAURENT*'s Journal
  • the game
  • fakhirs's Journal
  • A sound guy making a game.
  • Sisofys' Journal
  • Browser Scent
  • AuroraRL
  • Manager of Hell
  • Tales from the Engine's Core
  • Nemo Persona
  • victoriaadams02's Journal
  • Rico's Development Log
  • Funky Monkey Studios Dev Blog (French)
  • Fear the Light: The Path to Playable
  • Astari
  • mousetails RPG
  • Developing a JRPG
  • goldmoelly's Journal
  • Goblin War
  • Phaetonium's Journal
  • Flame
  • Reactor Engine
  • Boardspace.net Game AI Journal
  • TheComet's Journal
  • Negazina and his shenanigans
  • Realm Crawler Development Journal
  • Becoming an indie
  • The Wizards Blog
  • SIMSpace 8.0
  • Educating an artist
  • Michael Staud's Journal
  • YanimStudio's Journal
  • Adventures into Unreal Engine & indie dev
  • GamzTV
  • Blacksea Odyssey Devlog
  • The Furious Ape Journal
  • Feras' Journal
  • SnailLife
  • Ray Tracing Devlog
  • hgoel0974's Journal
  • GameGeezer's Journal
  • Pavloid game
  • cozzie's Journal
  • Han''s Quest Journal
  • Lost Repo
  • DevBlog: Wolves at the Door
  • victorx's Journal
  • TheChubu's Journal
  • Mobile Game Dev Journal
  • Protheus Engine
  • ducanhtuvu's Journal
  • YGGDRASIL STUDIO's Journal
  • Skinned Mesh/Skeletal Animation Editor in D3D11
  • Proceedings of TheUnimake
  • Inko makes Prototypes
  • Caldera Games' Journal
  • Machine Made
  • YAAG
  • Xam'n'Eggs
  • Developer Journal
  • Game Tale
  • Jygle's Journal
  • Sol-Ark's developer journal
  • Blender - skinned meshes and animation DirectX export
  • Night Lone Engine: Journal and progress
  • Vortex Game Studios
  • williamssara005's Journal
  • Onigiri Flash's Journal
  • The Week of Awesome III
  • Simmie's Journal
  • The Dark Prognosticus
  • Game explorations
  • Danmaku no Kyojin
  • Epicelitedude's Journal
  • Thinking about treasure lately
  • IYP's Graphics Journal
  • My Stuff
  • Trades with Spirals Development
  • WoA 3 (2015)
  • Seven Spells Of Destruction Development Journal
  • Battleships Development
  • An arcade console developer's Journal
  • Spidi, Magic Item Tech Journal
  • Galactic Adventures
  • Week of Awsome III journal
  • TeamTeamEric's Journal
  • From The Forth Dev journal
  • Speed's Progress
  • Gooey's Journal
  • Week of Awesome III
  • ArThor's Journal
  • hu3 team - WoA III
  • Inside the blizzard
  • JamCats' Week Of Awesome III
  • Our Week of Awesome Project
  • Lich Dev Log
  • Single-Handed Game Dev
  • GTEntertainment's Journal
  • Soulwielder Dev Journal (Week of Awesome III)
  • MarioLuigiMan's Journal
  • WoA3 - Still Flying
  • Calinabris' Journal
  • DKoding's Journal - Koding Nights
  • alexokita's Journal
  • TBFC's Week Of Awesome III Dev Journal
  • My First Game !!
  • Dusters Devblog
  • Bigdog57's Journal
  • El Tomba - Developer Diary
  • Starshard Dev Journal
  • alexmasen's Journal
  • bobbentz's Journal
  • Merc Tactics
  • WatsonTBK's Journal
  • Spiral Lords: Armada
  • Arms of Telos
  • Really Slick Blog
  • c++ SFML TEAL
  • A random Game
  • Creation of Zergification tech demo
  • Opiniocracy
  • Kill All Demons!
  • Moon Pub Games
  • KruSuPhy's Journal
  • KruSuPhy's Journal
  • Final Year
  • Monster Chronicles: Mobile Strategy RPG
  • Shinylane's OpenGL Journal
  • psychedelia smith's Journal
  • Conkoon's Journal
  • GE2015's Journal
  • We the Innovation
  • Engine development for fun and bachelors thesis
  • Farom Studio
  • Geometer's Apprentice
  • NavWorkshop
  • an unnamed youtube simulator
  • Eck's Star Citizen Efforts
  • Project Gift
  • opmania35's Journal
  • Westorm's Journal
  • What I did
  • Short rules for beginners in game dev
  • DEV - War of Kingdoms Pocket
  • MoonKiteTree's Journal
  • Tinus Tate's Journal
  • Fowl Flying
  • Memorial Trees: forget-me-not Journal
  • Fidelum Games
  • Hexmind's Journal
  • MVG Interactive
  • EXODUS - A New Age Dawns
  • OmnicidalStudios Akintoo Journal
  • Kingpin
  • iMini Development
  • Oblivion Wars Development Journal
  • devlion's Journal
  • 2D Platformer
  • Cleemo's Journal
  • Becoming the Lord of Dwarves
  • Rogue555's Journal
  • Not Yet Implemented
  • Prali Games
  • Multiplayer RPG dev diary
  • Venatus
  • AVaW2015's Journal
  • Faison92's Journal
  • ProcGen Journal
  • Sector0's Journal
  • P2p online's Journal
  • One Piece Ultimate War
  • Syrena's Journal
  • w32's Journal
  • Max-Green's Journal
  • [GBA] Kingdom of Twilight a retro rom
  • Gamescrye's Game Design Blog
  • GameDev.net Partners
  • Blend4Web Development Journal
  • STAR SHIFT
  • Sweat, tears and blood
  • Amanda/adamSnowflake's Journal
  • Unity Parkour Game
  • Lawnjelly's Journal
  • ProcFxGen's Journal
  • dpadam450's Journal
  • Sungazer Software Development Log
  • A New Developer's Journey
  • De Feet - a 3D interactive story RPG
  • V0xel Sp4ce Development
  • yoshi_t's Journal
  • Strategy Empire's Journal
  • VikingVRStudio's Journal
  • Towards The Pantheon Devlogs
  • GameArch
  • SilviuShaders' WoA Dev Journal
  • Frango Digital Log - The Week of Awesome IV
  • AlienCore's Journal
  • Mousetails WoA 5 journal
  • Mind of Khan
  • XycsoscyX's Journal
  • The Week of Awesome IV
  • WOA 2016 | Team Bytetroll
  • EarthBanana's Journal
  • GameDev.net Staff Blog
  • Unnamed Turn-Based Strategy
  • "Popular" progress.
  • 3D, AI, procedural generation and black jack
  • Avalander's Journal
  • Andrey Macritskiy
  • Drone Combat Devlog
  • Rog Games' Journal
  • The Xoid Isometric Survival... from the start
  • Journal of Gruffler
  • Project Tidalwave
  • Ultra Kai's Graphics Journal
  • MY FIRST INDIE GAME! :D
  • DoomedGaming
  • V-Play Cross-Platform Game Engine
  • Bacterius' WoA Feedback
  • Project Mistwrapped
  • Game Development Adventures
  • The Achilles Journal
  • The Cptn's first voyage
  • A short Journey over Zeno's Bridge
  • MagForceSeven's Journal
  • TheCaptainSly's Journal
  • School and Mazes
  • Development of My Own Civilization
  • Richie2Pixel's Journal
  • khaniiuc's Journal
  • saadtaame's Journal
  • First Complete Game
  • Turn-based strategy about agriculture
  • Systemic Games
  • anyone needs a 3d modeller?
  • Vidar DevBlog
  • Vertexwahn's Journal
  • Opportunities in AR/VR
  • AngleWyrm Studios
  • "Project SpeceVille" Developer Journal
  • Floatlands devblog
  • Game Creation Journal: Midievalry
  • Arceneaux's Log
  • ViciousGaming's Journal
  • ACE Team's Journal
  • yps_sps' Journal
  • Alchemist
  • Project Life
  • GrindQuest
  • Paninairo's Journal
  • JacPete's Super Mage World
  • Resilients Journey
  • Who is Who? Dev blog
  • Multiverse: Cosmic Conquest TCG Development Journal
  • Aggroblakh's Journal
  • Fight the ADHD
  • The Time Rider Community Journal
  • Too few shopkeeper games!
  • VFX Highlights & Games
  • lougv22's Journal
  • First Impact: Rise of a Hero's Journal
  • Labraid's Journal
  • BattleForte Game DevLog
  • WinterDragon Says Print("hello")
  • Ascension Game Journal
  • bogosaur's great journal of wisdom.
  • AurumDust journal
  • Progress on The Last Score
  • BrykuTheDev's Journal
  • Developing a good looking story to make it a game
  • Rebirth of a classic card game
  • Ships vs Sea Monsters. From sketches to final edition
  • SquaserZ - The Devlog
  • Dev Quest With AriiMoose
  • ohoyy056's Journal
  • TheLastKind's Journal
  • ohoyy070's Journal
  • essaywriting
  • Idea To A Game
  • XyraniaDev's journal
  • ohoyy082's Journal
  • Pirate Dawn Universe
  • Deep Waters Devblog
  • brigittepetrie's Journal
  • GoldbarGames' Journal
  • Kickstarter/Greenlight Dev Journals/Tips/Insights
  • Delphinity
  • Big List of Mobile Game Reviews [UPDATED DAILY]
  • 0day's Blog
  • DuelingDevblogs
  • Jaden's Blog
  • Tee_Hunter
  • GDC 2017
  • Voxelaxy
  • Power Pong Devblog
  • Spinbot's Blog
  • SerikASA's Blog
  • Brewing the tee
  • Johnnymorgan's Blog
  • Blog #1 - You can't push a rope!
  • Korvas' Game Dev
  • Tough Story Volume I - Big Hell
  • VirtualRN's Blog
  • Game Blog
  • Dadou666's Blog
  • SHIRO Developers Log
  • Star Heritage
  • Bluword
  • Appodeal Blog
  • juegostudios
  • saraedward's Blog
  • shirawinget's Blog
  • Baro's Beginning
  • phil67rpg's Blog
  • Video Game Sound by Olivier Girardot
  • Deep Worked Blog
  • Swim Out
  • Bypassed - DevBlog
  • Muisca's Blog
  • AlexHoratio's Blog
  • Hell Warders
  • hydra1's Krypton Development Team
  • tommorow's Blog
  • ¿How to do Game?
  • My 1st GDC: Recap
  • Beyonce's Blog
  • donislawdev's Blog
  • Creating Complexity
  • dovodi's Blog
  • Stitched Showcase
  • itSeez3D Avatar SDK
  • 40Ggames' Blog
  • GamerX1221's Blog
  • HunterGaming
  • Nicolas Bertoa's Blog
  • Masters VR
  • PiN
  • Ben's Appallingly Humble Blog
  • Starfall Tactics
  • Ermergerd Ent's Blog
  • Secure Vend LLC's Blog
  • Cascapadia
  • Last Regiment Dev Blog
  • sarwar's Blog
  • Spaceguard 80
  • appguruz's Blog
  • ios\Android games promotions!
  • Forgiveness devblog
  • The creative industries digital game.
  • xboxoneya's Blog
  • Untitled: My journey with LibGDX and bullet hell
  • Block Builder Update Blog
  • noisechip's Blog
  • Call of Avatar
  • behc's Blog
  • Terrible Mess Games
  • polyfrag's Blog
  • polyfrag's Blog
  • Dr. Lexus Blog
  • Jungle Tag by The Kid Can Drive
  • polyfrag's Blog
  • Wormhole Devlog
  • Age of Dark
  • Trym Studios' Concept Blog
  • PSG's Blog
  • sinopgames
  • Space Warfare Blog
  • EdenAeternum's Blog
  • APPTUTTi's Blog
  • SlammaJammaMovie's Blog
  • Village Monsters Dev Diary
  • Rox087's Blog
  • THEDARKMEME's Blog
  • Progorion's Blog
  • lexnewgate's Blog
  • Starminer7Z7 of Fullpower's Blog
  • Progorion's Blog
  • DualTD
  • OandO's Blog
  • From UltDip to ...
  • io games
  • .io Games
  • JohnTheRipper88's Insight and Ramblings
  • Moosehunt
  • VBexEngine
  • Games Development Notes
  • Eart - a similar to an rpg but with typical elements of a bullet hell games
  • Valley of Crescent Mountain
  • Charly Men's BIZARRE
  • 울산오피 ○1○《⑻⑼⑷⑺)⑥⑥④⑧ 세계일등클래스
  • 청담안마 OlO⇔2816⇔2526 〃최저가 청담안마방 청담역안마 청담안마시술소 청담안마추천 청담역안마가격 청담안마위치 청담동안마방 청담동안마추천 청담안마예약
  • 인천출장샵
  • ⅸ강원도출장샵 阝카톡gg882출장콜걸.홈피 kiss45.COM출장안마/ 출장마사지/출장샵/출장업소/콜걸연락처/섹파/콜걸아가씨카톡/업소연락처.
  • Michael Zhou
  • が대구출장샵阝카톡gg882출장콜걸.홈피 kiss45.COM출장안마/ 출장마사지/출장샵/출장업소/콜걸연락처/섹파/콜걸아가씨카톡/업소연락처.
  • Battle of Millenia Update #1
  • ⅸ아산출장샵 阝카톡gg882출장콜걸.홈피 kiss45.COM출장안마/ 출장마사지/출장샵/출장업소/콜걸연락처/섹파/콜걸아가씨카톡/업소연락처.
  • A Passive Gamer's Blog
  • Newbie Gamer
  • Android, the most popular mobile platform throughout the world these days
  • Aggressive Gaming
  • 경마사이트추천 ⟡->『 AA77.ME 』<-⟡인터넷경마사이트
  • The Yii Development Framework for fast, extremely professional performance
  • Psychology in game design
  • Check out my Game!
  • Hell Warders Development blog
  • Wildlife control service
  • EP (A Platform Game)
  • Outentiq
  • See Gee Eye
  • Jenny's Magical Adventure
  • Last Hills Teaser Trailer (Horror Game) - Red Projekt -
  • Want to help make a game
  • New Game - ArcAngel is released.
  • Corona Labs Blog
  • Java&Python game development
  • How to write outstanding game reviews
  • Exactly how Does the Euromillions Millionaire Raffle Work?
  • puppysss
  • World Game Info
  • Rick Henderson And The Artifact Of Gods
  • Mobile Application Development Today
  • Runica: The Ancient Dungeon
  • Benefits of Mobile Application Development
  • Enterprise App Development you need to know
  • Mobile Application Development
  • krkrgames
  • My First Success - Dev Blog
  • Alchemica
  • Elemento : Development Blog
  • Remote Jobseekers
  • Bird With Toes Development Log
  • Forward Creating
  • ギ일산출장마사지 << ㅇIㅇ / ②8ㅇ④ / ③⑧⑧⑤ >>キ빠끈신속 정확선입금 NO24시간 일산출장마사지
  • ゴ여천동출장마사지 ☎ 0①ⓞ.2⑧O④.③885 コ입니다.출장 콜걸뜨거운핫한 여천동출장마사지
  • ズ매곡동출장마사지 << ㅇ①ㅇ / ②⑧ⓞ④ / 3885 >>ス시원빠끈 신속후불선입금 NO 매곡동출장마사지
  • セ진천동출장마사지 < 0!0=2⑦1⑥=!8②⑧ >ズ빠끈신속 정확선입금 NO24시간 진천동출장마사지
  • Drunken Monday, developers of Slash Arena: Online
  • pythoblack
  • Game Developer
  • Levels of Lean Six Sigma Certification
  • Josh Grams - WoA V
  • POSTWORLD Development Diaries
  • Week of Awesome V
  • Journal of development
  • WOA - 5
  • Week of Awesome V - Dev Blog
  • WoA ProjectCastle
  • Ludologists
  • bestpharmacy
  • Micro Brood Games Devlog
  • Bouncy Bob Crunch Journal
  • golds
  • Mobile App Development Company
  • Why Brands Are Missing Out On Mobile Games
  • RPG Grind!
  • Kade Markoux
  • Project XSYS - WIP
  • Higame
  • Chromasia
  • BITSZER SOFTWARE/EARN BITCOINS
  • This is for my rpg game i am working on
  • ggd
  • Kavarna's blog
  • Mobile App And Game Development Blog
  • opensource & javascript game development
  • Fooliery: Build with tiles
  • Super Reaction Speed Arcade Game
  • Mobile Application & Game Development Blog
  • How To Choose The Right Learning App For Your Preschooler?
  • Project Industry[Unity Indie Game]
  • hello World
  • From Zero To VR
  • Mobile Game App Blog
  • A cute casual game
  • Game Design
  • Project Idra
  • Kung Fu Runner
  • PistacheGames
  • Dream Build Play - Resources
  • Modern game narratives - Writing better, stronger, more intriguing game stories.
  • onqtam
  • How to turn off Windows, Mac computers remotely using smartphone?
  • Game Testing and a Cup of Coffee
  • Mobile App Technologies, Unity3D Game Development Blog
  • Android Application Development and Growing Importance of Android Developers
  • disini
  • PandemicZ
  • Picswars.io devlog
  • First Blog
  • New Free Sound For You Guys
  • Cool Designing Tips They Don’t Teach You in Classes #1
  • Blog by Mobile App Development Company
  • 7 Things Every Mobile Team Needs to now
  • 선릉역안마 ゥェ1ゥェ。ィ.2816_〃2526 윤실장 ω환상의코스ω24Open #선릉역안마윤실장 선릉역안마연예인급사이즈 선릉역안마아가씨 #선릉역안마실장 선릉역안마정보 선릉역안마안내
  • Exploring Level Design
  • Mobile App & Game Development
  • Beneath the Waves
  • Mobile App and Game Programming Blog
  • Take my heart to this game
  • Mobile App, Web & Game Design News
  • BEST MEDICAMENT ONLINE
  • Embedded Training in Chennai
  • Free SOFTWARE PURE APK
  • South America Tours - Anubhav
  • Why BrainMobi is ranked among the best Android App Development Companies?
  • Origin Dehumidifier
  • lioryan
  • The Gragons Farm
  • Simple game for Pixabay's developer challenge
  • Oracle course in Chennai
  • Game Android
  • It's Bouncy
  • Homebrew Gamedevelopement Experiment
  • Gift of Parthax - An Ablaze Interactive game
  • White Harvest.
  • The Balcony
  • ScrewDriver
  • Major Factors need to consider in Wearable Development
  • Indienamic
  • Something Ate My Alien
  • Medical VR
  • Hadoop Training in Chennai
  • SAS Analytics
  • Software
  • Salesforce
  • Porting the mobile game to Gameroom (FaceBook)
  • Veteran Game Localization, Voiceover & Publishing
  • How to Develop Mobile Apps which are Engaging and also Improve the Revenue Stream?
  • Colony 7: Performance and Progression Blog
  • Thorns and Blood

Group


About Me


Website


Industry Role


Twitter


Github


Twitch


Steam

Found 27 results

  1. When Apple announced a redesign for its decade old App Store just a few months ago, app makers for the platform all over the world felt expectant and apprehensive about the kind of impact it's going to have to their apps. Apps with a star-studded presence in App Store were most apprehensive, quite naturally. For a vast majority of mobile app development companies, it was rather a good one as it could make their app rating and positioning better if not worse. In all considerations, such a big update received a lot of buzzfrom the developer community. Apart from the general awe, apprehension and expectations, what does an update of such nature mean for the apps and their prospects? That is precisely what we would like to explain here. Finding apps would be easier than ever If you take a deeper look at how the apps generate revenue and get discovered, you are bound to recognise that apps that deserve most buzz for their long-term usefulness often remain undiscovered while apps that become popular for shorter span get the most limelight. Many users simply cannot know of certain useful apps just because they remain unknown and undiscovered. The latest update of the App Store will help us deal with this issue of discoverability. From now on the editorial team of the Apple will choose apps for featured list and various chosen categories as per the quality of the app. With the new focus on quality, the App Store now through a card based system of a display will showcase best apps of each category. The various featured cards that will help to showcase best apps include Sneak Peak, Apple of the Day, Major Update, Now Trending, etc. Obviously, this new system will make finding apps easier than ever before. Optimised product page One of the best things with the new update is the optimised product page which will allow offering more detailed information about the apps. Having a good preview of the app is always impressive and boosting for users to download an app. The new App Store update will have value-added previews, localization details of the app, and new text fields. The app previews in the new App Store only got better and detailed with an array of attributes. The product page also allows showcasing in-app purchases, and users can make purchases way before downloading the app. Far better search function Another impressive way new App Store can add value to the user experience and app discoverability is the new and better search function. Users can find apps and related contents about the apps more quickly with enhanced search. Search results now will consist of detailed layers of information including in-app purchases, app developers, ratings, a collection of apps from the same publisher, categories, editorial remarks and stories, tips, etc. A search function allowing users having so many information about an app right from the App Store will obviously render positive impacts on download. Editors have a lot to say and for the better If you look at the new and updated App Store, you are bound to recognise that instead of depending on so-called machine algorithms, Apple this time is bent on improving quality through its editorial team. App Store this time is all set to deliver an editorial experience to the users just for the sake of making the user experience better. Based on the quality of the apps in each category Apple introduced a card based selection system to feature quality apps across categories. From introducing users it's the regularly updated contents through selection like Meet the Developer and Behind the Scenes or What’s on My iPhone to more need focused contents through selections like Pro Tip, Life Hack, The Basics, the curated and edited contents of the new App Store will help us access apps better as per preference and needs. Ratings revamped for the better The new App Store helped apps coming with their app updates without needing to be concerned about messing with the app rating. Unlike earlier times when ratings were meant separately for each different update, app ratings are now considered with all subsequent updates together. This will help developers coming with a freshly updated app to come out clean and get a rating based on the latest update. This will obviously help developers to come with more frequent updates as this is not likely to bring down the rating of an app. The focus is on user experience and nothing else The focus of the new App Store primarily rests on user experience. Apple is head bent to help users find apps they need while allowing quality app producers more exposure to the users their apps are meant for. Apple has realised that the App Store has come of age and is a densely crowded place with a multitude of apps. To give more exposure to quality apps for specific user contexts and needs, Apple had to devise a redesign to clear the clutter with a consistent focus on quality. For mobile app developers, the new App Store unleashed a bounty of never before opportunity to reach their target audience more easily and garner more traction and downloads from the users. In the long run, the new App Store will only push the qualitative focus and make a better place for the users as well as developers of the iOS platform.
  2. Hey devs! Want to get rid of all the bugs in your game? I co-own a video game QA company called Level_0 Studios, we perform professional QA testing for game developers. Our goal is to help you create bug free games your players will enjoy. Partnering with Level_0 allows you to focus more time towards game development while we find those pesky bugs. If you’re interested and in need of professional game testers contact us at contact@level0studios.com and check out our website at https://level0studios.com for more information.
  3. In DirectX 11 we have a 24 bit integer depth + 8bit stencil format for depth-stencil resources ( DXGI_FORMAT_D24_UNORM_S8_UINT ). However, in an AMD GPU documentation for consoles I have seen they mentioned, that internally this format is implemented as a 64 bit resource with 32 bits for depth (but just truncated for 24 bits) and 32 bits for stencil (truncated to 8 bits). AMD recommends using a 32 bit floating point depth buffer instead with 8 bit stencil which is this format: DXGI_FORMAT_D32_FLOAT_S8X24_UINT. Does anyone know why this is? What is the usual way of doing this, just follow the recommendation and use a 64 bit depthstencil? Are there performance considerations or is it just recommended to not waste memory? What about Nvidia and Intel, is using a 24 bit depthbuffer relevant on their hardware? Cheers!
  4. Hi all, More than a decade ago, a problem came up on this forum for computing a fast transpose of a 3x3 matrix using SSE. The most sensible implementation stores the matrix internally as a 3x4 matrix (so, one row stores 4 elements, aligned in a vector). A version, which I believe to be the fastest currently known, was presented: I am pleased to report that I have been able to come up with a version which should be faster: inline void transpose(__m128& A, __m128& B, __m128& C) { //Input rows in __m128& A, B, and C. Output in same. __m128 T0 = _mm_unpacklo_ps(A,B); __m128 T1 = _mm_unpackhi_ps(A,B); A = _mm_movelh_ps(T0,C); B = _mm_shuffle_ps( T0,C, _MM_SHUFFLE(3,1,3,2) ); C = _mm_shuffle_ps( T1,C, _MM_SHUFFLE(3,2,1,0) ); } This should be 5 instructions instead of ajas95's 8 instructions. Of course, to get that level of performance with either version, you need to inline everything, or else you spend tons of time on moving floating point arguments to/from input registers. The other thing that is crucial is that the instruction set be VEX encoded. This allows generating instructions that take three arguments, like `vunpcklps`, instead of instructions like `unpcklps` that take only two. VEX is only available in AVX and higher (usually passing e.g. `-mavx` is sufficient to get the compiler to generate VEX instructions). -G
  5. After a feeled million hours of coding in the past 16 years there have been many ways to write code in many different languages. Some seemed correct to the time they were used, some seemed to be too strict or too chaotic and I also evolved my coding style with each new line written. Now considering the results of over 5 years in professionall game development, tools and engine code as hobbyist and on small and large commercial projects up to AAA titles, there are still many ways one could write code in different languages but also in the same language on different projects in one and the same but also different companies. I mostly agree with; see some trends in C#, C++ coding guidelines that are fully worth to go for but the major difference is on the naming conventions. Because I have currently to write my own coding guidelines (not for a special project but primary as a personal convention to refer to when coding) and seek for a way I'm happy with, I did some research on different guidelines and came up with following references: When Epic Games write about Unreal This seems a bit confusing when seeking for some type like Animation or Skin (that are both different prefixed with A and F) but prevents various naming conflicts to types and variables when writing a function that accepts FSkin Skin as parameter for example. Googles c++ guidelines point into a completely different direction when they write So they heavily make use of typos, underscores and also lower case prefixes to identify different kinds of member, static, nonstatic and function names and in the same breath except there rules for various special cases. Some other examples from different projexts I was invovled to also use and do not use prefixing types or use underscores class Class { const <type> cConstant; const <type> Constant; const <type> __Constant; <type> _myClassMember; <type> _MyClassMember; <type> myClassmember; <type> mMyClassMember; <type> function(<type> parameter); <type> Function(<type> parameter); <type> Function(<type> aParameter); } class NAClass //avoid using namespaces, instead prefix anything with a 2 letter namespace like identifier { ... } Dont need to mention that Visual Studio will raise a Warning/Exception that a type is named as same as a function parameter when using a class class Container { private int size; //current size public Resize(int size) //will cause compiler telling that type matches a member type { //do resize here } } So in the end anyone does he or she thinks that it is worth to be done and so me do too. I would like to hear your opinions to why and what codings style do you prefer or are involved to in whatever way. What do you think makes a good standard especially for the most common point, Naming Convetions? Will be corious to read your opinions
  6. Hi, I am releasing my 2d game on Steam, so sent it to review and they said it has some black and white rectangles covering parts of the screen. I don't have this issue on my old pc of course (amd 6670 vga), and I tested on a laptop too (amd gpu), without any problem. The game uses Direct3d11 with c++, nothing fancy, 2 layer of tiles, and some sprites for decorations and some postprocess effects. I have no idea what to do. Released it a while ago on Itch.io, had some 20+ downloads, nobody said anything about not working - or anything at all, sadly. So anyone does have any tips, how to figure out a graphical bug that is not reproductable on your end, and you doesn't even have a screenshot?
  7. I've been starting to optimize my code in anyway possible. I saw that some cpu's actually have 256-bit SIMD, but I was wondering if there is a way to detect this and fallback to the 128-bit on an unsupported cpu, or how else to deal with this.
  8. Hi guys, I'm writing my math library and implemented some matrix inverse function I would like to share. The SIMD version I got is more than twice as fast as non-SIMD version (which is what Unreal is using). It is also faster than some other math libraries like Eigen or DirectX Math. (result from my test, the first 3 columns are my methods) If you are interested in either theory or implementation, I put together my math derivation and source code in this post: https://lxjk.github.io/2017/09/03/Fast-4x4-Matrix-Inverse-with-SSE-SIMD-Explained.html I would appreciate any feedback
  9. Multipacker is an Unreal Engine 4 Plugin editor for manipulate AtlasTextures & Channels(and experimental various Masks inside the same Channel) inside Unreal Engine. Its greatlly helpfull for Mobile Projects, allowing a great save of texture memory. The plugin is intended to be simple and the same time powerfull. The Plugin is on Gumroad now: And have a CodeOffer discount 7.50: initialfeedback https://gumroad.com/l/cYyEo Will be updated ASAP adding new features. More Info: https://drive.google.com/drive/folders/0B63pISMLaAAgcHc2Y1BBcXV1c0k?usp=sharing Daily information of the progress on my Twitter https://twitter.com/turbocheke Whats done now: Version 0.2: -Get from a TextureAtlas a number of opacity Masks: -Set 1 Opacity Mask on a Channel RGB/RGBA. -Set 3 Opacity Masks on a Channel RGB/RGBA (allowing 9 opacity Masks on RGB, and 12 on RGBA). -One or more Texture Inputs -Input by Specific Channel (RGB, Red, Green, Blue, Alpha, RGBA) What will be on future releases: 0.25: -Save TextureAtlas 0.3: -Save a Texture Database for a faster icon management -Blueprint functions to manipulate the texture with the Database -Base Blueprint to generate buttons icons(press, normal); and a differrent types of procedural ussage of the icons. 0.4: -SDF from texture mask -Can save SDF on Atlas and Channels RGBA 0.5: -Hot reload Textures based on the AutoImport functionality of the Unreal Engine Editor.
  10. For example I have 6000 entities on a 2D map and I want to get about 180 which are on my player's screen. When my player is moving new entities may appear on the map, at the same time some entities or enemies die so they disappear. I used to clear the entire spatial hash and insert everything again a few times a second. But I am thinking maybe it is better to only update those entities that change on the map, the number of changes may be huge though, but still, compared to the number of entities on the map it is still small. I am just not sure if this is worthy or not.
  11. What exactly is an Octree? If you're completely unfamiliar with them, I recommend reading the wikipedia article (read time: ~5 minutes). This is a sufficient description of what it is but is barely enough to give any ideas on what it's used for and how to actually implement one. In this article, I will do my best to take you through the steps necessary to create an octree data structure through conceptual explanations, pictures, and code, and show you the considerations to be made at each step along the way. I don't expect this article to be the authoritative way to do octrees, but it should give you a really good start and act as a good reference. Assumptions Before we dive in, I'm going to be making a few assumptions about you as a reader: You are very comfortable with programming in a C-syntax-style language (I will be using C# with XNA). You have programmed some sort of tree-like data structure in the past, such as a binary search tree and are familiar with recursion and its strengths and pitfalls. You know how to do collision detection with bounding rectangles, bounding spheres, and bounding frustums. You have a good grasp of common data structures (arrays, lists, etc) and understand Big-O notation (you can also learn about Big-O in this GDnet article). You have a development environment project which contains spatial objects which need collision tests. Setting the stage Let's suppose that we are building a very large game world which can contain thousands of physical objects of various types, shapes and sizes, some of which must collide with each other. Each frame we need to find out which objects are intersecting with each other and have some way to handle that intersection. How do we do it without killing performance? Brute force collision detection The simplest method is to just compare each object against every other object in the world. Typically, you can do this with two for loops. The code would look something like this: foreach(gameObject myObject in ObjList) { foreach(gameObject otherObject in ObjList) { if(myObject == otherObject) continue; //avoid self collision check if(myObject.CollidesWith(otherObject)) { //code to handle the collision } } } Conceptually, this is what we're doing in our picture: Each red line is an expensive CPU test for intersection. Naturally, you should feel horrified by this code because it is going to run in O(N^2) time. If you have 10,000 objects, then you're going to be doing 100,000,000 collision checks (hundred million). I don't care how fast your CPU is or how well you've tuned your math code, this code would reduce your computer to a sluggish crawl. If you're running your game at 60 frames per second, you're looking at 60 * 100 million calculations per second! It's nuts. It's insane. It's crazy. Let's not do this if we can avoid it, at least not with a large set of objects. This would only be acceptable if we're only checking, say, 10 items against each other (100 checks is palatable). If you know in advance that your game is only going to have a very small number of objects (i.e., asteriods), you can probably get away with using this brute force method for collision detection and ignore octrees altogether. If/when you start noticing performance problems due to too many collision checks per frame, consider some simple targeted optimizations: 1. How much computation does your current collision routine take? Do you have a square root hidden away in there (ie, a distance check)? Are you doing a granular collision check (pixel vs pixel, triangle vs triangle, etc)? One common technique is to perform a rough, coarse check for collision before testing for a granular collision check. You can give your objects an enclosing bounding rectangle or bounding sphere and test for intersection with these before testing against a granular check which may involve a lot more math and computation time. Use a "distance squared" check for comparing distance between objects to avoid using the square root method. Square root calculation typically uses the newtonian method of approximation and can be computationally expensive. 2. Can you get away with calculating fewer collision checks? If your game runs at 60 frames per second, could you skip a few frames? If you know certain objects behave deterministically, can you "solve" for when they will collide ahead of time (ie, pool ball vs. side of pool table). Can you reduce the number of objects which need to be checked for collisions? A technique for this would be to separate objects into several lists. One list could be your "stationary" objects list. They never have to test for collision against each other. The other list could be your "moving" objects, which need to be tested against all other moving objects and against all stationary objects. This could reduce the number of necessary collision tests to reach an acceptable performance level. 3. Can you get away with removing some object collision tests when performance becomes an issue? For example, a smoke particle could interact with a surface object and follow its contours to create a nice aesthetic effect, but it wouldn't break game play if you hit a predefined limit for collision checks and decided to stop ignoring smoke particles for collision. Ignoring essential game object movement would certainly break game play though (ei, player bullets stop intersecting with monsters). So, perhaps maintaining a priority list of collision checks to compute would help. First you handle the high priority collision tests, and if you're not at your threshold, you can handle lower priority collision tests. When the threshold is reached, you dump the rest of the items in the priority list or defer them for testing at a later time. 4. Can you use a faster but still simplistic method for collision detection to get away from a O(N^2) runtime? If you eliminate the objects you've already checked for collisions against, you can reduce the runtime to O(N(N+1)/2), which is much faster and still easy to implement. (technically, it's still O(N^2)) In terms of software engineering, you may end up spending more time than it's worth fine-tuning a bad algorithm & data structure choice to squeeze out a few more ounces of performance. The cost vs. benefit ratio becomes increasingly unfavorable and it becomes time to choose a better data structure to handle collision detection. Spatial partitioning algorithms are the proverbial nuke to solving the runtime problem for collision detection. At a small upfront cost to performance, they'll reduce your collision detection tests to logarithmic runtime. The upfront costs of development time and CPU overhead are easily outweighed by the scalability benefits and performance gains. Conceptual background on spatial partitioning Let's take a step back and look at spatial partitioning and trees in general before diving into Octrees. If we don't understand the conceptual idea, we have no hope of implementing it by sweating over code. Looking at the brute force implementation above, we're essentially taking every object in the game and comparing their positions against all other objects in the game to see if any are touching. All of these objects are contained spatially within our game world. Well, if we create an enclosing box around our game world and figure out which objects are contained within this enclosing box, then we've got a region of space with a list of contained objects within it. In this case, it would contain every object in the game. We can notice that if we have an object on one corner of the world and another object way on the other side, we don't really need to, or want to, calculate a collision check against them every frame. It'd be a waste of precious CPU time. So, let's try something interesting! If we divide our world exactly in half, we can create three separate lists of objects. The first list of objects, List A, contains all objects on the left half of the world. The second list, List B, contains objects on the right half of the world. Some objects may touch the dividing line such that they're on each side of the line, so we'll create a third list, List C, for these objects. We can notice that with each subdivision, we're spatially reducing the world in half and collecting a list of objects in that resulting half. We can elegantly create a binary search tree to contain these lists. Conceptually, this tree should look something like so: In terms of pseudo code, the tree data structure would look something like this: public class BinaryTree { //This is a list of all of the objects contained within this node of the tree private List m_objectList; //These are pointers to the left and right child nodes in the tree private BinaryTree m_left, m_right; //This is a pointer to the parent object (for upward tree traversal). private BinaryTree m_parent; } We know that all objects in List A will never intersect with any objects in List B, so we can almost eliminate half of the number of collision checks. We've still got the objects in List C which could touch objects in either list A or B, so we'll have to check all objects in List C against all objects in Lists A, B & C. If we continue to sub-divide the world into smaller and smaller parts, we can further reduce the number of necessary collision checks by half each time. This is the general idea behind spatial partitioning. There are many ways to subdivide a world into a tree-like data structure (BSP trees, Quad Trees, K-D trees, OctTrees, etc). Now, by default, we're just assuming that the best division is a cut in half, right down the middle, since we're assuming that all of our objects will be somewhat uniformly distributed throughout the world. It's not a bad assumption to make, but some spatial division algorithms may decide to make a cut such that each side has an equal amount of objects (a weighted cut) so that the resulting tree is more balanced. However, what happens if all of these objects move around? In order to maintain a nearly even division, you'd have to either shift the splitting plane or completely rebuild the tree each frame. It'd be a bit of a mess with a lot of complexity. So, for my implementation of a spatial partitioning tree I decided to cut right down the middle every time. As a result, some trees may end up being a bit more sparse than others, but that's okay -- it doesn't cost much. To subdivide or not to subdivide? That is the question. Let's assume that we have a somewhat sparse region with only a few objects. We could continue subdividing our space until we've found the smallest possible enclosing area for that object. But is that really necessary? Let's remember that the whole reason we're creating a tree is to reduce the number of collision checks we need to perform each frame -- not to create a perfectly enclosing region of space for every object. Here are the rules I use for deciding whether to subdivide or not: If we create a subdivision which only contains one object, we can stop subdividing even though we could keep dividing further. This rule will become an important part of the criteria for what defines a "leaf node" in our octree. The other important criteria is to set a minimum size for a region. If you have an extremely small object which is nanometers in size (or, god forbid, you have a bug and forgot to initialize an object size!), you're going to keep subdividing to the point where you potentially overflow your call stack. For my own implementation, I defined the smallest containing region to be a 1x1x1 cube. Any objects in this teeny cube will just have to be run with the O(N^2) brute force collision test (I don't anticipate many objects anyways!). If a containing region doesn't contain any objects, we shouldn't try to include it in the tree. We can take our subdivision by half one step further and divide the 2D world space into quadrants. The logic is essentially the same, but now we're testing for collision with four squares instead of two rectangles. We can continue subdividing each square until our rules for termination are met. The representation of the world space and corresponding data structure for a quad tree would look something like this: If the quad tree subdivision and data structure make sense, then an octree should be pretty straight forward as well. We're just adding a third dimension, using bounding cubes instead of bounding squares, and have eight possible child nodes instead of four. Some of you might wonder what should happen if you have a game world with non-cubic dimensions, say 200x300x400. You can still use an octree with cubic dimensions -- some child nodes will just end up empty if the game world doesn't have anything there. Obviously, you'll want to set the dimensions of your octree to at least the largest dimension of your game world. Octree Construction So, as you've read, an octree is a special type of subdividing tree commonly used for objects in 3D space (or anything with 3 dimensions). Our enclosing region is going to be a three dimensional rectangle (commonly a cube). We will then apply our subdivision logic above, and cut our enclosing region into eight smaller rectangles. If a game object completely fits within one of these subdivided regions, we'll push it down the tree into that node's containing region. We'll then recursively continue subdividing each resulting region until one of our breaking conditions is met. At the end, we should expect to have a nice tree-like data structure. My implementation of the octree can contain objects which have either a bounding sphere and/or a bounding rectangle. You'll see a lot of code I use to determine which is being used. In terms of our Octree class data structure, I decided to do the following for each tree: Each node has a bounding region which defines the enclosing region Each node has a reference to the parent node Contains an array of eight child nodes (use arrays for code simplicity and cache performance) Contains a list of objects contained within the current enclosing region I use a byte-sized bitmask for figuring out which child nodes are actively being used (the optimization benefits at the cost of additional complexity is somewhat debatable) I use a few static variables to indicate the state of the tree Here is the code for my Octree class outline: public class OctTree { BoundingBox m_region; List m_objects; /// /// These are items which we're waiting to insert into the data structure. /// We want to accrue as many objects in here as possible before we inject them into the tree. This is slightly more cache friendly. /// static Queue m_pendingInsertion = new Queue(); /// /// These are all of the possible child octants for this node in the tree. /// OctTree[] m_childNode = new OctTree[8]; /// /// This is a bitmask indicating which child nodes are actively being used. /// It adds slightly more complexity, but is faster for performance since there is only one comparison instead of 8. /// byte m_activeNodes = 0; /// /// The minumum size for enclosing region is a 1x1x1 cube. /// const int MIN_SIZE = 1; /// /// this is how many frames we'll wait before deleting an empty tree branch. Note that this is not a constant. The maximum lifespan doubles /// every time a node is reused, until it hits a hard coded constant of 64 /// int m_maxLifespan = 8; // int m_curLife = -1; //this is a countdown time showing how much time we have left to live /// /// A reference to the parent node is nice to have when we're trying to do a tree update. /// OctTree _parent; static bool m_treeReady = false; //the tree has a few objects which need to be inserted before it is complete static bool m_treeBuilt = false; //there is no pre-existing tree yet. } Initializing the enclosing region The first step in building an octree is to define the enclosing region for the entire tree. This will be the bounding box for the root node of the tree which initially contains all objects in the game world. Before we go about initializing this bounding volume, we have a few design decisions we need to make: 1. What should happen if an object moves outside of the bounding volume of the root node? Do we want to resize the entire octree so that all objects are enclosed? If we do, we'll have to completely rebuild the octree from scratch. If we don't, we'll need to have some way to either handle out of bounds objects, or ensure that objects never go out of bounds. 2. How do we want to create the enclosing region for our octree? Do we want to use a preset dimension, such as a 200x400x200 (X,Y,Z) rectangle? Or do we want to use a cubic dimension which is a power of 2? What should be the smallest allowable enclosing region which cannot be subdivided? Personally, I decided that I would use a cubic enclosing region with dimensions which are a power of 2, and sufficiently large to completely enclose my world. The smallest allowable cube is a 1x1x1 unit region. With this, I know that I can always cleanly subdivide my world and get integer numbers (even though the Vector3 uses floats). I also decided that my enclosing region would enclose the entire game world, so if an object leaves this region, it should be quietly destroyed. At the smallest octant, I will have to run a brute force collision check against all other objects, but I don't realistically expect more than 3 objects to occupy that small of an area at a time, so the performance costs of O(N^2) are completely acceptable. So, I normally just initialize my octree with a constructor which takes a region size and a list of items to insert into the tree. I feel it's barely worth showing this part of the code since it's so elementary, but I'll include it for completeness. Here are my constructors: /*Note: we want to avoid allocating memory for as long as possible since there can be lots of nodes.*/ /// /// Creates an oct tree which encloses the given region and contains the provided objects. /// /// The bounding region for the oct tree. /// The list of objects contained within the bounding region private OctTree(BoundingBox region, List objList) { m_region = region; m_objects = objList; m_curLife = -1; } public OctTree() { m_objects = new List(); m_region = new BoundingBox(Vector3.Zero, Vector3.Zero); m_curLife = -1; } /// /// Creates an octTree with a suggestion for the bounding region containing the items. /// /// The suggested dimensions for the bounding region. /// Note: if items are outside this region, the region will be automatically resized. public OctTree(BoundingBox region) { m_region = region; m_objects = new List(); m_curLife = -1; } Building an initial octree I'm a big fan of lazy initialization. I try to avoid allocating memory or doing work until I absolutely have to. In the case of my octree, I avoid building the data structure as long as possible. We'll accept a user's request to insert an object into the data structure, but we don't actually have to build the tree until someone runs a query against it. What does this do for us? Well, let's assume that the process of constructing and traversing our tree is somewhat computationally expensive. If a user wants to give us 1,000 objects to insert into the tree, does it make sense to recompute every subsequent enclosing area a thousand times? Or, can we save some time and do a bulk blast? I created a "pending" queue of items and a few flags to indicate the build state of the tree. All of the inserted items get put into the pending queue and when a query is made, those pending requests get flushed and injected into the tree. This is especially handy during a game loading sequence since you'll most likely be inserting thousands of objects at once. After the game world has been loaded, the number of objects injected into the tree is orders of magnitude fewer. My lazy initialization routine is contained within my UpdateTree() method. It checks to see if the tree has been built, and builds the data structure if it doesn't exist and has pending objects. /// /// Processes all pending insertions by inserting them into the tree. /// /// Consider deprecating this? private void UpdateTree() //complete & tested { if (!m_treeBuilt) { while (m_pendingInsertion.Count != 0) m_objects.Add(m_pendingInsertion.Dequeue()); BuildTree(); } else { while (m_pendingInsertion.Count != 0) Insert(m_pendingInsertion.Dequeue()); } m_treeReady = true; } As for building the tree itself, this can be done recursively. So for each recursive iteration, I start off with a list of objects contained within the bounding region. I check my termination rules, and if we pass, we create eight subdivided bounding areas which are perfectly contained within our enclosed region. Then, I go through every object in my given list and test to see if any of them will fit perfectly within any of my octants. If they do fit, I insert them into a corresponding list for that octant. At the very end, I check the counts on my corresponding octant lists and create new octrees and attach them to our current node, and mark my bitmask to indicate that those child octants are actively being used. All of the left over objects have been pushed down to us from our parent, but can't be pushed down to any children, so logically, this must be the smallest octant which can contain the object. /// /// Naively builds an oct tree from scratch. /// private void BuildTree() //complete & tested { //terminate the recursion if we're a leaf node if (m_objects.Count <= 1) return; Vector3 dimensions = m_region.Max - m_region.Min; if (dimensions == Vector3.Zero) { FindEnclosingCube(); dimensions = m_region.Max - m_region.Min; } //Check to see if the dimensions of the box are greater than the minimum dimensions if (dimensions.X <= MIN_SIZE && dimensions.Y <= MIN_SIZE && dimensions.Z <= MIN_SIZE) { return; } Vector3 half = dimensions / 2.0f; Vector3 center = m_region.Min + half; //Create subdivided regions for each octant BoundingBox[] octant = new BoundingBox[8]; octant[0] = new BoundingBox(m_region.Min, center); octant[1] = new BoundingBox(new Vector3(center.X, m_region.Min.Y, m_region.Min.Z), new Vector3(m_region.Max.X, center.Y, center.Z)); octant[2] = new BoundingBox(new Vector3(center.X, m_region.Min.Y, center.Z), new Vector3(m_region.Max.X, center.Y, m_region.Max.Z)); octant[3] = new BoundingBox(new Vector3(m_region.Min.X, m_region.Min.Y, center.Z), new Vector3(center.X, center.Y, m_region.Max.Z)); octant[4] = new BoundingBox(new Vector3(m_region.Min.X, center.Y, m_region.Min.Z), new Vector3(center.X, m_region.Max.Y, center.Z)); octant[5] = new BoundingBox(new Vector3(center.X, center.Y, m_region.Min.Z), new Vector3(m_region.Max.X, m_region.Max.Y, center.Z)); octant[6] = new BoundingBox(center, m_region.Max); octant[7] = new BoundingBox(new Vector3(m_region.Min.X, center.Y, center.Z), new Vector3(center.X, m_region.Max.Y, m_region.Max.Z)); //This will contain all of our objects which fit within each respective octant. List[] octList = new List[8]; for (int i = 0; i < 8; i++) octList = new List(); //this list contains all of the objects which got moved down the tree and can be delisted from this node. List delist = new List(); foreach (Physical obj in m_objects) { if (obj.BoundingBox.Min != obj.BoundingBox.Max) { for (int a = 0; a < 8; a++) { if (octant[a].Contains(obj.BoundingBox) == ContainmentType.Contains) { octList[a].Add(obj); delist.Add(obj); break; } } } else if (obj.BoundingSphere.Radius != 0) { for (int a = 0; a < 8; a++) { if (octant[a].Contains(obj.BoundingSphere) == ContainmentType.Contains) { octList[a].Add(obj); delist.Add(obj); break; } } } } //delist every moved object from this node. foreach (Physical obj in delist) m_objects.Remove(obj); //Create child nodes where there are items contained in the bounding region for (int a = 0; a < 8; a++) { if (octList[a].Count != 0) { m_childNode[a] = CreateNode(octant[a], octList[a]); m_activeNodes |= (byte)(1 << a); m_childNode[a].BuildTree(); } } m_treeBuilt = true; m_treeReady = true; } private OctTree CreateNode(BoundingBox region, List objList) //complete & tested { if (objList.Count == 0) return null; OctTree ret = new OctTree(region, objList); ret._parent = this; return ret; } private OctTree CreateNode(BoundingBox region, Physical Item) { List objList = new List(1); //sacrifice potential CPU time for a smaller memory footprint objList.Add(Item); OctTree ret = new OctTree(region, objList); ret._parent = this; return ret; } Updating a tree Let's imagine that our tree has a lot of moving objects in it. If any object moves, there is a good chance that the object has moved outside of its enclosing octant. How do we handle changes in object position while maintaining the integrity of our tree structure? Technique 1: Keep it super simple, trash & rebuild everything. Some implementations of an Octree will completely rebuild the entire tree every frame and discard the old one. This is super simple and it works, and if this is all you need, then prefer the simple technique. The general consensus is that the upfront CPU cost of rebuilding the tree every frame is much cheaper than running a brute force collision check, and programmer time is too valuable to be spent on an unnecessary optimization. For those of us who like challenges and to over-engineer things, the "trash & rebuild" technique comes with a few small problems: You're constantly allocating and deallocating memory each time you rebuild your tree. Allocating new memory comes with a small cost. If possible, you want to minimize the amount of memory being allocated and reallocated over time by reusing memory you've already got. Most of the tree is unchanging, so it's a waste of CPU time to rebuild the same branches over and over again. Technique 2: Keep the existing tree, update the changed branches I noticed that most branches of a tree don't need to be updated. They just contain stationary objects. Wouldn't it be nice if, instead of rebuilding the entire tree every frame, we just updated the parts of the tree which needed an update? This technique keeps the existing tree and updates only the branches which had an object which moved. It's a bit more complex to implement, but it's a lot more fun too, so let's really get into that! During my first attempt at this, I mistakenly thought that an object in a child node could only go up or down one traversal of the tree. This is wrong. If an object in a child node reaches the edge of that node, and that edge also happens to be an edge for the enclosing parent node, then that object needs to be inserted above its parent, and possibly up even further. So, the bottom line is that we don't know how far up an object needs to be pushed up the tree. Just as well, an object can move such that it can be neatly enclosed in a child node, or that child's child node. We don't know how far down the tree we can go. Fortunately, since we include a reference to each node's parent, we can easily solve this problem recursively with minimal computation! The general idea behind the update algorithm is to first let all objects in the tree update themselves. Some may move or change in size. We want to get a list of every object which moved, so the object update method should return to us a boolean value indicating if its bounding area changed. Once we've got a list of all of our moved objects, we want to start at our current node and try to traverse up the tree until we find a node which completely encloses the moved object (most of the time, the current node still encloses the object). If the object isn't completely enclosed by the current node, we keep moving it up to its next parent node. In the worst case, our root node will be guaranteed to contain the object. After we've moved our object as far up the tree as possible, we'll try to move it as far down the tree as we can. Most of the time, if we moved the object up, we won't be able to move it back down. But, if the object moved so that a child node of the current node could contain it, we have the chance to push it back down the tree. It's important to be able to move objects down the tree as well, or else all moving objects would eventually migrate to the top and we'd start getting some performance problems during collision detection routines. Branch Removal In some cases, an object will move out of a node and that node will no longer have any objects contained within it, nor have any children which contain objects. If this happens, we have an empty branch and we need to mark it as such and prune this dead branch off the tree. There is an interesting question hiding here: When do you want to prune the dead branches off a tree? Allocating new memory costs time, so if we're just going to reuse this same region in a few cycles, why not keep it around for a bit? How long can we keep it around before it becomes more expensive to maintain the dead branch? I decided to give each of my nodes a count down timer which activates when the branch is dead. If an object moves into this nodes octant while the death timer is active, I double the lifespan and reset the death timer. This ensures that octants which are frequently used are hot and stick around, and nodes which are infrequently used are removed before they start to cost more than they're worth. A practical example of this usefulness would be apparent when you have a machine gun shooting a stream of bullets. Those bullets follow in close succession of each other, so it'd be a shame to immediately delete a node as soon as the first bullet leaves it, only to recreate it a fraction of a second later as the second bullet re-enters it. And if there's a lot of bullets, we can probably keep these octants around for a little while. If a child branch is empty and hasn't been used in a while, it's safe to prune it out of our tree. Anyways, let's look at the code which does all of this magic. First up, we have the Update() method. This is a method which is recursively called on all child trees. It moves all objects around, does some house keeping work for the data structure, and then moves each moved object into its correct node (parent or child). public void Update(GameTime gameTime) { if (m_treeBuilt == true) { //Start a count down death timer for any leaf nodes which don't have objects or children. //when the timer reaches zero, we delete the leaf. If the node is reused before death, we double its lifespan. //this gives us a "frequency" usage score and lets us avoid allocating and deallocating memory unnecessarily if (m_objects.Count == 0) { if (HasChildren == false) { if (m_curLife == -1) m_curLife = m_maxLifespan; else if (m_curLife > 0) { m_curLife--; } } } else { if (m_curLife != -1) { if(m_maxLifespan <= 64) m_maxLifespan *= 2; m_curLife = -1; } } List movedObjects = new List(m_objects.Count); //go through and update every object in the current tree node foreach (Physical gameObj in m_objects) { //we should figure out if an object actually moved so that we know whether we need to update this node in the tree. if (gameObj.Update(gameTime)) { movedObjects.Add(gameObj); } } //prune any dead objects from the tree. int listSize = m_objects.Count; for (int a = 0; a < listSize; a++) { if (!m_objects[a].Alive) { if (movedObjects.Contains(m_objects[a])) movedObjects.Remove(m_objects[a]); m_objects.RemoveAt(a--); listSize--; } } //recursively update any child nodes. for( int flags = m_activeNodes, index = 0; flags > 0; flags >>=1, index++) if ((flags & 1) == 1) m_childNode[index].Update(gameTime); //If an object moved, we can insert it into the parent and that will insert it into the correct tree node. //note that we have to do this last so that we don't accidentally update the same object more than once per frame. foreach (Physical movedObj in movedObjects) { OctTree current = this; //figure out how far up the tree we need to go to reinsert our moved object //we are either using a bounding rect or a bounding sphere //try to move the object into an enclosing parent node until we've got full containment if (movedObj.BoundingBox.Max != movedObj.BoundingBox.Min) { while (current.m_region.Contains(movedObj.BoundingBox) != ContainmentType.Contains) if (current._parent != null) current = current._parent; else break; //prevent infinite loops when we go out of bounds of the root node region } else { while (current.m_region.Contains(movedObj.BoundingSphere) != ContainmentType.Contains)//we must be using a bounding sphere, so check for its containment. if (current._parent != null) current = current._parent; else break; } //now, remove the object from the current node and insert it into the current containing node. m_objects.Remove(movedObj); current.Insert(movedObj); //this will try to insert the object as deep into the tree as we can go. } //prune out any dead branches in the tree for (int flags = m_activeNodes, index = 0; flags > 0; flags >>= 1, index++) if ((flags & 1) == 1 && m_childNode[index].m_curLife == 0) { m_childNode[index] = null; m_activeNodes ^= (byte)(1 << index); //remove the node from the active nodes flag list } //now that all objects have moved and they've been placed into their correct nodes in the octree, we can look for collisions. if (IsRoot == true) { //This will recursively gather up all collisions and create a list of them. //this is simply a matter of comparing all objects in the current root node with all objects in all child nodes. //note: we can assume that every collision will only be between objects which have moved. //note 2: An explosion can be centered on a point but grow in size over time. In this case, you'll have to override the update method for the explosion. List irList = GetIntersection(new List()); foreach (IntersectionRecord ir in irList) { if (ir.PhysicalObject != null) ir.PhysicalObject.HandleIntersection(ir); if (ir.OtherPhysicalObject != null) ir.OtherPhysicalObject.HandleIntersection(ir); } } } else { } } Note that we call an Insert() method for moved objects. The insertion of objects into the tree is very similar to the method used to build the initial tree. Insert() will try to push objects as far down the tree as possible. Notice that I also try to avoid creating new bounding areas if I can use an existing one from a child node. /// /// A tree has already been created, so we're going to try to insert an item into the tree without rebuilding the whole thing /// /// A physical object /// The physical object to insert into the tree private void Insert(T Item) where T : Physical { /*make sure we're not inserting an object any deeper into the tree than we have to. -if the current node is an empty leaf node, just insert and leave it.*/ if (m_objects.Count <= 1 && m_activeNodes == 0) { m_objects.Add(Item); return; } Vector3 dimensions = m_region.Max - m_region.Min; //Check to see if the dimensions of the box are greater than the minimum dimensions if (dimensions.X <= MIN_SIZE && dimensions.Y <= MIN_SIZE && dimensions.Z <= MIN_SIZE) { m_objects.Add(Item); return; } Vector3 half = dimensions / 2.0f; Vector3 center = m_region.Min + half; //Find or create subdivided regions for each octant in the current region BoundingBox[] childOctant = new BoundingBox[8]; childOctant[0] = (m_childNode[0] != null) ? m_childNode[0].m_region : new BoundingBox(m_region.Min, center); childOctant[1] = (m_childNode[1] != null) ? m_childNode[1].m_region : new BoundingBox(new Vector3(center.X, m_region.Min.Y, m_region.Min.Z), new Vector3(m_region.Max.X, center.Y, center.Z)); childOctant[2] = (m_childNode[2] != null) ? m_childNode[2].m_region : new BoundingBox(new Vector3(center.X, m_region.Min.Y, center.Z), new Vector3(m_region.Max.X, center.Y, m_region.Max.Z)); childOctant[3] = (m_childNode[3] != null) ? m_childNode[3].m_region : new BoundingBox(new Vector3(m_region.Min.X, m_region.Min.Y, center.Z), new Vector3(center.X, center.Y, m_region.Max.Z)); childOctant[4] = (m_childNode[4] != null) ? m_childNode[4].m_region : new BoundingBox(new Vector3(m_region.Min.X, center.Y, m_region.Min.Z), new Vector3(center.X, m_region.Max.Y, center.Z)); childOctant[5] = (m_childNode[5] != null) ? m_childNode[5].m_region : new BoundingBox(new Vector3(center.X, center.Y, m_region.Min.Z), new Vector3(m_region.Max.X, m_region.Max.Y, center.Z)); childOctant[6] = (m_childNode[6] != null) ? m_childNode[6].m_region : new BoundingBox(center, m_region.Max); childOctant[7] = (m_childNode[7] != null) ? m_childNode[7].m_region : new BoundingBox(new Vector3(m_region.Min.X, center.Y, center.Z), new Vector3(center.X, m_region.Max.Y, m_region.Max.Z)); //First, is the item completely contained within the root bounding box? //note2: I shouldn't actually have to compensate for this. If an object is out of our predefined bounds, then we have a problem/error. // Wrong. Our initial bounding box for the terrain is constricting its height to the highest peak. Flying units will be above that. // Fix: I resized the enclosing box to 256x256x256. This should be sufficient. if (Item.BoundingBox.Max != Item.BoundingBox.Min && m_region.Contains(Item.BoundingBox) == ContainmentType.Contains) { bool found = false; //we will try to place the object into a child node. If we can't fit it in a child node, then we insert it into the current node object list. for(int a=0;a<8;a++) { //is the object fully contained within a quadrant? if (childOctant[a].Contains(Item.BoundingBox) == ContainmentType.Contains) { if (m_childNode[a] != null) m_childNode[a].Insert(Item); //Add the item into that tree and let the child tree figure out what to do with it else { m_childNode[a] = CreateNode(childOctant[a], Item); //create a new tree node with the item m_activeNodes |= (byte)(1 << a); } found = true; } } if(!found) m_objects.Add(Item); } else if (Item.BoundingSphere.Radius != 0 && m_region.Contains(Item.BoundingSphere) == ContainmentType.Contains) { bool found = false; //we will try to place the object into a child node. If we can't fit it in a child node, then we insert it into the current node object list. for (int a = 0; a < 8; a++) { //is the object contained within a child quadrant? if (childOctant[a].Contains(Item.BoundingSphere) == ContainmentType.Contains) { if (m_childNode[a] != null) m_childNode[a].Insert(Item); //Add the item into that tree and let the child tree figure out what to do with it else { m_childNode[a] = CreateNode(childOctant[a], Item); //create a new tree node with the item m_activeNodes |= (byte)(1 << a); } found = true; } } if (!found) m_objects.Add(Item); } else { //either the item lies outside of the enclosed bounding box or it is intersecting it. Either way, we need to rebuild //the entire tree by enlarging the containing bounding box //BoundingBox enclosingArea = FindBox(); BuildTree(); } } Collision Detection Finally, our octree has been built and everything is as it should be. How do we perform collision detection against it? First, let's list out the different ways we want to look for collisions: Frustum intersections. We may have a frustum which intersects with a region of the world. We only want the objects which intersect with the given frustum. This is particularly useful for culling regions outside of the camera view space, and for figuring out what objects are within a mouse selection area. Ray intersections. We may want to shoot a directional ray from any given point and want to know either the nearest intersecting object, or get a list of all objects which intersect that ray (like a rail gun). This is very useful for mouse picking. If the user clicks on the screen, we want to draw a ray into the world and figure out what they clicked on. Bounding Box intersections. We want to know which objects in the world are intersecting a given bounding box. This is most useful for "box" shaped game objects (houses, cars, etc). Bounding Sphere Intersections. We want to know which objects are intersecting with a given bounding sphere. Most objects will probably be using a bounding sphere for coarse collision detection since the mathematics is computationally the least expensive and somewhat easy. The main idea behind recursive collision detection processing for an octree is that you start at the root/current node and test for intersection with all objects in that node against the intersector. Then, you do a bounding box intersection test against all active child nodes with the intersector. If a child node fails this intersection test, you can completely ignore the rest of that child's tree. If a child node passes the intersection test, you recursively traverse down the tree and repeat. Each node should pass a list of intersection records up to its caller, which appends those intersections to its own list of intersections. When the recursion finishes, the original caller will get a list of every intersection for the given intersector. The beauty of this is that it takes very little code to implement and performance is very fast. In a lot of these collisions, we're probably going to be getting a lot of results. We're also going to want to have some way of responding to each collision, depending on what objects are colliding. For example, a player hero should pick up a floating bonus item (quad damage!), but a rocket shouldn't explode if it hits said bonus item. I created a new class to contain information about each intersection. This class contains references to the intersecting objects, the point of intersection, the normal at the point of intersection, etc. These intersection records become quite useful when you pass them to an object and tell them to handle it. For completeness and clarity, here is my intersection record class: public class IntersectionRecord { Vector3 m_position; /// /// This is the exact point in 3D space which has an intersection. /// public Vector3 Position { get { return m_position; } } Vector3 m_normal; /// /// This is the normal of the surface at the point of intersection /// public Vector3 Normal { get { return m_normal; } } Ray m_ray; /// /// This is the ray which caused the intersection /// public Ray Ray { get { return m_ray; } } Physical m_intersectedObject1; /// /// This is the object which is being intersected /// public Physical PhysicalObject { get { return m_intersectedObject1; } set { m_intersectedObject1 = value; } } Physical m_intersectedObject2; /// /// This is the other object being intersected (may be null, as in the case of a ray-object intersection) /// public Physical OtherPhysicalObject { get { return m_intersectedObject2; } set { m_intersectedObject2 = value; } } /// /// this is a reference to the current node within the octree for where the collision occurred. In some cases, the collision handler /// will want to be able to spawn new objects and insert them into the tree. This node is a good starting place for inserting these objects /// since it is a very near approximation to where we want to be in the tree. /// OctTree m_treeNode; /// /// check the object identities between the two intersection records. If they match in either order, we have a duplicate. /// ///the other record to compare against /// true if the records are an intersection for the same pair of objects, false otherwise. public override bool Equals(object otherRecord) { IntersectionRecord o = (IntersectionRecord)otherRecord; // //return (m_intersectedObject1 != null && m_intersectedObject2 != null && m_intersectedObject1.ID == m_intersectedObject2.ID); if (otherRecord == null) return false; if (o.m_intersectedObject1.ID == m_intersectedObject1.ID && o.m_intersectedObject2.ID == m_intersectedObject2.ID) return true; if (o.m_intersectedObject1.ID == m_intersectedObject2.ID && o.m_intersectedObject2.ID == m_intersectedObject1.ID) return true; return false; } double m_distance; /// /// This is the distance from the ray to the intersection point. /// You'll usually want to use the nearest collision point if you get multiple intersections. /// public double Distance { get { return m_distance; } } private bool m_hasHit = false; public bool HasHit { get { return m_hasHit; } } public IntersectionRecord() { m_position = Vector3.Zero; m_normal = Vector3.Zero; m_ray = new Ray(); m_distance = float.MaxValue; m_intersectedObject1 = null; } public IntersectionRecord(Vector3 hitPos, Vector3 hitNormal, Ray ray, double distance) { m_position = hitPos; m_normal = hitNormal; m_ray = ray; m_distance = distance; // m_hitObject = hitGeom; m_hasHit = true; } /// /// Creates a new intersection record indicating whether there was a hit or not and the object which was hit. /// ///Optional: The object which was hit. Defaults to null. public IntersectionRecord(Physical hitObject = null) { m_hasHit = hitObject != null; m_intersectedObject1 = hitObject; m_position = Vector3.Zero; m_normal = Vector3.Zero; m_ray = new Ray(); m_distance = 0.0f; } } Intersection with a Bounding Frustum /// /// Gives you a list of all intersection records which intersect or are contained within the given frustum area /// ///The containing frustum to check for intersection/containment with /// A list of intersection records with collisions private List GetIntersection(BoundingFrustum frustum, Physical.PhysicalType type = Physical.PhysicalType.ALL) { if (m_objects.Count == 0 && HasChildren == false) //terminator for any recursion return null; List ret = new List(); //test each object in the list for intersection foreach (Physical obj in m_objects) { //skip any objects which don't meet our type criteria if ((int)((int)type & (int)obj.Type) == 0) continue; //test for intersection IntersectionRecord ir = obj.Intersects(frustum); if (ir != null) ret.Add(ir); } //test each object in the list for intersection for (int a = 0; a < 8; a++) { if (m_childNode[a] != null && (frustum.Contains(m_childNode[a].m_region) == ContainmentType.Intersects || frustum.Contains(m_childNode[a].m_region) == ContainmentType.Contains)) { List hitList = m_childNode[a].GetIntersection(frustum); if (hitList != null) { foreach (IntersectionRecord ir in hitList) ret.Add(ir); } } } return ret; } The bounding frustum intersection list can be used to only render objects which are visible to the current camera view. I use a scene database to figure out how to render all objects in the game world. Here is a snippet of code from my rendering function which uses the bounding frustum of the active camera: /// /// This renders every active object in the scene database /// /// public int Render() { int triangles = 0; //Renders all visible objects by iterating through the oct tree recursively and testing for intersection //with the current camera view frustum foreach (IntersectionRecord ir in m_octTree.AllIntersections(m_cameras[m_activeCamera].Frustum)) { ir.PhysicalObject.SetDirectionalLight(m_globalLight[0].Direction, m_globalLight[0].Color); ir.PhysicalObject.View = m_cameras[m_activeCamera].View; ir.PhysicalObject.Projection = m_cameras[m_activeCamera].Projection; ir.PhysicalObject.UpdateLOD(m_cameras[m_activeCamera]); triangles += ir.PhysicalObject.Render(m_cameras[m_activeCamera]); } return triangles; } Intersection with a Ray /// /// Gives you a list of intersection records for all objects which intersect with the given ray /// ///The ray to intersect objects against /// A list of all intersections private List GetIntersection(Ray intersectRay, Physical.PhysicalType type = Physical.PhysicalType.ALL) { if (m_objects.Count == 0 && HasChildren == false) //terminator for any recursion return null; List ret = new List(); //the ray is intersecting this region, so we have to check for intersection with all of our contained objects and child regions. //test each object in the list for intersection foreach (Physical obj in m_objects) { //skip any objects which don't meet our type criteria if ((int)((int)type & (int)obj.Type) == 0) continue; if (obj.BoundingBox.Intersects(intersectRay) != null) { IntersectionRecord ir = obj.Intersects(intersectRay); if (ir.HasHit) ret.Add(ir); } } // test each child octant for intersection for (int a = 0; a < 8; a++) { if (m_childNode[a] != null && m_childNode[a].m_region.Intersects(intersectRay) != null) { List hits = m_childNode[a].GetIntersection(intersectRay, type); if (hits != null) { foreach (IntersectionRecord ir in hits) ret.Add(ir); } } } return ret; } Intersection with a list of objects This is a particularly useful recursive method for determining if a list of objects in the current node intersect with any objects in any child nodes (See: Update() method for usage). It's the method which will be used most frequently, so it's good to get this right and efficient. What we want to do is start at the root node of the tree. We compare all objects in the current node against all other objects in the current node for collision. We gather up any of those collisions as intersection records, and insert them into a list. We then pass our list of tested objects down to our child nodes. The child nodes will then test their objects against themselves, then against the objects we passed down to them. The child nodes will capture any collisions in a list, and return that list to its parent. The parent then takes the collision list received from its child nodes and appends it to its own list of collisions, finally returning it to its caller. If you count out the number of collision tests in the illustration above, you can see that we conducted 29 hit tests and recieved 4 hits. This is much better than [11*11 = 121] hit tests. private List GetIntersection(List parentObjs, Physical.PhysicalType type = Physical.PhysicalType.ALL) { List intersections = new List(); //assume all parent objects have already been processed for collisions against each other. //check all parent objects against all objects in our local node foreach (Physical pObj in parentObjs) { foreach (Physical lObj in m_objects) { //We let the two objects check for collision against each other. They can figure out how to do the coarse and granular checks. //all we're concerned about is whether or not a collision actually happened. IntersectionRecord ir = pObj.Intersects(lObj); if (ir != null) { intersections.Add(ir); } } } //now, check all our local objects against all other local objects in the node if (m_objects.Count > 1) { #region self-congratulation /* * This is a rather brilliant section of code. Normally, you'd just have two foreach loops, like so: * foreach(Physical lObj1 in m_objects) * { * foreach(Physical lObj2 in m_objects) * { * //intersection check code * } * } * * The problem is that this runs in O(N*N) time and that we're checking for collisions with objects which have already been checked. * Imagine you have a set of four items: {1,2,3,4} * You'd first check: {1} vs {1,2,3,4} * Next, you'd check {2} vs {1,2,3,4} * but we already checked {1} vs {2}, so it's a waste to check {2} vs. {1}. What if we could skip this check by removing {1}? * We'd have a total of 4+3+2+1 collision checks, which equates to O(N(N+1)/2) time. If N is 10, we are already doing half as many collision checks as necessary. * Now, we can't just remove an item at the end of the 2nd for loop since that would break the iterator in the first foreach loop, so we'd have to use a * regular for(int i=0;i tmp = new List(m_objects.Count); tmp.AddRange(m_objects); while (tmp.Count > 0) { foreach (Physical lObj2 in tmp) { if (tmp[tmp.Count - 1] == lObj2 || (tmp[tmp.Count - 1].IsStatic && lObj2.IsStatic)) continue; IntersectionRecord ir = tmp[tmp.Count - 1].Intersects(lObj2); if (ir != null) intersections.Add(ir); } //remove this object from the temp list so that we can run in O(N(N+1)/2) time instead of O(N*N) tmp.RemoveAt(tmp.Count-1); } } //now, merge our local objects list with the parent objects list, then pass it down to all children. foreach (Physical lObj in m_objects) if (lObj.IsStatic == false) parentObjs.Add(lObj); //parentObjs.AddRange(m_objects); //each child node will give us a list of intersection records, which we then merge with our own intersection records. for (int flags = m_activeNodes, index = 0; flags > 0; flags >>= 1, index++) if ((flags & 1) == 1) intersections.AddRange(m_childNode[index].GetIntersection(parentObjs, type)); return intersections; } ;i++)> Screenshot Demos This is a view of the game world from a distance showing the outlines for each bounding volume for the octree. This view shows a bunch of successive projectiles moving through the game world with the frequently-used nodes being preserved instead of deleted. Complete Code Sample I've attached a complete code sample of the octree class, the intersection record class, and my generic physical object class. I don't guarantee that they're all bug-free since it's all a work in progress and hasn't been rigorously tested yet.
  12. Performance is everybody's responsibility, no matter what your role. When it comes to the GPU, 3D programmers have a lot of control over performance; we can optimize shaders, trade image quality for performance, use smarter rendering techniques... we have plenty of tricks up our sleeves. But there's one thing we don't have direct control over, and that's the game's art. We rely on artists to produce assets that not only look good but are also efficient to render. For artists, a little knowledge of what goes on under the hood can make a big impact on a game's framerate. If you're an artist and want to understand why things like draw calls, LODs, and mipmaps are important for performance, read on! To appreciate the impact that your art has on the game's performance, you need to know how a mesh makes its way from your modelling package onto the screen in the game. That means having an understanding of the GPU - the chip that powers your graphics card and makes real-time 3D rendering possible in the first place. Armed with that knowledge, we'll look at some common art-related performance issues, why they're a problem, and what you can do about it. Things are quickly going to get pretty technical, but if anything is unclear I'll be more than happy to answer questions in the comments section. Before we start, I should point out that I am going to deliberately simplify a lot of things for the sake of brevity and clarity. In many cases I'm To appreciate the impact that your art has on the game's performance, you need to know how a mesh makes its way from your modelling package onto the screen in the game. That means having an understanding of the GPU - the chip that powers your graphics card and makes real-time 3D rendering possible in the first place. Armed with that knowledge, we'll look at some common art-related performance issues, why they're a problem, and what you can do about it. Things are quickly going to get pretty technical, but if anything is unclear I'll be more than happy to answer questions in the comments section. Before we start, I should point out that I am going to deliberately simplify a lot of things for the sake of brevity and clarity. In many cases I'm generalizing, describing only the typical case, or just straight up leaving things out. In particular, for the sake of simplicity the idealized version of the GPU I describe below more closely matches that of the previous (DX9-era) generation. However when it comes to performance, all of the considerations below still apply to the latest PC & console hardware (although not necessarily all mobile GPUs). Once you understand everything described here, it will be much easier to get to grips with the variations and complexities you'll encounter later, if and when you start to dig deeper. Part 1: The rendering pipeline from 10,000 feet For a mesh to be displayed on the screen, it must pass through the GPU to be processed and rendered. Conceptually, this path is very simple: the mesh is loaded, vertices are grouped together as triangles, the triangles are converted into pixels, each pixel is given a colour, and that's the final image. Let's look a little closer at what happens at each stage. After you export a mesh from your DCC tool of choice (Digital Content Creation - Maya, Max, etc.), the geometry is typically loaded into the game engine in two pieces; a Vertex Buffer (VB) that contains a list of the mesh's vertices and their associated properties (position, UV coordinates, normal, color etc.), and an Index Buffer (IB) that lists which vertices in the VB are connected to form triangles. Along with these geometry buffers, the mesh will also have been assigned a material to determine what it looks like and how it behaves under different lighting conditions. To the GPU this material takes the form of custom-written shaders - programs that determine how the vertices are processed, and what colour the resulting pixels will be. When choosing the material for the mesh, you will have set various material parameters (eg. setting a base color value or picking a texture for various maps like albedo, roughness, normal etc.) - these are passed to the shader programs as inputs. The mesh and material data get processed by various stages of the GPU pipeline in order to produce pixels in the final render target (an image to which the GPU writes). That render target can then be used as a texture in subsequent shader programs and/or displayed on screen as the final image for the frame. For the purposes of this article, here are the important parts of the GPU pipeline from top to bottom: Input Assembly. The GPU reads the vertex and index buffers from memory, determines how the vertices are connected to form triangles, and feeds the rest of the pipeline. Vertex Shading. The vertex shader gets executed once for every vertex in the mesh, running on a single vertex at a time. Its main purpose is to transform the vertex, taking its position and using the current camera and viewport settings to calculate where it will end up on the screen. Rasterization. Once the vertex shader has been run on each vertex of a triangle and the GPU knows where it will appear on screen, the triangle is rasterized - converted into a collection of individual pixels. Per-vertex values - UV coordinates, vertex color, normal, etc. - are interpolated across the triangle's pixels. So if one vertex of a triangle has a black vertex color and another has white, a pixel rasterized in the middle of the two will get the interpolated vertex color grey. Pixel Shading. Each rasterized pixel is then run through the pixel shader (although technically at this stage it's not yet a pixel but 'fragment', which is why you'll see the pixel shader sometimes called a fragment shader). This gives the pixel a color by combining material properties, textures, lights, and other parameters in the programmed way to get a particular look. Since there are so many pixels (a 1080p render target has over two million) and each one needs to be shaded at least once, the pixel shader is usually where the GPU spends a lot of its time. Render Target Output. Finally the pixel is written to the render target - but not before undergoing some tests to make sure it's valid. For example in normal rendering you want closer objects to appear in front of farther objects; the depth test can reject pixels that are further away than the pixel already in the render target. But if the pixel passes all the tests (depth, alpha, stencil etc.), it gets written to the render target in memory. There's much more to it, but that's the basic flow: the vertex shader is executed on each vertex in the mesh, each 3-vertex triangle is rasterized into pixels, the pixel shader is executed on each rasterized pixel, and the resulting colors are written to a render target. Under the hood, the shader programs that represent the material are written in a shader programming language such as HLSL. These shaders run on the GPU in much the same way that regular programs run on the CPU - taking in data, running a bunch of simple instructions to change the data, and outputting the result. But while CPU programs are generalized to work on any type of data, shader programs are specifically designed to work on vertices and pixels. These programs are written to give the rendered object the look of the desired material - plastic, metal, velvet, leather, etc. To give you a concrete example, here's a simple pixel shader that does Lambertian lighting (ie. simple diffuse-only, no specular highlights) with a material color and a texture. As shaders go it's one of the most basic, but you don't need to understand it - it just helps to see what shaders can look like in general. float3 MaterialColor; Texture2D MaterialTexture; SamplerState TexSampler; float3 LightDirection; float3 LightColor; float4 MyPixelShader( float2 vUV : TEXCOORD0, float3 vNorm : NORMAL0 ) : SV_Target { float3 vertexNormal = normalize(vNorm); float3 lighting = LightColor * dot( vertexNormal, LightDirection ); float3 material = MaterialColor * MaterialTexture.Sample( TexSampler, vUV ).rgb; float3 color = material * lighting; float alpha = 1; return float4(color, alpha); } A simple pixel shader that does basic lighting. The inputs at the top like MaterialTexture and LightColor are filled in by the CPU, while vUV and vNorm are both vertex properties that were interpolated across the triangle during rasterization. And the generated shader instructions: dp3 r0.x, v1.xyzx, v1.xyzx rsq r0.x, r0.x mul r0.xyz, r0.xxxx, v1.xyzx dp3 r0.x, r0.xyzx, cb0[1].xyzx mul r0.xyz, r0.xxxx, cb0[2].xyzx sample_indexable(texture2d)(float,float,float,float) r1.xyz, v0.xyxx, t0.xyzw, s0 mul r1.xyz, r1.xyzx, cb0[0].xyzx mul o0.xyz, r0.xyzx, r1.xyzx mov o0.w, l(1.000000) ret The shader compiler takes the above program and generates these instructions which are run on the GPU; a longer program produces more instructions which means more work for the GPU to do. As an aside, you might notice how isolated the shader steps are - each shader works on a single vertex or pixel without needing to know anything about the surrounding vertices/pixels. This is intentional and allows the GPU to process huge numbers of independent vertices and pixels in parallel, which is part of what makes GPUs so fast at doing graphics work compared to CPUs. We'll return to the pipeline shortly to see where things might slow down, but first we need to back up a bit and look at how the mesh and material got to the GPU in the first place. This is also where we meet our first performance hurdle - the draw call. The CPU and Draw Calls The GPU cannot work alone; it relies on the game code running on the machine's main processor - the CPU - to tell it what to render and how. The CPU and GPU are (usually) separate chips, running independently and in parallel. To hit our target frame rate - most commonly 30 frames per second - both the CPU and GPU have to do all the work to produce a single frame within the time allowed (at 30fps that's just 33 milliseconds per frame). To achieve this, frames are often pipelined; the CPU will take the whole frame to do its work (process AI, physics, input, animation etc.) and then send instructions to the GPU at the end of the frame so it can get to work on the next frame. This gives each processor a full 33ms to do its work at the expense of introducing a frame's worth of latency (delay). This may be an issue for extremely time-sensitive twitchy games like first person shooters - the Call of Duty series for example runs at 60fps to reduce the latency between player input and rendering - but in general the extra frame is not noticeable to the player. Every 33ms the final render target is copied and displayed on the screen at VSync - the interval during which the monitor looks for a new frame to display. But if the GPU takes longer than 33ms to finish rendering the frame, it will miss this window of opportunity and the monitor won't have any new frame to display. That results in either screen tearing or stuttering and an uneven framerate that we really want to avoid. We also get the same result if the CPU takes too long - it has a knock-on effect since the GPU doesn't get commands quickly enough to do its job in the time allowed. In short, a solid framerate relies on both the CPU and GPU performing well. Here the CPU takes too long to produce rendering commands for the second frame, so the GPU starts rendering late and thus misses VSync. To display a mesh, the CPU issues a draw call which is simply a series of commands that tells the GPU what to draw and how to draw it. As the draw call goes through the GPU pipeline, it uses the various configurable settings specified in the draw call - mostly determined by the mesh's material and its parameters - to decide how the mesh is rendered. These settings, called GPU state, affect all aspects of rendering, and consist of everything the GPU needs to know in order to render an object. Most significantly for us, GPU state includes the current vertex/index buffers, the current vertex/pixel shader programs, and all the shader inputs (eg. MaterialTexture or LightColor in the above shader code example). This means that to change a piece of GPU state (for example changing a texture or switching shaders), a new draw call must be issued. This matters because these draw calls are not free for the CPU. It costs a certain amount of time to set up the desired GPU state changes and then issue the draw call. Beyond whatever work the game engine needs to do for each call, extra error checking and bookkeeping cost is introduced by the graphics driver, an intermediate layer of code written by the GPU vendor (NVIDIA, AMD etc.) that translates the draw call into low-level hardware instructions. Too many draw calls can put too much of a burden on the CPU and cause serious performance problems. Due to this overhead, we generally set an upper limit to the number of draw calls that are acceptable per frame. If this limit is exceeded during gameplay testing, steps must be taken such as reducing the number of objects, reducing draw distance, etc. Console games will typically try to keep draw calls in the 2000-3000 range (eg. on Far Cry Primal we tried to keep it below 2500 per frame). That might sound like a lot, but it also includes any special rendering techniques that might be employed - cascaded shadows for example can easily double the number of draw calls in a frame. As mentioned above, GPU state can only be changed by issuing a new draw call. This means that although you may have created a single mesh in your modelling package, if one half of the mesh uses one texture for the albedo map and the other half uses a different texture, it will be rendered as two separate draw calls. The same goes if the mesh is made up of multiple materials; different shaders need to be set, so multiple draw calls must be issued. In practice, a very common source of state change - and therefore extra draw calls - is switching texture maps. Typically the whole mesh will use the same material (and therefore the same shaders), but different parts of the mesh will use different sets of albedo/normal/roughness maps. With a scene of hundreds or even thousands of objects, using many draw calls for each object will cost a considerable amount of CPU time and so will have a noticeable impact on the framerate of the game. To avoid this, a common solution is to combine all the different texture maps used on a mesh into a single big texture, often called an atlas. The UVs of the mesh are then adjusted to look up the right part of the atlas, and the entire mesh (or even multiple meshes) can be rendered in a single draw call. Care must be taken when constructing the atlas so that adjacent textures don't bleed into each other at lower mips, but these problems are relatively minor compared to the gains that can be had in terms of performance. A texture atlas from Unreal Engine's Infiltrator demo Many engines also support instancing, also known as batching or clustering. This is the ability to use a single draw call to render multiple objects that are mostly identical in terms of shaders and state, and only differ in a restricted set of ways (typically their position and rotation in the world). The engine will usually recognize when multiple identical objects can be rendered using instancing, so it's always preferable to use the same object multiple times in a scene when possible, instead of multiple different objects that will need to be rendered with separate draw calls. Another common technique for reducing draw calls is manually merging many different objects that share the same material into a single mesh. This can be effective, but care must be taken to avoid excessive merging which can actually worsen performance by increasing the amount of work for the GPU. Before any draw call gets issued, the engine's visibility system will determine whether or not the object will even appear on screen. If not, it's very cheap to just ignore the object at this early stage and not pay for any draw call or GPU work (also known as visibility culling). This is usually done by checking if the object's bounding volume is visible from the camera's point of view, and that it is not completely blocked from view (occluded) by any other objects. However, when multiple meshes are merged into a single object, their individual bounding volumes must be combined into a single large volume that is big enough to enclose every mesh. This increases the likelihood that the visibility system will be able to see some part of the volume, and so will consider the entire collection visible. That means that it becomes a draw call, and so the vertex shader must be executed on every vertex in the object - even if very few of those vertices actually appear on the screen. This can lead to a lot of GPU time being wasted because the vertices end up not contributing anything to the final image. For these reasons, mesh merging is the most effective when it is done on groups of small objects that are close to each other, as they will probably be on-screen at the same time anyway. A frame from XCOM 2 as captured with RenderDoc. The wireframe (bottom) shows in grey all the extra geometry submitted to the GPU that is outside the view of the in-game camera. As an illustrative example take the above capture of XCOM 2, one of my favourite games of the last couple of years. The wireframe shows the entire scene as submitted to the GPU by the engine, with the black area in the middle being the geometry that's actually visible by the game camera. All the surrounding geometry in grey is not visible and will be culled after the vertex shader is executed, which is all wasted GPU time. In particular, note the highlighted red geometry which is a series of bush meshes, combined and rendered in just a few draw calls. Since the visibility system determined that at least some of the bushes are visible on the screen, they are all rendered and so must all have their vertex shader executed before determining which can be culled... which turns out to be most of them. Please note this isn't an indictment of XCOM 2 in particular, I just happened to be playing it while writing this article! Every game has this problem, and it's a constant battle to balance the CPU cost of doing more accurate visibility tests, the GPU cost of culling the invisible geometry, and the CPU cost of having more draw calls. Things are changing when it comes to the cost of draw calls however. As mentioned above, a significant reason for their expense is the overhead of the driver doing translation and error checking. This has long been the case, but the most modern graphics APIs (eg. Direct3D 12 and Vulkan) have been restructured in order to avoid most of this overhead. While this does introduce extra complexity to the game's rendering engine, it can also result in cheaper draw calls, allowing us to render many more objects than before possible. Some engines (most notably the latest version used by Assassin's Creed) have even gone in a radically different direction, using the capabilities of the latest GPUs to drive rendering and effectively doing away with draw calls altogether. The performance impact of having too many draw calls is mostly on the CPU; pretty much all other performance issues related to art assets are on the GPU. We'll now look at what a bottleneck is, where they can happen, and what we can do about them. Part 2: Common GPU bottlenecks The very first step in optimization is to identify the current bottleneck so you can take steps to reduce or eliminate it. A bottleneck refers to the section of the pipeline that is slowing everything else down. In the above case where too many draw calls are costing too much, the CPU is the bottleneck. Even if we performed other optimizations that made the GPU faster, it wouldn't matter to the framerate because the CPU is still running too slowly to produce a frame in the required amount of time. 4 draw calls going through the pipeline, each being the rendering of a full mesh containing many triangles. The stages overlap because as soon as one piece of work is finished it can be immediately passed to the next stage (eg. when three vertices are processed by the vertex shader then the triangle can proceed to be rasterized). You can think of the GPU pipeline as an assembly line. As each stage finishes with its data, it forwards the results to the following stage and proceeds with the next piece of work. Ideally every stage is busy working all the time, and the hardware is being utilized fully and efficiently as represented in the above image - the vertex shader is constantly processing vertices, the rasterizer is constantly rasterizing pixels, and so on. But consider what happens if one stage takes much longer than the others: What happens here is that an expensive vertex shader can't feed the following stages fast enough, and so becomes the bottleneck. If you had a draw call that behaved like this, making the pixel shader faster is not going to make much of a difference to the time it takes for the entire draw call to be rendered. The only way to make things faster is to reduce the time spent in the vertex shader. How we do that depends on what in the vertex shader stage is actually causing the bottleneck. You should keep in mind that there will almost always be a bottleneck of some kind - if you eliminate one, another will just take its place. The trick is knowing when you can do something about it, and when you have to live with it because that's just what it costs to render what you want to render. When you optimize, you're really trying to get rid of unnecessary bottlenecks. But how do you identify what the bottleneck is? Profiling Profiling tools are absolutely essential for figuring out where all the GPU's time is being spent, and good ones will point you at exactly what you need to change in order for things to go faster. They do this in a variety of ways - some explicitly show a list of bottlenecks, others let you run 'experiments' to see what happens (eg. "how does my draw time change if all the textures are tiny", which can tell you if you're bound by memory bandwidth or cache usage). Unfortunately this is where things get a bit hand-wavy, because some of the best performance tools available are only available for the consoles and therefore under NDA. If you're developing for Xbox or Playstation, bug your friendly neighbourhood graphics programmer to show you these tools. We love it when artists get involved in performance, and will be happy to answer questions and even host tutorials on how to use the tools effectively. Unity's basic built-in GPU profiler The PC already has some pretty good (albeit hardware-specific) profiling tools which you can get directly from the GPU vendors, such as NVIDIA's Nsight, AMD's GPU PerfStudio, and Intel's GPA. Then there's RenderDoc which is currently the best tool for graphics debugging on PC, but doesn't have any advanced profiling features. Microsoft is also starting to release its awesome Xbox profiling tool PIX for Windows too, albeit only for D3D12 applications. Assuming they also plan to provide the same bottleneck analysis tools as the Xbox version (tricky with the wide variety of hardware out there), it should be a huge asset to PC developers going forward. These tools can give you more information about the performance of your art than you will ever need. They can also give you a lot of insight into how a frame is put together in your engine, as well as being awesome debugging tools for when things don't look how they should. Being able to use them is important, as artists need to be responsible for the performance of their art. But you shouldn't be expected to figure it all out on your own - any good engine should provide its own custom tools for analyzing performance, ideally providing metrics and guidelines to help determine if your art assets are within budget. If you want to be more involved with performance but feel you don't have the necessary tools, talk to your programming team. Chances are they already exist - and if they don't, they should be created! Now that you know how GPUs work and what a bottleneck is, we can finally get to the good stuff. Let's dig into the most common real-world bottlenecks that can show up in the pipeline, how they happen, and what can be done about them. Shader instructions Since most of the GPU's work is done with shaders, they're often the source of many bottlenecks of the you'll see. When a bottleneck is identified as shader instructions (sometimes referred to as ALUs from Arithmetic Logic Units, the hardware that actually does the calculations), it's simply a way of saying the vertex or pixel shader is doing a lot of work and the rest of the pipeline is waiting for that work to finish. Often the vertex or pixel shader program itself is just too complex, containing many instructions and taking a long time to execute. Or maybe the vertex shader is reasonable but the mesh you're rendering has too many vertices which adds up to a lot of time spent executing the vertex shader. Or the draw call covers a large area of the screen touching many pixels, and so spends a lot of time in the pixel shader. Unsurprisingly, the best way to optimize a shader instruction bottleneck is to execute less instructions! For pixel shaders that means choosing a simpler material with less features to reduce the number of instructions executed per pixel. For vertex shaders it means simplifying your mesh to reduce the number of vertices that need to be processed, as well as being sure to use LODs (Level Of Detail - simplified versions of your mesh for use when the object is far away and small on the screen). Sometimes however, shader instruction bottlenecks are instead just an indication of problems in some other area. Issues such as too much overdraw, a misbehaving LOD system, and many others can cause the GPU to do a lot more work than necessary. These problems can be either on the engine side or the content side; careful profiling, examination, and experience will help you to figure out what's really going on. One of the most common of these issues - overdraw - is when the same pixel on the screen needs to be shaded multiple times, because it's touched by multiple draw calls. Overdraw is a problem because it decreases the overall time the GPU has to spend on rendering. If every pixel on the screen has to be shaded twice, the GPU can only spend half the amount of time on each pixel and still maintain the same framerate. A frame capture from PIX with the corresponding overdraw visualization mode Sometimes overdraw is unavoidable, such as when rendering translucent objects like particles or glass-like materials; the background object is visible through the foreground, so both need to be rendered. But for opaque objects, overdraw is completely unnecessary because the pixel shown in the buffer at the end of rendering is the only one that actually needs to be processed. In this case, every overdrawn pixel is just wasted GPU time. Steps are taken by the GPU to reduce overdraw in opaque objects. The early depth test (which happens before the pixel shader - see the initial pipeline diagram) will skip pixel shading if it determines that the pixel will be hidden by another object. It does that by comparing the pixel being shaded to the depth buffer - a render target where the GPU stores the entire frame's depth so that objects occlude each other properly. But for the early depth test to be effective, the other object must have already been rendered so it is present in the depth buffer. That means that the rendering order of objects is very important. Ideally every scene would be rendered front-to-back (ie. objects closest to the camera first), so that only the foreground pixels get shaded and the rest get killed by the early depth test, eliminating overdraw entirely. But in the real world that's not always possible because you can't reorder the triangles inside a draw call during rendering. Complex meshes can occlude themselves multiple times, or mesh merging can result in many overlapping objects being rendered in the "wrong" order causing overdraw. There's no easy answer for avoiding these cases, and in the latter case it's just another thing to take into consideration when deciding whether or not to merge meshes. To help early depth testing, some games do a partial depth prepass. This is a preliminary pass where certain large objects that are known to be effective occluders (large buildings, terrain, the main character etc.) are rendered with a simple shader that only outputs to the depth buffer, which is relatively fast as it avoids doing any pixel shader work such as lighting or texturing. This 'primes' the depth buffer and increases the amount of pixel shader work that can be skipped during the full rendering pass later in the frame. The drawback is that rendering the occluding objects twice (once in the depth-only pass and once in the main pass) increases the number of draw calls, plus there's always a chance that the time it takes to render the depth pass itself is more than the time it saves from increased early depth test efficiency. Only profiling in a variety of cases can determine whether or not it's worth it for any given scene. Particle overdraw visualization of an explosion in Prototype 2 One place where overdraw is a particular concern is particle rendering, given that particles are transparent and often overlap a lot. Artists working on particle effects should always have overdraw in mind when producing effects. A dense cloud effect can be produced by emitting lots of small faint overlapping particles, but that's going to drive up the rendering cost of the effect; a better-performing alternative would be to emit fewer large particles, and instead rely more on the texture and texture animation to convey the density of the effect. The overall result is often more visually effective anyway because offline software like FumeFX and Houdini can usually produce much more interesting effects through texture animation, compared to real-time simulated behaviour of individual particles. The engine can also take steps to avoid doing more GPU work than necessary for particles. Every rendered pixel that ends up completely transparent is just wasted time, so a common optimization is to perform particle trimming: instead of rendering the particle with two triangles, a custom-fitted polygon is generated that minimizes the empty areas of the texture that are used. Particle 'cutout' tool in Unreal Engine 4 The same can be done for other partially transparent objects such as vegetation. In fact for vegetation it's even more important to use custom geometry to eliminate the large amount of empty texture space, as vegetation often uses alpha testing. This is when the alpha channel of the texture is used to decide whether or not to discard the pixel during the pixel shader stage, effectively making it transparent. This is a problem because alpha testing can also have the side effect of disabling the early depth test completely (because it invalidates certain assumptions that the GPU can make about the pixel), leading to much more unnecessary pixel shader work. Combine this with the fact that vegetation often contains a lot of overdraw anyway - think of all the overlapping leaves on a tree - and it can quickly become very expensive to render if you're not careful. A close relative of overdraw is overshading, which is caused by tiny or thin triangles and can really hurt performance by wasting a significant portion of the GPU's time. Overshading is a consequence of how GPUs process pixels during pixel shading: not one at a time, but instead in 'quads' which are blocks of four pixels arranged in a 2x2 pattern. It's done like this so the hardware can do things like comparing UVs between pixels to calculate appropriate mipmap levels. This means that if a triangle only touches a single pixel of a quad (because the triangle is tiny or very thin), the GPU still processes the whole quad and just throws away the other three pixels, wasting 75% of the work. That wasted time can really add up, and is particularly painful for forward (ie. not deferred) renderers that do all lighting and shading in a single pass in the pixel shader. This penalty can be reduced by using properly-tuned LODs; besides saving on vertex shader processing, they can also greatly reduce overshading by having triangles cover more of each quad on average.' A 10x8 pixel buffer with 5x4 quads. The two triangles have poor quad utilization -- left is too small, right is too thin. The 10 red quads touched by the triangles need to be completely shaded, even though the 12 green pixels are the only ones that are actually needed. Overall, 70% of the GPU's work is wasted. (Random trivia: quad overshading is also the reason you'll sometimes see fullscreen post effects use a single large triangle to cover the screen instead of two back-to-back triangles. With two triangles, quads that straddle the shared edge would be wasting some of their work, so avoiding that saves a minor amount of GPU time.) Beyond overshading, tiny triangles are also a problem because GPUs can only process and rasterize triangles at a certain rate, which is usually relatively low compared to how many pixels it can process in the same amount of time. With too many small triangles, it can't produce pixels fast enough to keep the shader units busy, resulting in stalls and idle time - the real enemy of GPU performance. Similarly, long thin triangles are bad for performance for another reason beyond quad usage: GPUs rasterize pixels in square or rectangular blocks, not in long strips. Compared to a more regular-shaped triangle with even sides, a long thin triangle ends up making the GPU do a lot of extra unnecessary work to rasterize it into pixels, potentially causing a bottleneck at the rasterization stage. This is why it's usually recommended that meshes are tessellated into evenly-shaped triangles, even if it increases the polygon count a bit. As with everything else, experimentation and profiling will show the best balance. Memory Bandwidth and Textures As illustrated in the above diagram of the GPU pipeline, meshes and textures are stored in memory that is physically separate from the GPU's shader processors. That means that whenever the GPU needs to access some piece of data, like a texture being fetched by a pixel shader, it needs to retrieve it from memory before it can actually use it as part of its calculations. Memory accesses are analogous to downloading files from the internet. File downloads take a certain amount of time due to the internet connection's bandwidth - the speed at which data can be transferred. That bandwidth is also shared between all downloads - if you can download one file at 6MB/s, two files only download at 3MB/s each. The same is true of memory accesses; index/vertex buffers and textures being accessed by the GPU take time, and must share memory bandwidth. The speeds are obviously much higher than internet connections - on paper the PS4's GPU memory bandwidth is 176GB/s - but the idea is the same. A shader that accesses many textures will rely heavily on having enough bandwidth to transfer all the data it needs in the time it needs it. Shaders programs are executed by the GPU with these restrictions in mind. A shader that needs to access a texture will try to start the transfer as early as possible, then do other unrelated work (for example lighting calculations) and hope that the texture data has arrived from memory by the time it gets to the part of the program that needs it. If the data hasn't arrived in time - because the transfer is slowed down by lots of other transfers, or because it runs out of other work to do (especially likely for dependent texture fetches) - execution will stop and it will just sit there and wait. This is a memory bandwidth bottleneck; making the rest of the shader faster will not matter if it still needs to stop and wait for data to arrive from memory. The only way to optimize this is to reduce the amount of bandwidth being used, or the amount of data being transferred, or both. Memory bandwidth might even have to be shared with the CPU or async compute work that the GPU is doing at the same time. It's a very precious resource. The majority of memory bandwidth is usually taken up by texture transfers, since textures contain so much data. As a result, there are a few different mechanisms in place to reduce the amount of texture data that needs to be shuffled around. Memory bandwidth might even have to be shared with the CPU or async compute work that the GPU is doing at the same time. It's a very precious resource. The majority of memory bandwidth is usually taken up by texture transfers, since textures contain so much data. As a result, there are a few different mechanisms in place to reduce the amount of texture data that needs to be shuffled around. First and foremost is a cache. This is a small piece of high-speed memory that the GPU has very fast access to, and is used to keep chunks of memory that have been accessed recently in case the GPU needs them again. In the internet connection analogy, the cache is your computer's hard drive that stores the downloaded files for faster access in the future. When a piece of memory is accessed, like a single texel in a texture, the surrounding texels are also pulled into the cache in the same memory transfer. The next time the GPU looks for one of those texels, it doesn't need to go all the way to memory and can instead fetch it from the cache extremely quickly. This is actually often the common case - when a texel is displayed on the screen in one pixel, it's very likely that the pixel beside it will need to show the same texel, or the texel right beside it in the texture. When that happens, nothing needs to be transferred from memory, no bandwidth is used, and the GPU can access the cached data almost instantly. Caches are therefore vitally important for avoiding memory-related bottlenecks. Especially when you take filtering into account - bilinear, trilinear, and anisotropic filtering all require multiple texels to be accessed for each lookup, putting an extra burden on bandwidth usage. High-quality anisotropic filtering is particularly bandwidth-intensive. Now think about what happens in the cache if you try to display a large texture (eg. 2048x2048) on an object that's very far away and only takes up a few pixels on the screen. Each pixel will need to fetch from a very different part of the texture, and the cache will be completely ineffective since it only keeps texels that were close to previous accesses. Every texture access will try to find its result in the cache and fail (called a 'cache miss') and so the data must be fetched from memory, incurring the dual costs of bandwidth usage and the time it takes for the data to be transferred. A stall may occur, slowing the whole shader down. It will also cause other (potentially useful) data to be 'evicted' from the cache in order to make room for the surrounding texels that will never even be used, reducing the overall efficiency of the cache. It's bad news all around, and that's not to even mention the visual quality issues - tiny movements of the camera will cause completely different texels to be sampled, causing aliasing and sparkling. This is where mipmapping comes to the rescue. When a texture fetch is issued, the GPU can analyze the texture coordinates being used at each pixel, determining when there is a large gap between texture accesses. Instead of incurring the costs of a cache miss for every texel, it instead accesses a lower mip of the texture that matches the resolution it's looking for. This greatly increases the effectiveness of the cache, reducing memory bandwidth usage and the potential for a bandwidth-related bottleneck. Lower mips are also smaller and need less data to be transferred from memory, further reducing bandwidth usage. And finally, since mips are pre-filtered, their use also vastly reduces aliasing and sparkling. For all of these reasons, it's almost always a good idea to use mipmaps - the advantages are definitely worth the extra memory usage. A texture on two quads, one close to the camera and one much further away The same texture with a corresponding mipmap chain, each mip being half the size of the previous one Lastly, texture compression is an important way of reducing bandwidth and cache usage (in addition to the obvious memory savings from storing less texture data). Using BC (Block Compression, previously known as DXT compression), textures can be reduced to a quarter or even a sixth of their original size in exchange for a minor hit in quality. This is a significant reduction in the amount of data that needs to be transferred and processed, and most GPUs even keep the textures compressed in the cache, leaving more room to store other texture data and increasing overall cache efficiency. All of the above information should lead to some obvious steps for reducing or eliminating bandwidth bottlenecks when it comes to texture optimization on the art side. Make sure the textures have mips and are compressed. Don't use heavy 8x or 16x anisotropic filtering if 2x is enough, or even trilinear or bilinear if possible. Reduce texture resolution, particularly if the top-level mip is often displayed. Don't use material features that cause texture accesses unless the feature is really needed. And make sure all the data being fetched is actually used - don't sample four RGBA textures when you actually only need the data in the red channels of each; merge those four channels into a single texture and you've removed 75% of the bandwidth usage. While textures are the primary users of memory bandwidth, they're by no means the only ones. Mesh data (vertex and index buffers) also need to be loaded from memory. You'll also notice in first GPU pipeline diagram that the final render target output is a write to memory. All these transfers usually share the same memory bandwidth. In normal rendering these costs typically aren't noticeable as the amount of data is relatively small compared to the texture data, but this isn't always the case. Compared to regular draw calls, shadow passes behave quite differently and are much more likely to be bandwidth bound. A frame from GTA V with shadow maps, courtesy of Adrian Courreges' great frame analysis This is because shadow maps are simply depth buffer that represent the distance from the light to the closest mesh, so most of the work that needs to be done for shadow rendering consists of transferring data to and from memory: fetch the vertex/index buffers, do some simple calculations to determine position, and then write the depth of the mesh to the shadow map. Most of the time, a pixel shader isn't even executed because all the necessary depth information comes from just the vertex data. This leaves very little work to hide the overhead of all the memory transfers, and the likely bottleneck is that the shader just ends up waiting for memory transfers to complete. As a result, shadow passes are particularly sensitive to both vertex/triangle counts and shadow map resolution, as they directly affect the amount of bandwidth that is needed. The last thing worth mentioning with regards to memory bandwidth is a special case - the Xbox. Both the Xbox 360 and Xbox One have a particular piece of memory embedded close to the GPU, called EDRAM on 360 and ESRAM on XB1. It's a relatively small amount of memory (10MB on 360 and 32MB on XB1), but big enough to store a few render targets and maybe some frequently-used textures, and with a much higher bandwidth than regular system memory (aka DRAM). Just as important as the speed is the fact that this bandwidth uses a dedicated path, so doesn't have to be shared with DRAM transfers. It adds complexity to the engine, but when used efficiently it can give some extra headroom in bandwidth-limited situations. As an artist you generally won't have control over what goes into EDRAM/ESRAM, but it's worth knowing of its existence when it comes to profiling. The 3D programming team can give you more details on its use in your particular engine. And there's more... As you've probably gathered by now, GPUs are complex pieces of hardware. When fed properly, they are capable of processing an enormous amount of data and performing billions of calculations every second. On the other hand, bad data and poor usage can slow them down to a crawl, having a devastating effect on the game's framerate. There are many more things that could be discussed or expanded upon, but what's above is a good place to start for any technically-minded artist. Having an understanding of how the GPU works can help you produce art that not only looks great but also performs well... and better performance can let you improve your art even more, making the game look better too. There's a lot to take in here, but remember that your 3D programming team is always happy to sit down with you and discuss anything that needs more explanation - as am I in the comments section below! Further Technical Reading Render Hell - Simon Trumpler Texture filtering: mipmaps - Shawn Hargreaves Graphics Gems for Games - Findings from Avalanche Studios - Emil Persson Triangulation - Emil Persson How bad are small triangles on GPU and why? - Christophe Riccio Game Art Tricks - Simon Trumpler Optimizing the rendering of a particle system - Christer Ericson Practical Texture Atlases - Ivan-Assen Ivanov How GPUs Work - David Luebke & Greg Humphreys Casual Introduction to Low-Level Graphics Programming - Stephanie Hurlburt Counting Quads - Stephen Hill Overdraw in Overdrive - Stephen Hill Life of a triangle - NVIDIA's logical pipeline - NVIDIA From Shader Code to a Teraflop: How Shader Cores Work - Kayvon Fatahalian A Trip Through the Graphics Pipeline (2011) - Fabian Giesen Note: This article was originally published on fragmentbuffer.com, and is republished here with kind permission from the author Keith O'Conor. You can read more of Keith's writing on Twitter (@keithoconor).
  13. This tutorial video shows you how to use Qualcomm Snapdragon Profiler to detect bottlenecks and optimize your application’s performance and power efficiency. In addition, it provides an overview of its three mode: Realtime, Trace Capture and Snapshot Capture.
  14. Hi I have finished my multiplayer game interpolation code. It works fine. But I am looking for ways to optimize it and what could be done to improve performance. As for now I have too many temporary variables and objects inside the interpolation function which is running at 60 times per second on client side. I've read some articles that creating those temp variables and objects too many times may slow my game. To make things simple, I create a object literal like this in the class that defines the interpolation function { timestamp:0, allStates: {}, allOtherStuff: {} } In each interpolation I will clear the object, which means I am just creating a new empty object. Then in the interpolation function I use a for loop to push the interpolated value and other unchanged properties from previous state into object.allStates and object.allOtherStuff. Although this works perfectly but the interpolation function looks bloated. Is there anything I can do to improve this?
  15. Iñigo Quilez presented techniques for raytracing and distance fields in 4096 bytes on the GPU at NVSCENE 2008. Click the link below to view the presentation PDF. PDF: click here.
  16. I'm a college game design major, but I have also picked up on some basic programming. I've done some stuff in Javascript, AS3, Visual Basic, Stencyl, and I'm now moving into using C# in Unity. Just as a general programming question, what are some tricks/techniques that any programmer can do, regardless of coding language, to make sure that their game runs as smoothly as it possibly can, in terms of frame rate?
  17. Hello everyone! Im using mvc framework for wrapper. So i have UIController, UIView for this problem. The object of type UIView is display object and works as container(like in ActionScript). So it holds some static buttons wich control sound,fullscreen and etc. and another dynamic controls wich control the state and current rules of the game. When the game is in different states the buttons can be active or inactive for pressing, can be with different texts over them, wich can cause different functionallity to be performed in the controller. So i have around 10-13 states of the game in wich the ui buttons are in different state so: Control state of the buttons in the controller. It is not ok cuz the controller is more than 300 rows and its ugly for reading and understanding. It shouldnt be. To create custom object in the controller and to pass to it the ui buttons and with some function called changeState to set the appropriate appearance to the buttons. How to structure and name that custom object to be enough descriptive. Or is there some well known pattern ? Or do u have better idea ?
  18. Didn't do much today mainly messed with the player hub and Optimized the game code to where I can hold so far 60 AIs at once! I will be working on the Ai's code more tomorrow and will show a video seeing how much AI's I can fit in one battlefield! Also for those of yall who are interested in keeping up-to-date more consistently I have a new twitter account follow me here: https://twitter.com/ACTNS_Ent
  19. Hi, probably a very stupid question but anyway: My lecturer told me that this "++i" is faster than "i++" when incrementing a for loop. Can anybody argue this point? And if it's true, could you possibly explain why it's faster?  Cheers
  20. Advice for LOD switching

    I'm currently working on an open-world, dense urban project using the dev tools released by a design studio for a game they have released.   I can run the base game (which is also set in dense urban areas) at 1080p with ultra settings with a solid 60FPS but if I go to 4K then I get about 30FPS.   The minimum specs of the game: CPU: 3.4GHZ GPU: 1GB VRAM   The recommended specs of the game: CPU: 4.0GHZ GPU: 2GB VRAM   My question is about LOD switching. Using the dev tools, you can create your own unique buildings but I'm worried about how I should create the LODs. All the different buildings I create will use many similar objects such as windows and detailed objects like air conditioners, chimneys e.c.t. It seems more convenient to me to create many smaller LODs rather than creating a new singular LOD for every building that's made to save time and also, if I edit the values of a smaller decoration, it would take effect across all the other smaller LODs already created. I hope this has made sense to you.   If I create a LOD for multiple parts of a single building then I can keep creating new ones easily and all the LODs are already created. But of course, that could effect the performance. However, with minimum specs like 3.4GHZ, could I compromise with more LOD switches?   I'm new to generating and creating LODs and could use a bit of advice and guidance. Unfortunately, I cannot disclose too much about the project or show screenshots as it is currently under wraps. Any help would be appreciated - thanks!  
  21. I've read in several places at this point that to get the most out of your CPU's cache, it's important to pack relevant data together, and access it in a linear fashion. That way the first access to that region of memory loads it into a cache line, and the remaining accesses will be much cheaper. One thing that isn't clear to me, however, is how many cache lines you can have "active" at once.   So for example, if you have a series of 3D vectors, and you lay them out like this: [xxxx...] [yyyy...] [zzzz...] And then you access your data as: for (std::size_t i = 0; i < len; ++i) { auto x_i = x[i]; auto y_i = y[i]; auto z_i = z[i]; // Do something with x, y, and z } Does each array get it's own cache line? Or does accessing the 'y' element push 'x' out of the cache, and then accessing the 'z' element push 'y' out of the cache? If you were to iterate backwards, would that cause more cache misses than iterating forwards?   On another note, while I try to follow best practices for this stuff where possible, I literally have zero idea how effective (or ineffective) it is, since I have no tools for profiling it, and I don't have time write one version of something and then test it against another. Are there any free (or free for students) tools for cache profiling on Windows? I'd love to use Valgrind, but I don't have anything that can run Linux that is also powerful enough to run my game.   Thanks!
  22. MMOG Optimizations

    Hi community, here is Emanuele from Crimson Games Development Department. An user asked me about how I am dealing with main MMOGs problems in Heroes of Asgard, so I prepared an article about this topic. So today we will discuss about main optimization problems that you can find in a MMO game development. I will be happy if someone will add his contribute, so we can learn together: I will add it to open post! DEFINITION By definition, a MMOG should allow you to play with a huge amount of people at once and interact with them as if you are in a normal multiplayer game, this in a persistent world. Now, if we want to dissect a little more this statement, we will see that this is impossible without applying various “tricks” behind the scenes. WE ARE COMPLAINING ABOUT PERFORMANCES You can definitely understand how when the amount of connected players grows, server performances will be degraded. Many operations on the server are required to operate on all connected players or a subset of them, on all objects around the world, on all monsters and their AI, etc. All these calculations are executed several times per second: imagine, then, to have to iterate over 200 players, having to iterate over 2,000 players or having to iterate over 20,000 players, frame each frame of your server simulation. For each iteration, I have to send packets, make calculations, change positions, etc. There is, therefore, an exponential growth of the computational load for each new connected player. As you can well imagine, is a very large amount of work for a single machine, this due to an obvious hardware limitation. Usually, therefore, there is a maximum threshold of concurrent players simultaneously processed, after which the server itself (the physical machine) can not keep up, creating a negative game experience (lag, unresponsive commands, etc). You can not accept new connections beyond this threshold until a seat becomes available, in order to not ruin the experience for those who are already connected and playing. You could then start multiple servers on different machines, so you can host more players, but of course they can not interact with players from other servers. The division into various “server instance” definitely does not fall within the definition of MMOG, as it does not allow you to interact with all players in a persistent world, but it creates different instances of the same world. It is acceptable, of course: but it isn’t what we want to achieve. That said, what can we do to “bypass” a little bit this problem? And what did I already do for Heroes of Asgard? What I describe is the result of my experience and, therefore, it is also what I provided for Heroes of Asgard, obviously trying to get the best. WHAT CAN WE DO? There are several measures that can be applied to improve the maximum threshold. Yes, improve it: there will always be a maximum threshold beyond which it is difficult to go (by maintaining the same hardware, of course). YOU ARE THE CODE THAT YOU WRITE As first thing: write good code, with your brain attached to this task and without unnecessary waste of resources. It may seem obvious and trite, but it is not. Wasting resources is equivalent to worsen server’s available resources. Wasting bandwidth means exhaust it in no time, every single piece of data that is transmitted has to be carefully selected. If I send an extra byte for each user, when my server hosts 20,000 players, it means sending about additional 20KB for each frame. Wasting CPU cycles is like shooting myself in the foot: the actions you perform must be kept to a bare minimum, add a single more function call per user may mean adding N additional CPU cycles, which for 20,000 users will be N x 20000 additional CPU cycles. Waste memory (and therefore to allocate unnecessary resources) is harmful: the allocation requires both additional CPU cycles and memory. And system memory ends. In managed environments, also leave resources allocated causes garbage collection, which may mean spending huge CPU cycles to free resources, instead of serving the players and simulate the world. Ultimately, wasting resources in your code will ensure that you will spend more money and more frequently to improve your servers (when your userbase increases), in order to maintain acceptable performance. FIX YOUR SIMULATION As you certainly know, the simulation of a virtual world can be executed a certain number of times per second by the server. This means that every second, all entities and systems in the world are “simulated” a certain number of times. The simulation can include AI routines, positions/rotations updates, etc. It allows you to infuse ”life” to your virtual world. The number of times your simulation is performed is called FPS or Frames Per Second. It is obvious that if the simulation is cumbersome and requires time, our hardware will tend to simulate the world less times in one second. This can lead to a degradation of the simulation. But consider: does we need a big amount of simulations performed by the server? Does we need to strive our hardware in this manner? Can we, however, improve this? Yes. For most games with few players in the same map, and a high game speed (see the FPS, with a high number of commands) our world can be simulated 60 times per second (or less, obviously it depends on game type). For a MMOG a more little amount can be enough, depending on the genre. There is no need to simulate the world many times per second as possible, since this will change the simulation in a minimal way, wasting more resources than necessary. In Heroes of Asgard, for example, the world is simulated 20 times per second (at the moment). DO WE NEED TO KNOW ABOUT THE ENTIRE WORLD? We said that in an MMOG we must be able to interact with other players and with the surrounding environment and I should be able to do it with anyone in the world at that time. Quite right, of course. But, from the point of view of a player, do you really need to know what a player is doing on the other side of the map? No, not always. Indeed, in the majority of cases this player isn’t interested to know if another player, as example, is walking or not in another far area. Send an information that can not be displayed on the user’s screen is a waste of resources. This observation is important, it allows us to implement a big optimization. How can I inform a particular player only on entities that may interest him? Why not break the map (or maps) in zones? A simple subdivision is grid one: divide the map in N x M zones, where N and M are greater than or equal to 1. This technique is also known as space partitioning or zones partitioning. In this way, a player can only receive information on the entities contained in its area, without needing to have knowledge of distant entities. If in my map 8000 entities are uniformly distributed and it is divided into a 4 x 4 grid, the player who is in the [1, 1] zone will have the burden of receiving information only about 500 entities. A great advantage, doesn’t it? But consider: what if the player is on zone’s borders? It will not see the players in the nearby zones, although they are visible. We can therefore understand that the player will have to be informed about the entities contained in its zone and in zones immediately contiguous. The size of the zones allows you to optimize a lot this method, so depending on the size of a map the size of the grid can vary , in order to obtain the best effect. Also the shape of the zones can vary, to better fit to the composition of the map. LOOK FAR AS THE EYE CAN SEE As mentioned, zone division already offers a decent level of optimization, allowing us to send information about a single entity to the players who really can benefit from them. But let us ask ourselves a question: can we identify useless information in our zone division (remember that also include those contiguous, so in a regular grid we have to dealt with 9 zones in the worst case)? Of course we can. Most likely a player does not affect entities outside of his field of view. If I can not see an entity, I do not care to trace what it is doing, although it may be in my own zone. Then sending information about that entity is a waste of resources. How can you determine what your server needs to send to a specific player? The easiest way is to trace, in fact, the field of view. Everything within that radius is what matters to the specific player, entities outside are not necessary to the specific player’s world simulation. And since we already have a zone subdivision, we can simply iterate over the entities in player’s zones of interest (instead of all entities in the map) to determine who is within our field of view. This concept is also called area of interest or AoI. So, continuing the example before, let’s iterate on 500 entities instead of 8000, to extrapolate those hypothetical 25 which fall within the visual range and exchange information through the network only with them. From 8000 to 25, a good result: doesn’t it? And without the user suffers of missing information as it does not see them. Indeed, it will notice less use of resources. You can further enhance the area of interest, by applying various measures:organize various levels of visual rays; the most distant entity will receive updates less frequentlyfilter the interesting entities depending on the morphology of the map; if an entity is in our sight, but behind a mountain, I can possibly ignore it. This measure, however, (in my opinion) only makes sense if you already use culling for other things, so you don’t introduce additional calculations to filter few other entitiesDISTRIBUTE YOUR COMPUTATION LOAD We already said that a single machine will still have a certain threshold beyond which, despite all the optimizations made, you will experience performance degradation (and thus a bad gaming experience). Fine, but then why not take advantage of multiple computers simultaneously? There are obviously different ways to do it. For example, in Heroes of Asgard each map that composes the world is hosted on a separate process. This causes each map can be hosted on a different physical machine. Obviously, however, you can go down even more and accommodate sets of zones on separate processes (so a single map may be divided into several parts and hosted by different servers). SLICE YOUR PIE You can also combine global services (such as chat) in different server processes, to give to your player the impression that, even being connected to different maps (so different servers), you can interact with distant players. Furthermore, break those services from the main world is getting an additional gain in performance. RECYCLE YOUR TOYS As mentioned, allocate memory costs a good amount of resources. So why not reuse what we already allocated? The use of objects pools is of great importance in the multiplayer development. It allows to shift the burden of allocating costs when it can be faced with no problems, for example during bootstrap of our app server. A monster is defeated and dies? Well, I put it aside. I can use it again when another monster must be spawned, just recovering from my pool. Of course it is clear that you have to use a certain criteria in order to choose which objects to keep in memory and which are not. Should I keep in memory a pool of a monsters that spawns once a month? No, it may be useless. Should I keep in memory a pool of objects representing the drop of the currency? Yes, it makes more sense. USEFUL LINKS Of course, an important part of this thread is for resources. Articles, papers: each thing you think that can be useful on this topic. Spatial Partitioning http://gameprogrammingpatterns.com/spatial-partition.html Objects Pooling http://gameprogrammingpatterns.com/object-pool.html Game loop http://gafferongames.com/game-physics/fix-your-timestep/ Feel free to add your questions or your contribute! Best regards, Emanuele
  23. when checking if some object is within a certain area, which approach would have better performance if using glm library?   vec3 pos;   // Using a bounding box to represent that area 1) if ( pos.x > box.MinX && pos.x < box.MaxX      && pos.y > box.MinY....) { // do something..}   // Using a sphere to represent that area 2) if ( glm::length ( pos - sphere.centerPosition ) <= sphere.radius ) { // do something..}      
  24. Guys, I have 7 animated enemies. And my fps is 62 for now( not capped). But when I add 5 more enemies and make them 12, my fps drops to 31. I traced the problem and I finally found it, it's my BoneTransform() function, which fills my vector of TransformMatrices that I use in the vertex shader in order to animate the skeleton. But it rapes my CPU. ( when I comment the BoneTransform() function, framerate goes from 30 to 166!( sometimes jumps between 166 and 200 ). And I kind of stole most of the function from a tutorial on skeletal animation, and I'm sure it's pretty optimized, so there must be some other reason. [attachment=32770:lowfps.gif] I used some models from World of Warcraft. And the interesting thing is that I have the game, and when I play it( when I play WoW ), I can have 20 players around me, and my fps is great, but when I add the same models in my own game, my fps drops like crazy and it's 10 times slower than the original game, why? ( bear in mind that I haven't even loaded any map, I just spawn 12 enemies walking on air, and my cpu runs like a fat truckdriver, wtf is that?? ).
  25. Hi Guys,   At present, I send the W, V, & P matrices to the shader where they are multiplied within the shader to position vertices.   Would it be more efficient to pre-multiply these on the CPU and then pass the result to the shader?   Thanks in advance :)