diff --git a/cv.typ b/cv.typ index 96b6a53..d3e6bde 100644 --- a/cv.typ +++ b/cv.typ @@ -70,12 +70,15 @@ written a multiplayer web game engine in TypeScript (with several interesting ne as well as a (Git-based) beginner-oriented version control system. To facilitate prototype art we also experimented with Blender automation and machine learning in production, -so I've also written & deployed Python / CUDA / ONNX backed services. +writing & deploying Python + CUDA / ONNX services. #divider() #event[Game modding / game-hacking][Self-employed][2016 -- 2025][] +Game development & game modding is a very effective entrypoint into programming at large. +I started in 2007(!!) developing ROBLOX games. + - _GTA Online_: C++ (primarily), Rust - _Minecraft_: Java, Kotlin (primarily), Scala, JVM Bytecode - _Counter-Strike: Global Offensive_: C++ (primarily), Rust @@ -84,6 +87,7 @@ so I've also written & deployed Python / CUDA / ONNX backed services. In my teens, I used to sell a custom client for Minecraft (5-figure USD revenue from 2016 -- 2019), and a subscription trainer menu for GTA Online. +I find the resulting end-to-end product experience & reverse engineering skills valuable to this day. #divider() @@ -108,14 +112,14 @@ The flagship "Splashforce" product was an end-user e-commerce automation suite for various sneaker sites. My duties included: - `cronet`: Custom patches for & isolation of Chromium's HTTP stack. - (To evade TLS fingerprinting.) + (for use as a library to evade TLS fingerprinting in the application.) - Pairing an Electron (node.js / web JavaScript) frontend to a Go backend. - Anti-piracy, reverse-engineer-deterrent releases for the Go backend. (Code virtualization, `cgo` FFI bindings, etc.). -- Reverse engineering bot protection measures on websites. +- Reverse engineering JS & WASM bot protection measures on websites. - Reverse engineering & circumventing bot prevention measures on Android apps. (Java, Smali, etc). ]) -#pagebreak() +/* #pagebreak() -TODO: PAGE 2 +TODO: PAGE 2 */ diff --git a/layout.typ b/layout.typ index 615a9d9..894deff 100644 --- a/layout.typ +++ b/layout.typ @@ -100,27 +100,44 @@ accent: rgb("#870c66"), company_newline: false, title, company, period, location ) = [ - #text(1.2em)[ - #text(weight: "semibold")[#title] - #h(1fr) - #if not company_newline { - text(fill: accent, weight: "bold", size: 0.8em, baseline: -0.125em)[_#[#company]_] - } else { - text(fill: accent, weight: "bold", size: 0.8em)[\ - _#[#company]_] - } - ]\ - #text(1em)[ - #if period != [] { + #if company_newline { + grid( + columns: (auto, 1fr), + align: (left + bottom, right + bottom), + box[ + #text(1.2em, weight: "semibold")[#title]\ + #text(0.96em, fill: accent, weight: "bold")[_#[#company]_] + ], + box[ + #if period != [] { + icon("calendar", shift: 0.18em) + [_#[#period]_] + }\ + #if location != [] { + icon("location") + location + } + ] + ) + } else { + grid( + columns: (1fr, auto), + align: (left + top, right + top), + box(text(1.2em, weight: "semibold")[#title]), + box(text(0.96em, fill: accent, weight: "bold")[_#[#company]_]) + ) + + v(-0.5em) + if period != [] { icon("calendar", shift: 0.18em) [_#[#period]_] } - #h(1fr) - #if location != [] { + h(1fr) + if location != [] { icon("location") location } - ] + } ] #let article(