Tutorial 05: Structs and Enums
Difficulty: Beginner
Time: ~35 minutes
Prerequisites: Tutorial 04
Goal
Model gameplay state with struct and enum, then organize behavior with match and impl.
struct
A struct groups related fields into one named type.
rs
struct PlayerStats {
name: string,
kills: int,
alive: bool,
}Create a value:
rs
let stats: PlayerStats = {
name: "Alex",
kills: 0,
alive: true
}Access fields with dot syntax:
rs
stats.kills = stats.kills + 1enum
An enum describes a value that can be one of several named variants.
rs
enum MatchState {
Lobby,
Countdown,
Running,
Finished,
}This is better than encoding modes as raw integers.
match
match is the natural way to handle enum variants:
rs
fn show_state(state: MatchState) {
match state {
MatchState::Lobby => { say("In lobby") },
MatchState::Countdown => { say("Starting soon") },
MatchState::Running => { say("Match live") },
MatchState::Finished => { say("Match ended") },
}
}impl Methods
Use impl to attach methods to a struct.
rs
struct Counter {
value: int,
}
impl Counter {
fn increment(self) {
self.value = self.value + 1
}
fn reset(self) {
self.value = 0
}
}Methods make related logic easier to discover and keep together.
Full Example
rs
namespace tutorial05
enum MatchState {
Lobby,
Countdown,
Running,
Finished,
}
struct Game {
round: int,
max_rounds: int,
active: bool,
state: MatchState,
}
impl Game {
fn start(self) {
self.active = true
self.state = MatchState::Countdown
}
fn next_round(self) {
self.round = self.round + 1
if (self.round > self.max_rounds) {
self.state = MatchState::Finished
self.active = false
}
}
fn summary(self) -> string {
return f"Round {self.round}/{self.max_rounds}, active={self.active}"
}
}
let game: Game = {
round: 1,
max_rounds: 3,
active: false,
state: MatchState::Lobby
}
@on_trigger("start_match")
fn start_match() {
game.start()
say("Match is starting")
}
@tick(rate=20)
fn tick_game() {
match game.state {
MatchState::Lobby => {
actionbar(@a, "Lobby")
},
MatchState::Countdown => {
title(@a, "3...")
game.state = MatchState::Running
},
MatchState::Running => {
actionbar(@a, game.summary())
},
MatchState::Finished => {
actionbar(@a, "Finished")
},
}
}Why This Matters
structkeeps related fields togetherenumgives names to valid statesmatchmakes state handling explicitimplkeeps data and behavior close
Practice
- Add a
wins: intfield toGame. - Add a new enum state such as
Paused. - Add an
implmethod that resets the game back toLobby.
Next: Tutorial 06: Stdlib Tour