Explore

Pathways in design, games and film — pick yours and start today

Courses you can join

Highlights

Work and conversations the team picked, and what your classmates reacted to this fortnight

Nothing highlighted yet — the first project you post could be here

Read

  1. Tips

    Blender: apply scale before the model leaves for the engine

    When you scale an object with S you are not changing the mesh. You are writing a number on the object that says "draw this at twice the size".…

    Read more

    When you scale an object with S you are not changing the mesh. You are writing a number on the object that says "draw this at twice the size". Blender respects that number; an engine sometimes does not. The familiar result is a model that looks correct in Blender and arrives in Unity or Unreal at double size, or with a physics collider that does not match what the eye sees.

    The damage starts before export, too. Bevel measures its width in object units, so a non-uniform scale like (1, 1, 0.4) gives you a thick edge on one axis and a thin one on another. Solidify and cloth simulation behave the same way.

    The habit: before exporting, and before any modifier that depends on distance, select the object and press Object ▸ Apply ▸ Scale, or Ctrl+A ▸ Scale. Then check the item panel with N — scale should read 1.0 on all three axes.

  2. Tips

    Unreal: use IsValid, not a comparison against None

    A reference in Unreal has three states, not two: null, valid, and destroyed-but-still-held. Comparing != None only separates the first from the other…

    Read more

    A reference in Unreal has three states, not two: null, valid, and destroyed-but-still-held. Comparing != None only separates the first from the other two, so the wrong branch runs for an enemy that had Destroy Actor called on it a moment ago, and the crash arrives inside the next function rather than where the mistake is.

    The IsValid node checks both conditions at once, and it is a single node with two execution outputs, which replaces the hand-rolled branch entirely. In C++ it is the same call: if (IsValid(Target)), not if (Target != nullptr).

    The habit worth fixing: any reference you store in a variable across frames — the current target, the last checkpoint, the vehicle you were driving — gets an IsValid check at every use, not at assignment. The moment you stored the reference says nothing about the moment you read it.

  3. Tips

    Unity: the editor is the wrong place to measure performance

    Profiler numbers taken inside the editor are not your game's numbers. The editor runs its own loop, loads assets uncompressed, and allocates memory…

    Read more

    Profiler numbers taken inside the editor are not your game's numbers. The editor runs its own loop, loads assets uncompressed, and allocates memory for its own tooling, so the graph shows spikes that vanish entirely in a real build — and a whole evening goes into chasing a cost that does not exist.

    The right way: File ▸ Build Settings, tick Development Build and Autoconnect Profiler, build to the device the game will actually be played on, and attach the Profiler to the running build.

    Before reading any number, open the GC Alloc column and sort by it. Per-frame allocation — a string assembled inside Update, or Physics.RaycastAll returning a fresh array — does not show up as steady slowness. It shows up as a hitch every few seconds when the garbage collector runs, and that hitch is what a player complains about, not your average frame rate.

  4. Tips

    Unity: split the code with asmdef files and stop waiting on compiles

    By default every .cs file in your project lands in one enormous assembly called Assembly-CSharp. Editing any line recompiles all of it, and as the…

    Read more

    By default every .cs file in your project lands in one enormous assembly called Assembly-CSharp. Editing any line recompiles all of it, and as the project grows, changing a single number turns into a twenty-second wait before you can press play again.

    The fix: Assets ▸ Create ▸ Assembly Definition inside each major system folder — movement, UI, saving, AI — then declare what each one needs in Assembly Definition References. After that, a change to the UI compiles the UI.

    There is a benefit better than the speed. Having to declare those references makes your dependencies visible: if you find that the movement system needs a reference to the main-menu assembly, the compiler has just shown you an architectural mistake that was hiding behind a casual using. Start with two or three boundaries rather than ten — over-splitting trades a waiting problem for a references problem.

  5. Tips

    Unreal: reach for a Blueprint Interface before Cast To

    The Cast To node is convenient, and it quietly does two things. First it creates a hard reference to the class you cast to, so that class — and every…

    Read more

    The Cast To node is convenient, and it quietly does two things. First it creates a hard reference to the class you cast to, so that class — and every material, mesh and sound it references — loads the moment the Blueprint holding the node loads. One door that casts to BP_PlayerCharacter is enough to drag the whole character into the memory of your main menu.

    Second, the failure is silent for every other class. You write a door that opens for the player, then the AI companion or the destructible variant walks into it and nothing happens, with no error anywhere.

    Instead: Content Browser ▸ Blueprints ▸ Blueprint Interface. Declare a function like Interact or CanOpenDoor, then send that message straight to the actor rather than casting. Whoever implements the interface responds; whoever does not, ignores it. The door knows nothing about the player, and your level's memory footprint stays the size of your level.

  6. Tips

    Blender: modifier order is not a detail

    The modifier stack evaluates top to bottom, and each modifier's result is the next one's input. That makes Mirror above Subdivision Surface and Bevel…

    Read more

    The modifier stack evaluates top to bottom, and each modifier's result is the next one's input. That makes Mirror above Subdivision Surface and Bevel a rule rather than a preference: drop the mirror below the subdivision and you are smoothing one half and then reflecting it, which prints a visible seam down the middle of the model no matter how carefully you place the vertices.

    The order that works for most hard-surface models is Mirror ▸ Bevel ▸ Subdivision Surface, with Clipping enabled on the mirror so vertices weld at the plane instead of crossing it.

    Where: Properties ▸ Modifier Properties (the wrench) ▸ Add Modifier, then drag by the six-dot handle or press Ctrl+Page Up to move a modifier up the stack. And before any Bevel, apply the scale with Ctrl+A ▸ Scale, or the edge width comes out different on each axis.

Sitara