This Week In Veloren 73
This week, we have a lot of updates from external platforms. @Pfau has another art blog to show off. There is a lot of updates from the writing working group. We hear about testing and documentation from @AngelOnFira.
- AngelOnFira, TWiV Editor
Contributor Work
Thanks to this week's contributors, @xMAC94x, @kevinglasson, @AngelOnFira, @Songtronix, @imbris, @Slipped, @xvar, and @scottc!
Recently, Veloren has made it to the front page of most-starred projects on GitLab! Our YouTube channel has made it to 1000 subscribers as well. @Pfau has released another art blog. @Pfau has been working on a trading window concept. @Felixader completed a design document for the direction of the writing working group. He is also working on a document detailing the cultural design philosophy. @WelshPixie wrote race descriptions for inside the character creation menu. They also added lots of new lines for when villagers get hit by players. @Gemu is still reworking some old models. So far, all larger quadrupeds and reptilians are done. @Snowram and @Slipped have been working on the animations and implementations of these new models.
@kevinglasson added persistence of the hotbar, allowing it to be saved when the game is exited. They also worked with @xMAC94x and @Songtronix to change logging over to use the tracing crate. @Slipped is working on adding sneaking, rebuilding climbing to be more fun, and adding glider wall running. @mainCharacter was working on proofreading content that the player would see.
Improving Test Coverage by @AngelOnFira
In the last few weeks, I've been interested increasing test coverage and documentation of the project. I've worked with @Kevinglasson and @Shandley on this endeavor. Test coverage allows us to catch errors and regressions before merging our code into the main branch. Documentation gives better information to developers who touch many different parts of the codebase, or who are learning about a new section.
Rust offers a great workflow for both documentation and test coverage. In fact, you can build tests right into documentation for functions. This has two benefits. First, the code that makes up this test can be used to show how a function works. Second, if the tests in the function's documentation fail, likely the documentation needs to be changed at the same time.
On top of doc tests, Rust has a great way of generating readable documentation. It collects comments that are above functions and adds them to a static site that it generates. You can see what that looks like here. On this site, we see information about what this function expects as parameters, and what type these parameters are. We then see the documentation written for this function. Finally, we see the doc test written at the bottom. We can see an assert_eq!
at the end. If someone changes how equip works, and this assert fails, then they would have to fix the documentation to reflect the change. Below is what this entire function looks like in the codebase.
/// Equip an item from a slot in inventory. The currently equipped item will go
/// into inventory. If the item is going to mainhand, put mainhand in
/// offhand and place offhand into inventory.
///
/// ```
/// use veloren_common::{
/// assets,
/// comp::{
/// slot::{equip, EquipSlot},
/// Inventory, Item,
/// },
/// LoadoutBuilder,
/// };
///
/// let boots: Option<Item> = Some(assets::load_expect_cloned(
/// "common.items.testing.test_boots",
/// ));
///
/// let mut inv = Inventory {
/// slots: vec![boots.clone()],
/// amount: 1,
/// };
///
/// let mut loadout = LoadoutBuilder::new().defaults().build();
///
/// equip(0, &mut inv, &mut loadout);
/// assert_eq!(boots, loadout.foot);
/// ```
pub fn equip(slot: usize, inventory: &mut Inventory, loadout: &mut Loadout) {
use item::{armor::Armor, ItemKind};
let equip_slot = inventory.get(slot).and_then(|i| match &i.kind {
ItemKind::Tool(_) => Some(EquipSlot::Mainhand),
ItemKind::Armor { kind, .. } => Some(EquipSlot::Armor(match kind {
Armor::Head(_) => ArmorSlot::Head,
Armor::Neck(_) => ArmorSlot::Neck,
Armor::Shoulder(_) => ArmorSlot::Shoulders,
Armor::Chest(_) => ArmorSlot::Chest,
Armor::Hand(_) => ArmorSlot::Hands,
Armor::Ring(_) => ArmorSlot::Ring,
Armor::Back(_) => ArmorSlot::Back,
Armor::Belt(_) => ArmorSlot::Belt,
Armor::Pants(_) => ArmorSlot::Legs,
Armor::Foot(_) => ArmorSlot::Feet,
Armor::Tabard(_) => ArmorSlot::Tabard,
})),
ItemKind::Lantern(_) => Some(EquipSlot::Lantern),
_ => None,
});
if let Some(equip_slot) = equip_slot {
// If item is going to mainhand, put mainhand in offhand and place offhand in
// inventory
if let EquipSlot::Mainhand = equip_slot {
swap_loadout(EquipSlot::Mainhand, EquipSlot::Offhand, loadout);
}
swap_inventory_loadout(slot, equip_slot, inventory, loadout);
}
}
I've worked on documenting and adding tests to a single file so far, specifically slots.rs
. I plan on doing more in the future. It is a good way for me to get better at Rust as a low to mid level Rustacean. Hopefully, other developers will work to document what they're doing as well. It's a lot easier to add a few lines as you're writing rather than for you or someone else to come back to it later :)
Cultivating a Healthy Open Source Community by @AngelOnFira
New Villager Retorts by @WelshPixie
"Tis but a scratch!"
"Heinous wretch, be gone with you!"
"Stop it! Go away!"
"Oi! Who do you think you are?!"
"I'll have your head for that!"
"I'll set my brother on you, he's bigger than I am!"
"Nooo, I'm telling mother!"
"Your weapon works, you can put it away now!"
"Today is turning out to be a very bad day..."
"Eek!"
"A pox upon you!"
"This isn't fun."
"You must have me confused with someone else!"
"Guards, throw this monster in the lake!"
"I'll set my tarrasque on you!"