Joe Alwyn at Cannes 2023
seen from United States
seen from Japan

seen from Germany
seen from Türkiye

seen from Malaysia
seen from China
seen from France
seen from Singapore
seen from United States
seen from United States
seen from United States

seen from United States
seen from Brazil

seen from Malaysia
seen from United States
seen from Germany
seen from Jordan

seen from Malaysia

seen from Pakistan
seen from United States
Joe Alwyn at Cannes 2023
This Ken is Transgender, a triple amputee, and named Joe.
I have told this story on this site before; but only on comments to other posts. So here I am telling the story again. When I was four, or five I didn’t have a Ken doll; so I cut the hair off one of my Barbies and named him Joe (first male name I could think of.). Before I even knew what being trans was I made a transgender Ken doll.
Then when I was eight, or nine my dog Emma chewed off his legs, and one of his hands. So Joe became an amputee. Here he is now T-Posing to assert dominance on Transphobia, and ableism.
Meet Joe – YouTube via Meet Joe - YouTube
Avoiding Obstacles In Your Path
I have been continuing my efforts to get my NPC Joe to move around without getting stuck. As it turns out, this is not as easy as it sounds.
At first thought, a simple algorithm is detect when moving is making no progress, turn away from the obstacle, and then keep moving.
Detecting when movement is not happening is not that hard. You just save your location and check it later to see how far you have moved. If it is less than some threshold value, then you set a flag that says “I’m Stuck” and run a function that gets you unstuck.
The next part gets tricky. NPCs are blind. They do not know what is around them. When stuck, you know the NPC is not making progress, but you do not know why or where from. That makes turing away difficult because you don’t know where way that would be.
The bottom line is that you need more input. I struggled with this some because I am still very new with Roblox and don’t have a lot of knowledge of available features. Step one involved searching for ways to help. Searching for something you don’t know about is hard. I ended up making guess at solutions and searching to see if there was something that supported it. The risk here is that you end up doing something that works, but isn’t really the right way.
That is where I am. I came up with a solution that works, but may or may not be the right way. I approached the problem by wishing I knew where an obstruction was in relation to NPC Joe and knowing when it was near. My idea was to give NPC Joe “sensors”. I created a block in his script that was directly north of his torso and followed him in that relative position.
local detectionRingModel = Instance.new("Model") local detectionRingCenter = game.Workspace.Joe.Torso local detectionRingNodeSize = Vector3.new(1,1,1) local detectionRingPositionNorth = Vector3.new(0,1,3) detectionRingModel.Parent = game.Workspace local north = Instance.new("Part")
First I created a model. That will consist of all of the blocks for my detection ring. The detection ring consists of 4 parts (a basic block is called a part). Each part is at a compass position, North, South, East, and West.
I am going to focus on the North block for my examples for conciseness.
I set a variable "detectionRingCenter" to be NPC Joe's torso piece. That gives me a base position. The next line sets a variable for the size of the detection parts which I call nodes. "detectionRingPositionNorth" is a variable for the relative position of the north block from the center. I call positive Z North and want this block 3 units (studs) in the Z direction from the center of the model. I then set the parent of the detection ring model to be the Workspace which puts this model with all of the other models. Finally, I create a part for the north node and call it "north".
When you create a part in a script, you usually need to set some properties as well. For my north part, I went with the following property settings.
north.Parent = detectionRingModel north.Anchored = false north.Shape = "Ball" north.Size = detectionRingNodeSize north.CanCollide = true north.Transparency = 1.0 north.Position = detectionRingCenter.Position + detectionRingPositionNorth
The settings are deliberate, even if they are the same as default values. I wanted it to be clear that the part was NOT anchored and could collide.
Transparency = 1.0 makes the part invisible. While creating your code and testing, don't use this value. It is very helpful to SEE your blocks as you are testing things out. However, when you have players play your game, you would not want them to see the detection blocks.
The position is important and set to a relative position based on the NPC's position. Parts in a model will move together as long as they are joined together. The detection ring is not connected to the NPC. I chose to not do that in order for the detection blocks to maintain their compass point position regardless of which direction the NPC is facing. This makes determining which way the NPC should move easier. However, there is a cost and that cost is that the detection ring blocks need to be told how to move in addition to the NPC being moved.
There are two things I needed in order to do this. First, I needed to use BodyPosition objects. BodyPosition is for moving blocks.
local northBodyPosition = Instance.new("BodyPosition") northBodyPosition.position = detectionRingCenter.Position + detectionRingPositionNorth northBodyPosition.maxForce = Vector3.new(0,2500,0) northBodyPosition.Parent = north
I created the BodyPosition for north and defined how it worked. "maxForce" sets up physics for the block. The 2500 makes the block float. Setting the BodyPosition parent to "north" links the two and now the north block will move with BodyPosition.
Honestly, I don't fully understand BodyPosition yet. I may change this code later.
The second thing that needs to happen is that the blocks need to be have their position changed as the NPC moves. In the move function, another function is called that updates the positions of the detection ring.
function updateSatelliteObjects() if currentCharacterSatellites then for _, satellite in pairs(currentCharacterSatellites) do satellite["object"].Position = joesLocation.Position + satellite["offset"] end end end
The detection blocks are put in a table for this function to use in the following.
currentCharacterSatellites = { {["object"] = north, ["offset"] = detectionRingPositionNorth}, {["object"] = south, ["offset"] = detectionRingPositionSouth}, {["object"] = east, ["offset"] = detectionRingPositionEast}, {["object"] = west, ["offset"] = detectionRingPositionWest} }
The next task is to get the detection blocks to detect. This is done with events. This article is not about events, but will be covered in the future. Basically, an event is a notification that is sent to a script when a specific "something" happens outside of the script. In this case, I need to know when a detection block is touched by another block. So, I connect to the Touched event.
north.Touched:connect(onNorthTouched)
I also need to define what happens when I get notified of the event. That is done in the onNorthTouched function which I defined.
function onRingTouched(detectingRingNode, touchedPart, bumpDirection) print("Detection ring touched " .. touchedPart.Name) local obstructionLocation = detectingRingNode.Position game.Workspace.Joe.Humanoid.WalkToPoint = game.Workspace.Joe.Humanoid.WalkToPoint - (2*bumpDirection) wait(1) moveJoe(currentDestination, getJoesPath(currentDestination)) return end function onNorthTouched(touchedPart) onRingTouched(north, touchedPart, detectionRingPositionNorth) return end
Don't worry too much about the two functions. I created one function for all of the blocks, but I need to know which block the event was for, so the second function is specific to a block and passes in which detection block was touched.
The script is basic. It gets the position of the touched block and then has the NPC move 2 times the distance of the position in the opposite direction. After the course correction, the original path is resumed.
Here is a final note. That continuing move command is where I am still having problems. I am not sure that is really supposed to happen. I will post an update soon to correct that if needed.
That's it! When a detection ring blocks touches something, an event notification comes on that block and the NPC moves in the opposite direction a little. If another hit happens, the NPC moves more. There are potential issues with this approach, and the NPC make not move very smoothly, but the NPC does not get stuck on an object any more.
Pathfinding Issues
This is just a quick progress note.
I was experimenting in “Meet Joe” to see how well pathfinding worked. I put obstacles in the way, had him travel around the castle wall, sent him beyond the max distance, and stuff like that.
Joe can go around the castle. That is good. He does not try and go through an impassable object like a wall and the path service will find a path around if there is one.
Issues came up with all the other scenarios. First, I do not handle the case where the path requested is beyond the maximum distance given to the path service. This was expected and I need to add steps to my script to go far enough and then get a new path.
The real problem I was having is with smaller objects in the way. The path service created paths over or through them. That is not necessarily a problem, except that Joe could not follow the path without getting stuck. Getting stuck is a real problem.
The first case is a tree. The tree has foliage going to the ground (pine tree). Joe gets stuck on that foliage because the path goes through it. The path service has a parameter that defines impassable as a percentage of blockage in an area. I think that is the problem. The branches of the tree do not represent a lot of volume of blockage, but are enough to “snag” Joe.
I have not solved this problem yet. My next steps are to look to see if that property can be changed (change what it means to be blocked), or see if I can make objects more solid.
There is also one recurring problem I need to address. I need to detect when Joe is stuck and not moving, and I need to have a way for him to get unstuck. I don’t think the pathing will ever be perfect and I need a fallback plan, because once Joe is stuck, he will do nothing else. His script stops progressing. That is not good and users have a degraded experience.
I will post results of my next steps soon.
Whose Fault Is It? - Fun with bugs
This is common across all programming disciplines. Something is not going right, there is an issue, GASP! you have a bug.
How do you fix it? For those who may not note, you enter a phase called “Debugging”. You need to gather information on how things are behaving in order to discover where things are going wrong.
There a MANY was to debug software. There are sophisticated tools and there are simple methods. The simplest of these is the time-honored PRINT statement. “print” is a common command in programming languages (it may have other names) that allows you to write out information to a console or a log file. You put these in your code to allow the outside world to know what is going on in the inside. The goal is to show something that makes you go “That’s not right.” This doesn’t always happen, but it can happen.
There is a problem with modern software development. It is complicated. No one begins a program from scratch. You always use some sort of base created by somebody else to get you started. That is what development systems are all about. There is no sense in reinventing the wheel. It wastes time. It is why I am using Roblox. The downside is that now your program includes code that you don’t control, typically can’t change, and typically can’t even see. This would be a problem if THEIR code was bug-free, but that isn’t the case either. One would hope that it is nearly bug-free, and typically it is, but what if you found a bug?
That brings us to the title. Who’s to blame? From experience, you have around a 95% chance of causing the error. It is tempting to blame the provided code, but released code is different than your pre-pre-alpha code. When you toss in lack of experience, well, that bumps it up to 99% likely your code is wrong.
But that doesn’t keep you from thinking it and it is nice to prove to yourself that it isn’t the problem.
In my project “Meet Joe”, I am having a problem with no immediate solution. Joe is supposed to walk a predetermined path. He follows a series of waypoints until he reaches his end. It is currently very simple.
Joe’s Destination = Waypoint 1
Move to Destination
Roblox handles the moving by calling a function on a Humanoid object that has him move. Periodically, an event is fired that gives me the opportunity to check progress and halt or continue as needed. (I will work on explaining technical stuff later. Folks can ask and I will answer if you want.) Basically, Joe heads to his destination and periodically asks “Are we there yet?”. When he gets there (as determined by the Humaniod object, not me), I set the destination to a new point and send Joe moving again.
But Joe stops and doesn’t continue. It APPEARS that the Humanoid object (provided by Roblox) doesn’t send the message that the destination has been reached. Joes gets stuck in a loop asking if he is there, getting a “no” answer, and not going further because he is close enough.
It is so tempting to say “Roblox did it” and quit. However, that is against the 99%. What do you do? You assume you missed something or don’t know something. You add print statements or use the debugging tool to check values as the code progresses and see why you miss the message. Another option is to change how to handle things and try and come up with a better way to move.
I am doing two of those. There is a pathing system within Roblox that calculates waypoints and obstacles for you. Maybe that is the “proper” way to move a character. Also, maybe I need to have Joe get closer to the waypoint. Movement is not an exact science. Joe does not go exactly to the position of the waypoint. He just gets close to it. Maybe he doesn’t get close enough and a little nudge will help?
I tried pushing him closer to the waypoint with my player avatar, and that helped. He continued on his path. But I don’t really know if that is the correct answer.
BTW, this doesn’t happen all of the time. In “Solo Mode”, Joe never has a problem. In regular play mode, he often is fine, but sometimes he stops and then he just stays in one spot.
I am going to work on learning about the path system and see if that makes it better. I will be using it in the future anyway, so I might as well get my code to use it now.
Meet Joe.
Who I Am:
I’m Joe Napier: an inexperienced human being, but practicing every day. I am proud to claim the state of Florida as my home.
Stuff I Like:
I like words, stories, music, friends, and family. I like the sky, and I like college football. I like writing, singing, driving, t-shirts, and burritos.
Why I’m Here:
I am here because I know how dark the road we walk can be, and nobody should have to do that alone. I also know how wonderful this life can be, and nobody should have to do that alone. There are few things better than making a difference in someone else’s life, and here that is something I get to do every day.
I would most likely stuff the office fridge with:
Tuna salad, probably.
If my music is on, I’m listening to:
Lately: Bill Evans, Night Beds, Ben Howard, Old Crow Medicine Show, Grizzly Bear, and Dave Brubeck.
Favorites: Modest Mouse, Bright Eyes, Death Cab, and We Are The City.
Outside of the office, I’m most likely:
Playing music, listening to music, drinking coffee, playing games, and trying to be around the water.