Ironbelly Studios · Software Engineer
Updated · 2026-09-24

Ironbelly Studios Software Engineer
Interview Questions & Guide 2026

THE 60-SECOND BRIEF

A Software Engineer at Ironbelly Studios plays a foundational role in bringing complex interactive experiences to life. Whether you are working on high-fidelity gameplay mechanics for a Multiplayer FPS or architecting systems within Unreal Engine, your contributions affect the fluidity, performance, and player immersion of Ironbelly Studios' products. This role is not just about writing code; it is about solving technical challenges that demand both creative engineering and a deep understanding of game architecture.

Ask whether any round happens inside an existing repository instead of a blank file. Reading unfamiliar code, isolating a fault and making the smallest correct change is a different skill from writing a function from scratch, and it needs its own practice.

Ironbelly Studios candidates report 3 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.

Derive idempotency keys from server-authoritative stateAudit item supply from append-only ledgersPrevent negative balances with conditional single-statement debits

35 min read

Browse Software Engineer questions

See the practice prompts

13Practice promptsAcross five skill areas
3With worked solutionsIncluded in the practice prompts

A Software Engineer at Ironbelly Studios plays a foundational role in bringing complex interactive experiences to life. Whether you are working on high-fidelity gameplay mechanics for a Multiplayer FPS or architecting systems within Unreal Engine, your contributions affect the fluidity, performance, and player immersion of Ironbelly Studios' products. This role is not just about writing code; it is about solving technical challenges that demand both creative engineering and a deep understanding of game architecture.

You will operate in a fast-paced environment where technical precision is paramount. The work often involves pushing the boundaries of what is possible within C++ and the Unreal Engine framework. Candidates who thrive here are those who view code as a craft and are eager to contribute to projects that require scalability and high-performance standards. You will be expected to balance rapid iteration with the need for clean, maintainable, and well-documented systems that your teammates can rely on.

01

Initial Screening

reported

The title covers product work, platform work, infrastructure, mobile and frontend, and those are different jobs with different loops behind them. A screening call is the cheapest place to find out which one the seat is, and asking reads as experienced rather than fussy. The questions that separate them: what the team is on call for, what the last three projects were, and whether any round happens inside an existing repository instead of a blank file. Then say which of that you have done and which you have not. Claiming the whole posting is the fastest way to be found out one round later.

What to demonstrate

  • Whether you can locate your experience inside one flavour of the role honestly instead of claiming the entire requirements list
  • Whether you name what you have not done, which an experienced screener reads as a level signal and can plan the loop around
  • Whether what you want next matches what the seat is: someone who wants greenfield work landing on a team that mostly operates an existing system is a hire that leaves within the year

How to prepare

  • Mark every line of the posting as done, adjacent or new, and write one sentence for each adjacent line naming the closest thing you actually built
  • Split your last two years into rough percentages across feature work, operating and debugging live systems, and design or review, so a question about scope gets numbers rather than adjectives
  • Bring three questions that discriminate between seats: what the team is paged for, how much of the work is changing existing code versus standing up something new, and what shipped in the last quarter
PracHub interview research ↗
02

Hands-on Technical Demonstration

reported

What this round decides is narrow: whether you can produce code that runs and is correct on inputs nobody showed you. An elegant solution that does not compile scores below a plain one that does, so write a correct brute force first, say out loud that you know its cost, and improve it with the working version still on screen. What separates strong answers is who finds the broken case. Trace your own code against an empty input, a single element, and duplicate keys before you say you are finished, because being told is far more expensive than noticing.

What to demonstrate

  • Whether degenerate inputs get checked without being asked for: an empty collection, one element, every element equal, and the extreme value the input type allows
  • Whether the complexity you state matches the code you actually wrote, including a sort or a copy sitting inside a loop
  • Whether the finished answer is verified against the worked examples before you call it done, rather than assumed correct because the code reads correctly

How to prepare

  • Take five problems you have already solved and, without running anything, write down what each returns for empty input, a single element, and all-duplicates. Then run them and count how many you predicted wrong.
  • Drill the brute force as its own skill: on ten problems, write only the obviously-correct slow version and time how long it takes to get it passing. If that is more than a few minutes, that is what to practise, not the optimal version.
  • Add a fixed last step before you submit anything, reading only the loop bounds and the initial value of each accumulator, which is where most off-by-one errors live
PracHub interview research ↗
03

Final Technical Review

reported

Nobody in the room with you decides this. Interviewers typically write their rounds up separately, often before seeing anyone else's, and the outcome is settled later from those write-ups. A split panel gets resolved by whichever note carries specific evidence, so what you want out of each room is one concrete thing that person could write down: a bug you caught yourself, a trade-off you named, a decision you owned. The rest is arithmetic. The project you describe in a behavioural conversation is often the same system you sketched an hour earlier, and the two accounts have to agree.

What to demonstrate

  • Whether the scale, team size and timeline you attach to a project hold steady when that project resurfaces in a different round
  • Whether each interviewer leaves with a specific thing to cite rather than a general impression of competence
  • Whether a trade-off you defended in one round survives a challenge in another, instead of being quietly swapped for the answer the new interviewer seemed to want
  • Whether a question you have already answered earlier in the day gets the same answer at the same depth, without visible impatience

How to prepare

  • Write a one-page sheet per project fixing the figures you will quote — request volume, data size, team size, elapsed time, what broke — and say them aloud from the sheet until they come out identical every time
  • For each round on the schedule, decide in advance the one sentence you want in that person's notes, then check in a mock that you said it outright instead of leaving it to be inferred
  • Have someone ask you the same project question twice, an hour apart, and diff the two answers for numbers that moved or a trade-off that reversed
PracHub interview research ↗

PracHub editorial advice for the preparation topics above.

01

Treating the message queue as exactly-once, so the reward consumer applies a grant without a dedupe check.

A broker that redelivers on consumer failure is at-least-once by construction, and a consumer that crashes between writing the grant and acknowledging the message will see that message again. Exactly-once end-to-end would need a transaction spanning the broker and the database, which does not exist across heterogeneous systems, so the sink has to be idempotent. The failure is invisible in steady state and shows up as a burst of duplicate grants exactly when a deploy or an OOM restarts consumers.

02

Representing prices and balances as floating point, or storing a display currency amount instead of integer minor units plus a currency code.

Binary floating point cannot represent most decimal fractions exactly, so repeated credits and debits accumulate drift that only surfaces when reconciliation compares the ledger sum against the cached balance and finds them a fraction apart. Regional price books make it worse: the same SKU has different minor-unit scales across currencies, and a currency with no minor unit breaks any code that assumes two decimal places.

03

Sharing mutable state with no stated owner

Say which thread, request or task owns each mutable structure, and what protects it when the answer is more than one: a lock, a queue that hands ownership across, or an immutable copy per reader. A structure documented as safe for concurrent reads is usually not safe for a concurrent write alongside those reads.

04

Issuing one query per row of a result set

Fetch related rows in a single batched query keyed by the ids you already hold, or join them into the original query. A per-row round trip multiplies network latency by the row count, and it looks perfectly fine against the ten rows in your development database.

Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.

10 technical prompts3 include a worked solution

Budget per-tick visibility queries under a 16.7 ms tick

hard
spatial indextick budgetbandwidth

A match instance simulates 100 entities at 60 Hz in a 1000 m by 1000 m arena. Every tick, each entity needs the set of others within 60 m so the snapshot serialiser can skip the rest. Entities move at up to 8 m/s. The whole tick, meaning inputs, physics, visibility and serialisation, must fit in 16.7 ms, and one host runs many instances. Give the naive cost, a structure that beats it, its worst case on this exact workload, and the downstream bandwidth per client at 30 Hz with 40-byte per-entity deltas.

Approach
  1. Naive all-pairs is C(100,2) = 4,950 distance tests per tick, 297,000 per second per instance, and 5.9 x 10^8 per second across a 2,000-instance fleet at 200k concurrent players. The argument is the scaling, not the absolute number: at O(P^2) per tick, doubling the roster quadruples the work.
  2. Uniform grid with cell edge equal to the query radius, 60 m: ceil(1000/60) = 17 cells per side, 289 cells, mean occupancy 100/289 = 0.35. Cell edge at least the radius means the 3x3 neighbourhood provably covers every candidate, since a point within 60 m differs by at most one cell index on each axis. That is about 3.1 candidates per query and roughly 310 distance tests per tick, 16 times fewer. Rebuild clear-and-reinsert each tick at O(P); at P = 100 and 0.13 m of movement per tick that is cheaper than incremental updates and immune to stale-cell bugs.
  3. State the worst case on this workload rather than quoting the average as the budget. All 100 entities inside one cell, which is exactly what a contested objective looks like, makes the 9-cell scan return all 100 for every query: 10,000 tests, about twice the naive triangular count, because the grid neither halves symmetric pairs nor prunes anything.
  4. Choose by density, not by fashion. A uniform grid wins on roughly even spread with one fixed radius; a k-d tree or BVH costs O(P log P) to build and only pays off at much larger P or with widely varying query radii. Halve the work in either case by visiting each pair once, scanning only cells at or after the current cell in traversal order, and by comparing squared distances so no test carries a sqrt.
  5. Bandwidth: 30 visible entities at 40 B is 1,200 B per snapshot; at 30 Hz that is 36 KB/s, or 288 kbit/s downstream per client, plus about 28 B of UDP and IPv4 header per packet for another 840 B/s. At 60 Hz it doubles to 576 kbit/s, which is the concrete argument for running the snapshot rate below the simulation rate.
Follow-up
  • Entities converge on one objective and the grid degrades to its worst case. What do you change first: cell size, a cap on the visible set, or the snapshot rate, and what does each cost the player?
  • How does the visibility set interact with lag compensation, where the server rewinds to the shooter's view time to resolve a hit?

Merge cheapest active listings across shards without full scans

mediumWorked solution
k-way mergeheapsharding

market_listing is sharded by seller_account_id across 64 shards. A buyer opens the page for one item_def_id and wants the K = 50 cheapest status='active' listings by ask_price_minor, ties broken by created_at. Each shard can return its own listings for that def already sorted, in pages. Catalog load is concentrated: a popular def may have a million active rows shard-wide. Return the global cheapest K while reading as few rows as possible, state the number of rows you read, and name the index that makes each shard's page cheap.

Approach
  1. k-way merge driven by a min-heap holding one entry per shard, keyed on the full tuple (ask_price_minor, created_at, listing_id) so the ordering is total and the same query returns the same page twice. Heapify 64 heads in O(S), then K pops at O(log S) each: O(S + K log S), roughly 64 plus 50 times 6 comparisons.
  2. Rows read is at most S + K, here 114, against the million active rows for that def. Page each shard lazily, requesting its next row only when its current entry is popped, and batch the request into pages of roughly K/S plus margin so the round trips amortise.
  3. The per-shard query needs a partial composite index on (item_def_id, ask_price_minor, created_at) WHERE status = 'active'. Without it, each shard sorts a million rows to hand you one, and the partial predicate keeps the index off the sold, cancelled and expired rows that dominate the table over time.
  4. Name the other shape too: over a single unsorted stream of n rows, use a bounded max-heap of size K for O(n log K) time and O(K) space, rejecting an incoming row in O(1) when its price is worse than the heap root. Quickselect is O(n) average but needs all n resident and gives up streaming.
  5. State the concurrency caveat rather than pretending the result is a snapshot: the shards are read at slightly different instants, so a listing can sell between two shard reads. Revalidate the chosen listing's status transition at purchase time; the merge result is a view, not a lock.
Worked solution 25 min
  1. Take four shards with sorted prices in minor units: s0 = [120, 130, 400], s1 = [125, 126, 127], s2 = [500], s3 = [118, 900], and K = 5.
  2. Seed the heap with the four heads (118, 120, 125, 500) and record the read count as 4.
  3. Pop five times, advancing only the popped shard and incrementing the read count on each advance that returns a row.
  4. Sort the full nine-row union independently and compare the first five entries.
EXPECTED RESULTThe cheapest five are 118, 120, 125, 126, 127. The merge reads 8 rows out of the 9 that exist: 4 heads plus 4 successors, with the final pop draining s1 and triggering no read. The heap never holds more than 4 entries.
Follow-up
  • The buyer asks for page 20 rather than page 1. What does deep offset cost in a k-way merge, and what do you change to make it flat?
  • One shard times out. Do you return 49 listings, serve a cached page, or fail the request, and how does the answer differ for a browse page versus a purchase confirmation?

Parse decimal price strings into integer minor units safely

easy
parsingmoneyoverflow

Regional price books arrive as text. Write parse_minor(text, exponent, decimal_sep, group_sep) returning integer minor units for purchase_order.price_minor BIGINT. exponent is the currency's minor-unit digit count and is 0, 2 or 3 depending on the currency. Input may carry a leading sign, grouping separators, and fewer fraction digits than exponent. Reject rather than round any value carrying more fraction digits than exponent, and reject anything outside signed 64-bit range. No binary floating point may appear anywhere in the solution or its tests.

Approach
  1. Single character scan classifying sign, digit, group_sep and decimal_sep, rejecting anything else including a second sign or a second decimal separator. O(len) time, O(1) extra space.
  2. Accumulate the integer part into an integer accumulator, and before each acc = acc*10 + d check that acc <= (INT64_MAX - d) / 10. Detect overflow before it happens: signed overflow after the fact is undefined behaviour in C and C++ and wraps silently in most compiled languages, so a post-hoc check on the result is not a check.
  3. Count fraction digits as you read them. More than exponent is a reject. Fewer than exponent means multiply by 10^(exponent - count), using the same pre-multiply bound check.
  4. Combine as total = int_part * 10^exponent + padded_fraction and apply the sign last. At exponent 0 the presence of a decimal separator at all is a reject, not a truncation, because a currency with no minor unit has no place to put those digits.
  5. Keep locale out of the parser by taking decimal_sep and group_sep as arguments. The same glyph is a decimal separator in one locale and a thousands separator in another, so a parser that guesses turns one written amount into either 1500 or 1.5 depending on who typed it.
Follow-up
  • Now render the stored minor units back for display in the player's locale. What breaks at exponent 0 and at exponent 3?
  • The upstream store returns an exponent that disagrees with your price book for the same currency code. Which one wins, what do you store, and what do you log?

Four days sample coding, design, fundamentals and the practical rounds at deliberately shallow depth, which is enough to surface the topics you did not know were in scope. That map, rather than a guess made on day one, decides where the last three days go.

Small steps. Visible outcomes.0 / 7 completed
ONE WEEK · YOUR PACE

Prepare, practise & reflect

One practical outcome each day. Spend longer where you need it.

0 / 7 done
01Coding, one pass at shallow depth
  • Solve one problem from each of six families, an array with two pointers, hash counting, binary search, a tree traversal, a graph traversal and one dynamic program, under a hard twenty-minute cap with no extensions, marking each finished, late, or stalled.
  • For every stall, write the exact move you could not make rather than the subject, so the note reads could not turn the recurrence into a loop rather than bad at dynamic programming.
  • Fix nothing today. The value of the pass is the unfixed record.

Deliverable: Six timed attempts marked finished, late or stalled, each stall carrying a named blocking move.

Practice prompt ↗Practice prompt ↗Worked solution ↗
02Design, one pass at shallow depth
  • Spend twenty minutes each on three different shapes, a read-heavy feed, a write-heavy ingest path, and something needing a transaction across two entities, stopping each at requirements, interface and data model.
  • After each, write the first question you could not answer, which is usually a number you could not estimate or a failure mode you had no vocabulary for.
  • Mark which of the three you would be most relieved not to be asked, and treat that as data rather than as a preference.

Deliverable: Three shallow designs, each with the first unanswerable question written at the bottom.

Practice prompt ↗Practice prompt ↗
03Fundamentals and the practical rounds
  • Answer eight short questions in writing at four minutes each, covering the material that fills the gaps between the big rounds: what happens between a URL and a rendered page, what an index costs on write, when a process is preferable to a thread, and what conditions a deadlock requires.
  • Do one thirty-minute practical task of the kind a take-home compresses: read an unfamiliar two-hundred-line file and write what it does, what you would change, and the one thing you remain unsure of.
  • Score every answer fluent, correct but slow, or absent, and keep the absent ones visible.

Deliverable: Eight scored short answers and one written reading of unfamiliar code.

Practice prompt ↗Practice prompt ↗
04The rounds that are about you, and the map
  • Deliver three behavioural answers aloud against a timer, a conflict, a failure you owned, and a decision made without enough information, marking any that ran past three minutes or contained no number.
  • Assemble the map: every marked item from days one to three on a single page, sorted by how likely it is to appear in your loop rather than by how uncomfortable it felt.
  • Choose exactly two areas for the remaining three days and write down what you are deliberately abandoning.

Deliverable: A one-page scored map of the whole surface area with two areas chosen and the rest explicitly abandoned.

Practice prompt ↗Practice prompt ↗Worked solution ↗
05First chosen area, to the depth you skipped
  • Work the higher-ranked area in four focused blocks, choosing items one level above where you stalled rather than repeating what already works.
  • After each block write the rule you extracted in one sentence with its precondition attached, since a rule carrying no precondition is exactly what fails under a variation.
  • Re-attempt the day-one or day-two item that exposed this area and compare against the original timing.

Deliverable: Four worked blocks, a timed re-attempt against the original, and three one-sentence rules with preconditions.

Practice prompt ↗Practice prompt ↗
06Second chosen area, where the gap is coverage rather than speed
  • Treat the second area differently from the first. Day five drilled something you could already half-do; this one is usually a topic you had simply never met, so build one worked reference example end to end and keep it, rather than attempting six problems badly.
  • Write down the vocabulary you were missing on day two or three, five terms at most, each with the one sentence that makes it usable in an answer rather than the textbook definition.
  • Redo the shallow attempt that exposed this area and note whether you now fail later in the problem, because moving the failure point is the realistic gain from a single day and is worth more than a score that did not change.

Deliverable: One worked reference example for the newly covered area, a five-term vocabulary list, and a note on where the failure point moved.

Practice prompt ↗Practice prompt ↗
07Reassemble the loop
  • Sit two rounds back to back with no gap, ordering them so the area you chose second comes last, because the map was built from rested, isolated attempts and the loop will reach your weaker area when you are already spent.
  • Write where the second round suffered from the first, which is normally the point at which structure collapses into narration.
  • Reduce the week to one page holding only the rules you can state without reading them.

Deliverable: Mock notes on cross-round carryover plus a one-page card of rules you can recite from memory.

Practice prompt ↗Worked solution ↗

Expand any day for tasks and deliverables. Your progress is saved on this device.

Engineers over-index on what they repaired. A stronger answer covers something you knowingly left broken: the alert you tuned down, the data inconsistency you documented instead of chasing, the cleanup you deferred past two quarters. Give the reasoning and the condition that would have reopened it, so it reads as a decision and not as neglect.

What is your experience with source control and collaborative developm…

medium
behavioural and engineering judgement

What is your experience with source control and collaborative development workflows?

Approach
  1. Close with what you would do differently, concretely.
  2. Name the disagreement and how you resolved it with evidence.
  3. State the situation in two sentences and spend the rest on the reasoning.
Follow-up
  • How did you know your change caused the improvement?
  • What did you decide not to do, and why?

Ship to a fixed date with debt you can name

medium
deadlinestechnical debtrisk

Prepare a five-minute account of shipping to a date that could not move, with shortcuts you took knowingly. Pick work where the load was also spiky — a launch, a seasonal rollover, a migration window — rather than a routine sprint. Constraint: name at least two shortcuts you took deliberately and one you refused, and say which invariant each one put at risk. Deliverable: the decision as it stood at the time, the kill switch or fallback you kept, the debt's paid-or-open status today, and what you would cut first if the date moved closer.

Approach
  1. Anchor on what made the date immovable and what made the load spiky. An event or rollover that multiplies write volume by 20 to 50 times for a few hours is not simply more of the same traffic; it is the concurrency at which lost-update and duplicate-write races stop being theoretical and start firing on every deploy.
  2. Classify each shortcut by reversibility. A skipped cache warm is recoverable in minutes. A skipped unique index on an idempotency key creates value or state you cannot claw back once it has moved between accounts. Strong answers cut only in the recoverable column and say explicitly that the line exists.
  3. Name the refusal and its price in days or scope. Someone who cut nothing was not really under a deadline; someone who cut everything had no line. The refusal is where the judgement is visible.
  4. Describe the fallback you kept live: a flag that disables the path without a deploy, a consumer you could pause, a dual-write with the old path still authoritative. Say who could pull it at three in the morning and whether that person had been told.
  5. Close with the debt's state today and the mechanism that kept it visible — a ticket with an owner and a trigger condition beats a wiki page. 'We never went back' is an acceptable ending only if you can say what made it acceptable.
Follow-up
  • Which of those shortcuts would you refuse at any deadline now, and what changed your mind?
  • How did you communicate the residual risk to whoever owned the date?

Reverse a decision after the data contradicted you

hard
reversalmigrationevidence

Prepare a six-minute account of a technical decision you made and later reversed, where the reversal cost something real: shipped code, migrated data, or a commitment another team had already planned around. Constraint: the trigger must be an observation rather than a change of mood, and you must state what you had predicted. Deliverable: the original decision with its stated assumption, the measurement that broke it, the cost of unwinding and who paid it, and how you sequenced the reversal so the system stayed correct while both paths were live.

Approach
  1. State the original decision with its assumption attached, because a reversal is only interesting when the assumption was written down. 'We denormalised the definition id onto the listing row so the cheapest-N query needs no join, assuming reads dominate and the catalog is stable' is reversible reasoning; 'we chose the denormalised schema' is not.
  2. Name the observation that falsified it and the lag between the first contradicting data and your acting on it. That lag is the honest part of the story, and volunteering it rather than being asked is most of what distinguishes the answer.
  3. Sequence the unwind as a migration, not a revert. Reverting code restores behaviour; it does not un-write rows. Describe the period where both paths were live with one authoritative, the comparison job that measured the difference between them, and the criterion that finally permitted the old path to be retired.
  4. Quantify what it cost and who paid: engineer-weeks, a slipped commitment, a backfill over N rows with its runtime and its throttle so it did not starve the write path. Reversals are expensive, and pretending otherwise reads as never having done one.
  5. Close with the property that made the reversal cheap, or the missing one that made it expensive: a flag around the read path, an append-only table you could replay, a soft delete instead of a hard one.
Follow-up
  • What would you have instrumented on day one to learn this sooner?
  • How did you decide the old path was safe to delete, and what did you keep a copy of and for how long?
  • Did anyone argue against the reversal, and what was their strongest point?
  • 01

    What is your experience with source control and collaborative development workflows?

  • 02

    Prepare a five-minute account of shipping to a date that could not move, with shortcuts you took knowingly. Pick work where the load was also spiky — a launch, a seasonal rollover, a migration window — rather than a routine sprint. Constraint: name at least two shortcuts you took deliberately and one you refused, and say which invariant each one put at risk. Deliverable: the decision as it stood at the time, the kill switch or fallback you kept, the debt's paid-or-open status today, and what you would cut first if the date moved closer.

  • 03

    Prepare a six-minute account of a technical decision you made and later reversed, where the reversal cost something real: shipped code, migrated data, or a commitment another team had already planned around. Constraint: the trigger must be an observation rather than a change of mood, and you must state what you had predicted. Deliverable: the original decision with its stated assumption, the measurement that broke it, the cost of unwinding and who paid it, and how you sequenced the reversal so the system stayed correct while both paths were live.

PracHub interview preparation framework ↗
Is this an official Ironbelly Studios interview guide?

No. It is PracHub's own research and practice material for the Software Engineer role at Ironbelly Studios. Rounds and questions reflect what candidates have reported, not a process Ironbelly Studios has published, and they change over time. Confirm the current format and scope with your recruiter.

PracHub interview research ↗
How long should I prepare for the technical demo?

Dedicate enough time to ensure your code is polished and follows industry standards. Quality is preferred over speed, so ensure your submission is well-commented and easy to navigate.

PracHub interview research ↗
What differentiates a successful candidate?

Successful candidates are those who can communicate their thought process clearly. Be ready to explain the "why" behind your implementation choices, not just write the code.

PracHub interview research ↗
What is the company culture like?

Ironbelly Studios is a team-oriented environment where technical skill is highly respected. Candidates describe open communication and a shared commitment to building high-quality interactive experiences.

PracHub interview research ↗
How long does the process take?

Timelines vary by project urgency. You can expect clear communication at each stage regarding your status.

PracHub interview research ↗
Sources & methodology 3 sources ↗

No official company page is cited. Rounds and questions come from candidate reports and PracHub editorial material; each source shows the date it was read.