Adding an Arena Config
To begin with, let's make the Arena dimensions configurable. Add this structure to a new file config.rs.
#[derive(Debug, Deserialize, Serialize)]
struct ArenaConfig {
pub height: f32,
pub width: f32,
}
impl Default for ArenaConfig {
fn default() -> Self {
ArenaConfig {
height: 100.0,
width: 100.0,
}
}
}
The default values match the values used in the full example, so if we don't use a config file things will
look just like the Pong example. Another option would be to use [#serde(default)], which allows
you to set the default value of a field if that field is not present in the config file. This is different
than the Default trait in that you can set default values for some fields while requiring others
be present. For now though, let's just use the Default trait.
Adding the Config to the World
Now, in main.rs, add the following lines:
use config::ArenaConfig;
We'll need to load the config at startup, so let's add this to the run function in main.rs
let arena_config = ArenaConfig::load(&config);
Now that we have loaded our config, we want to add it to the world so other modules can access
it. We do this by adding the config as a resource during Application creation:
.with_resource(arena_config)
.with_bundle(PongBundle::default())?
Now for the difficult part: replacing every use of ARENA_WIDTH and ARENA_HEIGHT with our config object.
First, let's change our initialisation steps in pong.rs.
Add the following line to the top of pong.rs:
use config::ArenaConfig;
Now, in the initialise_paddles() function, add the following lines after the initialisation of the
left_transform and right_transform.
let (arena_height, arena_width) = {
let config = &world.read_resource::<ArenaConfig>();
(config.height, config.width)
};
Now replace all references to ARENA_HEIGHT with arena_height and all references to ARENA_WIDTH with
arena_width. Do this for each initialisation function in pong.rs.
Accessing Config Files from Systems
It is actually simpler to access a Config file from a system than via the World directly. To access
it in the System's run() function, add it to the SystemData type. This is what the BounceSystem looks
like when it wants to access the ArenaConfig.
use config::ArenaConfig;
...
type SystemData = (
WriteStorage<'s, Ball>,
ReadStorage<'s, Paddle>,
ReadStorage<'s, Transform>,
Fetch<'s, AssetStorage<Source>>,
Fetch<'s, Sounds>,
Fetch<'s, Option<Output>>,
Fetch<'s, ArenaConfig>,
);
...
fn run(&mut self,
(mut balls, paddles, transforms, storage, sounds, audio_output, arena_config): SystemData) {
Now, in the run() function, replace the reference to ARENA_HEIGHT with arena_config.height.
Add Fetch<'s, ArenaConfig> to the WinnerSystem and PaddleSystem as well, replacing the reference to
ARENA_WIDTH with arena_config.width.
Making config.ron
Now for the final part: actually creating our config.ron file. This will be very simple right now, and
expand as we add more configurable items. For now, just copy and paste the following into a new file. Feel
free to modify the height and width if you want.
arena: (
height: 100.0,
width: 100.0,
)