Paying Technical Debts

The last few days I spent setting things up, fixing stuff, paying technical debts and working on hardware projects.

Yesterday I finally fixed the issue with my Pi server booting from USB. It was the enclosure I was using. You have to make sure when you plug it in that the drive has the name of the actual SSD inside the enclosure, if not... you'll probably have a bad time. I had to trade the one I bought for this purpose for an older one, now all is well and I am running that as my DB server. I have updated Mantilogs accordingly and it now uses that server's PostgreSQL and I don't have to fear the certain doom of the SD card destroying my DB. Next step is to write myself an auto-backup system that backs up the entire RDBMS off premises.

I also built myself a 9-DOF motion tracker with an MPU9250 and a ESP32. Not much to say other than it works and it took a little bit of hackery. Once I have figured out a way to multiplex them and can read multiple sensors with one MCU, I might write up a guide on how to do it. I also need to write something to read the serial data as input coming from the whole system and expose it as some kind of API that I can then use for motion capture or whatever other purposes I come up with.

Today I finally sat down and set up the 3 remote servers I maintain to use SSH keys instead of root login with password. I had neglected this as I was not certain I would not be reinstalling the OS on all of them again. If they were critical servers I would have done it anyway but all that's on them is some game servers right now. Minecraft, Terraria and Starbound. Mostly just to give them something to do while I work out the new direction of the MMO project. Also the server this site runs on is it's own thing, secured before I launched the site. (both times)

I've also been messing around with Rust, which so far is a pretty interesting programming language. The compiler is really helpful in telling you what you screwed up and how to fix it and the memory borrowing system seems to be passing by reference under the hood but I am not certain, though I do have a course I will be working through that should explain it in detail. If not, there's always the docs. One thing I am not so sure about is it seems to be fond of macros which always made me nervous in other languages. They had a tendancy to backfire a lot, though things may have changed in that area.

Today I was thinking of finishing the first section of the Rust course I have and maybe getting started on the character controller in Unity. I was thinking I should also make a Godot version but the purpose of this project is to learn my way around the animation/state machine system in Unity and have something I can use in future projects.

Well, I guess it's time to work through a section of this course now. Seems promising.

While working through explainations of how to declare variables with types and mutability and whatnot I decided I should check the speed between gcc C and Rust nowadays, I hadn't for a while. Now this is just one source but it is pretty impressive if true. Anyway, back to coursework.

Rust has Type Inference. So much modern convenience and somehow still this fast? What's the catch? I likely wont use type inference outside of iteration since I like to make sure I know what types will be where and throw errors if they are wrong. Undefined behavior is a big problem with inferred types in my experience.

//Imports use code blocks. How does namespace work here? (Spoilers, think C++)
use std::mem; // Memory

fn main() {
    println!("Hello, world!");
    //Variable Declaration
    // A LET binding. <var_name>: <type>
    // Immutable.
    // Instead of a wrap around like in C, if you assign a - number to unsigned it errors.
    let a: u8 = 123; // u8 = Unsigned. 8 bits. 0-255
    //The print line MACRO
    println!("a is {}", a);

    // Mutable
    let mut b: i8 = 22; // i8 = Signed, 8 bits. -128-+127
    b = 42; // Reassign b. Does it overwrite in memory or assign a new space?
    println!("b is {}", b);

    // Rust has type inference.
    let c = 123456789; // becomes an i32
    println!("c = {}, takes up {} bytes", c, mem::size_of_val(&c));

    // u8. u16, u32, u64, i8...

    // usize isize
    // Unsigned and Signed SYSTEM Specific size types.
    // On 64-bit arch, is u64,i64 on 32-bit, is u32, i32, etc.
    let z: isize = 12;
    let size_of_z = mem::size_of_val(&z);

    // size_of_z*8 == 64. If this were a 32-bit OS it would be 32 and take 4 bytes.
    println!("z={}, takes up {} bytes on {}-bit OS.", z, size_of_z, size_of_z*8);

    // A character.
    // Chars are 32bit Unicode.
    let d: char = 'r'; // A character
    let nl: char = '\n'; // A newline char.

    println!("{} is a char, size is {}. {} bytes.", d, mem::size_of_val(&d), nl);
    println!("Expect empty line above this printout.");

    // Floats are f32, f64 and are standardized. IEEE754
    // ALL signed.

    let e: f32 = 3.14;
    println!("e = {}, size is {} bytes", e, mem::size_of_val(&e));
    //If we use type inference it will default to f64 on this machine.

    let f = 4.2;
    println!("f = {}, size is {} bytes", f, mem::size_of_val(&f));

    // Booleans. (Can we pack bools as bits in a byte like C?)
    // What about bitmasking?
    let g: bool = false;
    println!("{}, size is {} byte", g, mem::size_of_val(&g));
}

Some notes on types experienced thus far.

Also some notes on Operators from the course, mostly as you would expect, though there is one thing that stands out to me.

fn main() {
    // Arithmetic Ops.
    let mut a = 2+3*4; // +-*/ Precedence
    println!("a = {}", a);
    a += 2;
    // Rust does not support ++ or --.
    println!("a = {}", a);
    // % is a modulo as per usual.
    println!("remainder of {} / {} = {}", a, 3, a%3);

    // Types have functions for operating on them.
    // This is pretty cool.
    let a_cubed = i32::pow(a,3);
    println!("{} cubed = {}", a,  a_cubed);

    let b = 2.5;
    let b_cubed = f64::powi(b, 3); // Takes an integral power, there is also powf()
    println!("{} cubed = {}", b, b_cubed);

    // You can find commonly used consts in their data type in the std lib
    // By convention, consts are always UPPERCASE.
    let b_to_pi = f64::powf(b, std::f64::consts::PI);
    println!("{} to the power of pi is {}", b, b_to_pi);

    // Bitwise Ops.
    // Only available for ints.
    // | OR, & AND, ^ XOR, ! NOR
    let c = 1 | 2; // 01 OR 10 = 11 (3, in Decimal)
    println!("1 | 2 = {}", c);

    //Bit shifting << >>
    let two_to_10 = 1 << 10;
    println!("2^10 = {}", two_to_10);

    // Logical Ops
    // > < >= <= ==
    let pi_less_than_4 = std::f64::consts::PI < 4.0; // true
}

I like that the types have accessible methods for working with them.

Interesting note about Shadowing and Scope.

fn main() {
    // Notes on scope and shadowing.
    // I am assuming at the start of this section that variables are scoped to funcs.
    // Scope is in fact bounded by {}
    let a = 56;
    {
        // Everything in here is in it's own scope.
        // However a is accessible here via shadowing.
        println!("a = {}", a);
        // a can be reassigned inside this scope.
        // Which is really strange to me. Would this break the multiple definition rules of C++?
        // I think so. But maybe it's fine here? Further experimenting is required.
        let a = 22;
        println!("a is overwritten to {}", a);
        let b = 3;
        println!("b = {}", b);
    }
    // Can not access B here.
    println!("a outside of the inner scope is {} and has not been overwritten", a);
}

You can redefine a var inside an inner scope. This is strange. May be a good thing? Time will tell.

Also on Consts and global mutability:

// Global Vars
const MEANING_OF_LIFE: u8 = 42; // No fixed address.
static Z: u32 = 1234; // Adds a fixed address.
static mut X: u32 = 31;

fn main() {
    // Declaring Consts in Rust
    println!("Meaning of life: {}", MEANING_OF_LIFE); // Replaces the MEANING_OF_LIFE in code with 42.
    // If you need a mutable static global, use an unsafe block.
    unsafe{
        // Here there be dragons.
        // You now control the vertical and the horizontal.
        // Tread carefully within.
        X = 4; // The compiler wont like this, but it will let you do it.
        // Try to avoid it.
    }
}

You can make a global mutable but it's memory unsafe, rust is allllll about that memory safety so I think one should probably try to avoid shrugging and charging in half-cocked with unsafe{}. I even try to avoid crap like this in C where I can unless it is something rock dumb, under 100 lines.

I ended up buying a CLion license with the last bit of money I had to be able to debug Rust projects going forward. I think I might start using it as the go-to for speed wherever I can. I will probably still have to use C, of course, though I am sure there must be ways to compile Rust for the various hardware dev kits I have.

I can also use Clion for better Unreal Engine development, which is something I will eventually go back into, once I have taken some time to learn my way around Blender properly and can create an animate my own models. The main reason I dropped Unreal was the lack of any real 2D support, though I could hack it in if I had to. I could also use it to develop GDNative plugins, assuming that gets stablized in 4.0. The point is I could see a reason to get it based on how many applications I will have for it.

I feel like I want to dive into creating a simple WebAssembly application once I finish this course. I'm not sure what it will be, though I am curious as to how it all works, especially with Rust. Mozilla being behind Rust you would expect their WebASM support to be robust as fuck, right? If I can get away with just developing desktop-style applications that run in the browser, you can bet your ass that's what I will do over all the convoluted bs that is modern web development with 100 frameworks for every task.

I feel like Rust has what it takes to become a big thing in the coming years, just based on the experience I have had with it so far. I am really glad to be getting in this early and hope to see it pay off in the long run. I already have a slew of projects I want to try building, ranging from a game engine to an emulator to a web backend and all kinds of interesting stuff in between. I also would like to give writing a few arduino projects with it a shot, see how it works out. I wonder how the C libs will interact with the Rust code and all.

I have finished the section of the course I intended to for today, tomorrow I might do 2, since the one is pretty short. I am interested to see how error handling is done, because the way Go does it makes me want to punt small animals into the sun.

Anywho, on to starting the Character Controller I had previously mentioned. Today I hope to at least get the sprites imported and hopefully get the walking around animations and controls implemented.

Getting started with setting up the animations. I created a scene specifically for the animations and testing them. Here we have Walk Down and Run Down.

Drow FTW.

Yes, FTW. Big whoop, wanna fight about it?

... and the animations for all 4 directions, running and walking.

Run, tiny drow!

The first page of animations is in, 3 pages to go.

Walk, Run, Push, Pull, Jump

There are some frames duplicated to smooth out the animations and add some exaguration to action. A lot of this is just from the readme that came with the base, stuff you think about when you are spriting but not when you are in the engine tools doing the actual animation setup(unless you made the sprite yourself, which I have done for some things but for this controller I want to use this base because it has so many animations and can be used for many prototypes to come)

After a bit setting up those animations I stopped and thought "Is this the engine I want to be using?" Still can't answer that. I don't really like the way it does things, though I do like C#, that's pretty nice. I feel like I keep getting stuck in between engines because I can not find one that fits well enough. Godot is the closest I have gotten to what I would like a 2D engine to work like, though I have not been able to use it for 3D yet. I am thinking though, that since I now have Clion I could use Unreal for my 3D games and Godot for my 2D games. That way I have 2 engines fully accessible via code thanks to the greatness that is open source.

This of course would mean I need to work on some Blender coursework before I do third prototype. Perhaps I should make the second prototype in Godot? There is the Godot Mono bindings if I want to mess around with C#. Unity would give me more potential work but I don't like it. I want to, I keep trying to, but for some reason it just doesn't work for me. Not to mention the walled garden issue.

The reason I wanted to jump from Godot was I wanted 3D for some things. The reason I gave up on Unreal was because I kept having to fight with visual studio. Also the engine crashing for any bad code when you try to debug and not being able to run it on my office laptop. If I could get a TV or HDMI monitor in there I guess I could just cart my PC back and forth.

Either way I intended to learn blender for 3D printing reasons. I also need to pick up  CAD software but I have no idea which one of the FOSS ones are most feature rich and or user friendly.

The important thing right now is the prototypes and the courses. I think the next course after Rust is a coin toss at the moment between Blender and Ethical Hacking. I do really need to secure my software and servers better. Though I suppose by the end of March I should be able to finish both of the courses.

Prototype-wise I am kinda leaning more and more toward that idea I had for an earthbound-like game and that would be full 2D and probably use 16x16 tiles so I think Godot would suit that perfectly. Maybe I could work on implementing that character controller in Godot in the off time for now.

I'll sleep on it and decide tomorrow. No point being hasty, trying to figure out my direction. I do know that Unreal is used in Robotics though and I really do want to get into that field.

Well, gonna sign off for today, post tomorrow with what I decided.

Cheers.