commit 7e5db6b23355a72d0eb2d27da30d10a1095f6478 Author: Jeremy Date: Tue Jan 13 00:08:58 2026 -0500 rust backend, example nix container building diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..a3b8947 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,572 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "axum" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +dependencies = [ + "axum-core", + "bytes", + "form_urlencoded", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "bytes" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", +] + +[[package]] +name = "hyper-util" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "hyper", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "libc" +version = "0.2.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "proc-macro2" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "site" +version = "0.1.0" +dependencies = [ + "axum", + "tokio", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "syn" +version = "2.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + +[[package]] +name = "tokio" +version = "1.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +dependencies = [ + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "zmij" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac93432f5b761b22864c774aac244fa5c0fd877678a4c37ebf6cf42208f9c9ec" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..136c00a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "site" +version = "0.1.0" +edition = "2024" + +[dependencies] +axum = "0.8.8" +tokio = { version = "1.49.0", features = ["macros", "rt-multi-thread"] } diff --git a/container-config.nix b/container-config.nix new file mode 100644 index 0000000..625dd19 --- /dev/null +++ b/container-config.nix @@ -0,0 +1,11 @@ +{ pkgs ? import { } +, pkgsLinux ? import { system = "x86_64-linux"; } +}: + + +pkgs.dockerTools.buildImage { + name = "site"; + config = { + Cmd = [ "${pkgsLinux.hello}/bin/hello" ]; + }; +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..23bfecc --- /dev/null +++ b/src/main.rs @@ -0,0 +1,19 @@ +use axum::{ + routing::get, + Router, + response::Html, +}; + +#[tokio::main] +async fn main() { + let site = Router::new().route("/", get(root)); + + let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); + println!("Running on http://127.0.0.1:3000"); + axum::serve(listener, site).await.unwrap(); +} + +async fn root() -> Html<&'static str> { + const HTML: &str = include_str!("../static/root.html"); + Html(HTML) +} \ No newline at end of file diff --git a/static/drone/graphing.jpg b/static/drone/graphing.jpg new file mode 100644 index 0000000..9b10369 Binary files /dev/null and b/static/drone/graphing.jpg differ diff --git a/static/drone/top.jpg b/static/drone/top.jpg new file mode 100644 index 0000000..ec5508a Binary files /dev/null and b/static/drone/top.jpg differ diff --git a/static/game/chunkfunc.webp b/static/game/chunkfunc.webp new file mode 100644 index 0000000..14316ff Binary files /dev/null and b/static/game/chunkfunc.webp differ diff --git a/static/game/flying.webp b/static/game/flying.webp new file mode 100644 index 0000000..c8e4b7d Binary files /dev/null and b/static/game/flying.webp differ diff --git a/static/phobos/demo.mp4 b/static/phobos/demo.mp4 new file mode 100644 index 0000000..c1c33d4 Binary files /dev/null and b/static/phobos/demo.mp4 differ diff --git a/static/root.html b/static/root.html new file mode 100644 index 0000000..52f55a5 --- /dev/null +++ b/static/root.html @@ -0,0 +1,361 @@ + + + + + + + + +
+

Hey! My name is

+ +

+ An experienced cybersecurity analyst and full stack developer with a + certificate in penetration testing. + Co-Op Computer Science Student at + the University of Toronto specializing + in Software Engineering, with a major in statistics and minor in astrophysics. + Active in CTFs, hackathons, programming competitions, and developing a videogame. +

+

+ This site is still being ported! More of my projects are listed on my resume +

+ +
+ +
+

Game Development

+
+ Zoomed out chunk generation +

Prototype terrain sample

+
+

+ I am currently developing an underground-submarine openworld multiplayer + physics inspired game. As a gamer and enjoyer of large, rich maps and + depth to gameplay, I would really like to say thats what I started out + trying to create. Instead, the story goes that I had this random idea + for terrain manipulation. Games like Minecraft and Terraria use squares + and cubes, which just feels boring in my opinion. I thought I could do + something much more visceral As a sort of tech-demo/proof of + concept I programmed a shape that could be modified by boolean geometry + operations, mainly union and subtract with a second polygon. This led to + a very interesting, but quickly boring "game" to hop around in. However, + since I could drill through and place prettymuch any shape I wanted to, + it felt like I could "fly" through the land, much like a submarine + "flies" through water.

I implemented some modularly built + vehicles with use of graphs theory and object oriented programming, and + terrain generation using cellular noise. The reason I used cellular + noise is because if you look at the lines between cells, they form a + network without dead ends. Then by applying an algorithm using a density + function on depth I am able to fine tune the width and density of the + caves without impacting their interconnectedness. By using this method + chunks can generate completely independent of their neighbor, which is + optimal.

"Multiplayer is the hardest part of game dev, maybe + release that later" I have been told by a lot of people. However, as a + hobby-server configurer and network security nerd, I thought I could + take it on. I was right, however as a network security nerd I have more + layers of firewalls than I do braincells. Every single time I have an + issue with networking, its a firewall. Once I found which ports were + blocked, yes multiplayer was easy.

The result? I could fly + drilling vehicles through terrain, pop out of the ground or into random + caves, mine materials, play hide and seek with friends, and even orbit + the planet. One of the things important to me in this game was accurate + physics: thrust, torque, gravity, mass, all the fun stuff. While I am a + physics minor, I am more importantly a heavy player of physics and + rocket science games such as Kerbal Space Program. I was able to glide + through AP physics simply because it + just part of the games world, it included everything we would + learn in the classroom. Realistic physics also added to the depth of + gameplay I was looking for.

After some formal computer + science education, I discovered new ways to more efficiently implement + many of the algorithms I had initially generated and rewrote them + ...multiple times. Currently everything runs buttery smooth and + framerates are high due to efficient caching of unloaded chunks, + multithreaded chunk generation, gpu accelerated compute shaders to + modify chunk density, enhanced use of object oriented programing and + graph algorithms to build massive modular vehicles, authoritative server + networking to disable hackers, and other performance tweaks.

+ So this sounds amazing, where's the game? Well, a game needs graphics, audio, + a sound track. As much as I'd love to release it now, its unplayable for + these reasons along with a few minor implementations left such as NPC's and + reworking the tech tree. +

+ +
+ Flying Vehicle +

A grid flying through caves

+
+
+ +
+

Servers & Networking

+

+ Open source and networking hobbies led me to depoly a set of + interconnected Linux servers: +

+
    +
  • +

    NGINX Reverse Proxy and VPN Server

    +

    + This server is the internets access to all of my other servers, + and the glue holding them together. I was using IPTables briefly + but have moved to NGINX to forward traffic from specified ports + onto private servers connected to it. This device doubles as a Wireguard VPN server which in the past connected servers on the same virtual + network, however I have switched to reverse ssh tunnels to connect + other servers to this one. The VPN is still useful for odd networking + tasks and troubleshooting. +

    +
  • +
  • +

    Lightweight Server

    +

    + Running on Raspberry Pi, this servers main job is to run + Subterstrike servers, Minecraft servers, other game servers, and + this website you're looking at. +

    +
  • +
  • +

    AI & FTP Server

    +

    + A powerful computer with an RX 6950 XT GPU runs my local + generative AI servers including Invoke AI + for Image Generation, + Ollama + and Open-WebUI for LLM + services. As this is also my primary device with a few spare + terabytes of NVMe storage it contains a + VSFTPD file server. By the way, this server runs on + Arch Linux :) +

    +
  • +
  • +

    Derelict Laptop Promoted to Server

    +

    + An ancient gaming laptop with significantly more computational + performance than physical durability was promoted to server, + where it runs my Nextcloud + self hosted office suite. While originally this was a 'because I + can' project, I felt justified when I later saw + Microsoft announcing USA demands come before Canadian + privacy. +

    +
  • +
+
+ +
+
+ Testing Input Response +

Testing Input Response

+ Internal View +

Internal View

+
+

Building a UAV

+

+ I chose to build a drone from scratch for my AP Physics final project. + We were given an open ended assignment to build something cool + and I wanted a drone. My choice was much more ambitious than the course required, + and took quite a while to complete.

+ + For the drones frame I finally had an excuse to purchase a 3d printer. I + modelled the frame and arms modularly to support future upgrades and + replacements from damage, reducing the cost of operation. Initially I + was using some 3d printed torodial propellers due to their higher + efficiency and lower sounds usage. Due to safety concerns of the + propellers not withstanding tension at higher RPMs and exploding I + switched to some generic acrylic propellers I bought. A challenge in + designing the frame was leaving enough room to contain the volume of the + wires. I went with the Elegoo Neptune 3 as the printer was open-source + and had a much better cost-to-utility than proprietary printers such as + the Ender series. I am not sponsored I just really like the printer.

+ + The flight computer was the most difficult part to program. Using an + ultrasonic distance sensor, gyroscope, and accelerometer the drone has + enough information to probably never crash. The autopilot is implemented + on an Arduino UNO using a + PID controller + for stabolization. The autopilot quality is currently impacted every time + the drones mass distribution changes, which can be fixed with a reinforcement + machine learning algorithm. For the higher level programming such as flight + automation, video transmission and WiFi communications I used a Raspberry + Pi Pico. There is also a 2.4GHz line of sight receiver for manual control. + A future upgrade may contain a SIM card for near-infinite remote control + connection, but drone regulations would make this difficult.

+ + The power system is the most physically challenging portion of the + drone. The motors took 14.6 Volts, while the UNO microcontroller took 5 + Volts, and the Pico and most sensors run at 3.3 Volts. All of the power + to the motors ran through the power distribution board, which I modified + to also output the lower voltages and used Bidirectional Logic Level + Converters to shift between 3.3 and 5V signals where needed. A potential + flaw with having all the power coming from the same source is spikes in + energy consumption to the motors may cause the microcomputers to receive + too little power, which could be fixed with a capacitor. Luckily, I + haven't experienced this yet as the 2C discharge rate on the 2.5Ah + capacity battery is more than enough. Having a battery this big does + mean it takes up about half the internal electronics volume and is half + of the drones mass, but it can also maintain full throttle for half an + hour making for long flights.

+ + The motors I used were a bit overkill for a 1.1kg drone, as going past + 20% throttle sends it shooting through the sky -- which is not a bad + issue to have. Here's the technical numbers behind that: I have + propellers with a 6cm radius on motors with a 2450KV rating (2450 rpm + per volt) at peaking at 14.6 Volts. From this the tip speed is computed + to be ~225m/s under no load at max throttle, quite a lot more than what + is safe or necessary to get into the air. +

+
+ +
+

Phobos

+

+ One of the coolest things I've developed is a game, fully written in + assembly.

+ I say this because it is the perfect intersection of many things I enjoy; + low level programming, physics, space, simulation development, and game design. + Also small enough of a project that I could complete it in under a couple + of months, so another win. I even named the game based on the emulator, as + Phobos is a moon of Mars

The instructions for this + assignment were very broad, to develop a platformer game in assembly. + This left a lot of room for creative freedom, especially due to the + loose definition of platformer. With infinite time I would have + developed a whole rocket simulator, and used the justification that the + launchpad was a platform. +
+
On the technical side this was a very difficult project. There are + only about 16 variables actually usable in MIPS, and a lot of them are reserved + to specific logical controls under best practice. Then following the many + loops and recursive, real-time functionality required extensive and efficient + use of the stack. Ideally accessing a few bytes shouldn't strike the fear + of low framerates to mind, but the Mars-MIPS emulator I was using was far + from efficient. +

+

Notable Features

+
    +
  • Raycast collision detection and repositioning
  • +
  • Sub-pixel velocity and positioning
  • +
  • Awesome pixel graphics (the rocket shoots fire!)
  • +
  • High framerates (for a low-performance emulator)
  • +
  • Enemies shooting at you!
  • +
  • Loot pickups
  • +
+

+ Probably the most annoying part of this was that the emulator couldn't + handle simutaineous key inputs. Fortunately I have over a thousand hours + experience landing rockets on the Mün + so I was comfortable giving a few unique key inputs per second. I never imagined + this is something I would be proud, and I still don't think I am. However, + it works.

At this point you may have realized I am a bit of a + space nerd. Enjoy this recording I made at 1am demonstrating the + features of my game to a TA, compressed to the point that the audio has + texture. +

+
+ The + source code is also available + for your enjoyment. +
+ +
+

Work Experience

+
    +
  • +

    Cybersecurity Analyst for Equifax

    +
      +
    • Analyzed Security Posture, Business Risk, Compliance
    • +
    • + Supported Vulnerability Management sourced from Penetration + Tests & automated tools +
    • +
    • Handled issues, exceptions, and deviations
    • +
    • + Provided Security Advisment Services for infrastructure and + code development +
    • +
    • + Used automated scanning tools, GCP, AWS, shell scripts, + Linux +
    • +
    +
  • +
  • +

    Software Developer for Parkside Pool

    +

    + This is a role that didn't exist before me. I was a lifeguard + and swim instructor here, and the pool I worked at was being + swamped with administrative work. Eventually I took on this work + for the money that came with it. For ten hours each week, I + would be reading emails, co-ordinating lessons, and sending out + schedules. Creating the schedules was a tedious task, with + siblings at different levels needing back to back lessons, + people not available some days or times, and other various soft + and hard requirements.

    Soon I found out there is no + easy algorithm known for finding solutions to problems with many + soft and hard requirements. This is a NP-hard and is described + in the + Nurse Scheduling Problem. Fortunately there was a cap of 128 students I could fit into + classes per week and the final algorithm was around O(n³) for n + swimmers, so the runtime wasn't horrible.

    + Implementing the reception and confirmation of lessons was straightforward + enough with a Flask site using Stripe for payments, and Firebase + service for sending confirmation emails. +

    +
  • +
+
+ +
+

Volunteering

+

+ I volunteer within the Computer Science, Mathematics, and Statistics + department at the University of Toronto as a Computer Science Ambassador + to help cultivate interest in the Mathematical Sciences in high school + students, as well as providing direction for first year students within + the programs. +

+
+ + \ No newline at end of file