I learned one really important lesson while working on Monster Train.

Keep your gameplay code completely separate from your UI/Animation/Input.

Here is how I put this into practice:

1/11

#gamedev #indiedev
First off, benefits:

1. Simpler code from avoiding mixing up game logic with input and visual controllers
2. Easier to network
3. Easier to create save/load systems
4. Easier to create debugging/testing tools
5. Easier to create replay systems

Now, onto the technique...

2/11
1. All game simulation state is contained in 1 structure (WorldState)

Components of sim are organized inside structures within that 1 data structure. This WorldState can be passed around to pure functions, serialized to disk or over the network, and inspected by tools.

3/11
2. All game logic is written as pure static function

The goal is to keep the sim state (WorldState) separate from the logic that manipulates the state. So the sim logic is written as static functions which contain no state themselves.

Also means we avoid all global state!

4/11
3. Game sim is modified by commands (WorldCommand)

An example is WorldCommandMove. A WorldCommand may have any number of arguments contained within it such as "speed" or "direction".

Input from controllers, etc result in creation of WorldCommands which modify WorldState.

5/11
4. Systems run every frame to update the WorldState

For realtime games like platformers or FPS, we need to automatically update the WorldState each frame. Systems are pure, static classes that are called one after another each frame.

6/11
An example is WorldSystemMovement to update object positions based on velocity and collision.

Another example is WorldSystemAI to update enemies based on AI driven behavior.

7/11
5. Helper utilities contain shared logic

When working with pure functions, we often need to share code that would be shared via inheritance in classic OO code. We have utils such as PhysicsUtil or CombatUtil which contain shared static code that is used by WorldCommands

8/11
6. Events are the output of the sim and drive the presentation

There are a few ways to drive the presentation layer (models, UI, VFX, SFX, etc) but one core tool I make use of are events which are emitted from the simulation.

9/11
I pass in a list of WorldEvents to WorldCommands which is populated with events. I process this list (outside the sim) to achieve the desired visuals.

Example is WorldEventDamage which would indicate something took damage. We display a damage number and SFX in response.

10/11
There are a lot of other details to this approach but that is the basic structure!

What do you think? Do you have your own approach?

11/11

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Brian Cronin 🌎🌍🌏🌡📈

Brian Cronin 🌎🌍🌏🌡📈 Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(