igorfs10 / rust_hero

Um jogo simples em rust
GNU General Public License v3.0
4 stars 1 forks source link

Configuration file format specification #14

Open 1sra3l opened 2 years ago

1sra3l commented 2 years ago

The current file is:

name = "Knight"
hp = 50
mp = 20
atk = 20
def = 20
m_atk = 20
m_def = 20
exp = 0
img_idle = "knight.png"
img_walking = ""
img_attacking = ""
playable = true

You mentioned making all characters playable, so playable = true would seem not to be needed. An "image" section would make more sense for TOML-style formats.

[image]
idle = "knight.png"
walking = "knight_walk.png"
attacking = "knight_attack.png"

but as I mentioned in rpgstat building animations as another header would look like this in TOML:

[animations]
left =  { one = "/path/to/image", two = "/path/to/image", three = "/path/to/image", four = "/path/to/image"}
right = { one = "/path/to/image", two = "/path/to/image", three = "/path/to/image", four = "/path/to/image"}
up = { one = "/path/to/image", two = "/path/to/image", three = "/path/to/image", four = "/path/to/image"}
down =  { one = "/path/to/image", two = "/path/to/image", three = "/path/to/image", four = "/path/to/image"}

Once we have the human readable TOML format fields specified, it should be easy to implement {reading from, writing to} other formats. the rpgstat ini files have more information possible, but do not need to be used:

[Knight]
name = "Ike"
# do we want descriptions?
short_description = "A  protector of the `Governmental` class"
long_description = ""
id = 0
hp = 50
mp = 20
xp = 1
hp_max = 50
mp_max = 20
xp_next = 10
gp = 10
speed = 7
atk = 20
def = 20
m_atk = 20
m_def = 20
# haven't been configured yet...
agi = 10
str = 10
int = 10
dex = 10
con = 10
char = 10
wis = 10
age = 10

The other thought would be to make the assets their own repository, once the file format is completed. This could allow for me to just work on art without always needing you to accept the commit. You could just submodule it, that way. It would be easier to consolodate characters and we could list each group in the main list.toml file.

characters = "Knight.toml" # ...
enemies = "Rat".toml #...
rare = "EasterBilby.toml" #...
bosses = "SantaClaus.toml" #... 
# etc...

We would also need to use the format for "Items" and things like hp = 50 would be used to calculate the hp increase.

igorfs10 commented 2 years ago

@1sra3l Yeah I'll remove the playable flag.

I agree, it's better to have a section for animation(images), I think we just have to add a struct to it. I want description to create a bestiary. 😛

I agree with a new repository, I just need one or two files to test. You can create your own and after I compile the game I will just need to copy files from repository.

The problem with groups in the list will be to use it in the location file to set the enemies. We will need to use an enum to make it work that way.

name = 'Forest'
description = ''
enemies_id = [
    0,
    1,
    2,
    3,
]
item_id = 0
background_img = 'assets/backgrounds/forest.png'

For items

Will turn into

name = 'Forest'
description = ''
enemies_id = [
    enemies(0),
    enemies(1),
    enemies(2),
    boss(0),
]
item_id = 0
background_img = 'assets/backgrounds/forest.png'

What you think about it?

For items we can use the struct I have, but change the effect with an enum like the attack.

pub enum ItemEffect {
    Heal(u16), // Base number that we can use with mana attribute to set the amount to heal
    AtkUP(u16), //Percentage to improve atk
    RemoveStatusAilment(Type), //We can create an enum for this
}

For these things to work I think it's better to migrate to RON format that can deal with enums, what you think? https://github.com/ron-rs/ron

1sra3l commented 2 years ago

Created initial libre-creatures repo. I am just currently generating all of the files via make_legendary.sh so we can quickly change the format initially. Once we settle on it I can remove the script, or modify it to write in a different place.

The short/long description are there for your bestiary I want Rust Hero to catch things and train them at some point :smile_cat:

Here is my current format test with [animation]

name = "Easter Bilby"
short_description = "Easter Bilby – Anthropomorphic bilby."
long_description = "Bilbies are native Australian marsupials that are endangered. To raise money and increase awareness of conservation efforts, bilby-shaped chocolates and related merchandise are sold within many stores throughout Australia as an alternative to Easter bunnies.  The first documented use of the Easter Bilby concept was in March 1968 when a 9-year-old girl Rose-Marie Dusting, wrote a story, 'Billy The Aussie Easter Bilby,' which she published as a book 11 years later. The story helped catalyse the public's interest in saving the bilby. In 1991, Nicholas Newland from the 'Foundation for Rabbit-Free Australia' also developed the idea of the Easter Bilby to raise awareness about the environmental damage that feral rabbits cause and to replace the Easter bunny with true native wildlife.  The first Chocolate Easter Bilbies were sold at the Warrawong Sanctuary when it was owned by John Wamsley"
[stats]
id = 358
hp = 10
mp = 10
xp = 10
hp_max = 10
mp_max = 10
xp_next = 10
gp = 10
speed = 10
level = 0
atk = 10
def = 10
m_atk = 10
m_def = 10
agility = 10
strength = 10
intelligence = 10
dexterity = 10
constitution = 10
charisma = 10
wisdom = 10
age = 10
[animation]
walk = { right = "EasterBilby_walk_right.png", left = "EasterBilby_walk_left.png", up = "EasterBilby_walk_up.png", down = "EasterBilby_walk_down.png" }
attack = { right = "EasterBilby_attack_right.png", left = "EasterBilby_attack_left.png", up = "EasterBilby_attack_up.png", down = "EasterBilby_attack_down.png" }
special = { right = "EasterBilby_special_right.png", left = "EasterBilby_special_left.png", up = "EasterBilby_special_up.png", down = "EasterBilby_special_down.png" }
1sra3l commented 2 years ago

For items, I am not sure if that is the best. If we give items a stat, we can increase any stat easily, or even decrease them, by giving the stats a negative value.

let mut stats = rpgstat::stats::Normal<f64>::default();
# hp down
stats.hp = -15.0;
# mp up
stats.mp += 1.0;
# level up
stats.level += 1.0;
# whatever other effects

We could make the item more like

pub Item {
  pub name:String,
  pub duration:f64,
  pub effect:EffectType,
  pub stats:Stats,
}

toml for item will be

name = "thing"
# forever = 0, otherwise probably use Milliseconds
duration = 0
effect = "EffectFromEnum"
[stats]
# everything 0 except what you change

I think this gives much more flexibility in the future, so we create lots of items with lots of effects

igorfs10 commented 2 years ago

@1sra3l The problem is that some item effects doesn't need to change a stat and for a rpg lib you can have an item that deals damage type damage or even a fixed amount of damage. In my game has an item that doubles the received xp. So I prefer to use an enum with parameters to easily configure each effect we can use.

Example:

pub struct Item {
    pub name: String,
    pub description: String,
    pub effect: ItemEffect,
}

pub enum ItemEffect {
    // (Time in seconds, Multiplier)
    TimedXPMultiplier(u64, u8),
    InflictStatusAilment(Type),
}

Possible RON file example( I need to test):

Item(
    name: "Experience potion",
    description: "Double the amount of xp received for a minute."
    effect: TimedXPMultiplier(60, 2),
)
Item(
    name: "Poison potion",
    description: "Inflict poison."
    effect: InflictStatusAilment(Poison),
)

I think this way will be more readable and easier to deal without using an interpreter.

1sra3l commented 2 years ago

All the examples you gave modified a stat. "damage" is "hp" or the function damage() in stats the Item could just:

pub struct Item {
  name:String,
  description:String,
  effect:Effect,
  duration:T,
  value:T,
}
impl Item {
  pub effect(&self, mut other:Stat) -> T {
    // check Effect
    match *self.effect {
      Effect::Damage = > other.damage(self.value),
   /// etc...
    }
  }
}

to avoid needing a stat, and just have simple duration and value. The effect would determine what functions were called on the other:Stat I could build traits for this type of thing, when you layout your effects.

Okay, how about this make a single file as a code example and push it to the repo. This will allow me to really test what you are wanting.

I would like to use toml because it is extremely human readable and that is important for kids, new contributors, and maintainers. Cargo uses toml format so it would seem to have long term support built into the Rust community. All Rust programmers will understand the basic format of the file without needing to learn another config.

That said, I want the game to be able to do what you want, I just think the character's own stats could react to an effect, with a value and a duration.

It would be cool to make a chart for your idea MarkDown makes easy tables:

a|b|c
---|---|---
x|o|x
o|o|o
x|x|o

becomes:

a b c
x o x
o o o
x x o
igorfs10 commented 2 years ago

I forgot that is the game repo and not the rpg lib 🤦‍♂️. I was thinking about how we can implement in a complex battle system. Toml is famous but the crate still need to deal with enums with value and their repo seems to have not much activity recently, that is why I suggested ron, it's not hard and is looks like Rust. In this example I can remove Item name and let everything inside ( ). But returning to game, items and attacks will be hard coded, ui and the game system was planned with this in mind, just items to temporary improve available stats which is small, as battle system is very simple with probably a simple auto attack and a powerful attack and items. Just locations and characters can be customized with what I have in my mind, and for that we can continue with toml which fits great.

1sra3l commented 2 years ago

:smile: I comment too many places. So stats can be toml, and Item can be ron format? I suppose using two formats for totally different game types makes sense so it is easy to make them different. Adding FltkForm to your own structs is very easy. Do a test. The best way I have found is to make the group in FLUID a certain color, and make a button that will show/hide the group. When you show() it generate() the struct into the group. The example code is basically all you need to get a UI.

Another reason to want to avoid the nested enum is FltkForm can not work either:frowning_face:

igorfs10 commented 2 years ago

Yeah stats can be toml. Item won't be customizable in this game, at least for now, the battle and game mechanics are so simple to have customizable items. FltkForm is on my radar, it will be very usefull to load config file for my image converter.

1sra3l commented 2 years ago

Ok I am working at overhauling rpgstat and working with fltk-form to make it more functional together (and for others). Currently I have a specific premade f64 stat that derives FltkForm to output. I recently added image loading support in fltk-form, so I will add this into the struct, it is simply a wrapper type around a string, which is the path. This would be useful to easily see what images are done.

Feel free to comment over there if there is anything

1sra3l commented 2 years ago

@igorfs10 Hey haven't heard from you in a while, and I really enjoy how kind you are communicating with me. I hope things are going well for you, all things considered. It has been a very hard bit of time here, and it has likely been hard there. Just wanted to reach out and say that I do think kindly about you and hope you are well! Also, I know this isn't the most appropriate place to reach out, but I don't know you IRL, or have a way to contact you otherwise.

igorfs10 commented 2 years ago

@1sra3l I'm ok, just trying to stay away from computer to spend my time with my gf and playing video game to relax from my work, recently I'm just turning my computer on for work. I feel for you, I hope things get better. You can reach me with email that I use in github, It's easier to me to read and reply than gh.