Code Monkey home page Code Monkey logo

asciimon's Introduction

Welcome to my Github!

I put pretty much everything I do here, from playing around and general experimentation, to my own personal hobby projects.

You can find videos of some projects on my youtube here: https://www.youtube.com/c/hopsonn

I also have a (Work in Progress) website here: https://hopson97.github.io/

asciimon's People

Contributors

dmitmel avatar eternalmc avatar herman-l avatar hopson97 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

asciimon's Issues

Can't open game

Hi, I'm very new to game dev, however i cant open the game, please tell me how.

The unasked for code review

This is my first time using Rust, so the code probably isn't going to be very idiomatic or whatever, so feel free to tell me if I am doing something "not rusty" :).

Don't mind if I do! This will mostly be high-level notes, but I'd like to point out a few things for at least surface-level improvements.

Clippy

cargo clippy should be your friend. Do you like rustc's pickiness, and wish it would be more opinionated in an attempt to guide you to better code? That's what clippy is. With the magic of rustup and cargo, it's as easy to use on your project as:

$ rustup install nightly
$ rustup component add clippy-preview --toolchain=nightly
$ cargo +nightly clippy

clippy-preview is currently only available on the nightly toolchain, but is riding the trains to stable, just as happened with rustfmt-preview.

To overview a few of the lints it currently spits for this project:

warning: using `println!("")`
  --> src\main.rs:15:5
   |
15 |     println!("");println!("");
   |     ^^^^^^^^^^^^ help: replace it with: `println!()`
   |
   = note: #[warn(println_empty_string)] on by default
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#println_empty_string

warning: using `println!("")`
  --> src\main.rs:15:18
   |
15 |     println!("");println!("");
   |                  ^^^^^^^^^^^^ help: replace it with: `println!()`
   |
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#println_empty_string

There's no reason to give an empty string to println. In this case I might actually write print!("\n\n"), as println!("\n") is probably a bit too interesting of a behavior.

warning: returning the result of a let binding from a block. Consider returning the expression directly.
  --> src\game\game_state\state_explore.rs:36:9
   |
36 |         state
   |         ^^^^^
   |
   = note: #[warn(let_and_return)] on by default
note: this expression can be directly returned
  --> src\game\game_state\state_explore.rs:31:21
   |
31 |           let state = StateExplore {
   |  _____________________^
32 | |             player:         Player::new(),
33 | |             last_action:    Action::NoAction,
34 | |             maps:           MapManager::new()
35 | |         };
   | |_________^
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#let_and_return

pub fn new() -> StateExplore {
let state = StateExplore {
player: Player::new(),
last_action: Action::NoAction,
maps: MapManager::new()
};
state
}

This is more simply written as:

StateExplore {
    player:         Player::new(),
    last_action:    Action::NoAction,
    maps:           MapManager::new()
}

The intermediate binding adds no information. Rust's grammar is expression-oriented, and single-expression functions are quite common in idiomatic code, especially for ::new() functions.

Some self-explanatory warnings for some things:

warning: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise
   --> src\graphics\renderer.rs:106:20
    |
106 |         let sect = self.render_sections.get(section).unwrap();
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&self.render_sections[section]`
    |
    = note: #[warn(get_unwrap)] on by default
    = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#get_unwrap

warning: the variable `line_num` is used as a loop counter. Consider using `for (line_num, item) in data.enumerate()` or similar iterators
   --> src\graphics\renderer.rs:187:21
    |
187 |         for line in data {
    |                     ^^^^
    |
    = note: #[warn(explicit_counter_loop)] on by default
    = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#explicit_counter_loop

warning: identical conversion
  --> src\graphics\colour.rs:26:9
   |
26 | /         String::from(format!(
27 | |             "\x1b[{};2;{};{};{}m", id, r, g, b
28 | |         ))
   | |__________^ help: consider removing `String::from()`; `format!` returns a `String`
   |
   = note: #[warn(identity_conversion)] on by default
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#identity_conversion

warning: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices.
  --> src\game\game_state\mod.rs:16:44
   |
16 |     fn handle_input(&mut self, input_args: &Vec<&str>) -> ReturnResult;
   |                                            ^^^^^^^^^^ help: change this to: `&[&str]`
   |
   = note: #[warn(ptr_arg)] on by default
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#ptr_arg

warning: use of `expect` followed by a function call
  --> src\game\map.rs:44:18
   |
44 |                 .expect(&format!("Unable to open file for map {} {}", x, y));
   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| panic!("Unable to open file for map {} {}", x))`
   |
   = note: #[warn(expect_fun_call)] on by default
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#expect_fun_call

warning: usage of `contains_key` followed by `insert` on a `HashMap`
  --> src\game\map_manager.rs:32:17
   |
32 | /                 if !self.maps.contains_key(&pos) {
33 | |                     let map = match Map::load(map_x, map_y) {
34 | |                         None =>  continue,
35 | |                         Some(map) =>  map
...  |
38 | |                     self.maps.insert(pos, map);
39 | |                 }
   | |_________________^ help: consider using: `self.maps.entry(pos)`
   |
   = note: #[warn(map_entry)] on by default
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#map_entry

warning: you seem to want to iterate on a map's values
  --> src\game\map_manager.rs:43:25
   |
43 |         for (_, map) in &self.maps {
   |                         ^^^^^^^^^^
   |
   = note: #[warn(for_kv_map)] on by default
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#for_kv_map
help: use the corresponding method
   |
43 |         for map in self.maps.values() {
   |             ^^^    ^^^^^^^^^^^^^^^^^^

warning: single-character string constant used as pattern
  --> src\game\mod.rs:76:68
   |
76 |                     let input_args: Vec<&str> = input.trim().split(" ").collect();
   |                                                 -------------------^^^- help: try using a char instead: `input.trim().split(' ')`
   |
   = note: #[warn(single_char_pattern)] on by default
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#single_char_pattern

(I fixed the help string on identity_conversion; it's broken currently, and I submitted an issue for it.)

Actual human thought

Asciimon/src/game/mod.rs

Lines 11 to 17 in 0d09090

use self::game_state::ReturnResult;
use self::game_state::GameState;
use self::game_state::state_explore::StateExplore;
use std::io::Write;
use std::io::stdin;
use std::io::stdout;

This applies to a few areas, and is something easily missable if you're used to other languages with a one-import-per-line design. You can (and it's typical to) import multiple names from a module in one use statement:

use self::game_state::{ReturnResult, GameState, state_explore::StateExplore};

use std::io::{Write, stdin, stdout};

Another bit seen here is that in game/game_state/mod.rs, it might make sense to have pub use self::state_explore::StateExplore; then you can refer to it as game::game_state::StateExplore instead of game::game_state::state_explore::StateExplore.

fn update(&mut self) -> ReturnResult {
let mut ret_result = ReturnResult::None;
match self.last_action {
Action::MovePlayer(x, y) => {
ret_result = ReturnResult::Redraw;
self.handle_move_player(x, y);
}
Action::NoAction => {}
}
ret_result
}

This could more cleanly be written using Rust's expression-orientedness:

fn update(&mut self) -> ReturnResult {
    match self.last_action {
        Action::NoAction => ReturnResult::None,
        Action::MovePlayer(x, y) => {
            self.handle_move_player(x, y);
            ReturnResult::Redraw
        }
   }
}

Asciimon/src/game/map.rs

Lines 92 to 97 in 0d09090

//rust is annoying with finding the char of a string via index, so only way i can think of is to literally iterate over the string
for (i, c) in line.chars().enumerate() {
if i == x as usize {
return c
}
}

This is because finding the nth character in a UTF-8 string is an O(n) operation. If you're sure that you've only got ASCII (single byte characters) in the string, you can convert it through a byte string (line.as_bytes()[x as usize] as char) or slice to the correct location (line[x as usize..].chars().next().unwrap_or('.')).

pub fn get_size(&self) -> &Vector2D<i32> {

Typically getters in Rust are named without a get_ prefix. This doesn't cause any problems: function and value namespaces are separate (for better or for worse).

The last note I have is that you tend to document your functions with /* */ mutliline comments: if you use /// doc comments, the documentation will show up in tooling (I'm unsure about RLS in vscode, but cargo doc for sure (for public functions of a library, internal binary documentation is... rough)). Everything else is me being overly picky about formatting since your formatting doesn't line up perfectly with cargo fmt.

I hope you've been enjoying Rust, it's definitely my favorite language right now. Every language has its use cases, but I certainly enjoy Rust because for me, it allows me to have the productivity I have in Java/Kotlin but with much more control. Rust's borrow checker has made me a better programmer as I know much more about how my code treats data now. And fearless concurrency is nice too ๐Ÿ˜›.

This is a hopefully friendly member of the rust evangelicalism strike force signing off! I hope you enjoy this project and continue to use Rust in the future!

Can't Expand map.

I think it would be very useful to allow players to expand the map.

Representation of Asciimon in the game

When it comes to creating the acsiimon for the game, there are basically 2 types.

  1. Basic base data of the Asciimon.

This is things like base stats, their type, what level they evolve into other Asciimon and what they evolve into, their cry, what they look like (from behind and in front), what moves they can learn etc

This is the sort of things that is shown when looking up the Asciimon in an "AsciiDex". (Which is another issue on its own!)

  1. Asciimon owned by the player (and maybe trainers throughout the world?)

This is what level the Asciimon is, what the asciimon is, what it's stats are, their nature, what moves that particular Asciimon has.. I believe this is seperate from the "base data" representation of the Asciimon.


The issue is, what could be the best way to actually represent this kind of thing in the code, without duplication of data.

Making a world

So, currently, the only way to create the world is to edit the chunk files inside a text editor. This is simple when editing a single chunk, but it becomes really hard to create a big world with many chunks using this method. So what I suggest:

  1. Make a world generator (maybe using a noise function, I've already got one in Haskell)
  2. Generate some chunks (we can start with 15x15 chunks world) with basic terrain (fields, woods, mountains, lakes etc)
  3. Edit these chunks and add some structures to them (roads, buildings, towns etc)
  4. ???
  5. PROFIT!!!

panic when moving too far left

thread 'main' panicked at 'index out of bounds: the len is 100 but the index is 18446744073709551615', C:\projects\rust\src\libcore\slice\mod.rs:2336:10

[DISCUSSION] Code architecture

This is a thread for discussing general things about code architecture in Asciimon. Code architecture means usage of structs and traits, relationships between structs, patterns etc.

THIS IS A DISCUSSION, DO NOT CLOSE!!!

Magic numbers

The game is using way to many meaningless numbers, particularly when creating rendering sections.

Any ideas for improving this?

This is what I am talking about:

        game.renderer
            .add_render_section("game", Vector2D::new(0, 7), GAME_AREA_SIZE);

        game.renderer
            .add_render_section("logo", Vector2D::new(0, 0), Vector2D::new(50, 6));

        game.renderer.add_render_section(
            "input",
            Vector2D::new(50, 0),
            Vector2D::new(GAME_AREA_SIZE.x - 50, 6),
        );

        game.renderer.add_render_section(
            "console",
            Vector2D::new(GAME_AREA_SIZE.x + 1, 0),
            Vector2D::new(32, 52),
        );

Cannot run the game

$ cargo run --verbose
failed to parse lock file at: /Users/antonte/prj/Asciimon/Cargo.lock

Caused by:
  expected a section for the key `root`

Mac OS X

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.