General Game Programming Flashcards
How would you go about resizeing a game to fit all devices?
There are lots of approaches and it would depend on the game, and target devices.
One simple - approach is to react to an resize event, and scale the game canvas based on the devices dimensions. You can use .innerWidth and .innerHeight to change the canvas. The game can keep it’s original game dimenions - but you apply a scaling factor based on the new dimensions / ratio to all positioning. This works pretty well, but has some drawbacks - images are stretched, It’s more complex to do the positioning (plus more calculations required in the main game loop )
Another alternative is to determine the ratio of your game, then determine the ratio of the device. With these ratios you can determine whether the device is wider or taller - then you can decide how to position the canvas in the div.
If the device is wider than the canvas - you might have bars on the left side. If the device is taller, you might have bars top and bottom.
This allows you to preserve the screen ratio.
How would you go about importing JSON data into a game?
There are no really good ways to read data from a file in JavaScript (mainly for security reasons) - but we can use AJAX style calls to achieve the same thing.
You create a XMLHttpRequest object, specify the mime type and file location - and you should be able to get the JSON and parse it.
Is Javascript asynchronous?
It appears to be, however it isn’t. While it seems like it can deal with things in an asynchronous manner, (events can fire at anytime, files can be fetched in a non-blocking manner) - in actual fact it runs in a single thread. The reason it appears to be asycnhronous is because of it’s callback system and the event loop.
Explain the event loop?
The javascript runtime contains a message queue - which is processed by the event loop. When events occur, they are placed in the queue. The queue is polled (each poll is called a tick) and if there is a message, it’s processed.
Now, because Javascript is actually single threaded, once a callback is taken out of the queue, it’s put on the call stack - and all polling of the queue is stopped until the call stack is cleared.
When you setup, say a timing event, with 0 millisecond delay, even though it’s 0 milliseconds it wont fire straight away - it’s placed in the queue ready for the next tick. The currently executing function will finish - then the queue is polled and the timer is executed.
Why are texture atlases important?
Most browsers will have a maximum number of requests that they can simultaneously allow to a server. This will be fairly low - around 6ish. If the request can’t be serviced, then it has to wait.
So the most optimal path is to create your assets to reduce the number of requests being made. One way to do this with images, is to create a texture atlas, a single png / jpg with all the assets on it.
Why does JSLint not like the new Array syntax?
The constructor is ambiguous, if you pass a number to it, it will create an empty array of that length. But if you pass the same value, as a string (i.e. ‘4’), then it will create a single element array with the value 4 in it.
It can also create some odd behavior - because .length will report that an empty array has x number of elements - and so much javascript code makes the assumption that .length is the size of the actual array (filled).
How can you reduce asset load times?
Use texture atlases can reduce the number of calls you make to the server reducing times.
If you use an asset manager, you can make sure you aren’t calling the same asset multiple times, you cache the asset and return that asset on request if it already exists.
What features should an asset manager have?
Cache
Async callbacks on load - that way we can do other processing while the File IO is underway, and react once we have the asset returned.
Batched asset loading - load lots of assets at once, and only give one callback.
How would you deal with users on a slow connection, if they are trying to load lots of data?
Using a preloader can help - it’s more about perception of speed. By making it feel responsive, it will help the user understand that something is actually happening as opposed to the game stalling.
How would you go about making sure code is reusable?
Writing clean, OO code (DRY, SOLID).
Making sure to maintain separation of concerns.
Avoid mixing presentation with logic.
Keep the scripting of the game (the actual gameplay code) separate from the entities within the game.
Plan ahead before coding.
If the UI is HTML - then you can keep that in it’s own layer.. It should be separate from the entities etc.
Reduce dependencies on external code.
Explain why you would prefer browser sniffing, over browser detection?
THe problem with browser detection is that it relys on fixed points in time of a browsers devvelopment. For instance, you may check for IE - but then, IE starts supporting the feature, so now you are check for a specific version, maybe there’s a patch. etc etc. It’s a liability that could lead to visitors with perfectly valid browsers missing out on features.
With sniffing, you can simply detect whether the specific feature is supported by the browser, and if so use, if not fall back to some other code path / way of doing it.
When would you choose to use CSS Animations?
If the animations are relatively simple, state based (only 1 or two states, or forwards and backwards are the same)
Also - it does depend to an extent on when you want them to trigger - if you need the animation to occur on :hover, :checked: or :active - then CSS might be the go.
Use javascript when the animation you are doing requires many different states, or different states depending on different inputs. Javascript is also the best option if you need to emulate physics.
You also need to consider browser support - while widely supported, it’s not 100%, so you have to consider whether the information being conveyed is critical or simply dressing. The good thing about CSS animations is that used properly, they are an excellent example of progressive enhancement, in that if the animation support isn’t there, it works fine without it - but if it is there, you get the additional benefit of the animation.
What are the most performant types of transitions in CSS?
opacity, scale, rotation and movement (when done with transforms)
What are the steps that a browser goes through to draw everything to the screen when animating?
Style, layout, paint, composite
Style, it calculates all the styles required for the element.
Then it works out it’s layout (that’s the geometry, position of each element). Then it fills in the pixels for the element, then it composites it on screen with everything else.
Some changes require going through all of these steps, and others do not, which is partly why some operations are more efficient than others.
Changes to transform and opacity properties - are done on the last step only.
What is the CSS translate3d hack?
Setting the transform: translate3d(0, 0, 0) forces the browser to use hardware acceleration, and forces the element onto a new layer - which also boosts performance.
You may be able to use the ‘will-change’ property.
Talk about how you deal with CSS files?
I tend to separate them based on page.
I may use a CSS reset if I am doing something large like a wordpress theme.
I tend to use a an autoprefixer to deal with vendor prefixes - you can use this with grunt. There is one called Autoprefixer.
I use a CSS linter.
I haven’t used SASS / LESS before, but I’m going to start, because the complexity of animation files I’m playing with is increasing, and the ability to preform loops would be excellent. That should fit nicely into the grunt workflow.
I use a minifier with grunt.
If I am doing a lot of CSS animations, I might put those into separate files for organisation purposes - again, I’ll use grunt to concatenate those files / minify it for production. etc.
Any considereations when using CSS animations?
Yes - design them such that they don’t look browken if the animation can’t trigger (lack of browser support etc). Try to use the most performant methods of animation, look at a site like csstriggers.com will give you a list of what browser render states are triggered during that type of animation / transition.
Make sure you animations don’t make it harder for the user to use them. (i.e. animations that move under the mouse and cancel :hover states etc).
And like any design - evaluate what it brings to the table. Does it serve a purpose, am I over doing this (i.e. does it make things more confusing).
If your target browsers don’t support everything you need - consider using JavaScript instead.
What are the downsides to using the revealing module pattern?
It becomes more difficult to use the prototypal inheritance pattern, you’ll need to return the exposed public interface from an IIFE.
When you create the object, all of the objects are created again - it can be bad for memory, as we are not getting one of the benefits of the prototypal inheritance (i.e. shared prototypes).
Its hard to extend.
Object types are unclear, as you can’t use instanceof.
Patching a module is very difficult (if not impossible) as the module will continue to refer to the internal implementation (due to the way the closure works)
NOTES: __proto__ is not standard (or at least may be deprecated)
Why would you use a module pattern?
Unlike many other OO languages, there is no syntax to declare member variables / methods as private, so a JavaScript object is technically always open for modification. This in fact has become part of the way people program in JavaScript - but it can lead to some issues.
For instance, if we have a member variable that needs to be modified by a method, say we have to perform some kind of transformation to it before use - a user of the interface could by pass that causing major problems.
Using _’s to indicate that it’s private is okay - but it doesn’t prevent access.
So using a module pattern such as revealing module will protect against that.
It’s easy to make members private without changing the internal implementation - just change the interface (the return object)
What is the difference between a primitive and an obect?
A primitive is a data type that is composed of no other data types and can not be broken down any further. They are the building blocks for Objects.
In JavaScript there are 5 primitive types are Number String Boolean Null Undefined
There is a new type in ECMA 6 called “Symbol”
NaN - is not a primitive, it’s not a Number - even though it returns Number when you do typeof NaN.
An object is usually made up of primitives, and other objects.
What is a “falsy” value?
There are six falsey values:
0, null, undefined, false, “”, NaN
Why should you use the === operator as a matter of practice?
If JavaScript needs to test equivalency, it first tries to get both sides of the expression to a similar type. In the case of the equality operator, it will convert the left and right operands
What does JS try to coerce values too in this type of expression?
foobar = foobar || {}
Boolean - if the left hand side is false, then the left hand side will be assigned to the variable. Because Objects are always true.
What is meant by Dependency Inversion?
It’s a method of decoupling dependencies in Object oriented programming.
The principle states that high level modules should not depend on low level modules, and abstractions should depend on details, details should depend on abstractions.
On technique is Dependency Injection - you often see modules that contain ‘new OtherModule’, which immediately creates a dependency and makes testing harder.
So DI (which is NOT dependency inversion by itself, instead it’s a component) - can be used to decouple the objects. Rather than instantiating directly within the object, you can pass a reference to the object, preferably via an interface - or abstract bass class.
Is there ever a reason to use eval?
Yes - when there is no other way to accomplish the given task with a reasonable level of clarity and within a reasonable number of lines of code.
This eliminates 99% of cases where eval is used, across the board in all languages and contexts.
The only reason I can think of that is valid - is when dynamically generating code.
What are AMD modules?
AMD stands for Asynchronous Module Definition.
AMD supposedly makes website performance better, by allowing the website to load the files asynchronously, only when required. You don’t need to load the entire code base at once.
The cool thing about it is that you can define dependencies, which means you don’t get into that problem of which file needs to load first - you can specify the dependencies up front.
One of the better known implementations would be Require.js
What is CommonJS?
Like AMD modules it was designed to modularise JavaScript code - but it was more server centric.
I’m not sure of the exact details - but it seemed to occupy a space that Node is now replacing with it’s own module system.
What is currying?
When a function doesn’t take all it’s required parameters up front - instead returning a new function. This continues until you have fulfilled all the parameter requirements at which point it returns the result.
This is particularly useful if you need a function that pass through the application and gradually receive the arguments it needs.
It is also useful in cases where you want a function to behave in different ways based on certain input. You can say prime the function with an initial value, saving that in a variable - then use that “primed” function with different parameters
What is lazy loading / initialisation?
It’s a creational pattern that helps defer the creation of expensive objects unless really need. It helps you avoid the repetition of expensive processes.
In Javascript an example might be a Lazy Factory to load the XMLHttpRequest object.
When you call the factory, it determines which XMLHttpRequst object you will use - then, it redefines itself, based on the check for which one is available. The function then calls itself, returning the result.
Subsequent calls will simply return the already retrieved result.
What are some performance tips for JavaScript?
Use local variables - this will reduce the amount of searching that must be done via the scope chain.
Use lazy initialisation
Use closures sparingly
Assigning object properties to a variable if they are access frequently - particularly in a game loop. Object property lookup is slower than literals.
Avoid deep arrays, array lookups can be slow, if you have a multilevel array - then that’s multiple array looksups.
Watch your loops - using a for loop has three operations to perform each iteration. You could optimise that down to a while loop. Probably not a big gain - but in a game loop might be useful.
If you are dealing HTML collection arrays - convert them to normal arrays. They are live objects, and have significant performance overhead.
Cache DOM objects - grab them once - and then store them.
It can be better to add a class to a DOM element, rather than directly changing it’s .styles object. This wont necessary prevent a reflow - but because a class can hold multiple styles, it may mean a single reflow, instead of one per style change.
Keep your DOM depth as shallow as possible. A change at one level can trigger changes all the way to root and the children - and this can take longer to reflow.
Avoid changing things with computed styles (i.e. percentage widths) in JavaScript - this will trigger a reflow / Layout.
Avoid using borders / shadows / gradients where possible. They are quite expensive. There are a number of steps in rendering - Layout (calcs) - Paint (draw) - Composite - the heavier effects will usually trigger a Paint step which increases the whole Reflow time.
Reduce the number of CSS rules you have.
Precalculate anything that has finite set of answers - use a dictionary - or array to store the data and look it up each time you need it, rather than recalculating it.
Function cachig.
Why is working with HTML collection arrays risky?
You can cause infinite loops - because they are live, you can add an element, which forever extends the page beyond the limit of the loop ending condition.
How could you increase the performance of a recursive function like the fibonaci series?
You could use memoization - by making the function able to cache it’s results - you can reduce the number of calls significantly.
How do gracefully deal with exceptions?
If you are using libaries that make use of exceptions, then you really must handle them. Otherwise, I try to avoid them if I can code defensiveily (i.e. using feature detection).
If there are no other options - then wrapping the code in a try/catch/finally block is a good option.
There is also the window.onerror message handler that you can use to detect any unhandled errors.
Explain hoisting?
When a block of code runs, an execution context is created. There are two phases for this - the creation phase (where memory is allocated), and the execution phase (where the code is run line by line).
The variables and functions that are within the execution context are allocated memory - and so when the execution phase occurs, the memory already exists for the variables and functions. For function statements, the memory already points to the code. For variables and function literals, they are initially set to ‘undefined’ in the creation phase. It is only during the execution phase when the code is executed that the data is assigned.
That is why you can access the variables before they have been assigned and you don’t get an error.
It’s called hoisting, because it appears as though the variables have been moved to the top of the lexical environment - even though that’s not really what is happening.
Why should you never use undefined yourself?
If you never assign it, then it makes debugging easier. You know that the variable exists, but hasn’t been set. That gives you a big clue as to where and what the bug is.
Explain the scope chain
Every function when executed is given it’s own execution context. Within that, is a reference to it’s outer environment.
The outer environment is determine by where the code sits lexically. So if function “b” exists within “a” - then “b”’s outer environment is “a”.
If you request a variable within that execution context, the search begins at the current execution context’s variable object. If it can’t be found, the engine will then check the outer environment for the same variable, moving up the chain until it reaches the global execution context.
What is the benefits / downsides to memoization?
It’s a relatively simple technique that can produce incredible speed increases. So in an algorithm (say a recursive algorithm), it will likely produce a lot of results multiple times in order to get the final answer. By caching the results - for a particular input, we can return the value, rather than calling the function again, which saves dramatically on the amount of processing.
The downside is that we often need fairly large data structures to deal with it.
So it’s a time vs space tradeoff.
What are the most common module types?
There is AMD, UMD and CommonJS. These are all methods to improve JavaScripts organisation, which was never designed to handle larger projects.
The most well known implementation of the AMD (Asycnchronous Module definition) specification is probably Require.JS - which I have used a bit. It’s nice because it asynchronously loads files when required, and can have the result of improving site performance.
CommonJS - which i’ve only used a little, but it’s typically a server side solution - although I believe Browserify is making use of it in the browser. It’s quite similar to AMD in many respects in that it encapsulates data in a private namespace, and exports the public interface as an object literal.
I’ve never used UMD however, I can’t talk to it’s good / bad points unfortunately.
What are the most important paradigms in JavaSCript
Prototypal inheritance, and functional programming.
What is functional programming?
It’s method of programming that breaks the problem into smaller, composable chunks. For instance, the JavaScript library has a number of functions (such as filter) that make use of functional programming.
Javascript is a pretty good language for functional programming because it supports higher order functions (functions that take / return other functions), first class functions, and closures and lambdas.
What is a lambda?
Essentially an anonymous function - usually used to describe a use of anonymous functions where you can store data within a function for use later on. You could also describe it as “functions used as data”.
Explain recursion.
Recursion is a programming technique that can be described as a routine that calls itself repeatedly to solve a problem.
Recursion is typically best used when a problem can be broken down into a similar, simpler subset of the original problem.
Eventually the function will call itself at be able to solve the problem - which is known as the base case. This is required to stop infinite recursion.
How would you implement a stack in JavaScript?
I probably wouldn’t - there is already a stack mechanism in the form of the array with the push and pop methods.
How would you implement a queue in JavaScript?
I probably wouldn’t, there is already a queue mechanism in Javascript in the form of the array - with the unshift / shift methods.
Even though there already exists the queue and the stack - why might you still implement your own?
They don’t have a peek method for one, you may also want to use a fixed size of array.
What is a priority queue?
Like a queue - but each element has a priority associated with it. It’s often implemented with a heap.
What are the typical steps in finding a solution using dynamic programming?
- Find a recursive solution
2. Memorise intermediate steps
What are two ways of handling collisions with hash tables?
Linear probing… (i.e. if you can’t take the first slot, give it the next available slot) O(n)
Separate Chaining (i.e. each entry in the array is a pointer to a separate array array) O(n/k) where k is the size of the table. However - O(n/k) can be written in worse case scenario as O(n) (because k is fixed)
What is the difference between an algorithm that finds a prime based on 2 to n searches, and one that uses the square root?
If you have to search from 2 to N the algorithm is around O(n) in terms of speed. This can be VERY long with large numbers. But you can speed this up by using the square root trick. (i.e. a number is a prime if it can’t be divided by any number from 2 - sqrt of n. ) This would give you O(sqrt(n)); complexity
What is a stable sorting algorithm?
One that preserves the original order of like objects - so if you had two cards, 6 of clubs, and 6 of diamonds, and before the sort they were in that order. A stable sort will retain that order after the sort.
What is the entry point for the DOM?
Window.documentElement (corresponds to html tag) - can get to the head here… i.e. title etc.
Window.document.body (corresponds to the body element)
WARNING Document.body can be null - especially if you are starting from a script in the head when the body hasn’t loaded yet.
What is the difference between an element and a tag?
A tag is used in HTML to markup the start and end of an element. It’s literally the opening / closing p.
But an element is the semantics or structure of a part of that page.
So p with text within it would be considered an element, while the p that is used to open the paragraph would be the tag.
What is one nice things about the JavaScript concurrency model?
Because it’s based on the event loop - which has the concept of run to completion - you shouldn’t end up with functions that are pre-empted by other functions. Each message must be processed completely before the next one is called from the event loop.
The downside is that if a message takes way too long to complete, the user interface can be held up as it is also processed through the event loop - giving users the impression of a sluggish / slow system.