1. Past hour
2. ## Codeblocks and Assimp setup procedures

COULD SOMEONE PLZ GIVE ME SOME PROPER INSTRUCTIONS STEP BY STEP how to successfully install ASSIMP to work with CODEBLOCKS i've been waiting for years searching. Its that what finally brought me here. Someone here must have a solid hard knowledge how to get it done step by step without issuses later on to worry about and deal with. Please reply with assistance
3. Today
4. ## How to make art like that?

That's pretty cool. When I think of vector graphics, I always thought of inkscape and illustrator. What is the advantage of using a modelling software like Blender?
5. ## GameDev Challenge : Tower Defense : 1st Video Feed Update ^_^y

It looks fantastic so far dexter! The boulder backgrounds is great and the particle effects. And having the ships flying in 3d instead of 2d brings in another dimension. Makes me think I should have some birds or something in mine!
6. ## Alpha Version

Haha yeah I don't think I've made it past level 4 either lol! Got lots of play balancing to do. There is difficulty which increases as you complete levels, I tested it on level 1 and 10. And I think it will be better with a few lives rather than just one because it is easy to miss an enemy making it through to your base. Glad that the downloads are working from dropbox. I may try and put it on itch.io when I have it more complete, someone else on here introduced me to that market and it's pretty good for indies! On the fast putting together, yes .. but .. and that is a 'big but', I cheated and used unity which does 99% of the work for you for this kind of thing. I'm also using free models and didn't spend days slaving over animation etc. It is comparing apples and oranges, I honestly wouldn't have a hope of putting something together at a lower level in this timescale (I've been working for years on my jungle game for example!).
7. ## Draw dashed line ? In modern way

If you don't wan't extra data a simple checkerboard pattern is the only thing i can think of to guarantee dashes at every angle. Found this paper: https://hal.inria.fr/hal-00907326/file/paper.pdf
8. ## How to make art like that?

The art style is known as vector art, Vector art should be a good choice for a new artist. Improving takes study and practice, not much that can be done about that. Since you probably won't be planning on learning anatomy you should draw over stuff, like this: The only tips I can give you is that vector art gets narrow near joints to make them visible. If you need animations you will need to draw over videos and you will need vector software that can do animations. Photoshop can if you have it, Blender is what I used above; took longer to find the image than to draw it. For animations you could also use 3D animations from motion capture and from animation sites, then draw 2D over that.
9. ## Raycast From Camera To Mouse Pointer

I'll give it a shot, even though my near z is 1 In the mean time, I'm constructing a camera array so there are 2 cameras to see where the hell my ray origin is going. Gonna see it as a 3D line. It's pretty hard to see it when its on ya.
10. ## Ball appears to pass through brick intermittently

That is kind of how Unity wants you to do it. A even more effective way would be to make a public GameObject variable at the top, then in the editor you drag your BrikcHolder in and reference that. What you are doing here is also OK.
11. ## Game funding questions

It's not about appeal, it is about proof. Imagine a random person walks up to you and tells you they are collecting money for a charity. However the person has no sign, no donation box or any indication that they are indeed collecting for a charity. You need to proof you are a developer, anyone can claim to be one, so that investors will take note. Then you need to proof progress of the game so that investors know that they aren't just burning money. If you don't need the money immediately then start a blog and crowd funding campaign using what you have. If you need the money immediately you will need to look for a investor that has so much money, that 15 000 is something they would just give away. PS can easily be replaced with Gimp on a indie project. Max can be replaced by Blender for 3D modelers, Blender's 3D modeling tools is on par with Max; just the absence of auto topology tools. Any 2D bone animation software like DragonBones and Spline is just 3D software with missing features. The reason people buy them is to have less clunky ness than 3D software. If you ever make a 2D game, just use Blender and you will have more features than Spline. 12. ## Ball appears to pass through brick intermittently Well I don't know what it was but I fixed it. lol. I had this set up so that the Boardmanager class was also moving the bricks. That's all this code we've been working on. Well, you mentioned just attaching the script to an instance of the brickHolder in the hierarchy. I didn't think it would be good practice to attach the Boardmanager script to it, so I removed all logic regarding brick movement and put it in a new script which got assigned to the brickHolder object. I was still having issues though because the bricks were not spawning for some reason. I finally found that if I change the Instantiation of the bricks to this: selectedPosition.AssociatedBrick = Instantiate(brick, selectedPosition.GridPosition, Quaternion.identity, GameObject.Find("BrickHolder").transform); Suddenly it worked fine! I ran it about 20 times, no errors. I test played, win and lose. Hit single and multiple explosive bricks. All looks good! And the code is much cleaner and easier to read as well! 13. ## How to make art like that? I saw a video which uses elegant and simple art at the same time which I'd love my game to look like. https://youtu.be/P5e7cl19Ha0 The art seems so simple that it looks easy, and I tried, but I have very little art skill and I can't do something as good. Is this kind of art doable by a non-art person? How can I learn to do that? How long can I improve from zero art skill to making good simple art like that? I say simple from an non-artist point of view, but is it? What kind of software do artists use to draw and animate characters like that? 14. ## Looking for People to Join Dev Team @Merlinus great, PM me your steam 15. ## Game funding questions Thank you for you answer The problem is that is the project is in a small scope and I already have a team (just plan to hire a freelancer for UI/Icons). Having the framework already done, I plan to have an early alpha in 2-3 month. Also having a lot of different artist is usually most harming for the project, as each one have his own style. that's was one of the reason of the bankruptcy of the company where I've worked, as the artistic director changed 5 times in two years, and there where periods without any person at this post. Thist is a variation of the crowdfunding thing. As the game is barely finished code-wise, and not started art-wise I have nothing appealing to show. I had this problem even with potential investors like "ok, I'm interested, show me your game images". I can't show him lines of code). I commissioned an artist to have some theoretical game pics, I'll see if it's gonna ease the thing. I'm using Unity and a framework that I've wrote my self. Don't know what the 3D artist is using. but as he's in the game industry since 10 years I suppose he's equipped. Also IMHO that's a bit controversial - that's probably true for code since most of engines are free nowadays (still, if your're lucky enough to find an ideally fitting stuff on the asset store that could be a lot of work saved). But i don't know to which point you can replace PS with Gimp or 3DSMax with Blender. I had a animator friend that complained a lot about DragonBones (Spine free version) for missing features. I'm not sure that a demo that is using grey boxes and grey floor instead of characters and environment would be appealing to people. I fear that it will even have the opposite effect. The problem here, is that is not really fitting for small projects. As the code is barely done I estimate that I could finish it in a month of full time work, then use 1-2 month for debug, playtest and integrate art. Same for art, the artist told me that he needs about 2-3 three weeks of concept, then about a month of full time to finish all the ingame 3D. As i said before we'll hire a freelancer for UI/Icons, a translator for English version and I have an compositor ready to give a helping hand and do the music for free. So it's probable that the moment when we'll have something to show = the moment we have our alpha ready, so we don't really need cash (never hurt for the release PR but far less critical then today). I've already checked that. Here (Russia) most of grants for IT/Gamedev companies are about tax and social contributions exemption. That's great for big establish companies, but don't really help to start. There is some grants given by big companies, but that's usually indie games contests, so you need at least a playable alpha. 16. ## GameDev Challenge : Tower Defense : 1st Video Feed Update ^_^y Game play revealed :-D It's a kinda PLANT Vs ZOMBIE in Space, the simpliest TD I can think of for this challenge. but hoping to expand it to a RTS in Space after this challenge ^ _^ Y The one I'm dropping in, is a "SOLAR THERMAL COLLECTOR" it's where your power comes from, to build another ship for defense/offense, it collects "20 ENERGON TUBE" ever 8 secs. The 3 Ship is just an enemy test wave that destroy all my Solar Collector, To counter it I need build offensive ships which it's not working yet LOL. The ship Collector can be upgraded to counter offense and can shoot attacking waves. 17. ## [Programmer] Looking for jobs I am an experienced Unity programmer with knowledge of C# and ShaderLab. I also know many other languages, and have experience with GameMaker, Monogame, and Unreal. I am available for the rest of the summer, and am wanting to work on a serious project with mature and dedicated individuals. I currently don't have discord access due to an error, but message me and I will give other ways we can speak. 18. ## Looking for People to Join Dev Team I am an experienced Unity programmer with knowledge of shaders and the like. I currently don't have access to discord, but ill pm you my steam. 19. ## OpenGL ES Line drawing in fragment shader I have a fullscreen sized quad, now i draw it on screen then in fragment shader i choose whenever linenis visible or not and draw it on screen (2d grid rendering) However when i zoom out lines dissapear not to mention i cant achieve one thickeness regardless of the zoom Left zoomed in right and below zoomed out https://imgur.com/a/c5cObJY And heres the shader precision highp float; uniform vec3 translation; uniform float grid_size; uniform vec3 bg_color; uniform vec3 grid_color; uniform float lthick; uniform float sw; uniform float sh; uniform float scale; varying vec3 vc; int modulo(float x, float y) { return int (x - y * float ( int (x/y))); } float modulof(float x, float y) { return x - y * float ( int (x/y) ); } void main() { bool found = false; vec2 fragcoord = vc.xy * 0.5 + 0.5; //find how much units do we have in worldspace for a halfspace vec2 sc = ( vec2(sw, sh) / 2.0 ) / scale; sc = sc * vc.xy + translation.xy; //world position int px = modulo(float (sc.x), grid_size); int py = modulo(float (sc.y), grid_size); if ( (px == 0) || (py == 0) ) found = true; if (found) gl_FragColor = vec4(grid_color, 1.0); else gl_FragColor = vec4(bg_color, 1.0); } I know that when zooming out, a fragment can not represent actual grid line. 20. Yesterday 21. ## OpenGL ES Draw dashed line ? In modern way I wonder how one could achieve that, personally i could pass another vertex data first would be actual geometric position, second would be next vertex in array. But its way too overcomplicated, ill have to build two sets of arrays so i just don't. Can't actually think of something. Something that would not force me to pass another attribute to shaders, something that wont force me to change my internal model atructure at all, By the way im drawing lines with usage of GL_LINE_LOOP Any thoughts ? 22. ## Ball appears to pass through brick intermittently You can remove this instantiate. It's a mono script so just place a object in the scene and attach that script. Dragging a object into the editor is the same as using instantiate. The only time you want to call instantiate is to make a clone of something. Doesn't look like this is it either. Can you post the full error? Post it as a spoiler by using the eye icon in the forum editor here. It's right next to the code <> icon. 23. ## How to improve FLEE in RPG videogames ?? frustration of random fails would be greatly reduced if you animate it in some way to reflect the rng rolls. Have character move half off screen or fully or whathaveyou. Thus they can see the difference between "Oh darn! I almost got away." and "Dang, didn't even make it a step" and thus base some of their strategy on that without knowing the nitty gritty of creature stats. 24. ## checkers If you're able to upload your entire source code (make sure I can compile and run it) I can look into this more to better explain a solution. 25. ## Alpha Version I only had enough time to play up to Level 4, but wow this is a very good! I'm shocked how fast you put all this together. Very good job! I'll play more this weekend and post back. Keep up the great work. 26. ## Ball appears to pass through brick intermittently The brick holder is just a prefab of an empty gameobject with nothing but a transform and a rigidbody on it. I instantiate it here: public GameObject brickHolder; void Awake () { brickHolder = Instantiate(brickHolder, Vector3.zero,Quaternion.identity) as GameObject; } I move it here: void Update () { brickHolder.transform.position = Vector3.MoveTowards(brickHolder.transform.position, target.transform.position , speed * Time.deltaTime); } And the only other place it is mentioned in code is here, where the bricks get instantiated: //LayoutObjectAtRandom accepts an array of game objects to choose from along with a minimum and maximum range for the number of objects to create. void LayoutObjectAtRandom (int brickCount) { bricks.Add(oneHitBrick); bricks.Add(twoHitBrick); bricks.Add(threeHitBrick); bricks.Add(explodingBarrel); //Instantiate objects until the randomly chosen limit objectCount is reached for(int i = 0; i < brickCount; i++) { //Choose a position for randomPosition by getting a random position from our list of available Vector3s stored in gridPosition GridSquare selectedPosition = RandomPosition(); GameObject brick = bricks[Random.Range(0,bricks.Count)]; //Instantiate tileChoice at the position returned by RandomPosition with no change in rotation selectedPosition.AssociatedBrick = Instantiate(brick, selectedPosition.GridPosition, Quaternion.identity, brickHolder.transform); } } 27. ## jumping animation Hi guys, so im developing a game using GMS2, following shaun spalding tutorials from youtube, my problem is that he explains only the basics on the mechanics, and since i have almost 0 knowledge in code, i cannot derail far from what he writes.. the main issue that i have now is developing the character animation; i want to make a jump, something like: impulse, ascending, descending, landing and also some smooth transition between ascencion and descent. now, in the way he wrote the code i get as follows: // animation if (!place_meeting(x,y+1,oWall)) { sprite_index = sPlayerA; image_speed = 0; if (sign(vsp) > 0) image_index = 1; else image_index = 0; } oWall is my collision object, sPlayerA is my jump sprite with two frames on it. that gives me a basic and solid jump, but i feel like its too static.... Any ideas on how to write something to get a nice smooth jump with more than just two frames? i'm aiming at four or five frames total. thanks in advance, here's a screenshot of the work in progress: 28. ## What goes into a "Transform" structure in C/C++? Thank you for such incredibly helpful replies! It makes sense to have a transform in the rendering engine to describe all general transforms that applies to your game objects (and other objects too) in one neat container. In hindsight it seem quite self-explanatory. Why Jason Gregory have it in their debug code in the AddAxis method also make sense: you'd put a set of axis in the world after it's been transformed -- if the axis don't end up where you want probably means you got something wrong somewhere. Many thanks again! Learning game programming has been an exhilarating, albeit somewhat painful experience Fred ## Members You Follow #### You must be logged in to view this content. Don't have a GameDev.net account? Sign Up ## Popular Entries ## Recent Blogs 1. Wazzup peepz! need some update for entry on GameDev Challenge : Tower Defense WHAT's NEW : ATMOSPHERE : Dust clouds scrolling Asteroids scrolling CAMERA CONTROL : Mouse : Left mouse : Dragging of Ship/Items Right Hold : left right : Rotate by mouse clockwise or counter clockwise Right Hold : Up down : Panning by mouse Scroll mouse : Zoom-in and Zoom-Out Keyboard equivalent : Left handed : A-D : Rotate clockwise or counter clockwise W-S : Room in - out Q-E : Pan in - out Right handed : <- -> : Rotate clockwise or counter clockwise ^ V : Zoom in - out Pup PDn : Pan in - out SHIP TRIALS : Finally my trail engine is now always facing the camera on every angle ^ _^ Y That's all folks for now busy on the day job to focus on this challenge. very slow progress... T __T 3 comments 2. In the spirit of release early and often I have a playable alpha version of my challenge entry. I am not quite sure where is reliable to upload to so I have been trying dropbox which I've had issues with in the past, fingers crossed these links might work, please let me know if the links work / it installs and runs. The zip file is about 30-40 megs and doesn't require any installation, and is typical unity fare. Linux 64 bit: https://www.dropbox.com/s/fmjzmi249a3otph/TowerD_010_Linux_x86_64.zip?dl=0 Windows 32 bit: https://www.dropbox.com/s/i7bxe1pub56rpc4/TowerD_010_win32.zip?dl=0 I've been developing on linux but just tested the windows version on my ancient laptop and it seems to work. Very much a test version, I need to put in credits for things like the music and assets (need to work out how to do scrolling credits). Instructions When you start choose new game. You start with a certain amount of cash, and enemies start appearing in waves. You must build towers to destroy them before they destroy your base. Click one of the 3 tower types to select it for building, then click on a location that comes up gray to build. Each tower will cost you money to build and to repair. You get cash when you kill enemies and on completing level. The enemies will move down the path towards your base but will also attack towers. If a tower is destroyed you can click on it to repair. The enemies go so close to towers when attacking they cannot defend themselves so you often have to build towers in pairs (this was more by accident than design lol). Cameras There are currently 3 camera types, and you can toggle between them by clicking the magnify glass icon. Overview shows the whole map from above, area mode tries to show the area where the action is taking place, and follow cam will follow the enemy of your choosing closeup. You can select which enemy to follow by clicking close to it on the path. The path the enemies follow is darker than the rest of the terrain. You can't build on the path, or on squares that have buildings or other props on them (these will indicate red). This means you have to be strategic about where to build towers. There's still quite a bit I intend to add, like multiple lives, high score table, balance the difficulty as you progress, more towers / enemies. 2 comments 3. Egypt: Old Kingdom is now available on Steam for Windows, MacOS, and Linux. About the game: Strategy simulator of the Great Pyramids construction period, where you take your path from the unification of Egyptian tribes to the foundation of The First Empire. Deep historical research and stylized graphics - these two are the main features of Egypt Old Kingdom, the game made by Clarus Victoria Studio in cooperation with egyptologists from CESRAS (Center for Egyptological Studies of the Russian Academy of Science). The player will lead a small group of Egyptians, who came to the Lower Egypt to found a new settlement. All he has is a minimal stock of food, a handful of people and a few soldiers as a protection from threats and wild animals. As player will advance from the foundation of Memphis to the building of the first Empire, he will realize that the great achievements of Egypt were possible without UFO or Atlantians interference. He'll find out how did Ancient Egypt kingdom function, what role has religion had, why common people were ready to labor in order to build all these temples and tombs. The player will have to overcome same difficulties as ancient Egyptians - droughts, fires, earthquakes, or enemies waiting for a good moment to strike. He will learn eventually what ruined the first ever empire and discover the facts which cannot be found in any book. The game was created with the support of CES RAS scientists. They are true explorers, who study Egyptian history in the field, organizing annual expeditions to Egypt to dig oit more knowledges in Giza, Memphis, Alexandria and other places. About developers: CES RAS - established in 1999, the Center has a subdivision in Cairo, which is a sience base for a field work in Egypt. The main goal of the Center is to carry out complex scientific research in the fields of history, culture, languages and religion of ancient, medieval, and modern Egypt. The research is based on study of the literary sources and the data yielded in the course of CESRAS' archaeological field projects. Clarus Victoria - independent developers of vcomputer games, established in 2013. The depth and versatility of their games is based on a reliable historical data. Our stuff is learning and improving with every project. At the moment, we have 3 complete games which were warmly welcomed by the players around the world. For more information please visit: clarusvictoria.com Our communities: VK: https://vk.com/precivilization FB: https://www.facebook.com/precivilization/ Twitter: https://twitter.com/ClarusVictoria Website: http://clarusvictoria.com/ 0 comments 4. So it’s been just over a month since my last update, and what a month! I’ve spent a bunch of time travelling, busy with work, and various other stuff. But it’s been great fun to squeeze in some time for Greyvar in the evenings when I can. I even set about creating a couple of new textures on a plane, just to sqeeze so time in, working mostly on some indoor assets; But I wanted to take most of the time in this update to talk about the map editor. Funnily enough, the map editor is something I started years and years ago, when I just wanted to have a fiddle with tile-based map editing. It grew and grew, and is largely became a reason for me making Greyvar in the first place. Here’s what the map editor looks like today, showing one of the debug maps I use to check for texture alignment, and trying to get the right perspective on textures too; As you can see, it’s a desktop based Java application. You can create individual maps (“grids”) in it, and I recently added support for “worlds” - which are many grids connected to each other. Making these grids is point and click, selecting textures from the texture viewer (below), and painting them much like you would do with pixel art. The editor is pretty functional today for making grids, but where it needs to go in the future is; Support for multiple “layers” - at the moment it can paint the background, but it should have support for; Background Layer Entity Layer (enemies, players, pickups, etc) Fluid Layer (water, lava, slime, etc) Writing grids as Yaml files. At the moment the grids are CSV files. It was OK to start off with, but really I need a file format with more structure today. Support for editing other areas of the game - rules, triggers, that sort of thing. Over the next month or so, I’ll continue to work on Yaml save support for the maps, and then Yaml loading on the server side (eugh, all the fun stuff!). Once that is done, it’s back to Multiplayer support and some polish on the input handling side. Then we can start working on basic game mechanics - that’s the fun stuff! 0 comments 5. Majong is a сhinese board games. Mahjong — one of the most popular games in the world. If you were looking for puzzle games and mahjong solitaire, then you are in the right place! Mahjong: Magic Chips — is a real brain training & sweet puzzle! Over 200 colorful levels and 10 different worlds are waiting for you! Collect all skins of chips and beautiful backgrounds from each Chapter! You can use them in free mode to fully customize the game to your taste. The rules of a puzzle games for adults and kids are pretty simple — you need to look for the same pictures on the tiles and remove this pairs from the game board. Once all pairs of tiles are removed, the level will be completed. Also you will meet the levels where there will be a timer — here you have to hurry to clear the game board for a certain time. Solitaire mahjong is both training of attention and real gymnastics for the mind. The simplest rules of the puzzle and the measured course of the game will allow you to relax after a hard day's work or pass the time on the bus or metro. The game is also known as mahjong king, mahjong shanghai or mahjong classic. Download mahjong games free and become a Mahjong Master of board game! Game Features: Mahjong solitaire free Over 200 colorful levels Collection of chips and backgrounds 4 different hints Pleasant sounds and melodious music Amazing quests and game modes Training mind and attention Download: Google Play App Store 0 comments By dovodi 6. I wanna thank everyone who helped me out with my last question, but now I got something possibly bigger than the last one. I just wanna know, how do you guys earn money while making your games to? Do you work a full time job and work on the game at the same time? Cause I gotta say, my full time job is awful, leaving me pretty much drained to the point I really can't do much of anything. So, I've been trying to figure out ways to earn money and work on a game at the same time. Cause I have a school debt to pay off, and now a car payment, so I can't not be working. I can't work at my current job any more for personal reasons. So I'm hoping I can get the help I'm looking for. 4 comments 7. Tomorrow, May 25th, the European Union’s General Data Protection Regulation (GDPR) becomes legally enforceable. Basically, for app users in the EU, you have to allow them to choose if you can collect private data on them. While you might not personally be collecting information, the services you are using may. Prior to daily build 2018.3286, Corona has collected users’ IP addresses, the iOS ID for Vendors, and the Android equivalent. Starting with 2018.3286 and later, the data we collect does not contain any personally identifiable data. Regardless, you need to either update your apps to ask for permission to collect data (if you need to use an older version of Corona) or build with a newer version since we don’t collect data that you need to get permission for. Our friends at Appodeal have produced another great Q&A on how they are handling GDPR and things you need to do to meet the requirements. It’s worth looking over these questions and answers to help you understand what you need to do. View the full article 1 comments 8. Hi, Please help us to decide if our current project is cool and interesting enough. If so we will finalise it. If not we will made demo of other comncept. So add to Wishlist if you like it and would like to play someday Video of Psycho Wolf demo: Reveal Trailer Steam Page: https://store.steampowered.com/app/867690/Psycho_Wolf/ Thanks ! 0 comments By ATM 9. Hi everybody, i'm ready to announce that Xilvan Design build games since 1993: Lights of Dreams IV v7.97. Candy World II v8.37. Candy Racing Cup v2.75. Candy World Adventures v5.37. Candy to the Rescue IV v5.97. Candy's Space Adventures v15.75. Candy's Space Mysteries II v6.27. Two updates since last edit: - Enhanced the Space, Missions & Sceneries in Candy's Space Adventures. - Verified bonus, options, maps & more tricks in Candy's Space Mysteries II. - Reverified all of our old games like Candy World II, Candy to the Rescue IV, Candy World Adventures IV. - I Adjusted the level Selector in Candy World Adventures IV v5.37. - I added a starfield in Candy World Adventures IV. - Maybe a Candy in Space III quest will be available soon. - We are planning Lights of Dreams V. - We are actually debuging all of our games since now then. They are available for download on my website: - Xilvan Design Websites - One new link are now available: a OneDrive link. But, there is still a Google Drive & old CNET.download.com link. Hope you'll appreciate ! If you want to watch the videos of our games: - My youtube Channel - Please, Subscribe to my channel for more infos about our new releases. Friendly, Xylvan, Xilvan Design. 2 comments By Xylvan 10. The Map System I've been subconsciously dreading has finally been implemented and the rest of the menus are coming together bit-by-bit as I program all the pieces separately and connect them together (instead of cramming everything I could into one giant, unreadable script like before). The results? See the latest gamedev update to find out. 0 comments ## Latest Forum Topics ## Latest News 1. WILD WEST Bandit for FUSE The pack contains the following Clothing items, that you can easily alter the material type, substance, and colour. Check out the Promo Pics on this product page, which depicts the clothing. The Pack contains: Hat Scarf Sweater Belt Trousers Trouser Over ChestBelt Pack is already imported and set up in fuse - simply follow the easy instructions and a scene is provided that shows the Avatar in FUSE, with the full costume assembled. Purchase for just14 from the below Arteria3d website link   WildWest Bandit – arteria3d
By arteria
3. Shuhei Yoshida, President of Sony Interactive Entertainment Worldwide Studios, has today been announced as the opening keynote speaker for this year’s Develop:Brighton conference and expo at the Hilton Brighton Metropole in July. Yoshida will also be awarded the Legend Award at the Develop Awards, organised by Future Publishing, on the evening of Wednesday 11 July. A 25-year veteran of the games industry, Shuhei Yoshida is a renowned software developer having been part of PlayStation®’s immense and sustained success since its inception more than 20 years ago. As part of the new three-day format, Yoshida will open Develop:Brighton on Tuesday 10 July with a fireside chat where he will share his perspective on a long and celebrated career from his start at Sony in the 1980s to joining the original PlayStation team two years ahead of its launch and overseeing the development of global best-selling franchises including God of War®, Grand Turismo®, The Last of Us™ and Uncharted™. As well as a look back, during the keynote Yoshida will also talk about the mission of managing the worldwide studios and share his insight on Sony’s current success. “We are delighted to welcome Shuhei Yoshida to Brighton this summer,” commented Andy Lane, managing director of Develop:Brighton organisers, Tandem Events. “Shuhei has a wealth of experience in developing world-renowned games and overseeing top class development studios which is hard to match. Looking back over his 20 years in games development, our delegates will have a fantastic opportunity to hear about the lessons learnt in forging a successful career from a man who was at the birth of the PlayStation and his insights into Sony’s current successes. I can’t think of anyone better to open this year’s conference.” Develop:Brighton, Europe’s leading game developer conference and expo, will consist of eight tracks: Design; Art; Audio; Business; Coding; Evolve; Indie and Discoverability across a new three day format with the expo open on Wednesday and Thursday. Other sessions already announced include: [KEYNOTE] The Future of AI in Games Creation
Chet Faliszek, Bossa Studios [BUSINESS] Five Stars – The Best Video Games of 2018 (so far)
Jordan Erica Webber, Games Journalist [BUSINESS] Cryptocurrency in Gaming: Today and Tomorrow
Alex Amsel, Fig [DISCOVERABILITY] Community Management in the Memeverse
Grace Carroll, Creative Assembly [DISCOVERABILITY] Your Game Isn’t Going to Sell. Let’s See What We Can Do About That
Mike Rose, No More Robots [EVOLVE] Artificial Stupidity to Killer Robots: The Evolution of AI
Ian Shaw, Games Technology Consulting [EVOLVE] VR and Disability: An Overdue Love Story
Paolo Torelli, Programmer and UX Expert [INDIE] Do Switch Quick, Get Rich Quick?
Tony Gowland, Ant Workshop [INDIE] What To Do When That One Big Deal, Doesn’t Turn Into The Next Big Deal
Aj Grand Scrutton, Dlala Studios [CODING] AI In Your Pocket: Character-Based Conversational Sims
Mitu Khandaker, Spirit AI [CODING] Enhancing Your Game’s AI Using Unity Machine Learning Agents
Alessia Nigretti, Unity Technologies [DESIGN] Design Workshop: Advanced Paper Prototyping
Dr. Mata Haggis-Burridge, NHTV [DESIGN] Leveraging Culturalisation for Building Better Game Worlds
Kate Edwards, Geogrify [AUDIO] Challenging Videogame Music Troops
Olivier Deriviere & James Hannigan, Composers [AUDIO] Horizon Zero Dawn™ – Dealing with Scope and Scale in a Brand New Open World
Bastian Seelbach, Guerrilla Games [ART] Solving an Invisible Problem: Designing for Colour-Blindness
Douglas Pennant, Creative Assembly [ART] Physically Based Workflows Explained
Claudia Doppioslash, Contafoe Registration is live for Develop:Brighton, with Early Bird tickets on sale until 6 June at www.developconference.com.
By khawk
4. bs::framework is a newly released, free and open-source C++ game development framework. It aims to provide a modern C++14 API & codebase, focus on high-end technologies comparable to commercial engine offerings and a highly optimized core capable of running demanding projects. Additionally it aims to offer a clean, simple architecture with lightweight implementations that allow the framework to be easily enhanced with new features and therefore be ready for future growth. Some of the currently available features include a physically based renderer based on Vulkan, DirectX and OpenGL, unified shading language, systems for animation, audio, GUI, physics, scripting, heavily multi-threaded core, full API documentation + user manuals, support for Windows, Linux and macOS and more. The next few updates are focusing on adding support for scripting languages like C#, Python and Lua, further enhancing the rendering fidelity and adding sub-systems for particle and terrain rendering. A complete editor based on the framework is also in development, currently available in pre-alpha stage. You can find out more information on www.bsframework.io.
5. CGTrader’s birthday sale is on May 22-29 with over 250,000 3D models (for games, VR, architecture and 3D printing) going on sale for up to 50% off. 3D artists are giving discounts to celebrate the 7th birthday of the marketplace that has the fairest conditions for designers worldwide. Here’s a link to the sale page - https://www.cgtrader.com/sale
By khawk
7. The EnhanceMyApp podcast is back with a brand new episode. Joined by David Hu, Director of User Acquisition for NCSOFT, the podcast discusses how to obtain new users on a budget and properly analyze user acquisition data to create a monetization strategy for your mobile app. Check out the EnhanceMyApp Podcast here.
8. Final Lens Effects package is now available on the Unity Asset Store. A free Demo (full-featured) is available for download.

About Final Lens Effects The Final Lens Effects package is a collection of image effects for simulating some properties of real camera lens such as depth of field, vignetting and distortion for Unity 5 (5.6 or higher). Package contains following effects: - Depth of field effect with polygonal aperture (Bokeh)
- Bloom effect
- Vignetting
- Chromatic aberrations
- Lens distortion
- Tone Mapping (ACES)
- Color LUTs Support

These effects can be used to make your scenes look closer to as if they were captured with real camera and lens - making computer generated graphics look more natural or to achieve the "cinematic look" for cut scenes or in-game. Being very tweakable, the effects can be combined, reordered, customized and overdone to create interesting looks or visual effects.
By khawk
10. Amazon announced Sumerian at AWS re:Invent 2017 but today announced its availability to developers. Sumerian is a web-based visual editor that allows creators to develop 2D, 3D, and VR experiences without having to master specialized tools.  Experiences can be deployed across multiple platforms without having to write custom code or worry about deployment systems. From the announcement: Learn more from the Amazon blog here.
By khawk

• Action
• Casual
• Puzzle
• Other
• Library/API
• Action
• Role Playing
• Puzzle
• Action
• Role Playing
• Action
• Other
• Puzzle
• Casual
• Strategy
• Action
• Simulation
• Action
• Action
• Strategy
• Casual

## Recent Articles and Tutorials

1. This is an excerpt from the book, Mastering C++ Game Development written by Mickey Macdonald and published by Packt Publishing. With this book, learn high-end game development with advanced C++ 17 programming techniques. One of the most common uses for shaders is creating lighting and reflection effects. Lighting effects achieved from the use of shaders help provide a level of polish and detail that every modern game strives for. In this post, we will look at some of the well-known models for creating different surface appearance effects, with examples of shaders you can implement to replicate the discussed lighting effect. Per-vertex diffuse To start with, we will look at one of the simpler lighting vertex shaders, the diffuse reflection shader. Diffuse is considered simple since we assume that the surface we are rendering appears to scatter the light in all directions equally. With this shader, the light makes contact with the surface and slightly penetrates before being cast back out in all directions. This means that some of the light's wavelength will be at least partially absorbed. A good example of what a diffuse shader looks like is to think of matte paint. The surface has a very dull look with no shine. Let's take a quick look at the mathematical model for a diffuse reflection. This reflection model takes two vectors. One is the direction of the surface contact point to the initial light source, and the second is the normal vector of that same surface contact point. This would look something like the following: It's worth noting that the amount of light that strikes the surface is partially dependent on the surface in relation to the light source and that the amount of light that reaches a single point will be at its maximum along the normal vector, and its lowest when perpendicular to the normal vector. Dusting off our physics knowledge toolbox, we are able to express this relationship given the amount of light making contact with a point by calculating the dot product of the point normal vector and incoming light vector. This can be expressed by the following formula: Light Density(Source Vector) Normal Vector $$LightDensity = Source Vector * Normal Vector$$$$Light Density = SourceVector \cdot NormalVector$$ The source and normal vector in this equation are assumed to be normalized. As mentioned before, some of the light striking the surface will be absorbed before it is re-cast. To add this behavior to our mathematical model, we can add a reflection coefficient, also referred to as the diffuse reflectivity. This coefficient value becomes the scaling factor for the incoming light. Our new formula to specify the outgoing intensity of the light will now look like the following: Outgoing Light = (Diffuse Coefficient x Light Density x Source Vector) Normal Vector $$Outgoing Light = (Diffuse Coefficient x Light Density x Source Vector) \cdot Normal Vector$$ With this new formula, we now have a lighting model that represents an omnidirectional, uniform scattering. OK, now that we know the theory, let's take a look at how we can implement this lighting model in a GLSL shader. The full source for this example can be found in the Chapter07 folder of the GitHub repository, starting with the Vertex Shader shown as follows: #version 410 in vec3 vertexPosition_modelspace; in vec2 vertexUV; in vec3 vertexNormal; out vec2 UV; out vec3 LightIntensity; uniform vec4 LightPosition; uniform vec3 DiffuseCoefficient ; uniform vec3 LightSourceIntensity; uniform mat4 ModelViewProjection; uniform mat3 NormalMatrix; uniform mat4 ModelViewMatrix; uniform mat4 ProjectionMatrix; void main() { vec3 tnorm = normalize(NormalMatrix * vertexNormal); vec4 CameraCoords = ModelViewMatrix * vec4(vertexPosition_modelspace,1.0); vec3 IncomingLightDirection = normalize(vec3(LightPosition - CameraCoords)); LightIntensity = LightSourceIntensity * DiffuseCoefficient * max( dot( IncomingLightDirection, tnorm ), 0.0 ); gl_Position = ModelViewProjection * vec4(vertexPosition_modelspace,1); UV = vertexUV; } We'll go through this shader block by block. To start out, we have our attributes, vertexPosition_modelspace, vertexUV, and vertexNormal. These will be set by our game application, which we will look at after we go through the shader. Then we have our out variables, UV and LightIntensity. These values will be calculated in the shader itself. We then have our uniforms. These include the needed values for our reflection calculation, as we discussed. It also includes all the necessary matrices. Like the attributes, these uniform values will be set via our game. Inside of the main function of this shader, our diffuse reflection is going to be calculated in the camera relative coordinates. To accomplish this, we first normalize the vertex normal by multiplying it by the normal matrix and storing the results in a vector 3 variable named tnorm. Next, we convert the vertex position that is currently in model space to camera coordinates by transforming it with the model view matrix. We then calculate the incoming light direction, normalized, by subtracting the vertex position in the camera coordinates from the light's position. Next, we calculate the outgoing light intensity by using the formula we went through earlier. A point to note here is the use of the max function. This is a situation when the light direction is greater than 90 degrees, as in the light is coming from inside the object. Since in our case we don't need to support this situation, we just use a value of 0.0 when this arises. To close out the shader, we store the model view projection matrix, calculated in clip space, in the built-in outbound variable gl_position. We also pass along the UV of the texture, unchanged, which we are not actually using in this example. Now that we have the shader in place, we need to provide the values needed for the calculations. We do this by setting the attributes and uniforms. We built an abstraction layer to help with this process, so let's take a look at how we set these values in our game code. Inside the GamePlayScreen.cpp file, we are setting these values in the Draw() function. I should point out this is for the example, and in a production environment, you would only want to set the changing values in a loop for performance reasons. Since this is an example, I wanted to make it slightly easier to follow: GLint DiffuseCoefficient = shaderManager.GetUniformLocation("DiffuseCoefficient "); glUniform3f(DiffuseCoefficient, 0.9f, 0.5f, 0.3f); GLint LightSourceIntensity = shaderManager.GetUniformLocation("LightSourceIntensity "); glUniform3f(LightSourceIntensity, 1.0f, 1.0f, 1.0f); glm::vec4 lightPos = m_camera.GetView() * glm::vec4(5.0f, 5.0f, 2.0f, 1.0f); GLint lightPosUniform = shaderManager.GetUniformLocation("LightPosition"); glUniform4f(lightPosUniform, lightPos[0], lightPos[1], lightPos[2], lightPos[3]); glm::mat4 modelView = m_camera.GetView() * glm::mat4(1.0f); GLint modelViewUniform = shaderManager.GetUniformLocation("ModelViewMatrix"); glUniformMatrix4fv(modelViewUniform, 1, GL_FALSE, &modelView[0][0]); glm::mat3 normalMatrix = glm::mat3(glm::vec3(modelView[0]), glm::vec3(modelView[1]), glm::vec3(modelView[2])); GLint normalMatrixUniform = shaderManager.GetUniformLocation("NormalMatrix"); glUniformMatrix3fv(normalMatrixUniform, 1, GL_FALSE, &normalMatrix[0][0]); glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &m_camera.GetMVPMatrix()[0][0]); I won't go through each line since I am sure you can see the pattern. We first use the shader manager's GetUniformLocation() method to return the location for the uniform. Next, we set the value for this uniform using the OpenGL glUniform*() method that matches the value type. We do this for all uniform values needed. We also have to set our attributes, and as discussed in the beginning of the chapter, we do this in between the compilation and linking processes. In this example case, we are setting these values in the OnEntry() method of the GamePlayScreen() class: shaderManager.AddAttribute("vertexPosition_modelspace"); shaderManager.AddAttribute("vertexColor"); shaderManager.AddAttribute("vertexNormal"); That takes care of the vertex shader and passed in values needed, so next, let's look at the fragment shader for this example: #version 410 in vec2 UV; in vec3 LightIntensity; // Ouput data out vec3 color; // Values that stay constant for the whole mesh. uniform sampler2D TextureSampler; void main() {  color = vec3(LightIntensity); } For this example, our fragment shader is extremely simple. To begin, we have the in values for our UV and LightIntensity, and we will only use the LightIntensity this time. We then declare our out color value, specified as a vector 3. Next, we have the sampler2D uniform that we use for texturing, but again we won't be using this value in the example. Finally, we have the main function. This is where we set the final output color by simply passing the LightIntensity through to the next stage in the pipeline. If you run the example project, you will see the diffuse reflection in action. The output should look like the following screenshot. As you can see, this reflection model works well for surfaces that are very dull but has limited use in a practical environment. Next, we will look at a reflection model that will allow us to depict more surface types:   Per-vertex ambient, diffuse, and specular The ambient, diffuse, and specular (ADS) reflection model, also commonly known as the Phong reflection model, provides a method of creating a reflective lighting shader. This technique models the interaction of light on a surface using a combination of three different components. The ambient component models the light that comes from the environment; this is intended to model what would happen if the light was reflected many times, where it appears as though it is emanating from everywhere. The diffuse component, which we modeled in our previous example, represents an omnidirectional reflection. The last component, the specular component, is meant to represent the reflection in a preferred direction, providing the appearance of a light glare or bright spot. This combination of components can be visualized using the following diagram: Source: Wikipedia This process can be broken down into separate components for discussion. First, we have the ambient component that represents the light that will illuminate all of the surfaces equally and reflect uniformly in all directions. This lighting effect does not depend on the incoming or the outgoing vectors of the light since it is uniformly distributed and can be expressed by simply multiplying the light source's intensity with the surface reflectivity. This is shown in the mathematical formula Ia = LaKa The next component is the diffuse component we discussed earlier. The diffuse component models a dull or rough surface that scatters light in all directions. Again, this can be expressed with the mathematical formula Id = LdKd(sn) The final component is the specular component, and it is used to model the shininess of the surface. This creates a glare or bright spot that is common on surfaces that exhibit glossy properties. We can visualize this reflection effect using the following diagram: For the specular component, ideally, we would like the reflection to be at is most apparent when viewed aligned with the reflection vector, and then to fade off as the angle is increased or decreased from this alignment. We can model this effect using the cosine of the angle between our viewing vector and the reflection angle, which is then raised by some power, as shown in this equation: (r v) p. In this equation, p represents the specular highlight, the glare spot. The larger the value input for p, the smaller the spot will appear, and the shinier the surface will look. After adding the values to represent the reflectiveness of the surface and the specular light intensity, the formula for calculating the specular effect for the surface looks like so: Is = LsKs(r v) p So, now, if we take all of our components and put them together in a formula, we come up with I = Ia + Id + Is or breaking it down more, I = LaKa + LdKd(sn) + LsKs(r v) p With our theory in place, let's see how we can implement this in a per-vertex shader, beginning with our vertex shader as follows: #version 410 // Input vertex data, different for all executions of this shader. in vec3 vertexPosition_modelspace; in vec2 vertexUV; in vec3 vertexNormal; // Output data ; will be interpolated for each fragment. out vec2 UV; out vec3 LightIntensity; struct LightInfo {  vec4 Position; // Light position in eye coords.  vec3 La; // Ambient light intensity  vec3 Ld; // Diffuse light intensity  vec3 Ls; // Specular light intensity }; uniform LightInfo Light; struct MaterialInfo {  vec3 Ka; // Ambient reflectivity  vec3 Kd; // Diffuse reflectivity  vec3 Ks; // Specular reflectivity  float Shininess; // Specular shininess factor };  uniform MaterialInfo Material;  uniform mat4 ModelViewMatrix;  uniform mat3 NormalMatrix;  uniform mat4 ProjectionMatrix;  uniform mat4 ModelViewProjection;  void main() {     vec3 tnorm = normalize( NormalMatrix * vertexNormal);     vec4 CameraCoords = ModelViewMatrix * vec4(vertexPosition_modelspace,1.0);     vec3 s = normalize(vec3(Light.Position - CameraCoords));     vec3 v = normalize(-CameraCoords.xyz);     vec3 r = reflect( -s, tnorm );     float sDotN = max( dot(s,tnorm), 0.0 );     vec3 ambient = Light.La * Material.Ka;     vec3 diffuse = Light.Ld * Material.Kd * sDotN;     vec3 spec = vec3(0.0);     if( sDotN > 0.0 )      spec = Light.Ls * Material.Ks * pow( max( dot(r,v), 0.0 ), Material.Shininess );     LightIntensity = ambient + diffuse + spec;     gl_Position = ModelViewProjection * vec4(vertexPosition_modelspace,1.0); } Let's take a look at what is different to start with. In this shader, we are introducing a new concept, the uniform struct. We are declaring two struct, one to describe the light, LightInfo, and one to describe the material, MaterialInfo. This is a very useful way of containing values that represent a portion in the formula as a collection. We will see how we can set the values of these struct elements from the game code shortly. Moving on to the main function of the function. First, we start as we did in the previous example. We calculate the tnorm, CameraCoords, and the light source vector(s). Next, we calculate the vector in the direction of the viewer/camera (v), which is the negative of the normalized CameraCoords. We then calculate the direction of the pure reflection using the provided GLSL method, reflect. Then we move on to calculating the values of our three components. The ambient is calculated by multiplying the light ambient intensity and the surface's ambient reflective value. The diffuse is calculated using the light intensity, the surface diffuse reflective value of the surface, and the result of the dot product of the light source vector and the tnorm, which we calculated just before the ambient value. Before computing the specular value, we check the value of sDotN. If sDotN is zero, then there is no light reaching the surface, so there is no point in computing the specular component. If sDotN is greater than zero, we compute the specular component. As in the previous example, we use a GLSL method to limit the range of values of the dot product to between 1 and 0. The GLSL function pow raises the dot product to the power of the surface's shininess exponent, which we defined as p in our shader equation previously. Finally, we add all three of our component values together and pass their sum to the fragment shader in the form of the out variable, LightIntensity. We end by transforming the vertex position to clip space and passing it off to the next stage by assigning it to the gl_Position variable. For the setting of the attributes and uniforms needed for our shader, we handle the process just as we did in the previous example. The main difference here is that we need to specify the elements of the struct we are assigning when getting the uniform location. An example would look similar to the following, and again you can see the full code in the example solution in the Chapter07 folder of the GitHub repository:   GLint Kd = shaderManager.GetUniformLocation("Material.Kd"); glUniform3f(Kd, 0.9f, 0.5f, 0.3f);   The fragment shader used for this example is the same as the one we used for the diffuse example, so I won't cover it again here. When you run the ADS example from the Chapter07 code solution of the GitHub repository, you will see our newly created shader in effect, with an output looking similar to the following: In this example, we calculated the shading equation within the vertex shader; this is referred to as a per-vertex shader. One issue that can arise from this approach is that our glare spots, the specular highlights, might appear to warp or disappear. This is caused by the shading being interpolated and not calculated for each point across the face. For example, a spot that was set near the middle of the face might not appear due to the fact that the equation was calculated at the vertices where the specular component was near to zero. You enjoyed an excerpt from the book, Mastering C++ Game Development written by Mickey Macdonald and published by Packt Publishing. Use the code ORGDB10 at checkout to get recommended eBook retail price for 10 only until May 31, 2018. 0 comments By khawk 2. Automated builds are a pretty important tool in a game developer's toolbox. If you're only testing your Unreal-based game in the editor (even in standalone mode), you're in for a rude awakening when new bugs pop up in a shipping build that you've never encountered before. You also don't want to manually package your game from the editor every time you want to test said shipping build, or to distribute it to your testers (or Steam for that matter). Unreal already provides a pretty robust build system, and it's very easy to use it in combination with build automation tools. My build system of choice is Gradle , since I use it pretty extensively in my backend Java and Scala work. It's pretty easy to learn, runs everywhere, and gives you a lot of powerful functionality right out of the gate. This won't be a Gradle tutorial necessarily, so you can familiarize yourself with how Gradle works via the documentation on their site. Primarily, I use Gradle to manage a version file in my game's Git repository, which is compiled into the game so that I have version information in Blueprint and C++ logic. I use that version to prevent out-of-date clients from connecting to newer servers, and having the version compiled in makes it a little more difficult for malicious clients to spoof that build number, as opposed to having it stored in one of the INI files. I also use Gradle to automate uploading my client build to Steam via the use of steamcmd. Unreal's command line build tool is known as the Unreal Automation Tool. Any time you package from the editor, or use the Unreal Frontend Tool, you're using UAT on the back end. Epic provides handy scripts in the Engine/Build/BatchFiles directory to make use of UAT from the command line, namely RunUAT.bat. Since it's just a batch file, I can call it from a Gradle build script very easily. Here's the Gradle task snippet I use to package and archive my client: task packageClientUAT(type: Exec) { workingDir = "[UnrealEngineDir]\\Engine\\Build\\BatchFiles" def projectDirSafe = project.projectDir.toString().replaceAll(/[\\]/) { m -> "\\\\" } def archiveDir = projectDirSafe + "\\\\Archive\\\\Client" def archiveDirFile = new File(archiveDir) if(!archiveDirFile.exists() && !archiveDirFile.mkdirs()) { throw new Exception("Could not create client archive directory.") } if(!new File(archiveDir + "\\\\WindowsClient").deleteDir()) { throw new Exception("Could not delete final client directory.") } commandLine "cmd", "/c", "RunUAT", "BuildCookRun", "-project=\"" + projectDirSafe + "\\\\[ProjectName].uproject\"", "-noP4", "-platform=Win64", "-clientconfig=Development", "-serverconfig=Development", "-cook", "-allmaps", "-build", "-stage", "-pak", "-archive", "-noeditor", "-archivedirectory=\"" + archiveDir + "\"" } My build.gradle file is in my project's directory, alongside the uproject file. This snippet will spit the packaged client out into [ProjectDir]\Archive\Client. For the versioning, I have two files that Gradle directly modifies. The first, a simple text file, just has a number in it. In my [ProjectName]\Source\[ProjectName] folder, I have a [ProjectName]Build.txt file with the current build number in it. Additionally, in that same folder, I have a C++ header file with the following in it: #pragma once #define [PROJECT]_MAJOR_VERSION 0 #define [PROJECT]_MINOR_VERSION 1 #define [PROJECT]_BUILD_NUMBER ### #define [PROJECT]_BUILD_STAGE "Pre-Alpha" Here's my Gradle task that increments the build number in that text file, and then replaces the value in the header file: task incrementVersion { doLast { def version = 0 def ProjectName = "[ProjectName]" def vfile = new File("Source\\" + ProjectName + "\\" + ProjectName + "Build.txt") if(vfile.exists()) { String versionContents = vfile.text version = Integer.parseInt(versionContents) } version += 1 vfile.text = version vfile = new File("Source\\" + ProjectName + "\\" + ProjectName + "Version.h") if(vfile.exists()) { String pname = ProjectName.toUpperCase() String versionContents = vfile.text versionContents = versionContents.replaceAll(/_BUILD_NUMBER ([0-9]+)/) { m -> "_BUILD_NUMBER " + version } vfile.text = versionContents } } } I manually edit the major and minor versions and the build stage as needed, since they don't need to update with every build. You can include that header into any C++ file that needs to know the build number, and I also have a few static methods in my game's Blueprint static library that wrap them so I can get the version numbers in Blueprint. I also have some tasks for automatically checking those files into the Git repository and committing them: task prepareVersion(type: Exec) { workingDir = project.projectDir.toString() commandLine "cmd", "/c", "git", "reset" } task stageVersion(type: Exec, dependsOn: prepareVersion) { workingDir = project.projectDir.toString() commandLine "cmd", "/c", "git", "add", project.projectDir.toString() + "\\Source\\[ProjectName]\\[ProjectName]Build.txt", project.projectDir.toString() + "\\Source\\[ProjectName]\\[ProjectName]Version.h" } task commitVersion(type: Exec, dependsOn: stageVersion) { workingDir = project.projectDir.toString() commandLine "cmd", "/c", "git", "commit", "-m", "\"Incrementing [ProjectName] version\"" } And here's the task I use to actually push it to Steam: task pushBuildSteam(type: Exec) { doFirst { println "Pushing build to Steam..." } workingDir = "[SteamworksDir]\\sdk\\tools\\ContentBuilder" commandLine "cmd", "/c", "builder\\steamcmd.exe", "+set_steam_guard_code", "[steam_guard_code]", "+login", "\"[username]\"", "\"[password]\"", "+run_app_build", "..\\scripts\\[CorrectVDFFile].vdf", "+quit" } You can also spit out a generated VDF file with the build number in the build's description so that it'll show up in SteamPipe. I have a single Gradle task I run that increments the build number, checks in those version files, packages both the client and server, and then uploads the packaged client to Steam. Another great thing about Gradle is that Jenkins has a solid plugin for it, so you can use Jenkins to set up a nice continuous integration pipeline for your game to push builds out regularly, which you absolutely should do if you're working with a team. 0 comments 3. If you are a software developer working in the video game industry and wondering what else you could do to improve the quality of your product or make the development process easier and you don't use static analysis – it's just the right time to start doing so. You doubt that? OK, I'll try to convince you. And if you are just looking to see what coding mistakes are common with video-game and game-engine developers, then you're, again, at the right place: I have picked the most interesting ones for you. Why you should use static analysis Although video-game development includes a lot of steps, coding remains one of the basic ones. Even if you don't write thousands of code lines, you have to use various tools whose quality determines how comfortable the process is and what the ultimate result will be. If you are a developer of such tools (such as game engines), this shouldn't sound new to you. Why is static analysis useful in software development in general? The main reasons are as follows: Bugs grow costlier and more difficult to fix over time. One of the principal advantages of static analysis is detecting bugs at early development stages (you can find an error when code writing). Therefore, by using static analysis, you could make the development process easier both for your coworkers and yourself, detecting and fixing lots of bugs before they become a headache. Static analysis tools can recognize a great variety of bug patterns (copy-paste, typos, incorrect use of functions, etc.). Static analysis is generally good at detecting those defects that defy dynamic analysis. However, the opposite is also true. Negative side effects of static analysis (such as false positives) are usually 'smoothed out' through means provided by the developers of powerful analyzers. These means include various mechanisms of warning suppression (individually, by pattern, and so on), switching off irrelevant diagnostics, and excluding files and folders from analysis. By properly tweaking the analyzer settings, you can reduce the amount of 'noise' greatly. As my colleague Andrey Karpov has shown in the article about the check of EFL Core Libraries, tweaking the settings helps cut down the number of false positives to 10-15% at most. But it's all theory, and you are probably interested in real-life examples. Well then, I've got some. Static analysis in Unreal Engine If you have read this far, I assume you don't need me telling you about Unreal Engine or the Epic Games company – and if you don't hold these guys in high regard, I wonder whom you do. The PVS-Studio team has cooperated with Epic Games a few times to help them adopt static analysis in their project (Unreal Engine) and fix bugs and false positives issued by the analyzer. I'm sure both parties found this experience interesting and rewarding. One of the effects of this cooperation was adding a special flag into Unreal Engine allowing the developers to conveniently integrate static analysis into the build system of Unreal Engine projects. The idea is simple: the guys do care about the quality of their code and adopt various techniques available to maintain it, static analysis being one of them. John Carmack on static analysis John Carmack, one of the most renowned video-game developers, once called the adoption of static analysis one of his most important accomplishments as a programmer: "The most important thing I have done as a programmer in recent years is to aggressively pursue static code analysis." The next time you hear someone say that static analysis is a tool for newbies, show them this quote. Carmack described his experience in this article, which I strongly recommend checking out – both for motivation and general knowledge. Bugs found in video games and game engines with static analysis One of the best ways to prove that static analysis is a useful method is probably through examples showing it in action. That's what the PVS-Studio team does while checking open-source projects. It's a practice that everyone benefits from: The project authors get a bug report and a chance to fix the defects. Ideally, it should be done in quite a different way, though: they should run the analyzer and check the warnings on their own rather than fix them relying on someone else's log or article. It matters, if only because the authors of articles might miss some important details or inadvertently focus on bugs that aren't much critical to the project. The analyzer developers can use the analysis results as the basis for improving the tool, as well as demonstrating its bug-detecting capabilities. The readers learn about bug patterns, gain experience, and get started with static analysis. So, isn't that proof of the effectiveness of this approach? Teams already using static analysis While some are pondering introducing static analysis into their development process, others have long been using and benefiting from it! These are, among others, Rocksteady, Epic Games, ZeniMax Media, Oculus, Codemasters, Wargaming (source). Top 10 software bugs in video-game industry I should point right off that this is not some ultimate top list, but simply bugs which were found by PVS-Studio in video games and game engines and which I found most interesting. As usual, I recommend trying to find the bug in each example on your own first and only then go on reading the warning and my comments. You'll enjoy the article more that way. Tenth place Source: Anomalies in X-Ray Engine The tenth place is given to the bug in X-Ray Engine employed by the S.T.A.L.K.E.R game series. If you played them, you surely remember many of funny (and not quite funny) bugs they had. This is especially true for S.T.A.L.K.E.R.: Clear Sky, which was impossible to play without patches (I still remember the bug that 'killed' all my saves). The analysis revealed there were many bugs indeed. Here's one of them. BOOL CActor::net_Spawn(CSE_Abstract* DC) { .... m_States.empty(); .... } PVS-Studio warning: V530 The return value of function 'empty' is required to be utilized. The problem is quite simple: the programmer is not using the logical value returned by the empty method describing whether the container is empty or not. Since the expression contains nothing but a method call, I assume the programmer intended to clear the container but called the empty method instead of clear by mistake. You may argue that this bug is too plain for a Top-10 list, but that's the nice thing about it! Even though it looks straightforward to someone not involved in writing this code, 'plain' bugs like that still appear (and get caught) in various projects. Ninth place Source: Long-Awaited Check of CryEngine V Going on with bugs in game engines. This time it's a code fragment from CryEngine V. The number of bugs I have encountered in games based on this engine was not as large as in games based on X-Ray Engine, but it turns out it has plenty of suspicious fragments too. void CCryDXGLDeviceContext:: OMGetBlendState(...., FLOAT BlendFactor[4], ....) { CCryDXGLBlendState::ToInterface(ppBlendState, m_spBlendState); if ((*ppBlendState) != NULL) (*ppBlendState)->AddRef(); BlendFactor[0] = m_auBlendFactor[0]; BlendFactor[1] = m_auBlendFactor[1]; BlendFactor[2] = m_auBlendFactor[2]; BlendFactor[2] = m_auBlendFactor[3]; *pSampleMask = m_uSampleMask; } PVS-Studio warning: V519 The 'BlendFactor[2]' variable is assigned values twice successively. Perhaps this is a mistake. As we mentioned many times in our articles, no one is safe from mistyping. Practice has also shown more than once that static analysis is very good at detecting copy-paste-related mistakes and typos. In the code above, the values of the m_auBlendFactor array are copied to the BlendFactor array, but the programmer made a mistake by writing BlendFactor[2] twice. As a result, the value at m_auBlendFactor[3] is written to BlendFactor[2], while the value at BlendFactor[3] remains unchanged. Eighth place Source: Unicorn in Space: Analyzing the Source Code of 'Space Engineers' Let's change course a bit and take a look at some C# code. What we've got here is an example from the Space Engineers project, a 'sandbox' game about building and maintaining various structures in space. I haven't played it myself, but one guy said in the comments, "I'm not much surprised at the results ". Well, we did manage to find some bugs worth mentioning, and here's two of them. public void Init(string cueName) { .... if (m_arcade.Hash == MyStringHash.NullOrEmpty && m_realistic.Hash == MyStringHash.NullOrEmpty) MySandboxGame.Log.WriteLine(string.Format( "Could not find any sound for '{0}'", cueName)); else { if (m_arcade.IsNull) string.Format( "Could not find arcade sound for '{0}'", cueName); if (m_realistic.IsNull) string.Format( "Could not find realistic sound for '{0}'", cueName); } } PVS-Studio warnings: V3010 The return value of function 'Format' is required to be utilized. V3010 The return value of function 'Format' is required to be utilized. As you can see, it's a common problem, both in C++-code and C#-code, where programmers ignore methods' return values. The String.Format method forms the resulting string based on the format string and objects to substitute and then returns it. In the code above, the else-branch contains two string.Format calls, but their return values are never used. It looks like the programmer intended to log these messages in the same way as they did in the then-branch of the if statement using the MySandboxGame.Log.WriteLine method. Seventh place Source: Analyzing the Quake III Arena GPL project Did I tell you already that static analysis is good at detecting typos? Well, here's one more example. void Terrain_AddMovePoint(....) { .... x = ( v[ 0 ] - p->origin[ 0 ] ) / p->scale_x; y = ( v[ 1 ] - p->origin[ 1 ] ) / p->scale_x; .... } PVS-Studio warning: V537 Consider reviewing the correctness of 'scale_x' item's usage. The variables x and y are assigned values, yet both expressions contain the p->scale_x subexpression, which doesn't look right. It seems the second subexpression should be p->scale_y instead. Sixth place Source: Checking the Unity C# Source Code Unity Technologies recently made the code of their proprietary game engine, Unity, available to the public, so we couldn't ignore the event. The check revealed a lot of interesting code fragments; here's one of them: public override bool IsValid() { .... return base.IsValid() && (pageSize >= 1 || pageSize <= 1000) && totalFilters <= 10; } PVS-Studio warning: V3063 A part of conditional expression is always true if it is evaluated: pageSize <= 1000. What we have here is an incorrect check of the range of pageSize. The programmer must have intended to check that the pageSize value was within the range [1; 1000] but made a sad mistake by typing the '||' operator instead of '&&'. The subexpression actually checks nothing. Fifth place Source: Discussing Errors in Unity3D's Open-Source Components This place was given to a nice bug found in Unity3D's components. The article mentioned above was written a year prior to revealing Unity's source code, but there already were interesting defects to find there at the time. public static CrawledMemorySnapshot Unpack(....) { .... var result = new CrawledMemorySnapshot { .... staticFields = packedSnapshot.typeDescriptions .Where(t => t.staticFieldBytes != null & t.staticFieldBytes.Length > 0) .Select(t => UnpackStaticFields(t)) .ToArray() .... }; .... } PVS-Studio warning: V3080 Possible null dereference. Consider inspecting 't.staticFieldBytes'. Note the lambda expression passed as an argument to the Where method. The code suggests that the typeDescriptions collection could contain elements whose staticFieldBytes member could be null – hence the check staticFieldBytes != null before accessing the Length property. However, the programmer mixed up the '&' and '&&' operators. It means that no matter the result of the left expression (true/false), the right one will also be evaluated, causing a NullReferenceException to be thrown when accessing the Length property if staticFieldBytes == null. Using the '&&' operator could help avoid this because the right expression won't be evaluated if staticFieldBytes == null. Although Unity was the only engine to hit this top list twice, it doesn't prevent enthusiasts from building wonderful games on it. Including one(s) about fighting bugs. Fourth place Source: Analysis of Godot Engine's Source Code Sometimes we come across interesting cases that have to do with missing keywords. For example, an exception object is created but never used because the programmer forgot to add the throw keyword. Such errors are found both in C# projects and C++ projects. There was one missing keyword in Godot Engine as well. Variant Variant::get(const Variant& p_index, bool *r_valid) const { .... if (ie.type == InputEvent::ACTION) { if (str =="action") { valid=true; return ie.action.action; } else if (str == "pressed") { valid=true; ie.action.pressed; } } .... } PVS-Studio warning: V607 Ownerless expression 'ie.action.pressed'. In the given code fragment it is obvious that a programmer wanted to return a certain value of the Variant type, depending on the values ie.type and str. Yet only one of the return statements – return ie.action.action; – is written properly, while the other is lacking the return operator, which prevents the needed value from returning and forces the method to keep executing. Third place Source: PVS-Studio: analyzing Doom 3 code Now we've reached the Top-3 section. The third place is awarded to a small code fragment of Doom 3's source code. As I already said, the fact that a bug may look straightforward to an outside observer and make you wonder how one could have made such a mistake at all shouldn't be confusing: there are actually all sorts of bugs to be found in the field... void Sys_GetCurrentMemoryStatus( sysMemoryStats_t &stats ) { .... memset( &statex, sizeof( statex ), 0 ); .... } PVS-Studio warning: V575 The 'memset' function processes '0' elements. Inspect the third argument. To figure this error out, we should recall the signature of the memset function: void* memset(void* dest, int ch, size_t count); If you compare it with the call above, you'll notice that the last two arguments are swapped; as a result, some memory block that was meant to be cleared will stay unchanged. Second place The second place is taken by a bug found in the code of the Xenko game engine written in C#. Source: Catching Errors in the Xenko Game Engine private static ImageDescription CreateDescription(TextureDimension dimension, int width, int height, int depth, ....) { .... } public static Image New3D(int width, int height, int depth, ....) { return new Image(CreateDescription(TextureDimension.Texture3D, width, width, depth, mipMapCount, format, 1), dataPointer, 0, null, false); } PVS-Studio warning: V3065 Parameter 'height' is not utilized inside method's body. The programmer made a mistake when passing the arguments to the CreateDescription method. If you look at its signature, you'll see that the second, third, and fourth parameters are named width, height, and depth, respectively. But the call passes the arguments width, width, and depth. Looks strange, doesn't it? The analyzer, too, found it strange enough to point it out. First place Source: A Long-Awaited Check of Unreal Engine 4 This Top-10 list is led by a bug from Unreal Engine. Just like it was with the leader of "Top 10 Bugs in the C++ Projects of 2017", I knew this bug should be given the first place the very moment I saw it. bool VertInfluencedByActiveBone( FParticleEmitterInstance* Owner, USkeletalMeshComponent* InSkelMeshComponent, int32 InVertexIndex, int32* OutBoneIndex = NULL); void UParticleModuleLocationSkelVertSurface::Spawn(....) { .... int32 BoneIndex1, BoneIndex2, BoneIndex3; BoneIndex1 = BoneIndex2 = BoneIndex3 = INDEX_NONE; if(!VertInfluencedByActiveBone( Owner, SourceComponent, VertIndex[0], &BoneIndex1) && !VertInfluencedByActiveBone( Owner, SourceComponent, VertIndex[1], &BoneIndex2) && !VertInfluencedByActiveBone( Owner, SourceComponent, VertIndex[2]) &BoneIndex3) { .... } PVS-Studio warning: V564 The '&' operator is applied to bool type value. You've probably forgotten to include parentheses or intended to use the '&&' operator. I wouldn't be surprised if you read the warning, looked at the code, and wondered, "Well, where's the '&' used instead of '&&'?" But if we simplify the conditional expression of the if statement, keeping in mind that the last parameter of the VertInfluencedByActiveBone function has a default value, this will clear it all up: if (!foo(....) && !foo(....) && !foo(....) & arg) Take a close look at the last subexpression: !VertInfluencedByActiveBone(Owner, SourceComponent, VertIndex[2]) &BoneIndex3 This parameter with the default value has messed things up: but for this value, the code would have never compiled at all. But since it's there, the code compiles successfully and the bug blends in as successfully. It's this suspicious fragment that the analyzer spotted – the infix operation '&' with the left operand of type bool and the right operand of type int32. Conclusion I hope I have convinced you that static analysis is a very useful tool when developing video games and game engines, and one more option to help you improve the quality of your code (and thus of the final product). If you are a video game industry developer, you ought to tell your coworkers about static analysis and refer them to this article. Wondering where to start? Start with PVS-Studio. 0 comments 4. Are you considering developing a mobile game? If you want to be successful, you should avoid making the most common mistakes. Trying to build a game without figuring out the right approach is a recipe for disaster. There are experienced developers like MyIsaak from Sweden, an expert in C# and Unity game development who frequently livestreams his Diablo III Board game development process. The more you learn from professionals like him, who have gone through the processes, the faster you can avoid making the common game development mistakes. Here are the top 5 game developments mistakes to avoid. 1. Ignoring the target group Creating a game without properly studying your target group is a huge barrier that will keep it from being downloaded and played. Who are you building the game for? What are their main interests? What activities do they like participating in? Can the target group afford the gaming app? Does your target audience use iOS or Android operating system? Seeking answers to the above questions and others can assist in correctly identifying your target group. Consequently, you can design its functionalities around their preferences. Just like an ice cream vendor is likely to set up shop at the beach during summer, you should focus on consumers whose behaviors are likely to motivate them to play your game. For example, if you want to create a gun shooting game, you can target college-educated men in their 20s and 30s, while targeting other demographic groups secondarily. 2. Failure to study the competitors To create a successful game that will increase positive reviews and retention, you should analyze the strengths and weaknesses of your competitors. Studying your competition will allow you to understand your capabilities to match or surpass the consumer demand for your mobile or web-based game. If you fail to do it, you will miss the opportunity to fill the actual needs in the gaming industry and correct the mistakes made by the developers in your niche. You should ask questions like “What is their target audience?” “How many downloads do their gaming app receive per month?” “What resources do they have?”. Answering such questions will give you a good idea of the abilities of your competition, the feasibility of competing with them, and the kind of strategies to adopt to out-compete them. Importantly, instead of copying the strategies of your competitors, develop a game that is unique and provides an added value to users. 3. Design failure When building a mobile or a web-based game, it’s essential that you employ a unique art style and visually appealing design—without any unnecessary sophistication. People are attracted to games based on the user interface design and intuitiveness. So, instead of spending a lot of time trying to write elegant and complicated lines of code, take your time to provide a better design. No one will download a game because its code is beautiful. People download games to play them. And, the design of the game plays a critical part in assisting them to make the download decision. 4. Trying to do everything If you try to code, develop 3D models, create animations, do voice-overs—all by yourself—then you are likely to create an unsuccessful game. The secret to succeeding is to complete tasks that align with your core competencies and outsource the rest of the work. Learn how to divide your work to other experts and save yourself the headaches. You should also avoid trying to reinvent the wheel. Instead of trying to do everything by yourself, go for robust tools available out there that can make your life easier. Trying to build something that is already provided in the open source community will consume a lot of your development time and make you feel frustrated. Furthermore, do not be the beta tester of your own game. If you request someone else to do the beta testing, you’ll get useful outside perspective that will assist in discovering some hidden issues. 5. Having unrealistic expectations Unrealistic expectations are very dangerous because they set your game development career up for failure. Do not put your expectations so high such that you force somethings to work your way. For example, dreaming too big can make you include too many rewards in your game. As much as rewards are pivotal for improving engagement and keeping users motivated, gamers will not take you seriously if you incorporate rewards in every little achievement they make. Instead, you should select specific rewards for specific checkpoints; this way, the players will feel that they’ve made major milestones. Conclusion The mistakes discussed in this article have made several game developers to be unsuccessful in their careers. So, be cautious and keep your head high so that you don’t fall into the same trap. The best way to avoid making the common mistakes is through learning how to build games from the experts. Who knows? You could develop the next big game in the industry. 0 comments 5. The Game Dev Loadout podcast (here and here) has shared their recent Cliff Harris interview with us. The original interview transcription is at Game Dev Loadout. You can also see more podcast interviews from Game Dev Loadout here on GameDev.net. Game designer, programmer, and running a one-man games business, Cliff Harris of Positech Games (@cliffski32 on GameDev.net) is behind strategy and simulation games such as Production Line, Democracy, and Gratuitous Space Battles. In this interview, Cliff talks about his journey in the game industry, emphasizes on making sure you are taking advice from the right people, and why you need to invest in a great chair for yourself and your team. How did you get started in the game industry? I started programming as a kid when I was 11 on a tiny home computer and then I kind of got out of computers, had all sorts of weird careers working on the stock market and in I.T and boat building and playing the guitar. I taught myself C++ from a home study course on floppy disks then I started making games and that was 20 years ago so it was before indie games were really a thing. I worked at Elixir Studios and Lionhead for 3 years and then I quit that and been full-time indie ever since. What was that push that made you join the game industry? At that time in the U.K, you couldn’t get a job as a programmer unless you had a former qualification as a programmer or you already had a job as a programmer. I always wanted to program video games like a lot of people did and it became possible with the internet that you could program games from home. It was a hobby that turned into a career and a proper business. What is something we probably don’t know about in AI mechanic that we should know? The thing that people don’t realize about AI is that it’s very easy to make something seem alive with few lines of code. Like I have two cats and they really both are predictable. Sometimes the way my cats behave I think you are just few thousand lines of C++. When you break it down, it’s not that difficult to program NPC’s in games that behave and move in quite a natural way. It’s funny because some stuff that you consider easy, it’s almost impossible. So like finding your way out of a maze, we’re pretty good at that but computers are rubbish at it. If you want to program an NPC with text so that it seems to converse with you in a way that doesn’t seem too scripted, that’s not too hard. The reason people tend to encounter rubbish NPC in AI games is due to an obsession with having voice acting for everything. It’s easy to program an NPC that can talk to you about 100 different topics with thousands of different variations that sound fluent and responsive to you. But if you want to record a thousand lines of dialogue and you have got some big name actor then, you can’t afford it. So that’s actually the bottleneck. The other possibility is the translation. The problem is the minute you translate it to German, it’s absolute chaos. The sentence structure is different and you obviously have to pay a little bit to translate the text into German. And if you have got like 20 languages and there are tons of different phrases in each language, suddenly that’s what becomes expensive and difficult. But as you program, it’s fairly easy and fun. Production Line Would you suggest new developers stick to text or voice acting? If you want to capture the whole audience and to have a successful indie game, you probably are going to want it in like 10 different languages. So to get it professionally done is probably like 10 cents a word. So every time you type like one line of dialogue, it’s going to cost you like 50 dollars. If you want to record the audio and then you want that in 10 languages, that’s going to cost you even more. And does it really add to the experience? I’m not sure it does. And the other thing is that I am very impatient and I value time a lot so I’d rather read the dialogue personally than hear it. I want to talk about the worst moment of your career, that one moment that’s still vivid in your mind. They are a few. I have left a game company in a very heated argument, which is funny because I recently bumped into the guy I had that argument with and he’s fine, and I am fine and we get along, but it was just really stressful. I have had bugs that are really bad. I had a bug that could potentially destroy someone’s computer and someone reported a problem to me and I was like “No, I am sure this is not a bug of mine” and I looked into it and I did a lot of experimentation to get this bug to trigger on my PC. I thought “Oh my God, I cannot believe I had made this mistake.” Yeah, I remember frantically coding this patch for it and putting it out immediately and no one else got infected by it. But I was really worried. It was a very rare circumstance but it would delete stuff on your hard drive. It started happening to me but people had anti-virus so it was like a flag going “Hey, what are you doing?” That’s a reputation-destroying bug that deleted a file where the player goes to delete some content intentionally and under certain circumstances, the file name that would be passed in would be empty and given the structure of that code it would then start to delete everything. I had to make loads of checks in all of the areas of my game that can never delete a file. There’s so much code wrapped around this and I can never ever get into that position again because that was bad. From the heated argument story, how did you handle the situation and what was the outcome? Well, I handled it badly, actually, everyone handled it badly. I mean, I had been in this company too long and I was very frustrated and sort of wanted to leave but I had stayed on the assumption that things would change. I just lost it, I got into a very strong argument and someone there had stormed off. And that was it, that was how I left. Looking back on it, I stayed in the company too long. I am very Indie, I don’t like working for other people. I am not very easy to employ because I am quite outspoken and maybe not massively respectful of authority. So it was kind of like a bad fit. To be honest I have stormed out of another job as well. So what should we take away from that experience? The game industry is a lot like the music industry because almost everyone in the music industry makes no money and some people make piles of money. And then there are many more people who want to be in games than the industry will support, which is a lot like music. So you end up with very stressed people who are doing what they love doing, they are very passionate about it and very intensely into it and they are working very hard. It is basically a recipe for everyone to get into huge fights and hate each other. It’s a bit better now I think but there were a lot of companies where people would work very long hours and they would work very late and they go beyond what you would normally put into a job. They aren’t massively well paid at any point. Also, the game industry attracts people like me who are fairly introverted, so we have good technical skills but not very good people skills. You put all that together and it is going to be tough. But I don’t think people hold grudges, I mean I have had two huge arguments with people, some famous and some not and always ended up getting along with them because ultimately very few people come into the industry for money because there isn’t much. So generally you realize that everyone is here just to try to make cool games and work on great stuff no matter how much we like kind of get on each other’s nerves. What are bad recommendations that you hear in your profession? There are a lot of people that will give you advice. Like if you go on to Reddit and sort of say “Oh I am thinking of making this game, oh I am thinking of porting to this platform”. You will get a massive amount of advice and almost all of it will be rubbish. That’s because the people who are always on Facebook, Twitter and Reddit, just sit there, waiting on giving advice to others. I am never like I have to go there and post it and see if anyone is ever asking about something I know about. I’ve read a huge amount of stuff that says there is no point in advertising your indie game. Some of them might say that I have spent like a100 on Facebook Ads, I didn’t notice any difference in the number of downloads of my game and what you can take from that is you know one person who spent a $100, they did not receive a direct difference. I’ve spent$265,000 on Facebook Ads over the years, so as you can imagine I am pretty convinced they work. But what I am saying is that I have literally a thousand times more data points on that issue. So if you see me talking about the Pro’s and Con’s of Facebook Ads, well I know what I am talking about. If you hear me talking about whether Android or iPhone is a better platform, then just slap me and tell me “Cliff you have no idea, no you don’t know anything about it”. Because you have never made a mobile game and I think that’s the most important thing, you have to know whose advice you are taking and on what basis. We will have an intuition about games and stuff and what should work, what shouldn’t work and often our intuition is wrong. I honestly think that free to play should not work but it clearly does. I think that there is no way you can run an entire games business based on selling virtual hacks, I know that cannot possibly work. But I know it does. So you have to listen to specific people on specific issues. What is one of the best investments you have ever made? Could be an investment in time, energy, or money. Okay, I’ll give you two, time and money. The time thing is learning how to code my own game engine. I learned to code everything like graphics, sound and whatever from scratch because I had to. It gives you a big insight into performance and why your game may be slow. I get to code very fast stuff when I need it. Also, I am not relying on anything else. I am not paying any money to Unity and if they update Unity or Unreal and it breaks everything, obviously I don’t care because I am not using it. So that’s given me an independence that’s very helpful. Obviously, it takes a lot of time. Gratuitous Space Battles The physical thing which I have told a lot of people over the years is this chair that I’m sitting in. If you’ve got a tech startup and you have coders and you have money then buy these Herman Miller Aeron chairs for everyone. It was 800 pounds which is a lot, $1100. I am fully aware that it’s a crazy amount of money. But I sit on it ten hours a day and they last forever. It affects your health and mood. It really is a good investment and even if you think it’s kind of over the top and unnecessary. Don’t buy a$20 chair from a cheap shop. Make some sort of investment in your comfort because in the end you spend a lot of time sitting in front of the keyboard and it’s so much better for you to be comfortable when you do that.  BETA PHASE: Rapid Fire Questions What was holding you back from joining the game industry? I don’t know. Nothing would stop me right now but back before I joined, the industry was tiny. It was not something people did. Nobody knew anyone in the games industry, but now nothing would hold me back. Back then it was just like “that’s not a real job”. What’s the personal habit that contributes to your success? Getting out bed early. I was a real workaholic. I would be working at my desk by 8 o’clock, which doesn’t sound that early but for a computer programmer, it is because then we work till like 8 o’clock in the evening. Just learning how to get out bed and go straight to work without messing around, that’s the best thing. What’s the best piece of advice you’ve ever received? Ask for more money. Most of the time you don’t get it, but occasionally you do and it’s just like free money and you’re like “Hey, they weren’t going to give me that unless I said it”. It’s really awkward but do it. What’s that great marketing tip to make yourself and your game stand out? Put faces in your games. Read into Neuroscience, a disproportionate amount of your brain is dedicated to looking for faces and looking for emotions in faces and if you have three images of games and if one of them has a face in the image, that is the one everyone looks at first. What resources should we game developers use to get started today? If you are technically-minded and if you want to be a programmer more than anything else, then buy some good C++ books and learn how to code everything from scratch. If you’re not, then use Unity but don’t put off the idea of coding from the ground up, it’s very valuable. Imagine you woke up the next morning in a brand new world and you knew no one, you still have all the experience and knowledge you currently have today, your food and shelter are taking care of and you have a laptop. What would you do step by step on the path to join and become successful in the game industry? I would make a PC strategy game and sell it on Steam. It would be 2D, top down. I would find an artist to do like revenue share on it and I would do all my end marketing and game designing and code it from scratch, probably don’t even need ‘Unity’ to do that and it might even be easier. That’s the safest and best route to actually making a game that will make money. You can listen to the entire podcast and more interviews with developers and others in the industry at Game Dev Loadout.
By khawk
8. I got into a conversation awhile ago with some fellow game artists and the prospect of signing bonuses got brought up. Out of the group, I was the only one who had negotiated any sort of sign on bonus or payment above and beyond base compensation. My goal with this article and possibly others is to inform and motivate other artists to work on this aspect of their “portfolio” and start treating their career as a business.  What is a Sign-On Bonus? Quite simply, a sign-on bonus is a sum of money offered to a prospective candidate in order to get them to join. It is quite common in other industries but rarely seen in the games unless it is at the executive level. Unfortunately, conversations centered around artist employment usually stops at base compensation, quite literally leaving money on the table. Why Ask for a Sign-On Bonus? There are many reasons to ask for a sign-on bonus. In my experience, it has been to compensate for some delta between how much I need vs. how much the company is offering. For example, a company has offered a candidate a position paying $50k/year. However, research indicates that the candidate requires$60k/year in order to keep in line with their personal financial requirements and long-term goals. Instead of turning down the offer wholesale, they may ask for a $10k sign on bonus with actionable terms to partially bridge the gap. Whatever the reason may be, the ask needs to be reasonable. Would you like a$100k sign-on bonus? Of course! Should you ask for it? Probably not. A sign-on bonus is a tool to reduce risk, not a tool to help you buy a shiny new sports car. Aspects to Consider Before one goes and asks for a huge sum of money, there are some aspects of sign-on bonus negotiations the candidate needs to keep in mind. - The more experience you have, the more leverage you have to negotiate - You must have confidence in your role as an employee. - You must have done your research. This includes knowing your personal financial goals and how the prospective offer changes, influences or diminishes those goals. To the first point, the more experience one has, the better. If the candidate is a junior employee (roughly defined as less than 3 years of industry experience) or looking for their first job in the industry, it is highly unlikely that a company will entertain a conversation about sign-on bonuses. Getting into the industry is highly competitive and there is likely very little motivation for a company to pay a sign-on bonus for one candidate when there a dozens (or hundreds in some cases) of other candidates that will jump at the first offer. Additionally, the candidate must have confidence in succeeding at the desired role in the company. They have to know that they can handle the day to day responsibilities as well as any extra demands that may come up during production. The company needs to be convinced of their ability to be a team player and, as a result, is willing to put a little extra money down to hire them. In other words, the candidate needs to reduce the company’s risk in hiring them enough that an extra payment or two is negligible. And finally, they must know where they sit financially and where they want to be in the short-, mid-, and long-term. Having this information at hand is essential to the negotiation process. The Role Risk Plays in Employment The interviewing process is a tricky one for all parties involved and it revolves around the idea of risk. Is this candidate low-risk or high-risk? The risk level depends on a number of factors: portfolio quality, experience, soft skills, etc. Were you late for the interview? Your risk to the company just went up. Did you bring additional portfolio materials that were not online? Your risk just went down and you became more hireable. If a candidate has an offer in hand, then the company sees enough potential to get a return on their investment with as little risk as possible. At this point, the company is confident in their ability as an employee (ie. low risk) and they are willing to give them money in return for that ability. Asking for the Sign-On Bonus So what now? The candidate has gone through the interview process, the company has offered them a position and base compensation. Unfortunately, the offer falls below expectations. Here is where the knowledge and research of the position and personal financial goals comes in. The candidate has to know what their thresholds and limits are. If they ask for $60k/year and the company is offering$50k, how do you ask for the bonus? Once again, it comes down to risk. Here is the point to remember: risk is not one-sided. The candidate takes on risk by changing companies as well. The candidate has to leverage the sign-on bonus as a way to reduce risk for both parties. Here is the important part: A sign-on bonus reduces the company’s risk because they are not commiting to an increased salary and bonus payouts can be staggered and have terms attached to them. The sign-on bonus reduces the candidate’s risk because it bridges the gap between the offered compensation and their personal financial requirements. If the sign-on bonus is reasonable and the company has the finances (explained further down below), it is a win-win for both parties and hopefully the beginning a profitable business relationship. A Bit about Finances First off, I am not a business accountant nor have I managed finances for a business. I am sure that it is much more complicated than my example below and there are a lot of considerations to take into account. In my experience, however, I do know that base compensation (ie. salary) will generally fall into a different line item category on the financial books than a bonus payout. When companies determine how many open spots they have, it is usually done by department with inter-departmental salary caps. For a simplified example, an environment department’s total salary cap is $500k/year. They have 9 artists being paid$50k/year, leaving $50k/year remaining for the 10th member of the team. Remember the example I gave earlier asking for$60k/year? The company cannot offer that salary because it breaks the departmental cap. However, since bonuses typically do not affect departmental caps, the company can pull from a different pool of money without increasing their risk by committing to a higher salary. Sweetening the Deal Coming right out of the gate and asking for an upfront payment might be too aggressive of a play (ie. high risk for the company). One way around this is to attach terms to the bonus. What does this mean? Take the situation above. A candidate has an offer for $50k/year but would like a bit more. If through the course of discussing compensation they get the sense that$10k is too high, they can offer to break up the payments based on terms. For example, a counterpoint to the initial base compensation offer could look like this: $50k/year salary$5k bonus payout #1 after 30 days of successful employment $5k bonus payout #2 after 365 days (or any length of time) of successful employment In this example, the candidate is guaranteed$55k/year salary for 2 years. If they factor in a standard 3% cost of living raise, the first 3 years of employment looks like this: Year 0-1 = $55,000 ($50,000 + $5,000 payout #1) Year 1-2 =$56,500 (($50,000 x 1.03%) +$5,000 payout #2) Year 2-3 = $53,045 ($51,500 x 1.03%) Now it might not be the $60k/year they had in mind but it is a great compromise to keep both parties comfortable. If the Company Says Yes Great news! The company said yes! What now? Personally, I always request at least a full 24 hours to crunch the final numbers. In the past, I’ve requested up to a week for full consideration. Even if you know you will say yes, doing due diligence with your finances one last time is always a good practice. Plug the numbers into a spreadsheet, look at your bills and expenses again, and review the whole offer (base compensation, bonus, time off/sick leave, medical/dental/vision, etc.). Discuss the offer with your significant other as well. You will see the offer in a different light when you wake up, so make sure you are not rushing into a situation you will regret. If the Company Say No If the company says no, then you have a difficult decision to make. Request time to review the offer and crunch the numbers. If it is a lateral move (same position, different company) then you have to ask if the switch is worth it. Only due diligence will offer that insight and you have to give yourself enough time to let those insights arrive. You might find yourself accepting the new position due to other non-financial reasons (which could be a whole separate article!). Conclusion/Final Thoughts When it comes to negotiating during the interview process, it is very easy to take what you can get and run. You might fear that in asking for more, you will be disqualifying yourself from the position. Keep in mind that the offer has already been extended to you and a company will not rescind their offer simply because you came back with a counterpoint. Negotiations are expected at this stage and by putting forth a creative compromise, your first impression is that of someone who conducts themselves in a professional manner. Also keep in mind that negotiations do not always go well. There are countless factors that influence whether or not someone gets a sign-on bonus. Sometimes it all comes down to being there at the right time at the right place. Just make sure you do your due diligence and be ready when the opportunity presents itself. Hope this helps! 0 comments By RyRyB 9. Recently a long-awaited event has happen - Unity Technologies uploaded the C# source code of the game engine, available for free download on Github. The code of the engine and the editor is available. Of course, we couldn't pass up, especially since lately we've not written so many articles about checking projects on C#. Unity allows to use the provided sources only for information purposes. We'll use them exactly in these ways. Let's try out the latest version PVS-Studio 6.23 on the Unity code. Introduction Previously we've written an article about checking Unity. At that time so much C#-code was not available for the analysis: some components, libraries and examples of usage. However, the author of the article managed to find quite interesting bugs. How did Unity please us this time? I'm saying "please" and hope not to offend the authors of the project. Especially since the amount of the source Unity C#-code, presented on GitHub, is about 400 thousand lines (excluding empty) in 2058 files with the extension "cs". It's a lot, and the analyzer had a quite considerable scope. Now about the results. Before the analysis, I've slightly simplified the work, having enabled the mode of the code display according to the CWE classification for the found bugs. I've also activated the warnings suppression mechanism of the third level of certainty (Low). These settings are available in the drop-down menu of PVS-Studio in Visual Studio development environment, and in the parameters of the analyzer. Getting rid of the warnings with low certainty, I made the analysis of the Unity source code. As a result, I got 181 warnings of the first level of certainty (High) and 506 warnings of the second level of certainty (Medium). I have not studied absolutely all the warnings, because there were quite a lot of them. Developers or enthusiasts can easily conduct an in-depth analysis by testing Unity themselves. To do this, PVS-Studio provides free trial and free modes of using. Companies can also buy our product and get quick and detailed support along with the license. Judging by the fact that I immediately managed to find couple of real bugs practically in every group of warnings with one or two attempts, there are a lot of them in Unity. And yes, they are diverse. Let's review the most interesting errors. Results of the check Something's wrong with the flags PVS-Studio warning: V3001 There are identical sub-expressions 'MethodAttributes.Public' to the left and to the right of the '|' operator. SyncListStructProcessor.cs 240 MethodReference GenerateSerialization() { .... MethodDefinition serializeFunc = new MethodDefinition("SerializeItem", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Public | // <= MethodAttributes.HideBySig, Weaver.voidType); .... } When combining enumeration flags MethodAttributes, an error was made: the Public value was used twice. Perhaps, the reason for this is the wrong code formatting. A similar bug is also made in code of the method GenerateDeserialization: V3001 There are identical sub-expressions 'MethodAttributes.Public' to the left and to the right of the '|' operator. SyncListStructProcessor.cs 309 Copy-Paste PVS-Studio warning: V3001 There are identical sub-expressions 'format == RenderTextureFormat.ARGBFloat' to the left and to the right of the '||' operator. RenderTextureEditor.cs 87 public static bool IsHDRFormat(RenderTextureFormat format) { Return (format == RenderTextureFormat.ARGBHalf || format == RenderTextureFormat.RGB111110Float || format == RenderTextureFormat.RGFloat || format == RenderTextureFormat.ARGBFloat || format == RenderTextureFormat.ARGBFloat || format == RenderTextureFormat.RFloat || format == RenderTextureFormat.RGHalf || format == RenderTextureFormat.RHalf); } I gave a piece of code, preliminary having formatted it, so the error is easily detected visually: the comparison with RenderTextureFormat.ARGBFloat is performed twice. In the original code, it looks differently: Probably, another value of enumeration RenderTextureFormat has to be used in one of two identical comparisons. Double work PVS-Studio warning: V3008 CWE-563 The 'fail' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 1633, 1632. UNetWeaver.cs 1633 class Weaver { .... public static bool fail; .... static public bool IsValidTypeToGenerate(....) { .... if (....) { .... Weaver.fail = true; fail = true; return false; } return true; } .... } The true value is assigned twice to the value, as Weaver.fail and fail is one and the same static field of the Weaver class. Perhaps, there is no crucial error, but the code definitely needs attention. No options PVS-Studio warning: V3009 CWE-393 It's odd that this method always returns one and the same value of 'false'. ProjectBrowser.cs 1417 // Returns true if we should early out of OnGUI bool HandleCommandEventsForTreeView() { .... if (....) { .... if (....) return false; .... } return false; } The method always returns false. Pay attention to the comment in the beginning. A developer forgot about the result PVS-Studio warning: V3010 CWE-252 The return value of function 'Concat' is required to be utilized. AnimationRecording.cs 455 static public UndoPropertyModification[] Process(....) { .... discardedModifications.Concat(discardedRotationModifications); return discardedModifications.ToArray(); } When concatenating two arrays discardedModifications and discardedRotationModifications the author forgot to save the result. Probably a programmer assumed that the result would be expressed immediately in the array discardedModifications. But it is not so. As a result, the original array discardedModifications is returned from the method. The code needs to be corrected as follows: static public UndoPropertyModification[] Process(....) { .... return discardedModifications.Concat(discardedRotationModifications) .ToArray(); } Wrong variable was checked PVS-Studio warning: V3019 CWE-697 Possibly an incorrect variable is compared to null after type conversion using 'as' keyword. Check variables 'obj', 'newResolution'. GameViewSizesMenuItemProvider.cs 104 private static GameViewSize CastToGameViewSize(object obj) { GameViewSize newResolution = obj as GameViewSize; if (obj == null) { Debug.LogError("Incorrect input"); return null; } return newResolution; } In this method, the developers forgot to consider a situation where the variable objis not equal to null, but it will not be able to cast to the GameViewSize type. Then the variable newResolution will be set to null, and the debug output will not be made. A correct variant of code will be like this: private static GameViewSize CastToGameViewSize(object obj) { GameViewSize newResolution = obj as GameViewSize; if (newResolution == null) { Debug.LogError("Incorrect input"); } return newResolution; } Deficiency PVS-Studio warning: V3020 CWE-670 An unconditional 'return' within a loop. PolygonCollider2DEditor.cs 96 private void HandleDragAndDrop(Rect targetRect) { .... foreach (....) { .... if (....) { .... } return; } .... } The loop will execute only one iteration, after that the method terminates its work. Various scenarios are probable. For example, return must be inside the unit if, or somewhere before return, a directive continue is missing. It may well be that there is no error here, but then one should make the code more understandable. Unreachable code PVS-Studio warning: V3021 CWE-561 There are two 'if' statements with identical conditional expressions. The first 'if' statement contains method return. This means that the second 'if' statement is senseless CustomScriptAssembly.cs 179 public bool IsCompatibleWith(....) { .... if (buildingForEditor) return IsCompatibleWithEditor(); if (buildingForEditor) buildTarget = BuildTarget.NoTarget; // Editor .... } Two identical checks, following one after another. It is clear that in case of buildingForEditor equality to the true value, the second check is meaningless, because the first method terminates its work. If the value buildingForEditor is false, neither then-brunch nor if operator will be executed. There is an erroneous construction that requires correction. Unconditional condition PVS-Studio warning: V3022 CWE-570 Expression 'index < 0 && index >= parameters.Length' is always false. AnimatorControllerPlayable.bindings.cs 287 public AnimatorControllerParameter GetParameter(int index) { AnimatorControllerParameter[] param = parameters; if (index < 0 && index >= parameters.Length) throw new IndexOutOfRangeException( "Index must be between 0 and " + parameters.Length); return param[index]; } The condition of the index check is incorrect - the result will always be false. However, in case of passing the incorrect index to the GetParameter method, the exception IndexOutOfRangeException will still be thrown when attempting to access an array element in the return block. Although, the error message will be slightly different. One has to use || in a condition instead of the operator && so that the code worked the way a developer expected: public AnimatorControllerParameter GetParameter(int index) { AnimatorControllerParameter[] param = parameters; if (index < 0 || index >= parameters.Length) throw new IndexOutOfRangeException( "Index must be between 0 and " + parameters.Length); return param[index]; } Perhaps, due to the use of the Copy-Paste method, there is another the same error in the Unity code: PVS-Studio warning: V3022 CWE-570 Expression 'index < 0 && index >= parameters.Length' is always false. Animator.bindings.cs 711 And another similar error associated with the incorrect condition of the check of the array index: PVS-Studio warning: V3022 CWE-570 Expression 'handle.valueIndex < 0 && handle.valueIndex >= list.Length' is always false. StyleSheet.cs 81 static T CheckAccess<T>(T[] list, StyleValueType type, StyleValueHandle handle) { T value = default(T); if (handle.valueType != type) { Debug.LogErrorFormat(.... ); } else if (handle.valueIndex < 0 && handle.valueIndex >= list.Length) { Debug.LogError("Accessing invalid property"); } else { value = list[handle.valueIndex]; } return value; } And in this case, a release of the IndexOutOfRangeException exception is possible.As in the previous code fragments, one has to use the operator || instead of && to fix an error. Simply strange code Two warnings are issued for the code fragment below. PVS-Studio warning: V3022 CWE-571 Expression 'bRegisterAllDefinitions || (AudioSettings.GetSpatializerPluginName() == "GVR Audio Spatializer")' is always true. AudioExtensions.cs 463 PVS-Studio warning: V3022 CWE-571 Expression 'bRegisterAllDefinitions || (AudioSettings.GetAmbisonicDecoderPluginName() == "GVR Audio Spatializer")' is always true. AudioExtensions.cs 467 // This is where we register our built-in spatializer extensions. static private void RegisterBuiltinDefinitions() { bool bRegisterAllDefinitions = true; if (!m_BuiltinDefinitionsRegistered) { if (bRegisterAllDefinitions || (AudioSettings.GetSpatializerPluginName() == "GVR Audio Spatializer")) { } if (bRegisterAllDefinitions || (AudioSettings.GetAmbisonicDecoderPluginName() == "GVR Audio Spatializer")) { } m_BuiltinDefinitionsRegistered = true; } } It looks like an incomplete method. It is unclear why it has been left as such and why developers haven't commented the useless code blocks. All, that the method does at the moment: if (!m_BuiltinDefinitionsRegistered) { m_BuiltinDefinitionsRegistered = true; } Useless method PVS-Studio warning: V3022 CWE-570 Expression 'PerceptionRemotingPlugin.GetConnectionState() != HolographicStreamerConnectionState.Disconnected' is always false. HolographicEmulationWindow.cs 171 private void Disconnect() { if (PerceptionRemotingPlugin.GetConnectionState() != HolographicStreamerConnectionState.Disconnected) PerceptionRemotingPlugin.Disconnect(); } To clarify the situation, it is necessary to look at the declaration of the methodPerceptionRemotingPlugin.GetConnectionState(): internal static HolographicStreamerConnectionState GetConnectionState() { return HolographicStreamerConnectionState.Disconnected; } Thus, calling the Disconnect() method leads to nothing. One more error relates to the same method PerceptionRemotingPlugin.GetConnectionState(): PVS-Studio warning: V3022 CWE-570 Expression 'PerceptionRemotingPlugin.GetConnectionState() == HolographicStreamerConnectionState.Connected' is always false. HolographicEmulationWindow.cs 177 private bool IsConnectedToRemoteDevice() { return PerceptionRemotingPlugin.GetConnectionState() == HolographicStreamerConnectionState.Connected; } The result of the method is equivalent to the following: private bool IsConnectedToRemoteDevice() { return false; } As we can see, among the warnings V3022 many interesting ones were found. Probably, if one spends much time, he can increase the list. But let's move on. Not on the format PVS-Studio warning: V3025 CWE-685 Incorrect format. A different number of format items is expected while calling 'Format' function. Arguments not used: index. Physics2D.bindings.cs 2823 public void SetPath(....) { if (index < 0) throw new ArgumentOutOfRangeException( String.Format("Negative path index is invalid.", index)); .... } There is no error in code, but as the saying goes, the code "smells". Probably, an earlier message was more informative, like this: "Negative path index {0} is invalid.". Then it was simplified, but developers forgot to remove the parameter index for the method Format. Of course, this is not the same as a forgotten parameter for the indicated output string specifier, i.e. the construction of the type String.Format("Negative path index {0} is invalid."). In such a case, an exception would be thrown. But in our case we also need neatness when refactoring. The code has to be fixed as follows: public void SetPath(....) { if (index < 0) throw new ArgumentOutOfRangeException( "Negative path index is invalid."); .... } Substring of the substring PVS-Studio warning: V3053 An excessive expression. Examine the substrings 'UnityEngine.' and 'UnityEngine.SetupCoroutine'. StackTrace.cs 43 static bool IsSystemStacktraceType(object name) { string casted = (string)name; return casted.StartsWith("UnityEditor.") || casted.StartsWith("UnityEngine.") || casted.StartsWith("System.") || casted.StartsWith("UnityScript.Lang.") || casted.StartsWith("Boo.Lang.") || casted.StartsWith("UnityEngine.SetupCoroutine"); } Search of the substring "UnityEngine.SetupCoroutine" in the condition is meaningless, because before that the search for "UnityEngine." is performed. Therefore, the last check should be removed or one has to clarify the correctness of substrings. Another similar error: PVS-Studio warning: V3053 An excessive expression. Examine the substrings 'Windows.dll' and 'Windows.'. AssemblyHelper.cs 84 static private bool CouldBelongToDotNetOrWindowsRuntime(string assemblyPath) { return assemblyPath.IndexOf("mscorlib.dll") != -1 || assemblyPath.IndexOf("System.") != -1 || assemblyPath.IndexOf("Windows.dll") != -1 || // <= assemblyPath.IndexOf("Microsoft.") != -1 || assemblyPath.IndexOf("Windows.") != -1 || // <= assemblyPath.IndexOf("WinRTLegacy.dll") != -1 || assemblyPath.IndexOf("platform.dll") != -1; } Size does matter PVS-Studio warning: V3063 CWE-571 A part of conditional expression is always true if it is evaluated: pageSize <= 1000. UNETInterface.cs 584 public override bool IsValid() { .... return base.IsValid() && (pageSize >= 1 || pageSize <= 1000) && totalFilters <= 10; } Condition for a check of a valid page size is erroneous. Instead of the operator ||, one has to use &&. The corrected code: public override bool IsValid() { .... return base.IsValid() && (pageSize >= 1 && pageSize <= 1000) && totalFilters <= 10; } Possible division by zero PVS-Studio warning: V3064 CWE-369 Potential division by zero. Consider inspecting denominator '(float)(width - 1)'. ClothInspector.cs 249 Texture2D GenerateColorTexture(int width) { .... for (int i = 0; i < width; i++) colors[i] = GetGradientColor(i / (float)(width - 1)); .... } The problem may occur when passing the value width = 1 into the method. In the method, it is not checked anyway. The method GenerateColorTexture is called in the code just once with the parameter 100: void OnEnable() { if (s_ColorTexture == null) s_ColorTexture = GenerateColorTexture(100); .... } So, there is no error here so far. But, just in case, in the method GenerateColorTexture the possibility of transferring incorrect width value should be provided. Paradoxical check PVS-Studio warning: V3080 CWE-476 Possible null dereference. Consider inspecting 'm_Parent'. EditorWindow.cs 449 public void ShowPopup() { if (m_Parent == null) { .... Rect r = m_Parent.borderSize.Add(....); .... } } Probably, due to a typo, the execution of such code guarantees the use of the null reference m_Parent. The corrected code: public void ShowPopup() { if (m_Parent != null) { .... Rect r = m_Parent.borderSize.Add(....); .... } } The same error occurs later in the code: PVS-Studio warning: V3080 CWE-476 Possible null dereference. Consider inspecting 'm_Parent'. EditorWindow.cs 470 internal void ShowWithMode(ShowMode mode) { if (m_Parent == null) { .... Rect r = m_Parent.borderSize.Add(....); .... } And here's another interesting bug that can lead to access by a null reference due to incorrect check: PVS-Studio warning: V3080 CWE-476 Possible null dereference. Consider inspecting 'objects'. TypeSelectionList.cs 48 public TypeSelection(string typeName, Object[] objects) { System.Diagnostics.Debug.Assert(objects != null || objects.Length >= 1); .... } It seems to me that Unity developers quite often make errors related to misuse of operators || and && in conditions. In this case, if objects has a null value, then this will lead to a check of second part of the condition (objects != null || objects.Length >= 1), which will entail the unexpected throw of an exception. The error should be corrected as follows: public TypeSelection(string typeName, Object[] objects) { System.Diagnostics.Debug.Assert(objects != null && objects.Length >= 1); .... } Early nullifying PVS-Studio warning: V3080 CWE-476 Possible null dereference. Consider inspecting 'm_RowRects'. TreeViewControlGUI.cs 272 public override void GetFirstAndLastRowVisible(....) { .... if (rowCount != m_RowRects.Count) { m_RowRects = null; throw new InvalidOperationException(string.Format("....", rowCount, m_RowRects.Count)); } .... } In this case, the exception throw (access by the null reference m_RowRects) will happen when generating the message string for another exception. Code might be fixed, for example, as follows: public override void GetFirstAndLastRowVisible(....) { .... if (rowCount != m_RowRects.Count) { var m_RowRectsCount = m_RowRects.Count; m_RowRects = null; throw new InvalidOperationException(string.Format("....", rowCount, m_RowRectsCount)); } .... } One more error when checking PVS-Studio warning: V3080 CWE-476 Possible null dereference. Consider inspecting 'additionalOptions'. MonoCrossCompile.cs 279 static void CrossCompileAOT(....) { .... if (additionalOptions != null & additionalOptions.Trim().Length > 0) arguments += additionalOptions.Trim() + ","; .... } Due to the fact that the & operator is used in a condition, the second part of the condition will always be checked, regardless of the result of the check of the first part. In case if the variable additionalOptions has the null value, the exception throw is inevitable. The error has to be corrected, by using the operator && instead of &. As we can see, among the warnings with the number V3080 there are rather insidious errors. Late check PVS-Studio warning: V3095 CWE-476 The 'element' object was used before it was verified against null. Check lines: 101, 107. StyleContext.cs 101 public override void OnBeginElementTest(VisualElement element, ....) { if (element.IsDirty(ChangeType.Styles)) { .... } if (element != null && element.styleSheets != null) { .... } .... } The variable element is used without preliminary check for null. While later in the code this check is performed. The code probably needs to be corrected as follows: public override void OnBeginElementTest(VisualElement element, ....) { if (element != null) { if (element.IsDirty(ChangeType.Styles)) { .... } if (element.styleSheets != null) { .... } } .... } In code there are 18 more errors. Let me give you a list of the first 10: V3095 CWE-476 The 'property' object was used before it was verified against null. Check lines: 5137, 5154. EditorGUI.cs 5137 V3095 CWE-476 The 'exposedPropertyTable' object was used before it was verified against null. Check lines: 152, 154. ExposedReferenceDrawer.cs 152 V3095 CWE-476 The 'rectObjs' object was used before it was verified against null. Check lines: 97, 99. RectSelection.cs 97 V3095 CWE-476 The 'm_EditorCache' object was used before it was verified against null. Check lines: 134, 140. EditorCache.cs 134 V3095 CWE-476 The 'setup' object was used before it was verified against null. Check lines: 43, 47. TreeViewExpandAnimator.cs 43 V3095 CWE-476 The 'response.job' object was used before it was verified against null. Check lines: 88, 99. AssetStoreClient.cs 88 V3095 CWE-476 The 'compilationTask' object was used before it was verified against null. Check lines: 1010, 1011. EditorCompilation.cs 1010 V3095 CWE-476 The 'm_GenericPresetLibraryInspector' object was used before it was verified against null. Check lines: 35, 36. CurvePresetLibraryInspector.cs 35 V3095 CWE-476 The 'Event.current' object was used before it was verified against null. Check lines: 574, 620. AvatarMaskInspector.cs 574 V3095 CWE-476 The 'm_GenericPresetLibraryInspector' object was used before it was verified against null. Check lines: 31, 32. ColorPresetLibraryInspector.cs 31 Wrong Equals method PVS-Studio warning: V3115 CWE-684 Passing 'null' to 'Equals' method should not result in 'NullReferenceException'. CurveEditorSelection.cs 74 public override bool Equals(object _other) { CurveSelection other = (CurveSelection)_other; return other.curveID == curveID && other.key == key && other.type == type; } Overload of the Equals method was implemented carelessly. One has to take into account the possibility of obtaining null as a parameter, as this can lead to a throw of an exception, which hasn't been considered in the calling code. In addition, the situation, when _other can't be cast to the type CurveSelection, will lead to a throw of an exception. The code has to be fixed. A good example of the implementation of Object.equals overload is given in the documentation. In the code, there are other similar errors: V3115 CWE-684 Passing 'null' to 'Equals' method should not result in 'NullReferenceException'. SpritePackerWindow.cs 40 V3115 CWE-684 Passing 'null' to 'Equals' method should not result in 'NullReferenceException'. PlatformIconField.cs 28 V3115 CWE-684 Passing 'null' to 'Equals' method should not result in 'NullReferenceException'. ShapeEditor.cs 161 V3115 CWE-684 Passing 'null' to 'Equals' method should not result in 'NullReferenceException'. ActiveEditorTrackerBindings.gen.cs 33 V3115 CWE-684 Passing 'null' to 'Equals' method should not result in 'NullReferenceException'. ProfilerFrameDataView.bindings.cs 60 Once again about the check for null inequality PVS-Studio warning: V3125 CWE-476 The 'camera' object was used after it was verified against null. Check lines: 184, 180. ARBackgroundRenderer.cs 184 protected void DisableARBackgroundRendering() { .... if (camera != null) camera.clearFlags = m_CameraClearFlags; // Command buffer camera.RemoveCommandBuffer(CameraEvent.BeforeForwardOpaque, m_CommandBuffer); camera.RemoveCommandBuffer(CameraEvent.BeforeGBuffer, m_CommandBuffer); } When the camera variable is used the first time, it is checked for null inequality. But further along the code the developers forget to do it. The correct variant could be like this: protected void DisableARBackgroundRendering() { .... if (camera != null) { camera.clearFlags = m_CameraClearFlags; // Command buffer camera.RemoveCommandBuffer(CameraEvent.BeforeForwardOpaque, m_CommandBuffer); camera.RemoveCommandBuffer(CameraEvent.BeforeGBuffer, m_CommandBuffer); } } Another similar error: PVS-Studio warning: V3125 CWE-476 The 'item' object was used after it was verified against null. Check lines: 88, 85. TreeViewForAudioMixerGroups.cs 88 protected override Texture GetIconForItem(TreeViewItem item) { if (item != null && item.icon != null) return item.icon; if (item.id == kNoneItemID) // <= return k_AudioListenerIcon; return k_AudioGroupIcon; } An error, that in some cases leads to an access by a null link. The execution of the condition in the first block if enables the exit from the method. However, if this does not happen, then there is no guarantee that the reference item is non-zero. Here is the corrected version of the code: protected override Texture GetIconForItem(TreeViewItem item) { if (item != null) { if (item.icon != null) return item.icon; if (item.id == kNoneItemID) return k_AudioListenerIcon; } return k_AudioGroupIcon; } In the code there are 12 similar errors. Let me give you a list of the first 10: V3125 CWE-476 The 'element' object was used after it was verified against null. Check lines: 132, 107. StyleContext.cs 132 V3125 CWE-476 The 'mi.DeclaringType' object was used after it was verified against null. Check lines: 68, 49. AttributeHelper.cs 68 V3125 CWE-476 The 'label' object was used after it was verified against null. Check lines: 5016, 4999. EditorGUI.cs 5016 V3125 CWE-476 The 'Event.current' object was used after it was verified against null. Check lines: 277, 268. HostView.cs 277 V3125 CWE-476 The 'bpst' object was used after it was verified against null. Check lines: 96, 92. BuildPlayerSceneTreeView.cs 96 V3125 CWE-476 The 'state' object was used after it was verified against null. Check lines: 417, 404. EditorGUIExt.cs 417 V3125 CWE-476 The 'dock' object was used after it was verified against null. Check lines: 370, 365. WindowLayout.cs 370 V3125 CWE-476 The 'info' object was used after it was verified against null. Check lines: 234, 226. AssetStoreAssetInspector.cs 234 V3125 CWE-476 The 'platformProvider' object was used after it was verified against null. Check lines: 262, 222. CodeStrippingUtils.cs 262 V3125 CWE-476 The 'm_ControlPoints' object was used after it was verified against null. Check lines: 373, 361. EdgeControl.cs 373 The choice turned out to be small PVS-Studio warning: V3136 CWE-691 Constant expression in switch statement. HolographicEmulationWindow.cs 261 void ConnectionStateGUI() { .... HolographicStreamerConnectionState connectionState = PerceptionRemotingPlugin.GetConnectionState(); switch (connectionState) { .... } .... } The method PerceptionRemotingPlugin.GetConnectionState() is to blame here. We have already come across it when we were analyzing the warnings V3022: internal static HolographicStreamerConnectionState GetConnectionState() { return HolographicStreamerConnectionState.Disconnected; } The method will return a constant. This code is very strange. It needs to be paid attention. Conclusions I think we can stop at this point, otherwise the article will become boring and overextended. Again, I listed the errors that I just couldn't miss. Sure, the Unity code contains a big number of the erroneous and incorrect constructions, that need to be fixed. The difficulty is that many of the issued warnings are very controversial and only the author of the code is able to make the exact "diagnosis" in each case. Generally speaking about the Unity project, we can say that it is rich for errors, but taking into account the size of its code base (400 thousand lines), it's not so bad. Nevertheless, I hope that the authors will not neglect the code analysis tools to improve the quality of their product. Use PVS-Studio and I wish you bugless code! 0 comments 10. Intention This article is intended to give a brief look into the logistics of machine learning. Do not expect to become an expert on the field just by reading this. However, I hope that the article goes into just enough detail so that it sparks your interest in learning more about AI and how it can be applied to various fields such as games. Once you finish reading the article, I recommend looking at the resources posted below. If you have any questions, feel free to message me on Twitter @adityaXharsh. How Neural Networks Work Neural networks work by using a system of receiving inputs, sending outputs, and performing self-corrections based on the difference between the output and expected output, also known as the cost. Neural networks are composed of neurons, which in turn compose layers, or collections of neurons. For example, there is an input layer and an output layer. In between the these two layers, there are layers known as hidden layers. These layers allow for more complex and nuanced behavior by the neural network. A neural network can be thought of as a multi-tier cake: the first tier of the cake represents the input, the tiers in between, or lack thereof, represent the hidden layers, and the last tier represents the output. The two mechanisms of learning are Forward Propagation and Backward Propagation. Forward Propagation uses linear algebra for calculating what the activation of each neuron of the next layer should be, and then pushing, or propagating, those values forward. Backward Propagation uses calculus to determine what values in the network need to be changed in order to bring the output closer to the expected output. Forward Propagation As can be seen from the gif above, each layer is composed of multiple neurons, and each neuron is connected to every other neuron of the following and previous layer, save for the input and output layers since they are not surrounding by layers from both sides. To put it simply, a neural network represents a collection of activations, weights, and biases. They can be defined as: Activation: A value representing how strongly a neuron is firing. Weight: How strong the connection is between two neurons. Affects how much of the activation is propagated onto the next layer. Bias: A minimum threshold for whether or not the current neuron's activation and weight should affect the next neuron's activation. Each neuron has an activation and a bias. Every connection to every neuron is represented as a weight. The activations, weights, biases, and connections can be represented using matrices. Activations are calculated using this formula: After the inner portion of the function has been computed, the resulting matrix gets pumped into a special function known as the Sigmoid Function. The sigmoid is defined as: The sigmoid function is handy since its output is locked between a range of zero and one. This process is repeated until the activations of the output neurons have been calculated. Backward Propagation The process of a neural network performing self-correction is referred to as Backward Propagation or backprop. This article will not go into detail about backprop since it can be a confusing topic. To summarize, the algorithm uses a technique in calculus known as Gradient Descent. Given a plane in an infinite number of dimensions, the direction of change that minimizes the error must be found. The goal of using gradient descent is to modify the weights and biases such that the error in the network approaches zero. Furthermore, you can find the cost, or error, of a network using this formula: Unlike forward propagation, which is done from input to output, backward propagation goes from output to input. For every activation, find the error in that neuron, how much of a role it played in the error of the output, and adjust accordingly. This technique uses concepts such as the chain rule, partial derivatives, and multi-variate calculus; therefore, it's a good idea to brush up on one's calculus skills. High Level Algorithm Initialize matrices for weights and biases for all layers to a random decimal number between -1 and 1. Propagate input through the network. Compare output with the expected output. Backwards propagate the correction back into the network. Repeat this for N number of training samples. Source Code If you're interested in looking into the guts of a neural network, check out AI Chan! It's a simple to integrate library for machine learning I wrote in C++. Feel free to learn from it and use it in your own projects. https://bitbucket.org/mrsaturnsan/aichan/ Resources http://neuralnetworksanddeeplearning.com/ https://www.youtube.com/channel/UCWN3xxRkmTPmbKwht9FuE5A 0 comments 11. The following is an excerpt from the book, Unity 2017 Game Development Essentials - Third Edition written by Tommaso Lintrami and published by Packt Publishing. Unity makes the game production process simple by giving you a set of logical steps to build any conceivable game scenario. Renowned for being non-game-type specific, Unity offers you a blank canvas and a set of consistent procedures to let your imagination be the limit of your creativity. Essential Unity concepts By establishing the use of the Game Object concept, you are able to break down parts of your game into easily manageable objects, which are made of many individual component parts. By making individual objects within the game, introducing functionality to them with each component you add, you are able to infinitely expand your game in a logical, progressive manner. Component parts in turn have Variables, which are essentially properties of the component, or settings to control them with. By adjusting these variables, you'll have complete control over the effect that a component has on your object. The following diagram illustrates this: Assets These are the building blocks of all Unity projects. From textures in the form of image files, through 3D models for meshes, and sound files for effects, Unity refers to the files you'll use to create your game as assets. This is why, in any Unity project folder, all files used are stored in a child folder named Assets. This Assets folder is mirrored in the Project panel of the Unity interface; see the interface section in this chapter for more detail. Scenes In Unity, you should think of scenes as individual levels or areas of game content. However, some developers create entire games in a single scene, such as puzzle games, by dynamically loading content through the code. By constructing your game with many scenes, you'll be able to distribute loading times and test different parts of your game individually. New scenes are often used separately to a game scene you may be working on in order to prototype or test a piece of potential gameplay. Any currently open scene is what you are working on. In Unity 2017, you can load more scenes into the hierarchy while editing, and even at runtime, through the new SceneManager API, where two or more scenes can be worked on simultaneously. Scenes can be manipulated and constructed by using the Hierarchy and Scene views. OK, now that we know what assets and scenes let’s start setting up a scene and building a game asset. Setting up a scene and preparing game assets Create a new scene from the main menu by navigating to Assets | Create | Scene, and name it ParallaxGame. In this new scene, we will set up, step by step, all the elements for our 2D game prototype. First of all, we will switch the camera setting in the Scene view to 2D by clicking on the button as shown by the red arrow in the following screenshot: As you can see, now the Scene view camera is orthographic. You can't rotate it as you wish, as you can do with the 3D camera. Of course, we will want to change this setting on our Main Camera as well. Also, we want to change the Orthographic size to 4.5 to have the correct view of the scene. Instead, for the Skybox, we will choose a very dark or black color as clear color in the depth setting. This is how the Inspector should look when these settings are done: While the Clipping Planes distances are important for setting the size of the frustum cone of a 3D, for the Perspective camera (inside which everything will be rendered by the engine), we should only set the Orthographic Size to 4.5, to have the correct distance of the 2D camera from the scene. When these settings are done, proceed by importing Chapter2-3-4.unitypackage into the project. You can either double-click on the package file with Unity open, or use the top menu: Assets | Import | Custom Package. If you haven't imported all the materials from the book's code already, be sure to include the Sprites subfolder. After the import, look in the Sprites/Parallax/DarkCave folder in the Project view and you will find some images imported as textures (as per default). The first thing we want to do now is to change the import settings of these images, in the Inspector, from Texture to Sprite (2D and UI). To do so, select all the images in the Project view in the Sprites/Parallax/DarkCave folder, all except the _reference_main_post file. Which is just a picture used as a reference of what the game level should look like: The Import Settings shown in the Inspector after selecting the seven images in the Project view The Max Size setting is hidden (-) because we have a multi-selection of image files. After having made the multiple selections, again, in the Inspector, we will do the following: Set the Texture Type option to Sprites (2D and UI). By default, images are imported as textures; to import them as Sprites, this type must be set. Uncheck the Generate Mip Maps option as we don't need MIP maps for this project as we are not going to look at the Sprites from a distant point of view, for example, games with the zoom-in/zoom-out feature (like the original Grand Theft Auto 2D game) would need this setting checked. Set Max Size to the maximum allowed. To ensure that you import all the images at their maximum resolution, set this to 8192. This is the maximum resolution size for an image on a modern PC, imported as a Sprite or texture. We set it so high because most of the background images we have in the collection are around 6,000 pixels wide. Click on the Apply button to apply these changes to all the images that were selected: The Project view showing the content of the folder after the images have been set to Sprite in the Import Settings. Placing the prefabs in the game Unity can place the prefabs in the game in many ways, the usual, visual method is to drag a stored prefab or another kind of file/object directly into the scene. Before dragging in the Sprites we imported, we will create an empty GameObject and rename it ParallaxCave. We will drag the layer images we just imported as Sprites, one by one, from the Project view (pointing at the Assets/Chapters2-3-4/Sprites/Background/DarkCave folder) into the Scene view, or more simply, directly in the Hierarchy view as the children of our ParallaxCaveGameObject, resulting in a scene Hierarchy like the one illustrated here: You can't drag all of them instantly because Unity will prompt you to save an animation filename for the selected collection of Sprites; we will see this later for our character and for the collectable graphics. Importing and placing background layers In any game engine, 2D elements, such as Sprites, are rendered following a sort order; this order is also called the z-order because it is a way to express the depth or to cope with the missing z axis in a two-dimensional context. The sort order is assigned an integer number which can be positive or negative; 0 is the middle point of this draw order. Ideally, a sort order of zero expresses the middle ground, where the player will act, or near its layer. Look at this image: Image courtesy of Wikipedia: parallax scrolling All positive numbers will render the Sprite element in front of the other elements with a lower number. The graphic set we are going to use was taken from the Open Game Art website at http://opengameart.org. For simplicity, the provided background image files are named with a number within parentheses, for example, middleground(z1), which means that this image should be rendered with a z sort order of 1. Change the sort order property of the Sprite component on each child object under ParallaxCave according to the value in the parentheses at the end of their filenames. This will rearrange the graphics into the appropriately sorted order. After we place and set the correct layer order for all the images, we should arrange and scale the layers in a proper manner to end as something like the reference image furnished in the Assets/Chapters2-3-4/Sprites/Background/DarkCave/ folder. You can take a look at the final result for this part anytime, by saving the current scene and loading the Chapter3_start.unity scene. You just read an excerpt from the book, Unity 2017 Game Development Essentials - Third Edition written by Tommaso Lintrami and published by Packt Publishing. Use the code ORGDA10 at checkout to get recommended eBook retail price for$10 only until April 30, 2018.
By khawk
12. This reference guide has now been proofread by @stimarco (Sean Timarco Baggaley). Please give your thanks to him. The guide should now be far easier to read and understand than previous revisions, enjoy! Note: The normal mapping tutorial has been temporarily moved, to be added back as its own topic, to help separate the two for more clarity.   If anyone has any corrections, please contact me. 3D Graphics Primer 1: Textures. This is a quick reference for artists who are starting out. The first topic revolves around textures and the many things an artist who is starting out needs to understand. I am primarily a 3d artist and my focus will therefore be primarily on 3d art. However, some of this information is applicable to 2d artists. Textures What is a texture?

By classical definition a texture is the visual and esp. tactile quality of a surface (Dictionary.com).

Since current games lack the ability to convey tactile sensations, a texture in game terms simply refers to the visual quality of a surface, with an implicit tactile quality. That is, a rock texture should give the impression of the surface of a rock, and depending on the type, a rough or smooth tactile quality. We see these types of surfaces in real life and feel them in real life. So when we see the texture, we know what it feels like without needing to touch it due to our past experiences. But a lot more goes into making a convincing texture beyond the simple tactile quality.

As you will learn as you read on, textures in games is a very complex topic, with many elements involved in creating them for realtime rendering.

We will look at: Texture File Types & Formats Texture Image Size Texture File Size Texture Types Tiling Textures Texture Bit Depth Making Normal Maps (Brief overview only) Pixel Density and Fill Rate Limitation Mipmaps Further Reading     Further Reading Creating and using textures is such a big subject that covering it entirely within this one primer is simply not sensible. All I can sensibly achieve here is a skimming over the surface, so here are some links to further reading matter.

Beautiful Yet Friendly - Written by Guillaume Provost, hosted by Adam Bromell. This is a very interesting article that goes into some depth about basic optimizations and the thought process when designing and modeling a level. It goes into the technical side of things to truly give you an understanding on what is going on in the background. You can use the information in this article to find out how to build models that use fewer resources -- polygons, textures, etc. -- for the same results.
This is the reason why this is the first article I am linking to: it is imperative to understand the topics discussed in this article. If you need any extra explanation after reading it, you can PM me and I am more than happy to help. However, parts of this article go outside the texture realm of things and into the mesh side, so keep that in mind if you're focusing on learning textures at the moment.

UVW Mapping Tutorial - by Waylon Brinck. This is about the best tutorial I have found for a topic that gives all 3D artists a headache: unwrapping your three-dimensional object into a two-dimensional plane for 2D painting. It is the process by which all 3D artists place a texture on a mesh (model). NOTE: while this tutorial is very good and will help you in learning the process, UVW mapping/unwrapping is just one of those things you must practice and experiment with for a while before you truly understand it.

Poop In My Mouth's Tutorials - By Ben Mathis. Probably the only professional I know who has such a scary website name, but don't be afraid! I swear there is nothing terrible beyond that link. He has a ton of excellent tutorials, short and long, that cover both the modeling and texturing processes, ranging from normal-mapping to UVW unwrapping. You may want to read this reference first before delving into some of his tutorials. Texture File Types & Formats In the computer world, textures are really nothing more than image files applied to a model. Because of this, a variety of common computer image formats can be used. These include, .TGA, .DDS, .BMP, and even .JPG (or .JPEG). Almost any digital image format can be used, but some things must be taken into consideration:

In the modern world of gaming, being heavily reliant on shaders, formats like the .JPG format are rarely used. This is because .JPG, and others like it, are lossy formats, where data in the image file is actually thrown away to make the file smaller. This process can result in compression artifacts The problem is that these artifacts will interfere with shaders, because these rely on having all the data contained within the image intact. Because of this, lossless formats are used -- formats like .DDS (if lossless option chosen), .BMP, and .TGA.

However, there is such a thing called S3TC (also known as "dxt") compression. This was a compression technique developed for use on Savage 3D graphics cards, with the benefit of keeping a texture compressed within video memory whereas non-S3TC-compressed textures are not. This results in a 1:8 or greater compression ratio and can allow either more textures to be used in a scene, or can be used to increase the resolution of a texture without using more memory. S3TC compression can be made to work with any format, but is most commonly associated with the .DDS format.

Just like the .jpg and other lossy formats, any texture using S3TC will suffer compression artifacts, and as such is not suitable for normal maps, (which we'll discuss a little later on).

Even with S3TC it is common to use a lossless format for the texture format, and then apply S3TC when necessary. This is done to provide an artist with the ability to have lossless textures when needed -- e.g. for normal maps -- but then provide them with a method for compression on textures that could benefit from S3TC compression, such as diffuse textures. Texture Image Size The engineers who design computers and their component parts like us to feed data to their hardware in chunks that have dimensions defined as powers of two. (E.g. 16 pixels, 32 pixels, 64 pixels, and so on.) While it is possible to have a texture that is not the power of two, it is generally a good idea to stick to power-of-two sizes for compatibility reasons (especially if you're targeting older hardware). That is, if you're creating a texture for a game, you want to use image dimensions that are the power of two. Examples, 32x32, 16x32, 2048x1024, 1024x1024, 512x512, 512x32, etc. Say for example, you have a mesh/model and you're UV Unwrapping, for a game you must work within dimensions that are a power of two.

Powers of two include: 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, and so on.

What if you want to use images that aren't powers of two? In such cases, you can often use uneven pixel ratios. This means you can create your texture at, say, 1024x768, and then you can save it as 1024x1024. When you're applying your texture to your mesh you can stretch it back out in proportion. However, it is best to go for a 1:1 pixel ratio and create the texture starting at the power of 2, but the stretching is one method for getting around this if needed

Please refer to the "Pixel Density and Fill Rate Limitation" section for more in depth info on how exactly to choose your image size. Texture File Size File size is important for a number of reasons. The file is the actual amount of memory (permanent or temporary) that the texture requires.
For an obvious example, an uncompressed .BMP could be 6MB, this is the space it requires to be saved on a hard drive and within the video and/or system RAM. Using compression we can squeeze the same image into a file size of, say, 400 KB, or possibly even smaller. Compression, like that used by .JPG and other similar formats, will only do compression on permanent storage media, such as hard drives. That is to say, when the image is stored in video card memory it must be uncompressed within the memory, so you truly only get a benefit on storing the texture on its permanent medium but not in memory during use. Enter S3TC The key benefit of the S3TC compression system is that it compresses on hard drives, discs, and other media, while also staying compressed within video card memory.

But why should you care what size it is within the video memory?

Video cards have onboard memory called, unsuprisingly enough, video memory, for storing data that needs to be accessed fast. This memory is limited, so considerations on the artists' part must be used. The good news is that video card manufacturers are constantly adding more of this video memory -- known as Video RAM (or VRAM for short). Where once 64 MB was considered good, we can now find video cards with up to 1 GB of RAM.

The more textures you have, the more RAM will be used. The actual amount is based primarily on the file size of each texture. Other data take up video memory, such as the model data itself, but the majority is used for textures. For this reason, it is a good idea to both plan your video memory usage and test how much you're using once in the engine. It is also advised that you have a minimum hardware configuration for what you want your game to run on. If this is the case, then you should always make sure your video memory usage does not go over the minimum target hardware's amount.

Another advantage of in-memory compression like S3TC is that it can increase available bandwidth. If you know your engine on your target hardware may be swapping textures back and forth frequently (something that should be avoided if possible, but is a technique used on consoles), then you may want to consider having the textures compressed and then decompress them on the fly. That is to say, you have the textures compressed, and then when they're required, they're transported and then decompressed as they're added to video memory. This results in less data having to be shunted across the graphics card's bus (transport line) to and from the computer's main memory, resulting in less bandwidth utilization, but with the added penalty of a few wasted processing clocks. Texture Types Now we're going to discuss such things are diffuse, normal, specular, parallax and cube mapping.
Aside from the diffuse map, these mapping types are common in what have become known as 'next-gen' engines, where the artist is given more control over how the model is rendered by use of control maps for shaders. Diffuse maps are textures which simply provide the color and any baked-in details. Games before shaders simply used diffuse textures. (You could say this is the 'default' texture type.) For example, when texturing a rock, the diffuse map of the rock would be just the color and data of that rock. Diffuse textures can be painted by hand or made from photographs, or a mixture of both.

However, in any modern engine, most lighting and shadow detail is preferred to not be 'baked' (i.e. pre-drawn directly into the texture) into the diffuse map, but instead to have just the color data in the diffuse and use other control maps to recreate such things as shadows, specular reflections, refraction effects and so on. This results in a more dynamic look for the texture overall, helping its believability once in-game. 'Baking' such details will hinder the game engine's ability to produce "dynamic" results, which will cause the end result to look unrealistic.

There is sometimes an exception to this rule: if you're providing "general" shading/lighting like ambient occlusion maps baked (merged) into the diffuse, then it is ok. These types of additions into the diffuse are general enough that they won't hinder the dynamic effect of running in a realtime engine, while achieving a higher level of realism.

Another point to remember is that while textures sourced from photographs tend to work very well in 3D environment work, it is often frowned upon to use such 'photosourced textures' for humans. Human diffuse textures are usually hand-painted.

Normal maps are used to provide lighting detail for dynamic lighting, however this is involved in an even more important role, as we will discuss shortly. Normal maps get their name from the fact that they recreate normals on a mesh using a texture. A 'normal' is a point (actually a vector) extending from a triangle on a mesh. This tells the game engine how much light the triangle should receive from a particular light source -- the engine simply compares the angle of the normal with the position and angle of the light itself and thus calculates how the light strikes the triangle. Without a normal map, the game engine can only use the data available in the mesh itself; a triangle would only have three normals for the engine to use -- one at each point -- regardless of how big that triangle is on the screen, resulting in a flat look. A normal map, on the other hand, creates normals right across a mesh's surface. The result is the capability to generate a normal map from a 2 million poly mesh and have this lighting detail recreated on a 200 poly mesh. This can allow an artist to recreate a high-poly mesh with relatively low polygons in comparison.

Such tricks are associated with 'next-gen' engines, and are heavily used in screenshots of the Unreal 3 Engine, where you can see large amounts of detail yet able to run in realtime due to the actual amount of polys used. Normal maps use the different color channels (red, green, and blue) for storing gray scale data of lighting information at different angles, however there is no set standard for how these channels can be interpreted and as such sometimes require a channel to be flipped for correct function in an engine.

Normal maps can be generated from high-poly meshes, or they can be image generated, that is, being generated from a gray scale map. However, high-poly generated normal maps tend to be preferred as they tend to have more depth. This is for various reasons, but the main one is that it is difficult for most to paint a grayscale map that is equal to the quality you'll receive straight from a model. Also, you will often find that the image generators tend to miss details, requiring the artist to edit the normal map by hand later. However, it is not impossible to receive near equal results using both methods, each have their own requirements, it is up to you on which to use in each situation

(Please refer to the tutorial section for extended information on normal maps.)

Specular maps are simple in creation. They are easy to paint by hand, because the map is simply a gray scale map that defines the specular level for any point on a mesh. However, in some engines and in 3D modeling applications this map can be full-color so the brightness defines the specular level and color defines the color of the specular highlights. This gives the artist finer control to produce more lifelike textures because the specific specular attribute of certain materials can be more defined and closer to reality. In this way you can give a plastic material a more plastic-like specular reflection, or simulate a stone's particular specular look.

Parallax mapping picks up where regular normal mapping fails. We create normals on a model by use of a normal map. A parallax map does the same thing as a normal map except it samples a grayscale map within the alpha channel. Parallax mapping works by using the angles recorded in the tangent space normal maps along with the heightmap to calculate which way to displace the texture coordinates. It uses the grayscale map to define how much the texture should be extruded outwards, and uses the angle information recorded in the tangent normal map to determine the angle to offset the texture. Doing things this way a parallax map can then recreate the extrusion of a normal map, but without the flattening that visible in ordinary normal mapping due to lack of data at different perspectives. It mainly gets its name from how the effect is created by the parallax effect. The end results are cleaner and deeper extrusions with less flattening that occurs in normal mapping because the texture coordinates are offset with your perspective.

Parallax mapping is usually more costly than normal mapping. Parallax also has the limitation of not being used on deformable meshes because of the tendency for the texture to "swim" due to the way textures are offset.

Cube mapping uses a texture that is not unlike an unfolded box and acts just like a sky box when used. Basically this texture is designed like an unfolded box where it all is folded back together when being used. This allows us to create a 3d dimensional reflection of sorts. The result is very realistic precomputed reflections. For example, you would use this technique to create a shiny, metal ball. The cube map would provide the reflection data. (In some engines, you can tell the engine itself to generate a cube map from a specific point in the scene and have it apply the result to a model. This is how we get shiny, reflective cars in racing games, for example. The engine is constantly taking cube map 'photos' for each car to ensure it reflects its surroundings accurately.) Tiling Textures Now, while you can have unique, specific textures made for specific models, a common thing to do to both save time and video memory, is tiling textures. These are textures which can be fitted together like floor or wall tiles, producing a single, seamless texture/image. The benefit is that you can texture an entire floor in an entire building using a single tiling texture, which both saves the artist's time, and video memory due to fewer textures being needed.

A tiling texture is achieved by having the left and right side of a texture blend into each other, and the same for the bottom and top of the texture. Such blending can be achieved by the use of a specialist program, a plugin, or by simply offsetting the texture a little to the left and down, cleaning up the seams, and then offsetting back to the original position

After you create your first tiling texture and test it, you're bound to see that each texture will produce a 'tiling artifact' which shows how and where the texture is tiled. Such artifacts can be reduced by avoiding high-contrast detail, unique detail (such as a single rock on a sand texture), and by tiling the texture less. Texture Bit Depth A texture is just an image file. This means most of the theory you're familiar with when it comes to working with images also applies to textures. One such would be bit depth. Here you will see such numbers as 8, 16, 24, and 32 bits. These each correspond to the amount of color data that is stored for each image.

How do we get the number 24 from an image file? Well, the number 24 refers to how many bits it contains. That is, that you have 3 channels, red, green, and blue, all of which are simply channels which contain a gray scale image, but are added together to produce a full color image. So black, in the red channel, means "no red" at that point, while white in the red channel means "lots of red". Same applies to blue and green. When these are combined, they produce a full color image, a mix of Red, Green and Blue (if using the RGB color model). The bits come in by the fact that they define how many levels of gray each channel has: 8 bits per channel, over 3 channels, is 24 bits total.

8 bits gives you 256 levels of gray. Combining the idea that 8 bits gives you 256 levels of gray and that each channel is simply gray scale and different levels of gray define a level within that color, we can then see that a 24 bit image will give us 16,777,216 different colors to play with. That is, 8 bits x 3 channels= 24 bits, 8 bits= 256 gray scale levels, so 256 x 3= 16,777,216 colors. This knowledge comes in useful when at certain times it is easier to edit the RGB channels individually, with a correct understanding you can then delve deeper into editing your textures.

However, with the increase in shader use, you'll often see a 32 bit image/texture file. These are image files which contain 4 channels, each of 8 bits: 4 x 8 = 32. This allows a developer to use the 4th channel to carry a unique control map or extra data needed for shaders. Since each channel is gray scale, a 32 bit image is ideal to carry a full color texture along with an extra map within it. Depending on your engine you may see a full color texture with the extra 4th channel being used to hold a gray scale map for transparency (more commonly known as an "alpha channel"), specular control map, or a gray scale map along with a normal map in the other channels to be used for parallax mapping.

As you paint your textures you may start to realize that you're probably not using all of the colors available to you in a 24 bit image. And you're probably right, this is why artists can at times use a lower bit depth texture to achieve the same or near the same look with a lesser memory footprint. There are certain cases where you will more than likely need a 24 bit image however: If your image/texture contains frequent gradations in the color or shading, then a 24 bit image is required. However, if your image/texture contains solid colors, little detail, little or no shading, and so on, you can probably get away with a 16, 8, or perhaps even a 4 bit texture.

Often, this type of memory conservation technique is best done when the artist is able to choose/make his own color pallette. This is where you hand pick the colors that will be saved with your image, instead of letting the computer automatically choose. By using a careful eye you have the possibility to choose more optimal colors which will fit your texture better. Basically, in a way, all you're doing is throwing out what would be considered useless colors which are being stored in the texture but not being used. Making Normal Maps There are two methods for creating normal maps: Using a detailed mesh/model. Creating a normal map from an image.
The first method is part of a common workflow that nearly all modelers who support normal map generation use. For generating a normal map from a model you can either generate it out to a straight texture, or if you're generating your normal map from a high-poly mesh, it is common to then model the low poly mesh around your high-poly mesh. (Some artists have prefer for modeling the low-poly version first while others like to do the high then the low, in the end there is no perfect way, its just preference.)

For generating normal maps you can always use the Nvidia Plugin, however it takes a lot of tweaking to get a good looking normal map. As such, I recommend Crazy Bump!. Crazy Bump will produce some very good normal maps if the given texture it is generating it from is good. Combining the two methods. It is common, even if you're generating a normal map from a 3d high-poly mesh to then generate an image generated normal map and overlay it over the high-poly generated one. This is done by generating one from your diffuse map, filling the resulting normal map's blue channel with 128 neutral gray, and then overlaying this over your high-poly generated one. This is done to add in those small details that only the image can generate. This way you get the high frequency detail along with the nice and cleanly generated mid-to-low frequency detail from your high-poly generated normal map. Pixel Density and Fill Rate Limitation Let's say you have a coin that you just finished UVW unwrapping, it will indeed be very small once in-game, however you decide it would be fine to use a 1024x1024 texture. What is wrong with the above situation? Firstly, you shouldn't need to UVW unwrap a coin! Furthermore, you should not be applying the 1024x1024 texture! Not only is this wasteful of video memory, but it will result in uneven pixel density and will increase your fill rate on that model for no reason. A good rule of thumb is to only use the amount of resources that would make sense based on how much screen space an object will take up. A building will take up more of the screen than a coin, so it needs a higher resolution texture and more polygons. A coin takes up less screen space and therefore needs fewer polys and a lower resolution texture to obtain a similar pixel density.

So, what is pixel density? It is the density of each pixel from a texture on a mesh. For example, take the UVW unwrapping tutorial linked to in the "Texture Image Size" section: There you will see a checkered pattern, this is not only used to make sure the texture is applied right, but to also keep track of pixel density. If you increased the pixel density, you would see the checkered pattern get more dense; if you decrease the density, the checkered pattern would be less dense, with fewer squares showing.

Maintaining a consistent pixel density in a game helps all of the art fit together. How would you feel if your high pixel density character walks up to a wall with a significantly lower pixel density? Your eyes would be able to compare the two and see that the wall looks like crap compared to the character, however would this same thing happen if the character were near the same pixel density of the wall? Probably not -- such things only become apparent (within reason) to the end user if they have something to compare it to. If you keep a consistent pixel density throughout all of the game's assets, you will see all of it fits together better.

It is important to note that there is one other reason for this, but we'll come to it in a moment. First, we need to look at two related problems that can arise: transform(ation) limited and fill-rate limited modeling. A transform-limited model will have less pixel density per polygon than a fill-rate limited model where it has a higher pixel density per polygon. The theory is that a model takes longer on either processing the polys, or processing the actual pixel-dense surface. Knowing this, we can see that our coin, with very few polys will have a giant pixel density per polygon, resulting in a fill rate limited mesh. However, it does not need to be fill rate limited if we lower the texture resolution, resulting in a lower pixel density.

The point is that your mesh will be held back when rendering based on which process takes longer: transform or fill rate. If your mesh is fill rate limited then you can speed up its processing by decreasing its pixel density, and its speed will increase until you reach transform limitation, in which your mesh is now taking longer to render based on the amount of polygons it contains. In the latter case, you would then speed up the processing of the model by decreasing the amount of polygons the model contains. That is, until you decrease the polygon count to the point where you're now fill rate limited once again! As you can see, it's a balancing act. The trick is to maximize the speed of the transform and fill rate processing (minimize the impact of both as much as you can), to get the best possible processing speed for your mesh.

That said, being fill rate limited can sometimes be a good thing. The majority of "next-gen" games are fill rate limited primarily because of their use of texture/shading techniques. So, if you can't possibly get any lower on the fill rate limitation and you're still fill rate limited, then you have a little bit of wiggle room to work around where you can actually introduce more polygons with no performance hit. However, you should always try to cut down on fill rate limitations when possible because of general performance concerns

Some methods revolve around splitting up a single polygon into multiple polygons on a single mesh (like a wall for example). This works by then decreasing the pixel density and processing (shaders) for the single polygon by splitting the work into multiple polygons. There are other methods for dealing with fill rate limitation, but mainly it is as simple as keeping your pixel density at a reasonable level.       MipMaps It is fitting that after we discuss pixel density and fill rate limitation that we discuss a thing called Mipmapping. Mipmaps (or mip maps) are a collection of precomputed lower resolution image copies for a texture contained in the texture. Let's say you have a 1024x1024 texture. If you generate mipmaps for your texture, it will contain the original 1024x1024 texture, but it will also contain a 512x512, 256x256, 128x128, 64x64, 32x32, 16x16, 8x8, 4x4, 2x2 version of the same texture, (exactly how many levels there are is up to you). These smaller mipmaps (textures) are then used in sequence, one after the other, according to the model's distance from the camera in the scene. If your model uses a 1024x1024 texture up close, it may be using a 256x256 texture when further away, and an even smaller mipmap texture level when it's way off in the distance. This is done because of many things: The further away you are from your mesh, the less polygonal and texture detail is needed. This is because all displays have a fixed display resolution and it is physically impossible for the player to decipher the detail of a 1024x1024 texture and 6,000 polygon mesh when the model takes up only 20 pixels on screen. The further away we are from the mesh, the fewer the polygons and the lower the texture resolution we need to render it. Because of the whole fill rate limitation described above, it is beneficial to use mipmaps as less texture detail must be processed for distant meshes. This results is a less fill-rate-heavy scene because only the closer models are receiving larger textures, whereas more distant models are receiving smaller textures. Texture filtering. What happens when the player tries to view a 1024x1024 texture at such a distance that only 40 pixels are given to render the mesh on screen? You get noise and aliasing artefacts! Without mipmaps, any textures too large for the display resolution will only result in unneeded and unwanted noise. Instead of filtering out this noise, mipmaps use a lower resolution texture for different distances, this results in less noise. It is important to note, that while mipmaps will increase performance overall, you're actually increasing your texture memory usage. The mipmaps and the whole texture will be loaded into memory. However, it is possible to have a system where the user or dev can select the highest mipmap they want and the ones higher than this limit will not be loaded into memory (as the system we're using now), however the mipmaps which meet or are lower than this limit will still be loaded into memory. It is widely agreed that the benefits of mipmaps vastly outweigh the small memory hit. NOTE: Mesh detail can also affect performance, so the equivalent method used for mesh detail is known as LOD -- "Level Of Detail. Multiple versions of the mesh itself are stored at different levels of detail. The less-detailed mesh is rendered when it's a long way away. Like mipmaps, a mesh can have any number of levels of detail you feel it requires.

The image below is of a level I created which makes use of most of what we've discussed. It makes use of S3TC compressed textures, normal mapping, diffuse mapping, specular mapping, and tiled textures.

17. Overview Welcome to the 2D UFO game guide using the Orx Portable Game Engine. My aim for this tutorial is to take you through all the steps to build a UFO game from scratch. The aim of our game is to allow the player to control a UFO by applying physical forces to move it around. The player must collect pickups to increase their score to win. I should openly acknowledge that this series is cheekily inspired by the 2D UFO tutorial written for Unity. It makes an excellent comparison of the approaches between Orx and Unity. It is also a perfect way to highlight one of the major parts that makes Orx unique among other game engines, its Data Driven Configuration System. You'll get very familiar with this system very soon. It's at the very heart of just about every game written using Orx. If you are very new to game development, don't worry. We'll take it nice and slow and try to explain everything in very simple terms. The only knowledge you will need is some simple C++. I'd like say a huge thank you to FullyBugged for providing the graphics for this series of articles.   What are we making? Visit the video below to see the look and gameplay of the final game: Getting Orx The latest up to date version of Orx can be cloned from github and set up with: git clone https://github.com/orx/orx.git Once cloning has completed, the setup script in the root of the files will start automatically for you. This script creates an $ORX environment variable for your system. The variable will point to the code subfolder where you cloned Orx. Why? I'll get to the in a moment, but it'll make your life easier. The setup script also creates several projects for various IDEs and operating system: Visual Studio, Codelite, Code::Blocks, and gmake. You can pick one of these projects to build the Orx library. Building the Orx Library While the Orx headers are provided, you need to compile the Orx library so that your own games can link to it. Because the setup script has already created a suitable a project for you (using premake), you can simply open one for your chosen OS/IDE and compile the Orx library yourself. There are three configurations to compile: Debug, Profile and Release. You will need to compile all three. For more details on compiling the Orx lbrary at: http://orx-project.org/wiki/en/tutorials/cloning_orx_from_github at the Orx learning wiki. The$ORX Environment Variable I promised I would explain what this is for. Once you have compiled all three orx library files, you will find them in the code/lib/dynamic folder: orx.dll orxd.dll orxp.dll Also, link libraries will be available in the same folder: orx.lib orxd.lib orxp.lib When it comes time to create our own game project, we would normally be forced to copy these library files and includes into every project. A better way is to have our projects point to the libraries and includes located at the folder that the $ORX environment variable points to (for example: C:\Dev\orx\code). This means that your projects will always know where to find the Orx library. And should you ever clone and re-compile a new version of Orx, your game projects can make immediate use of the newer version. Setting up a 2D UFO Project Now the you have the Orx libraries cloned and compiled, you will need a blank project for your game. Supported options are: Visual Studio, CodeLite, Code::Blocks, XCode or gmake, depending on your operating system. Once you have a game project, you can use it to work through the steps in this tutorial. Orx provides a very nice system for auto creating game projects for you. In the root of the Orx repo, you will find either the init.bat (for Windows) or init.sh (Mac/Linux) command. Create a project for our 2D game from the command line in the Orx folder and running: init c:\temp\ufo or init.sh ~/ufo Orx will create a project for each IDE supported by your OS at the specified location. You can copy this folder anywhere, and your project will always compile and link due to the$ORX environment variable. It knows where the libraries and includes are for Orx. Open your project using your favourite IDE from within the ufo/build folder. When the blank template loads, there are two main folders to note in your solution: config src Firstly, the src folder contains a single source file, ufo.cpp. This is where we will add the c++ code for the game. The config folder contains configuration files for our game.   What is config? Orx is a data driven 2D game engine. Many of the elements in your game, like objects, spawners, music etc, do not need to be defined in code. They can be defined (or configured) using config files. You can make a range of complex multi-part objects with special behaviours and effects in Orx, and bring them into your game with a single line of code. You'll see this in the following chapters of this guide. There are three ufo config files in the config folder but for this guide, only one will actually be used in our game. This is: ufo.ini All our game configuration will be done there. Over in the Orx library repo folder under orx/code/bin, there are two other config files: CreationTemplate.ini SettingsTemplate.ini These are example configs and they list all the properties and values that are available to you. We will mainly concentrate on referring to the CreationTemplate.ini, which is for objects, sounds, etc. It's good idea to include these two files into your project for easy reference. Alternatively you can view these online at https://github.com/orx/orx/blob/master/code/bin/CreationTemplate.ini and here: https://github.com/orx/orx/blob/master/code/bin/SettingsTemplate.ini   The code template Now to take a look at the basic ufo.cpp and see what is contained there. The first function is the Init() function. This function will execute when the game starts up. Here you can create objects have been defined in the config, or perform other set up tasks like handlers. We'll do both of these soon. The Run() function is executed every main clock cycle. This is a good place to continually perform a task. Though there are better alternatives for this, and we will cover those later. This is mainly used to check for the quit key. The Exit() function is where memory is cleaned up when your game quits. Orx cleans up nicely after itself. We won't use this function as part of this guide. The Bootstrap() function is an optional function to use. This is used to tell Orx where to find the first config file for use in our game (ufo.ini). There is another way to do this, but for now, we'll use this function to inform Orx of the config. Then of course, the main() function. We do not need to use this function in this guide. Now that we have everything we need to get start, you should be able to compile successfully. Run the program and an Orx logo will appear slowly rotating. Great. So now you have everything you need to start building the UFO game. If you experience an issue compiling, check the troubleshooting article for Orx projects    for help.   Setting up the game assets Our game will have a background, a UFO which the player will control, and some pickups that the player can collect. The UFO will be controlled by the player using the cursor keys. First you'll need the assets to make the game. You can download the file  assets-for-orx-ufo-game.zip which contains: The background file (background.png😞 The UFO and Pickup sprite images (ufo.png and pickup.png😞   And a pickup sound effect (pickup.ogg😞 pickup.ogg Copy the .png files into your data/texture folder Copy the .ogg file into your data/sound folder. Now these files can be accessed by your project and included in the game.   Setting up the Playfield We will start by setting up the background object. This is done using config. Open the ufo.ini config file in your editor and add the following:   [BackgroundGraphic] Texture = background.png Pivot = center   The BackgroundGraphic defined here is called a Graphic Section. It has two properties defined. The first is Texture which has been set as background.png. The Orx library knows where to find this image, due to the properties set in the Resource section:   [Resource] Texture = ../../data/texture   So any texture files that are required (just like in our BackgroundGraphic section) will be located in the ../../data/texture folder. The second parameter is Pivot. A pivot is the handle (or sometimes “hotspot” in other frameworks). This is set to be center. The position is 0,0 by default, just like the camera. The effect is to ensure the background sits in the center of our game window. There are other values available for Pivot. To see the list of values, open the CreationTemplate.ini file in your editor. Scroll to the GraphicTemplate section and find Pivot in the list. There you can see all the possible values that could be used. top left is also a typical value. We need to define an object that will make use of this graphic. This will be the actual entity that is used in the game:   [BackgroundObject] Graphic = BackgroundGraphic Position = (0, 0, 0)   The Graphic property is the section BackgroundGraphic that we defined earlier. Our object will use that graphic. The second property is the Position. In our world, this object will be created at (0, 0, 0). In Orx, the coordinates are (x, y, z). It may seem strange that Orx, being a 2D game engine has a Z axis. Actually Orx is 2.5D. It respects the Z axis for objects, and can use this for layering above or below other objects in the game. To make the object appear in our game, we will add a line of code in our source file to create it. In the Init() function of ufo.cpp, remove the default line: orxObject_CreateFromConfig("Object"); and replace it with: orxObject_CreateFromConfig("BackgroundObject"); Compile and run. The old spinning logo is now replaced with a nice tiled background object. Next, the ufo object is required. This is what the player will control. This will be covered in Part 2.
19. On the 2nd of November 2017 we launched a Kickstarter campaign for our game Nimbatus - The Space Drone Constructor, which aimed to raise $20,000. By the campaign’s end, 3000 backers had supported us with a total of$74,478. All the PR and marketing was handled by our indie developer team of four people with a very low marketing budget. Our team decided to go for a funding goal we were sure we could reach and extend the game’s content through stretch goals. The main goal of the campaign was to raise awareness for the game and raise funds for the alpha version.   Part 1 - Before Launch Is what we believed when we launched our first Kickstarter campaign in 2016. For this first campaign, we had built up a very dedicated group of people before the Kickstarter’s launch. Nimbatus also had a bit of a following before the campaign launched: ~ 300 likes on Facebook
~ 3500 followers on Steam However, there had been little interaction between players and us previous to the campaign's launch. This made us unsure whether or not the Nimbatus Kickstarter would reach its funding goal. A few weeks prior to launch, we started to look for potential ways to promote Nimbatus during the Kickstarter. We found our answer in social news sites. Reddit, Imgur and 9gag all proved to be great places to talk about Nimbatus. More about this in Part 3 - During the campaign. As with our previous campaign, the reward structure and trailer were the most time-consuming aspects of the page setup. We realised early that Nimbatus looks A LOT better in motion and therefore decided that we should show all features in action with animated GIFs. Two examples:   In order to support the campaigns storytelling, “we built a ship, now we need a crew!”, we named all reward tiers after open positions on the ship.   We were especially interested how the “Navigator” tier would do. This $95 tier would give backers free digital copies of ALL games our company EVER creates. We decided against Early Bird and Kickstarter exclusive rewards in order avoid splitting backers into “winners and losers”, based on the great advice from Stonemaier Game’s book A Crowdfunder’s Strategy Guide (EDS Publications Ltd. (2015). Their insights also convinced us to add a$1 reward tier because it lets people join the update loop to build up trust in our efforts. Many of our $1 backers later increased their pledge to a higher tier. Two of our reward tiers featured games that are similar to Nimbatus. The keys for these games were provided by fellow developers. We think that this is really awesome and it helped the campaign a lot! A huge thanks to Avorion, Reassembly , Airships and Scrap Galaxy <3 Youtubers and streamers are important allies for game developers. They are in direct contact with potential buyers/backers and can significantly increase a campaign’s reach. We made a list of content creators who’d potentially be interested in our game. They were selected mostly by browsing Youtube for “let’s play” videos of games similar to Nimbatus. We sent out a total of 100 emails, each with a personalized intro sentence, no money involved. Additionally, we used Keymailer . Keymailer is a tool to contact Youtubers and streamers. At a cost of$150/month you can filter all available contacts by games they played and genres they enjoy. We personalized the message for each group. Messages automatically include an individual Steam key. With this tool, we contacted over 2000 Youtubers/Streamers who are interested in similar games. How it turned out
- About 10 of the 100 Youtubers we contacted manually ended up creating a video/stream during the Kickstarter. Including some big ones with 1 million+ subscribers.
- Over 150 videos resulted from the Keymailer outreach. Absolutely worth the investment! Another very helpful tool to find Youtubers/Streamers is Twitter. Before, but also during the campaign we sent out tweets , stating that we are looking for Youtubers/Streamers who want to feature Nimbatus. We also encouraged people to tag potentially interested content creators in the comments. This brought in a lot of interested people and resulted in a couple dozen videos. We also used Twitter to follow up when people where not responding via email, which proved to be very effective. In terms of campaign length we decided to go with a 34 day Kickstarter. The main reason being that we thought it would take quite a while until the word of the campaign spread enough. In retrospective this was ok, but we think 30 days would have been enough too.
We were very unsure whether or not to release a demo of Nimbatus. Mainly because we were unsure if the game offered enough to convince players in this early state and we feared that our alpha access tier would potentially lose value because everyone could play already. Thankfully we decided to offer a demo in the end. More on this topic in Part 3 - During the campaign. Since we are based in Switzerland, we were forced to use CHF as our campaign’s currency. And while the currency is automatically re-calculated into $for American backers, it was displayed in CHF for all other international backers. Even though CHF and$ are almost 1:1 in value, we believed this to be a
hurdle. There is no way to tell for us how many backers were scared away because of this in the end.   Part 2: Kickstarter Launch We launched our Kickstarter campaign on a Thursday evening (UTC + 1) which is midday in the US. In order to celebrate the launch, we did a short livestream on Facebook. We had previously opened an event page and invited all our Facebook friends to it. Only a few people were watching and we were a bit stressed out. In order to help us spread the word we challenged our supporters with community goals. We promised that if all these goals were reached, each backer above $14 would receive an extra copy of Nimbatus. With most of the goals reached after the first week, we realized that we should have made the challenge a bit harder. The first few days went better than expected. We announced the Kickstarter on Imgur, Reddit, 9gag, Instagram, Facebook, Twitter, in some forums, via our Newsletter and on our Steam page. If you plan to release your game on Steam later on, we’d highly recommend that you set up your Steam page before the Kickstarter launches. Some people might not be interested in backing the game but will go ahead and wishlist it instead. Part 3: During The Campaign We tried to keep the campaign’s momentum going. This worked our mostly thanks to the demo we had released. In order to download the Nimbatus demo, people needed to head over to our website and enter their email address. Within a few minutes, they received an automated email, including a download link for the demo. We used Mailchimp for this process. We also added a big pop up in the demo to inform players about the Kickstarter. At first we were a bit reluctant to use this approach, it felt a bit sneaky. But after adding a line informing players they would be added to the newsletter and adding a huge unsubscribe button in the demo download mail, we felt that we could still sleep at night. For our previous campaign we had also released a demo. But the approach was significantly different. For the Nimbatus Kickstarter, we used the demo as a marketing tool to inform people about the campaign. Our previous Kickstarters’ demo was mainly an asset you could download if you were already checking out the campaign’s page and wanted to try the game before backing. We continued to frequently post on Imgur, Twitter, 9Gag and Facebook. Simultaneously, people streamed Nimbatus on Twitch and released videos on Youtube. This lead to a lot of demo downloads and therefore growth of our newsletter. A few hundred subs came in every day. Only about 10% of the people unsubscribed from the newsletter after downloading the demo. Whenever we updated the demo or reached significant milestones in the campaign, such as being halfway to our goal, we sent out a newsletter. We also opened a Discord channel, which turned out a be a great way to stay in touch with our players. We were quite surprised to see a decent opening and link click rate. Especially if you compare this to our “normal” newsletter, which includes mostly people we personally met at events. Our normal newsletter took over two years to build up and includes about 4000 subs. With the Nimbatus demo, we gathered 50’000 subs within just 4 weeks and without travelling to any conferences. (please note that around 2500 people subscribed to the normal newsletter during the Kickstarter) On the 7th day of the campaign we asked a friend if she would give us a shoutout on Reddit. She agreed and posted it in r/gaming. We will never forget what happened next. The post absolutely took off! In less than an hour, the post had reached the frontpage and continued to climb fast. It soon reached the top spot of all things on Reddit. Our team danced around in the office. Lots of people backed, a total of over$5000 came in from this post and we reached our funding goal 30 minutes after hitting the front page.   We couldn’t believe our luck. Then, people started to accuse us of using bots to upvote the post. Our post was reported multiple times until the moderators took the post down.
People downloaded the Nimbatus demo they heard about on social media/social news sites or from Youtubers/Streamers. By receiving newsletters and playing the demo they learned about the Kickstarter. Many of them backed and participated in community goals/competitions which brought in more new people.   Not much happened in terms of press. RockPaperShotgun and PCGamer wrote articles, both resulting in about $500, which was nice. A handful of small sites picked up the news too. We sent out a press release when Nimbatus reached its funding goal, both to manually picked editors of bigger sites and via gamespress.com. Part 4: Last Days Every person that hit the “Remind me” button on a Kickstarter page receives an email 48 hours before a campaign ends. This helpful reminder caused a flood of new pledges. We reached our last stretch goal a few hours before our campaign ended. Since we had already communicated this goal as the final one we withheld announcing any further stretch goals. We decided to do a Thunderclap 24 hours before the campaign ends. Even after having done quite a few Thunderclaps, we are still unsure how big of an impact they have. A few minutes before the Kickstarter campaign was over we cleaned up our campaign page and added links to our Steam page and website. Note that Kickstarter pages cannot be edited after the campaign ends! The campaign ended on a Tuesday evening (UTC + 1) and raised a total of$75’000, which is 369% of the original funding goal. After finishing up our “Thank you” image and sending it to our backers it was time to rest.   Part 5: Conclusion We are very happy with the campaign’s results. It was unexpected to highly surpass our funding goal, even though we didn’t have an engaged community when the campaign started. Thanks to the demo we were able to develop a community for Nimbatus on the go. The demo also allowed us to be less “promoty” when posting on social news sites. This way, interested people could get the demo and discover the Kickstarter from there instead of us having to ask for support directly when posting. This, combined with the ever growing newsletter, turned into a great campaign dynamic. We plan to use this approach again for future campaigns.
Growth 300 ------------------> 430 Facebook likes 1300 -----------------> 2120 Twitter followers 1000 -----------------> 50’000 Newsletter signups 3500 -----------------> 10’000 Followers on Steam 0 ---------------------> 320 Readers of subreddit 0 ---------------------> 468 People on Discord 0 ---------------------> 300 Members in our forum   More data 23% of our backers came directly from Kickstarter.
76% of our backers came from external sites.
For our previous campaign it was 36/64. The average pledge amount of our backers was \$26.
https://strayfawnstudio.com/
https://www.kickstarter.com/projects/strayfawnstudio/nimbatus-the-space-drone-constructor   Related Reading: Algo-Bot: Lessons Learned from our Kickstarter failure.

## GameDev Contractors

Email - studio@clintsuttonillustration.co.za
2. Hi. Our team deals with all kinds of graphics outsource. We work for any budget and are open for cooperation with indie developers. If you want to get high quality graphics for your games – you are welcome. We specialize in: - GUI design
- 2D characters with animations
- 2D locations Our portfolio can be found at: https://kalitrom.artstation.com Contact us: kalitrom@gmail.com
3. Sound design for games (soundtracks/SFX/VO) Your project will be filled with bright and juicy sound, and the music will be recognized from the very first notes! Our studio employs experienced specialists, so everyone is a professional in the business – musicians compose hits, sound designers create colorful sound effects, and dubbing actors play voices alive. Our team will help you to implement any idea in the field of sound – from rich and unique sound effects up to fascinating and thought-out soundtrack! We love and appreciate our customers, providing individual and responsible approach to every project. You will have full control over the operation and get a great result precisely to the intended deadline!

Portfolio and contacts on our website:
http://www.onsoundwaves.com
https://soundcloud.com/onsoundwaves

Contacts:
skype: yakovlev.j
mail: info@onsoundwaves.com

Reasons to choose us? We have developed sound design for more than 100 projects;
We can develop for you a unique sound design of the highest quality – your project will be implemented by the professionals who work in game development and have extensive experience in sound design for a number of successful projects;
We will do a test job on your project, so you can make sure of the quality of our work and the advantages of working with us;
Transfer of audio content is done by contract.
4. Hi. I'm Ziz. I want to Build Your Thing. I'm experienced with building systems and mechanics using Unity's C# scripting tools, ranging from fast 2D action games to complex number-crunchy backend things for RPGs. I'm a bit of a generalist; I can even do shader development in a pinch, and I have a solid base of other programming skillsets that might be of use to you - I've worked in Python, Ruby, C, C++, Javascript, and a bit of assembly hacking just 'cause. Hey, look, here's a screenshot of a cool cel shader thingy, and here are some jiffs with lots of nifty 2D effects, complex hand-rolled player physics, and whatnot. Also, I did all the pixel art there, so I guess that's another hat I can don if need be, huh. I have a few things up on my Github in varying stages of completion, if you wanna see some code. Contact me if you've got a proposal; I'm game for whatever.
5. Hello! My name is Mika Pilke and I've been a hobbyist musician and music writer for about 20 years. For now I haven't been too active looking for projects that need sounds or music, but I'd like to change that.
I've also been active gamer for 25 years, and it has been sort of a dream of creating them too. And since I like creating different atmospheres, it would seem quite logical move to offer my skills for someone who is developing them. Though of course I'm willing to do music for a lot more than for games only, if needed. I do have to mention that I'm not a rock-hard pro, but I am very serious with my stuff. Two years ago there was one project for what I did 30 songs/ambiences, but game never actually was finished. Does not really matter though, since it was a fun journey and did give some important experience nevertheless. I'm not sure of the total amount of songs I've done, but it is far over 100. As an artist I am quite versatile. I do have tendencies of creating a bit darker atmospheres, but really, feel free to ask anything or offer any kinds of projects! I might have something up in my sleeve. For now I have been mixing and mastering my work alone, but for commercial projects I do have some contacts I can use to master and enhance my creations to top quality (two ambient songs listed below are mastered a bit too quiet, since I lacked some tools for mastering back in the past). Right now I do have a full time job, so if you need 20 song in two weeks, I probably won't be able to do them all for you. But if you give me a month or (rather) few months, it definitely shouldn't be a problem. :) Anyway, here's some of my recent work. Everything you hear or see is my work (photos, 3D-modeling, animation, shooting, music, mixing, singing, editing ect.). Everything except artwork in the video of the song Hellbreaker in which Jaime Jasso has been creator of all the visual art. Dreamland Synthesis - Awaiting This song was made to serve as menu music or such (horror ect.). Dreamland Synthesis - Morbid Tomorrow Darkish ambient. Dreamland Synthesis - Nebula Core This one would maybe be suitable for some dark scifi-styled horror game. Dreamland Synthesis - Hellbreaker I think when I wrote this song I was imagining some sort of moment being chased. Dreamland Synthesis - In Peace With this one, my goal was to do a song that would fit to a RPG or JRPG. Village music? Dead Cold Ground - Towards Eternity This was my project at the beginning of this year. It kind of got out of the hand, and took almost a month to finish. :) Working alone takes it's toll.