The Programs of Thanksgiving Week
This Week’s Program: Nov 21 - Nov 25
Happy Thanksgiving! I hope you are sufficiently filled with food and thanks and holiday spirits. Maybe you can’t get to this email in your inbox right away because you are out there hustling those sweet, sweet deals for Black Friday. There is so much to be thankful for this Thanksgiving. A difficult and challenging year shines a light on the things that truly matter. Thank you for reading this TinyLetter and letting me be a part of your Holiday routine.
Last year at this time, I called out some people that I am thankful for. That’s a tradition that I can get behind!
- Evan Czaplicki, the author of Elm.
- John Holdun, my friend and colleague who is building dark rides in New York City. I got the pleasure of seeing his first this Halloween. He’s been writing a TinyLetter about his approach and progress and I’m so looking forward to his next one. He helped me with some geometry this week.
- Casey Kolderup, my friend and not-frequent-enough collaborator. He’s writing a TinyLetter with music recommendations as a spin-off to his Backtracks service. Casey has been a huge influence and help in my projects.
- Pasquale D’Silva and Jacob Bijani have recently formed a new company, Thinko, and are currently looking for clients and consulting projects. The two of them are immensely talented and I’ve been following their work for some time. Their game, OK Dracula, is something I’m really looking forward to playing.
78e1166cf4b7c967b4818ab6901b9b08a4f1400c
The thing I worked on this week is trying to find the closest Model within shooting range of a fighter. My first take did not work.
a58367eb5e5725549f4fdbba61e3815908e0063a
After consulting some friends of mine and the Elm-Lang Slack, I finally got a working solution to this. Here’s the problem: given an arc (or a pie slice within a circle), find if a point is within that arc. Seems like what should be pretty basic Geometry but I was really stumped. Here’s what I did to get this working:
- I convert all angles in the
Tabletop
module to use radians, which is the default used throughout Elm. Only when it’s time to render do I convert this to degrees for the purposes of SVG. - I make a new function,
translate
, which will just make an absolute point relative to an origin point. - I make a new predicate function in the
Tabletop
module,isWithinArc
. Itranslate
and convert the points in the arc to polar coordinates. It’s then easy for me to compare the angles of the different points from the origin (or where the shooter is located). - Here’s the tricky part: if the arc’s start angle is less than the
end angle, I can just see if the position I’m checking is within
that. If the end angle is greater than the start angle, that means
that I’ve gone around an axis and things are inverted. The thing
that was throwing me off here is the use of
xor
to say “one of these must be true”: either the start angle is less than the position angle, or the position angle is less than the end angle. - I use polar coordinates a little bit more throughout the
Tabletop
module and introducemakeAbsolute
, the reverse oftranslate
. I also introduce anArc
type to allow the type checker to be more involved in excluding edge conditions. withinShootingRange
is now a pipeline of filtering operations: The model can’t also be the shooter, the model must be within the weapon range, and the model’s position must fall within the arc.
After some variable renaming I’m able to determine what models are in range of a weapon.
I think this is a very simplified form of ray casting.
ea1f24cbb214ead926b7b4fed6a33494ce118bd1
I add one more List operation to my pipeline: A List.sortBy
to sort
the models within the arc by distance from the shooter. Calling
List.head
on this list will give us a Maybe Model
that is the
closest model in shooting range (or Nothing
). That’s the Model that
can be targetted.
3710d5e769b5929e94fbd25a5942ae8a54009fe9
I move some of this logic into the Player
module function
Player.getClosestModelInWeaponRange
. This function takes a Player
and a Weapon
and returns a Maybe Model
. Now I can shoot it.
🦃 Mark