GetUserThumbnailAsync() [Camping Game]

So I’ve been stuck on this problem for a couple of days. I simply want to pass information from a Script in ServerScriptService to a LocalScript inside of an ImageLabel. I’ve tried to use RemoteEvents but they don’t seem to work. I’m currently using values as they seem to work better than RemoveEvents. The issue is occurring in the LocalScript in PlayerImage

ServerScript [ServerScriptService]:

local Gui = game.StarterGui:FindFirstChild("DialogGui")
local Frame = Gui:FindFirstChild("Frame")
local FrameVisible = game.ReplicatedStorage:FindFirstChild("FrameVisible")
local TextValue = game.ReplicatedStorage:FindFirstChild("Text")
local SpeakerImage = game.ReplicatedStorage:FindFirstChild("SpeakerImage")
local SpeakerText = Frame:FindFirstChild("Text")
local SpeakerName = game.ReplicatedStorage:FindFirstChild("SpeakerName")
local Players = game:GetService("Players")
local RandomPlayer
local Message

function TypeSound()
    local Sound = Instance.new("Sound")
    Sound.Parent = game.Workspace
    Sound.Name = "TypeSound"
    Sound.SoundId = "http://www.roblox.com/asset/?id=3333976425"
    Sound.PlaybackSpeed = 1
    Sound.Volume = 0.5
    Sound:Play()
    coroutine.resume(coroutine.create(function()
        wait(1)
        Sound:Destroy()
    end))
end

function SetText(word)
    Message = word
    for i = 1, #Message do
        TextValue.Value = string.sub(Message, 1, i)
        TypeSound()
        wait(0.05)
    end
end

wait(10)
FrameVisible.Value = true
RandomPlayer = Players:GetChildren()[math.random(1, #Players:GetChildren())]
SpeakerName.Value = RandomPlayer.Name
-- (below) Making player's name the value of RandomPlayer
SpeakerImage.Value = RandomPlayer.Name
SetText("Hello and welcome to Part 9!")
wait(10)
SpeakerText.Text = RandomPlayer.Name
SetText("<- Random player selected")
wait(5)
SetText("Today we will be learning this dialog gui thingy")
wait(5)
SetText("And some other stuff, I guess...")
wait(5)
SetText("Well then, let's head on with the video!")
wait(5)
FrameVisible.Value = false

LocalScript [PlayerImage]:

local Players = game:GetService("Players")
local ThumbnailType = Enum.ThumbnailType.HeadShot
local ThumbnailSize = Enum.ThumbnailSize.Size150x150
local SpeakerImage
local Speaker

while wait() do
    SpeakerImage = game.ReplicatedStorage:FindFirstChild("SpeakerImage")
    Speaker = game.Players:FindFirstChild(SpeakerImage.Value)
    -- Problem is below
    script.Parent.Image = Players:GetUserThumbnailAsync(Speaker.userId, ThumbnailType, ThumbnailSize)
end

Explorer Tab:
Screenshot 2020-06-03 at 8.01.39 pm

I might’ve just made a simple mistake but this is just something I gave up working on myself.

2 Likes

What does the output show? 30 chars

Alright after analyzing your code for a while, we have ALOT of things to go over…

INTRO

Please do not take anything I say with offense. If something you see sounds degrading/rude, it’s not… at all.

With that being said, let’s move onto the basis of solving this issue, and other coding issues.

GENERAL HELPFUL TIPS

When you say ValueObjects are better than using RemoteEvents, something is definitely wrong with your code, in a philosophical sense.

Remember this in coding, don’t use a object for what it ISN’T supposed to be used for. ValueObjects are used for general storage of values, I see ValueObjects being abused almost on the daily for networking or saving data.

What is used for networking you may ask? RemoteEvents and RemoteFunctions, these are the tools in your roblox development that are crucial to creating games that work.

There are some moments where what other experienced developers say, just doesn’t make sense, like what am I supposed to do if using wait() is bad? Or if using ValueObjects to store things to communicate with Scripts and LocalScripts is bad practice.

A lot of coding is just nonsensical insanity, like why isn’t this working, what the hell, why did this randomly stop?

TECHNICAL SOLUTIONS

Let’s get one thing out of our way, the NETWORKING. Roblox has a great guide to this situation, and trust me, big ambitious projects are coder’s worst fears. It’s all nice and dandy at first, then issues, and issues, then 3 more issues, and finally this issue that prevents you from working on the game and you have to REWRITE EVERYTHING!!

Here is a guide that makes networking easier to understand, Guide for Networking.

Another guide also helps understanding how Servers and Clients work, Client and Servers.

If you didn’t see what you need to get for this situation already, that’s fine.
I’ll give you a freebie, what we need for your camping game is a RemoteFunction.

Make sure to click the hyperlink, the Roblox API Reference usually includes code samples to help you use classes.

Hold on wait a minute though, what about the SpeakerImage and SpeakerName stuff?
That’s fine, Roblox API Reference has your back all the time, for this, we’re not communicating two-way (client server client).

Using that criteria, we can find out that we need a RemoteEvent.

Considering the fact that this is a camping game, we know that everyone will be in a server at the same time, no joining individually. Using that knowledge, we can use a intermission timer to use a RemoteEvent to send the Speaker’s Name and Image to the clients using

RemoteEvent:FireAllClients(arguments)

That’s all nice and fine, but wait… what about the text?
Remember that criteria we used? We just need to send the target text to the client, and have the client do the text animation on their own terms!

What does that describe? One-Way Communication, so we need a Text RemoteEvent to communicate to all of the clients that we have some text, so show it to the person behind the screen.

That’s all cool and all, but now lets focus on the Client.

Ok, so we have the remotes set up, but what the heck do we do now? Whats the point? I’m assuming you have a general knowledge of RemoteEvents. We need to eliminate the while wait() do end stuff, that stuff is bad, really bad, dont ever wade in that… smelly code.

Alright, no wait() so what do even use?’

ADDRESSING CODE SMELLS

I see this commonly, and I did it too, I still do today, but the use of wait() in games is so bad, anyone can understand it.

So why? Why is wait() the devil? Because the reliance of the Roblox Task Scheduler is really unpredictable, so a lot of developers rely on this amazing service. RunService!!

If you read the API Reference, which I linked to, this service is optimal for time-management purposes and visual effects. We’re looking at the time-management purpose for now.

Most people rely on RunService.Heartbeat, we’re going to use this for our custom wait() function.

I provide this function because it’s the biggest life saver, this is also on my models as “BetterWait.”

local function wait(num) -- local function overrides globals
   num = num or 0.01 -- this is a coding macro in lua that protects against undefined arguments
   local elapsedTime = 0 -- elapsed time since wait() was called
   local heartbeat = game:GetService("RunService").Heartbeat -- we cache our heartbeat connection so we dont keep calling RunService

   while elapsedTime < num do -- while our elapsedTime is less than the amount of time we wanna sleep our thread for, we yield
    addToElapsedTime = heartbeat:Wait() -- RunService returns a delta (change in time) since 
    -- the last heartbeat, so we use this to have REALLY accurate waits
    elapsedTime = elapsedTime + addToElapsedTime
   end -- easy as that. 
end

Okay, so this is a IMMENSELY better wait function, like way way better. But this is all nice, dandy whatever, but you should STILL not rely on wait for every single thing.

This concept is called event driven programming.

In roblox, RBXScriptSignals are used internally by Roblox to create their events in instances. There is alot of popular events to yield on for game development.

However, for developers, we can’t use those. What we CAN use though is BindableEvent!
These are great for programming things, and they also have AMAZINGG perks.

You can use BindableEvents to make spawn() more accurate, but that’s not in the scope of this topic.

So how the heck does all of this even correlate to this camping game you made? It correlates not only to this, but to your general career as a programmer.

Using these techniques, and other stuff I just went over will excel your learning to even greater things, so those big and ambitious projects can come to life. But remember, you cannot learn everything in a day or so, but this concludes the body.

OTHER TIPS AND CONCLUSION

So, ending the post, you should really take the time to focus and read #resources:community-resources, #discussion, and solved posts in #help-and-feedback:scripting-support. The amount of pure goldmines in terms of programming in there is amazing, and you are BOUND to find amazing things that will solve all of your issues.

Not just this, but if you want, you can take a break from Roblox Lua and look into different programming languages to learn how they work, what paradigms works best for your projects and other things. I started from Java and ended up from so many programming languages to Lua, they both are immensely different, but I can always port my knowledge to Lua and other languages.

Another thing is to USE the Roblox API Reference, and use the devforum’s search bar. These will help you in most projects, trust me, but if you don’t find anything, don’t be afraid to make a post.

That concludes everything, but one thing as a programmer is not to go trigger-happy with this new coding technique/paradigm you trained yourself to use. Trust me alot of code-readability errors or issues come from overused paradigms, but this doesn’t take away their values, they all shine in their own ways in different projects, so it’s best to get experience now by training yourself with different genres of games.

To add more to my final statement, some things like Building or Fighting games use object-oriented-programming, and lets say you’re creating a functional UI, you would most definitely use event-driven-programming to listen for user input and stuff. And sometimes, just do some plain coding, nothing special, like creating mathematical algorithms such as perlin noise, that’s used for Open-World games.

Well, I don’t mean to bloat this post, but that is all!

EDIT 1

I noticed in your code that you were repeating your wait() and SetText() code, so let me also fix that for you. What clean code uses is the principle D.R.Y, make sure to go review that later when you got time.

So how do we fix this, it’s like everything we make needs fixing!

Okay, so when we’re doing NOTHING other than SetText() and wait() we can use a loop and a table to simplify this.

Tables will make this code cleaner, and life easier. Here we acknowledge that tables without indexs like `[1] = “test”’ will be autoindexed by 1 to however elements you have in the table.

Here, I’ll give you a simple code sample that should help you.

local Messages = {
   "Your messages here.",
   "And more here.",
   "Couple more here."
} -- define our table

local messageDelay = 5

for _, message in ipairs(Messages) do -- we use ipairs since we're using numerical indices.
  SetText(message)
  wait(messageDelay)
end -- we loop through our messages so we shorten our code to literally FOUR lines.  

This will shorten your code so much, and now you dont have to write SetText, wait, settext, wait…
Just add more text to the Messages table. Now, when other programmers help you in times of despair, they wont get despair themselves scrolling through endless amounts of SetText()!

And one other thing. Never. Ever. Half-fast coding. You will almost always end up writing a WET solution to your code.

Another thing when you look at the DRY principle I linked, if you’re wondering about how you wouldnt repeat yourself in specifically Roblox Lua, you use ModuleScripts. Roblox’s API Writers also go into DRY themselves, it’s a good read. ALWAYS use ModuleScripts in your games you put effort in, this will save tons of headaches and cussing.

GLOSSARY

Paradigms – a style or “way” to write code.
Yielding – halting execution of a thread that contains code
Thread – a container for code that gets executed
Code smell – a indicator that there is a bigger problem in your code such as design of the programming loop
Task Scheduler – a system that assigns code to execute at specific times

THE MOTHERLOAD

This is one of the best Wikipedia articles I will list here for the last time.

Also, here’s another one that you should use primarily in Roblox Lua.

2 Likes

Why are you trying to get the player with SpeakerImage.Value? What is the SpeakerImage value?

Its the image of the speaker and when somebody is speaking hes name shows on the SpeakerImage Value and who is talking he shows up on image label.