diff --git a/.gitignore b/.gitignore index 92d5b35..d31e426 100644 --- a/.gitignore +++ b/.gitignore @@ -116,3 +116,4 @@ Cargo.lock # End of https://www.toptal.com/developers/gitignore/api/rust,clion+all playground/ +/SDL2.dll diff --git a/README.md b/README.md index 937b428..4f52c9e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,33 @@ # RadiancePlatform A simple text-based game framework -# Running +# Installation +Head over to [the releases page](https://github.com/Radiance-Platform/RadiancePlatform/releases/) to grab the latest precompiled build of the platform. Download the version for your operating system, and then open the program in your favorite command line terminal. Games can be loaded using the command-line flag like `--config-path example_game/`. The example game will work with any operating system version. +# Running for Development First, ensure you have a working Rust installation with cargo. See https://www.rust-lang.org/tools/install Then, from within the main folder (the one this README is in), run `cargo run -- --config-path example_game/` compile and start the game engine using the provided example game configuration files. Press the escape key to exit. +# Building Releases +Radiance is designed to be run on both Windows and Linux systems. At this time, macOS is not directly supported, but will likely work fine with some customization to these build instructions. Build steps are designed around Ubuntu and will need some slight tweaking to work on other Linux distributions. Directions are based on [this guide](https://stackoverflow.com/questions/31492799/cross-compile-a-rust-application-from-linux-to-windows). + +From an Ubuntu Linux installation with Rust and cargo, run the following commands to prepare your environment: +```sh +sudo apt-get install libsdl2-dev mingw-w64 -y +rustup target add x86_64-pc-windows-gnu +rustup toolchain install stable-x86_64-pc-windows-gnu +curl -s https://www.libsdl.org/release/SDL2-devel-2.0.9-mingw.tar.gz | tar xvz -C /tmp +cp -r /tmp/SDL2-2.0.9/x86_64-w64-mingw32/lib/* ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/ +cp /tmp/SDL2-2.0.9/x86_64-w64-mingw32/bin/SDL2.dll . +``` + +Afterwards, run these two commands to build for Windows and Linux respectively. Build files can be found in the `target` folder, under +```sh +cargo build --release --target x86_64-pc-windows-gnu +cargo build --release +``` + # Notes / Useful Resources Used https://doc.rust-lang.org/book/ https://doc.rust-lang.org/rust-by-example/ diff --git a/src/game/characters/mod.rs b/src/game/characters/mod.rs index b117d5f..65cefd8 100644 --- a/src/game/characters/mod.rs +++ b/src/game/characters/mod.rs @@ -1,4 +1,3 @@ - use crate::game::characters::interactions::Interactions; use crate::game::characters::attribute::Attribute; use crate::game::objects::Object; diff --git a/src/game/config_parsers/characters.rs b/src/game/config_parsers/characters.rs index 56ee93f..babc2ec 100644 --- a/src/game/config_parsers/characters.rs +++ b/src/game/config_parsers/characters.rs @@ -35,7 +35,7 @@ fn get_character_from_data(characters: &mut HashMap, data: Ch attributes: vec![], inventory: vec![], icon: ' ', - interactions: interactions, + interactions, dialog_id: "".to_string(), }; character.inventory.resize(data.inventory_size.width as usize, vec![] ); @@ -76,18 +76,16 @@ fn get_character_from_data(characters: &mut HashMap, data: Ch let value: f32 = modifier_data.effect_per_point[1..].parse().unwrap(); attack.affected_by.push(interactions::Modifier { attribute_id: modifier_data.attribute_id, - sign: sign, - value: value, + sign, + value, }); } character.interactions.attacks.push(attack); } - //println!("CHARACTER: {:?}", character); characters.insert(character.id.clone(), character); } -// Temporary data structure CharacterData is used for Serde parsing and nothing else. - +// Temporary data structure that is used for Serde parsing and nothing else #[derive(Debug, Serialize, Deserialize)] pub struct CharacterData { pub id: String, diff --git a/src/game/config_parsers/game.rs b/src/game/config_parsers/game.rs index 6436cc7..04b02d6 100644 --- a/src/game/config_parsers/game.rs +++ b/src/game/config_parsers/game.rs @@ -12,12 +12,10 @@ pub fn process_config(game_data: &mut GameData, config_path: &Path) -> Result<() // Convert to YAML let docs = YamlLoader::load_from_str(&*file_contents).unwrap(); + // Multi document support, doc is a yaml::Yaml, need to extract the doc let doc = &docs[0]; - // Debug print - //println!("GAME DOC: {:?}\n", doc); - let game_info_hash = doc.as_hash().unwrap(); for key in game_info_hash.keys() { diff --git a/src/game/config_parsers/maps.rs b/src/game/config_parsers/maps.rs index 3bae085..ecf307e 100644 --- a/src/game/config_parsers/maps.rs +++ b/src/game/config_parsers/maps.rs @@ -12,8 +12,6 @@ pub struct MapItemData { pub objects: Vec, } - - #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct MapObject { diff --git a/src/game/config_parsers/mod.rs b/src/game/config_parsers/mod.rs index 5a171cf..75980a6 100644 --- a/src/game/config_parsers/mod.rs +++ b/src/game/config_parsers/mod.rs @@ -1,13 +1,12 @@ use std::ffi::OsStr; -use crate::game::maps::{Map, MapInfo}; use walkdir::WalkDir; +use crate::game::config_parsers::maps::MapItemData; +use crate::game::maps::{Map, MapInfo, MapData}; use crate::game::characters::Character; use crate::game::objects::Object; -use crate::game::maps::MapData; use crate::game::dialogs::Dialog; use std::collections::HashMap; use std::error::Error; -use crate::game::config_parsers::maps::MapItemData; mod characters; mod game; @@ -106,7 +105,7 @@ impl GameData { } // Takes the MapItemData, characters list, and objects list and inserts the characters and objects - // in the right spaces in the game map + // in the right spaces in the game map fn set_map_grid(&mut self, map_item_data: Vec, characters: HashMap, objects: HashMap< String, Object> ) -> Result<(), Box> { for map_item in map_item_data { diff --git a/src/game/config_parsers/objects.rs b/src/game/config_parsers/objects.rs index 4337a5e..e35ad4f 100644 --- a/src/game/config_parsers/objects.rs +++ b/src/game/config_parsers/objects.rs @@ -4,12 +4,11 @@ use std::path::Path; use std::collections::HashMap; use yaml_rust::YamlLoader; use yaml_rust::Yaml; -use crate::game::objects::{Object, ObjectState, - ObjectInteraction, ObjectInteractionActivate, +use crate::game::objects::{Object, ObjectState, ObjectInteraction, ObjectInteractionActivate, ObjectInteractionObjectUse}; // Takes an object config file and loads it into an object, then adds that object to the objects list -// so that it can later be added to the game map. +// so that it can later be added to the game map. pub fn process_config(objects: &mut HashMap, config_path: &Path) -> Result<(), Box> { // Load file contents @@ -17,6 +16,7 @@ pub fn process_config(objects: &mut HashMap, config_path: &Path) // Convert to YAML let docs = YamlLoader::load_from_str(&*file_contents).unwrap(); + // Multi document support, doc is a yaml::Yaml, need to extract the doc let doc = &docs[0]; diff --git a/src/game/dialogs/mod.rs b/src/game/dialogs/mod.rs index f8ac70f..5e507a6 100644 --- a/src/game/dialogs/mod.rs +++ b/src/game/dialogs/mod.rs @@ -1,7 +1,7 @@ use serde::Deserialize; // Dialog data structure. Contains a single dialog object consisting of -// some NPC dialog and two dialog options for the player. +// some NPC dialog and two dialog options for the player. #[derive(Debug, Clone, Deserialize)] pub struct Dialog { diff --git a/src/game/maps/mod.rs b/src/game/maps/mod.rs index 910cf89..3c5b3af 100644 --- a/src/game/maps/mod.rs +++ b/src/game/maps/mod.rs @@ -3,8 +3,7 @@ use crate::game::characters::Character; use crate::game::objects::Object; // Map data structure. Contains a single map with a grid of spaces. -// Each space can hold either nothing, a character, or -// an object. +// Each space can hold either nothing, a character, or an object. #[derive(Clone, Debug)] pub enum MapData { diff --git a/src/game/mod.rs b/src/game/mod.rs index 80ab318..129daea 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -1,7 +1,7 @@ use std::process::exit; use config_parsers::GameData; -use crate::game::screen::{Screen, VisualState}; use crossterm::{event::{Event, KeyCode}, Result}; +use crate::game::screen::{Screen, VisualState}; pub mod characters; pub mod dialogs; diff --git a/src/game/objects/mod.rs b/src/game/objects/mod.rs index 0ea3221..ea548e2 100644 --- a/src/game/objects/mod.rs +++ b/src/game/objects/mod.rs @@ -1,19 +1,14 @@ use serde::{Serialize,Deserialize}; +// Object data structure. These are items found in the game maps, or given to the player +// via an interaction. These make up the majority of the game's interactivity. + #[derive(Clone, Debug)] pub struct ObjectState { pub name: String, pub value: bool } - -/*#[derive(Clone, Debug)] -pub struct ObjectInteraction { - pub category: ObjectInteractionCategory, - pub values: String -}*/ - - #[derive(Clone, Debug)] pub enum ObjectInteraction { ObjectInteractionActivate(ObjectInteractionActivate), @@ -39,7 +34,7 @@ pub struct ObjectInteractionWorld { } -// TODO: Object's categories should probably be some sort of type rather than arbitrary strings +// TODO: Future Enhancement: Object's categories should probably be some sort of type rather than arbitrary strings /*pub enum ObjectCategory { "simple", "collidable" diff --git a/src/game/screen/mod.rs b/src/game/screen/mod.rs index 8fa6206..603571c 100644 --- a/src/game/screen/mod.rs +++ b/src/game/screen/mod.rs @@ -1,24 +1,20 @@ use std::fmt::Debug; -use crate::game::config_parsers::GameData; -use crate::game::GameState; - use std::io::{Error, ErrorKind, stdout}; use std::process::{exit}; - +use crate::game::config_parsers::GameData; +use crate::game::GameState; +use crate::game::maps::MapData; +use crate::game::characters::Character; +use crate::game::characters::attribute; +use crate::game::objects::{ObjectInteraction, Object}; use crossterm::{ execute, style::{Print}, ExecutableCommand, Result, - terminal::{SetSize, size}, - cursor::{MoveTo} + terminal::{SetSize, size, disable_raw_mode, enable_raw_mode, Clear, ClearType}, + cursor::{MoveTo, Hide, Show}, + event::{Event, KeyCode}, }; -use crossterm::cursor::{Hide, Show}; -use crossterm::event::{Event, KeyCode}; -use crossterm::terminal::{disable_raw_mode, enable_raw_mode, Clear, ClearType}; -use crate::game::maps::MapData; -use crate::game::characters::Character; -use crate::game::characters::attribute; -use super::objects::{ObjectInteraction, Object}; #[derive(Clone, Debug)] pub enum VisualState { diff --git a/src/main.rs b/src/main.rs index 6f3528d..422829e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,8 +16,6 @@ struct Args { } fn main() { - println!("Hello, Radiance!"); - // Make sure we have arguments or compiled-in // TODO: Some way to compile config files in, might need a custom build script or something let args = Args::parse();