# Deimos in a Game of Tiles ```deimos pub int TileGameMod mut fn init(s: mut TileGameState) -> Void mut fn tick(s: mut TileGameState) -> Void end pub extern class TileGameState pub extern fn tiles() -> List pub extern mut fn tilesMut() -> mut List pub extern fn player() -> Player end pub int Tile fn x() -> Size fn y() -> Size fn walkingSpeed() -> Speed fn runningSpeed() -> Speed fn draw(s: TileGameState) -> TileDraw end pub record Color(red: Float, green: Float, blue: Float) end pub val-class Brightness brightness: Double pub ctor(brightness: Double) if brightness >= 0 && brightness <= 1 then self.brightness = brightness else throw IllegalArgumentException("Cannot have a brightness outside of 0.0-1.0 range; given ${brightness}") end end end pub record TileDraw(color: Color, brightness: Brightness) end pub record Speed(speed: Double) end pub extern class Player pub extern fn isRunning() -> Boolean end pub class GrassTile(x: Size, y: Size) : Tile pub enum Season Green, Brown end mut season: Season pub mut fn flipSeason() -> Void match self.season Season::Green => self.season = Season::Brown, Season::Brown => self.season = Season::Green end end pub fn x() -> Size = self.size pub fn y() -> Size = self.size pub fn walkingSpeed() -> Speed = Speed(2.5) pub fn runningSpeed() -> Speed = Speed(4.0) fn getColor() -> Color if self.season == Season::Green Color(0.0F, 1.0F, 0.0F) else Color(0.6F, 0.3F, 0.0F) end end pub fn draw(s: TileGameState) -> TileDraw let color = self.getColor() if s.player().isRunning() then TileDraw(color, Brightness(0.9)) else TileDraw(color, Brightness(0.7)) end end end pub class CoreMod : TileGameMod mut tickCount = 0 pub mut fn init(s: mut TileGameState) -> Void for x in 0..10 do for y in 0..10 do s.tilesMut() << GrassTile(x, y) end end end pub mut fn tick(s: mut TileGameState) -> Void self.tickCount++ if tickCount == 16 * 10 then self.tickCount = 0 let randomX = std::num::randomSize(0, 10) let randomY = std::num::randomSize(0, 10) let tileNumber = randomX * 10 + randomY let tile = s.tilesMut().getMut(tileNumber) if tile is GrassTile then tile.flipSeason() end end end end ``` ```rust struct TileGameState { tiles: Gc<Object>, player: Gc<Player> } struct Player { running: bool, x: f64, y: f64 } struct Color { r: f32, g: f32, b: f32 } struct Brightness(f64); fn main() { let mut dvm_context = load_context_with_mods(); let mut dvm_state = DvmState::new(); dvm_context.add_platform_function("TileGameState::tiles", |args: &[Value]| { let this: Gc<TileGameState> = args[0].unwrap_native_object().downcast::<TileGameState>(); Value::Object(this.tiles) }); dvm_context.add_platform_function("TileGameState::player", |args: &[Value]| { let this: Gc<TileGameState> = args[0].unwrap_native_object().downcast::<TileGameState>(); Value::Object(this.player) }); dvm_context.add_platform_function("Player::isRunning", |args: &[Value]| { let this: Gc<Player> = args[0].unwrap_native_object().downcast::<Player>(); if this.running && is_in_bounds(this) { Value::Boolean(true) } else { Value::Boolean(false) } }); let core_mod: Gc<Object> = construct_object(&mut dvm_state, &dvm_context, "CoreMod"); let tile_game_state: GcAny = construct_native_object(&mut dvm_state, &dvm_context, "TileGameState", TileGameState { tiles: construct_object(&mut dvm_state, &dvm_context, "std::collections::List"), player: construct_native_object(&mut dvm_state, &dvm_context, "Player", Player { running: false, }).downcast::<Player>() }); call(&mut dvm_state, &dvm_context, "TileGameMod::init", &[ Value::Object(core_mod), Value::NativeObject(tile_game_state), ]); loop { if tick() { call(&mut dvm_state, &dvm_context, "TileGameMod::tick", &[ Value::Object(core_mod), Value::NativeObject(tile_game_state) ]); } if frame() { let tile_game_state: TileGameState = tile_game_state.downcast::<TileGameState>(); let tiles: Array<Gc<Object>> = call( &mut dvm_state, &dvm_context, "std::collections::List::toArray", &[Value::Object(tile_game_state)] ).unwrap_array(); for tile in tiles { let x: usize = call(&mut dvm_state, &dvm_context, "Tile::x", &[ Value::Object(tile) ]).unwrap_size(); let y: usize = call(&mut dvm_state, &dvm_context, "Tile::y", &[ Value::Object(tile) ]).unwrap_size(); let tile_draw: Gc<Object> = call(&mut dvm_state, &dvm_context, "Tile::draw", &[ Value::Object(tile), Value::NativeObject(tile_game_state) ]).unwrap_object(); let r: f32 = read_field_path(&tile_draw, "color.r").unwrap_float(); let g: f32 = read_field_path(&tile_draw, "color.g").unwrap_float(); let b: f32 = read_field_path(&tile_draw, "color.b").unwrap_float(); let color = Color { r, g, b }; let brightness = Brightness(read_field_path(&tile_draw, "brightness.brightness").unwrap_double()); draw_tile(x, y, color, brightness); } } } } ```