FlatRedBall2 Engine Overview
FlatRedBall2 is a 2D game engine built on MonoGame. It provides physics, collision, rendering, input, and UI (via Gum) out of the box. Game code creates Screens, Entities, and wires them together.
What the Engine Does Automatically
- Physics:
pos += vel*dt + acc*(dt^2/2), vel += acc*dt, vel -= vel*drag*dt — every frame, for every entity
- Collision resolution: All registered
CollisionRelationship pairs are tested and resolved after physics
- Rendering: Everything added via
screen.Add(renderable) is drawn, sorted by Layer + Z
- Input polling:
Input updates keyboard, mouse, and gamepad state each frame
- Gum UI updates: Click/hover/focus events routed to all active Gum elements
- Screen transitions: Old screen torn down, new screen initialized — entities, factories, Gum elements all cleaned up automatically
- Camera: Initialized from window viewport; transforms world coordinates to screen
What Game Code Must Implement
- Entity subclasses — override
CustomInitialize (add shapes, input) and CustomActivity (per-frame logic)
- Screen subclasses — override
CustomInitialize (create factories, entities, collision relationships, UI)
- Collision relationships — call
AddCollisionRelationship in screen's CustomInitialize
- Game1.cs — initialize
FlatRedBallService.Default, call Update/Draw each frame
- Save/load — the engine offers nothing here; use standard .NET (
System.IO + System.Text.Json, or your serializer of choice). There is no FRB2 save API to search for.
Frame Loop Order
Each frame runs in this order:
- Screen transition (if pending) — old screen destroyed, new screen initialized
- Input update — keyboard, mouse, gamepad polled
- Gum update — UI input events routed
- Physics — entity positions updated from velocity/acceleration/drag
- Collision — registered relationships resolved; positions corrected
- Entity
CustomActivity — each entity's per-frame logic
- Screen
CustomActivity — screen-level logic (sees post-collision, post-entity state)
- Draw — all registered renderables drawn
Bootstrapping a Game
Game1.cs wires the MonoGame loop to FRB: FlatRedBallService.Default.Initialize<TScreen>(this) in Initialize (sizes the window, initializes, starts the screen — or Initialize(this, "…gluj") to boot a whole Glue project), then Update/Draw each frame. The complete template — including the GraphicsProfile.HiDef setup that crashes at startup if omitted — lives in sample-project-setup; don't hand-roll it.
Key Design Rules
- Y+ is up in world space. Camera flips Y for screen rendering.
- Always use
Factory<T> to create entities — never new MyEntity(). Factory sets Engine, registers with the screen, and enables GetFactory<T>().
- No static state (engine infrastructure only) — only
FlatRedBallService.Default is static. Everything else is accessed via Engine on entities or directly on screens. Game code may use static singletons for global game data (e.g., GameData.Current holding a monster roster or player save state) — this rule prohibits engine-layer statics, not application-layer ones.
- Shapes default to
IsVisible = false — always set IsVisible = true.
Entity.Engine: Use CustomInitialize, not the constructor — Engine is null until Factory injects it.
- Use Gum for all UI — HUD, health bars, menus, win/lose screens, any text display. Shapes are for world-space game objects (collision geometry, projectiles, platforms). If you reach for a shape to build UI, stop and use Gum instead.
What a Screen Looks Like
A screen creates its Factory<T> instances in CustomInitialize, spawns entities with Create(), and wires AddCollisionRelationship over those factories — the gestalt the per-topic skills show piecewise:
public class GameScreen : Screen
{
private Factory<Player> _playerFactory = null!;
private Factory<Wall> _wallFactory = null!;
public override void CustomInitialize()
{
_playerFactory = new Factory<Player>(this);
_wallFactory = new Factory<Wall>(this);
_playerFactory.Create();
AddCollisionRelationship<Player, Wall>(_playerFactory, _wallFactory)
.MoveFirstOnCollision();
}
}
Sub-Systems (accessed via Engine.*)
| Property |
Type |
Purpose |
Input |
InputManager |
Keyboard, cursor, gamepads |
Content |
ContentLoader |
Load textures, fonts via .mgcb pipeline |
Random |
GameRandom |
Seeded random with helpers (Between, RadialVector2) |
Time |
TimeManager |
Frame timing, async delays |
Audio |
AudioManager |
Load/play SoundEffect and Song, music, volume (see audio) |
Which Skill to Read Next
| Task |
Skill |
| Set up screens and transitions |
screens |
| Create entities with shapes |
entities-and-factories |
| Load textures and use sprites |
content-and-assets |
| Set up collision |
collision-relationships |
| Handle input |
input-system |
| Physics and movement |
physics-and-movement |
| Platformer mechanics |
platformer-movement |
| Camera setup |
camera |
| UI/HUD with Gum |
gum-integration |
| Timers and cooldowns |
timing |
| Level layouts |
levels |
| Shapes (no-art visuals) |
shapes |
1---2name: engine-overview3description: Engine overview for FlatRedBall2. Start here for any game development task. Covers what the engine does automatically vs what game code must implement, the frame loop, bootstrapping, and known stubs. Trigger when starting a new game, needing to understand the engine architecture, or unsure how FlatRedBall2 works.4---56# FlatRedBall2 Engine Overview78FlatRedBall2 is a 2D game engine built on MonoGame. It provides physics, collision, rendering, input, and UI (via Gum) out of the box. Game code creates Screens, Entities, and wires them together.910## What the Engine Does Automatically1112- **Physics**: `pos += vel*dt + acc*(dt^2/2)`, `vel += acc*dt`, `vel -= vel*drag*dt` — every frame, for every entity13- **Collision resolution**: All registered `CollisionRelationship` pairs are tested and resolved after physics14- **Rendering**: Everything added via `screen.Add(renderable)` is drawn, sorted by Layer + Z15- **Input polling**: `Input` updates keyboard, mouse, and gamepad state each frame16- **Gum UI updates**: Click/hover/focus events routed to all active Gum elements17- **Screen transitions**: Old screen torn down, new screen initialized — entities, factories, Gum elements all cleaned up automatically18- **Camera**: Initialized from window viewport; transforms world coordinates to screen1920## What Game Code Must Implement2122- **Entity subclasses** — override `CustomInitialize` (add shapes, input) and `CustomActivity` (per-frame logic)23- **Screen subclasses** — override `CustomInitialize` (create factories, entities, collision relationships, UI)24- **Collision relationships** — call `AddCollisionRelationship` in screen's `CustomInitialize`25- **Game1.cs** — initialize `FlatRedBallService.Default`, call `Update`/`Draw` each frame26- **Save/load** — the engine offers nothing here; use standard .NET (`System.IO` + `System.Text.Json`, or your serializer of choice). There is no FRB2 save API to search for.2728## Frame Loop Order2930Each frame runs in this order:31321. **Screen transition** (if pending) — old screen destroyed, new screen initialized332. **Input update** — keyboard, mouse, gamepad polled343. **Gum update** — UI input events routed354. **Physics** — entity positions updated from velocity/acceleration/drag365. **Collision** — registered relationships resolved; positions corrected376. **Entity `CustomActivity`** — each entity's per-frame logic387. **Screen `CustomActivity`** — screen-level logic (sees post-collision, post-entity state)398. **Draw** — all registered renderables drawn4041## Bootstrapping a Game4243`Game1.cs` wires the MonoGame loop to FRB: `FlatRedBallService.Default.Initialize<TScreen>(this)` in `Initialize` (sizes the window, initializes, starts the screen — or `Initialize(this, "…gluj")` to boot a whole Glue project), then `Update`/`Draw` each frame. The complete template — including the `GraphicsProfile.HiDef` setup that crashes at startup if omitted — lives in `sample-project-setup`; don't hand-roll it.4445## Key Design Rules4647- **Y+ is up** in world space. Camera flips Y for screen rendering.48- **Always use `Factory<T>`** to create entities — never `new MyEntity()`. Factory sets `Engine`, registers with the screen, and enables `GetFactory<T>()`.49- **No static state** (engine infrastructure only) — only `FlatRedBallService.Default` is static. Everything else is accessed via `Engine` on entities or directly on screens. Game code may use static singletons for global game data (e.g., `GameData.Current` holding a monster roster or player save state) — this rule prohibits engine-layer statics, not application-layer ones.50- **Shapes default to `IsVisible = false`** — always set `IsVisible = true`.51- **`Entity.Engine`**: Use `CustomInitialize`, not the constructor — `Engine` is null until Factory injects it.52- **Use Gum for all UI** — HUD, health bars, menus, win/lose screens, any text display. Shapes are for world-space game objects (collision geometry, projectiles, platforms). If you reach for a shape to build UI, stop and use Gum instead.5354## What a Screen Looks Like5556A screen creates its `Factory<T>` instances in `CustomInitialize`, spawns entities with `Create()`, and wires `AddCollisionRelationship` over those factories — the gestalt the per-topic skills show piecewise:5758```csharp59public class GameScreen : Screen60{61 private Factory<Player> _playerFactory = null!;62 private Factory<Wall> _wallFactory = null!;6364 public override void CustomInitialize()65 {66 _playerFactory = new Factory<Player>(this);67 _wallFactory = new Factory<Wall>(this);68 _playerFactory.Create();6970 AddCollisionRelationship<Player, Wall>(_playerFactory, _wallFactory)71 .MoveFirstOnCollision();72 }73}74```7576## Sub-Systems (accessed via `Engine.*`)7778| Property | Type | Purpose |79|----------|------|---------|80| `Input` | `InputManager` | Keyboard, cursor, gamepads |81| `Content` | `ContentLoader` | Load textures, fonts via `.mgcb` pipeline |82| `Random` | `GameRandom` | Seeded random with helpers (`Between`, `RadialVector2`) |83| `Time` | `TimeManager` | Frame timing, async delays |84| `Audio` | `AudioManager` | Load/play `SoundEffect` and `Song`, music, volume (see `audio`) |8586## Which Skill to Read Next8788| Task | Skill |89|------|-------|90| Set up screens and transitions | `screens` |91| Create entities with shapes | `entities-and-factories` |92| Load textures and use sprites | `content-and-assets` |93| Set up collision | `collision-relationships` |94| Handle input | `input-system` |95| Physics and movement | `physics-and-movement` |96| Platformer mechanics | `platformer-movement` |97| Camera setup | `camera` |98| UI/HUD with Gum | `gum-integration` |99| Timers and cooldowns | `timing` |100| Level layouts | `levels` |101| Shapes (no-art visuals) | `shapes` |