diff --git a/.svelte-kit/ambient.d.ts b/.svelte-kit/ambient.d.ts index f762020..1ecb98d 100644 --- a/.svelte-kit/ambient.d.ts +++ b/.svelte-kit/ambient.d.ts @@ -29,7 +29,9 @@ declare module '$env/static/private' { export const SHELL: string; export const npm_command: string; export const SESSION_MANAGER: string; + export const WINDOWID: string; export const npm_config_userconfig: string; + export const QT_SCREEN_SCALE_FACTORS: string; export const COLORTERM: string; export const XDG_CONFIG_DIRS: string; export const npm_config_cache: string; @@ -49,6 +51,7 @@ declare module '$env/static/private' { export const NO_AT_BRIDGE: string; export const npm_config_globalconfig: string; export const EDITOR: string; + export const GTK_MODULES: string; export const XDG_SEAT: string; export const PWD: string; export const LOGNAME: string; @@ -67,7 +70,6 @@ declare module '$env/static/private' { export const XDG_CURRENT_DESKTOP: string; export const npm_package_version: string; export const MEMORY_PRESSURE_WATCH: string; - export const WAYLAND_DISPLAY: string; export const GIT_ASKPASS: string; export const XDG_SEAT_PATH: string; export const INVOCATION_ID: string; @@ -75,9 +77,9 @@ declare module '$env/static/private' { export const INIT_CWD: string; export const CHROME_DESKTOP: string; export const KDE_SESSION_UID: string; + export const ALACRITTY_SOCKET: string; export const npm_lifecycle_script: string; export const VSCODE_GIT_ASKPASS_EXTRA_ARGS: string; - export const XKB_DEFAULT_LAYOUT: string; export const npm_config_npm_version: string; export const XDG_SESSION_CLASS: string; export const LC_IDENTIFICATION: string; @@ -106,7 +108,6 @@ declare module '$env/static/private' { export const npm_package_json: string; export const LC_TIME: string; export const VSCODE_GIT_ASKPASS_MAIN: string; - export const QT_AUTO_SCREEN_SCALE_FACTOR: string; export const JOURNAL_STREAM: string; export const XDG_DATA_DIRS: string; export const KDE_FULL_SESSION: string; @@ -115,11 +116,13 @@ declare module '$env/static/private' { export const BROWSER: string; export const PATH: string; export const npm_config_node_gyp: string; + export const ALACRITTY_LOG: string; export const ORIGINAL_XDG_CURRENT_DESKTOP: string; export const DBUS_SESSION_BUS_ADDRESS: string; export const npm_config_global_prefix: string; export const KDE_APPLICATIONS_AS_SCOPE: string; export const MAIL: string; + export const ALACRITTY_WINDOW_ID: string; export const npm_node_execpath: string; export const npm_config_engine_strict: string; export const LC_NUMERIC: string; @@ -159,7 +162,9 @@ declare module '$env/dynamic/private' { SHELL: string; npm_command: string; SESSION_MANAGER: string; + WINDOWID: string; npm_config_userconfig: string; + QT_SCREEN_SCALE_FACTORS: string; COLORTERM: string; XDG_CONFIG_DIRS: string; npm_config_cache: string; @@ -179,6 +184,7 @@ declare module '$env/dynamic/private' { NO_AT_BRIDGE: string; npm_config_globalconfig: string; EDITOR: string; + GTK_MODULES: string; XDG_SEAT: string; PWD: string; LOGNAME: string; @@ -197,7 +203,6 @@ declare module '$env/dynamic/private' { XDG_CURRENT_DESKTOP: string; npm_package_version: string; MEMORY_PRESSURE_WATCH: string; - WAYLAND_DISPLAY: string; GIT_ASKPASS: string; XDG_SEAT_PATH: string; INVOCATION_ID: string; @@ -205,9 +210,9 @@ declare module '$env/dynamic/private' { INIT_CWD: string; CHROME_DESKTOP: string; KDE_SESSION_UID: string; + ALACRITTY_SOCKET: string; npm_lifecycle_script: string; VSCODE_GIT_ASKPASS_EXTRA_ARGS: string; - XKB_DEFAULT_LAYOUT: string; npm_config_npm_version: string; XDG_SESSION_CLASS: string; LC_IDENTIFICATION: string; @@ -236,7 +241,6 @@ declare module '$env/dynamic/private' { npm_package_json: string; LC_TIME: string; VSCODE_GIT_ASKPASS_MAIN: string; - QT_AUTO_SCREEN_SCALE_FACTOR: string; JOURNAL_STREAM: string; XDG_DATA_DIRS: string; KDE_FULL_SESSION: string; @@ -245,11 +249,13 @@ declare module '$env/dynamic/private' { BROWSER: string; PATH: string; npm_config_node_gyp: string; + ALACRITTY_LOG: string; ORIGINAL_XDG_CURRENT_DESKTOP: string; DBUS_SESSION_BUS_ADDRESS: string; npm_config_global_prefix: string; KDE_APPLICATIONS_AS_SCOPE: string; MAIL: string; + ALACRITTY_WINDOW_ID: string; npm_node_execpath: string; npm_config_engine_strict: string; LC_NUMERIC: string; diff --git a/.svelte-kit/generated/server/internal.js b/.svelte-kit/generated/server/internal.js index c5fe4d6..9e9c538 100644 --- a/.svelte-kit/generated/server/internal.js +++ b/.svelte-kit/generated/server/internal.js @@ -21,7 +21,7 @@ export const options = { app: ({ head, body, assets, nonce, env }) => "\n\n
\n \n \n \n \n \nHey! My name is
- -An experienced full stack developer, cybersecurity enthusiast, and Co-Op Computer Science Student at the University of Toronto active in CTFs, hackathons, programming competitions, and indie developer of the soon-to-be-released game Subterstrike
-This site is still being ported! More of my projects are listed on my resume
- +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 +
+
- - Prototype terrain sample -
+
+ 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. Currently I am contracting a graphical artist and sound designer. Alpha tests have been a lot of fun, and investors have appeared. The finish line is close.
+ 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.
- - A grid flying through caves -
+
+ A grid flying through caves
Open source and networking hobbies led me to depoly a set of interconnected Linux servers:
++ Open source and networking hobbies led me to depoly a set of + interconnected Linux servers: +
- 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. + 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.
- 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. + 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.
- 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 :) -
+ 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 :) + ++ 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 -
-
- - Internal View -
+
+ Testing Input Response
+
+ Internal View
- 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.
+ 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.
- 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.
+ 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 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 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 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.
+ 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.
Parkside Pool needed to automate their systems, and I had already worked as the head lifeaurd and Director of Operations so I knew exactly what needed to be done. We needed to automate:
-
- 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. The difficult part was building the schedule, which is a form of the NP-Hard Nurse Scheduling Problem. As there were at max a few hundred students per schedule, I solved this using a recursive algorithm and scoring system to choose the best generated option.
+ 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.
- 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. - + 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.