Talk:Restricted Doors

From Legacy Roblox Wiki
Jump to navigationJump to search

The restriction table

This strikes me as a very strange way to do it. Why not just use the or operator on all the items, rather than constructing a list? eg:

local allow = player.Name == "MrDoomBringer" 
           or player.Name == "JulienDethurens"
           or player.Name == "blocco"
           or player.Name == "NXTBoy"
           or player:IsInGroup(127081) and player:IsFriendsWith(game.CreatorId)
           or game:GetService('BadgeService'):UserHasBadge(player.userId, 1032571)
           or game.CreatorId == player.userId

if allow then
    open()
    delay(4, close)
end

I don't see any benefit whatsoever to using a table.

Also, while there's nothing wrong with it in general you shouldn't indent using tabs when posting on the wiki, as they get rendered as 8 spaces wide, which makes things unreadable. You can't change tab width in HTML.

09:30, 26 February 2012 (UTC)
I thought about using or, but that'd make it all hard to format, while using a table makes it easier. I do agree it's not something common to see, but it does work well, anyways, and I had to find something that would be simple to explain. As for indenting, I always use tabs and I will always use tabs. Don't forget most users that come here actually just come here to copy the code, and therefore, giving them code indented using spaces is a bad idea. It doesn't really matter if they have a width of 8.
26 February 2012
Anything wrong with formatting the ors as above? Are you against spaces for alignment?
11:36, 26 February 2012 (UTC)
Also, how about doing the requirements like this:
function any(...)
    for _, v in ipairs({...}) do
        if v then return true end
    end
    return false
end
function all(...)
    for _, v in ipairs({...}) do
        if not v then return false end
    end
    return true
end

local allow = any(
    player.Name == "MrDoomBringer",
    player.Name == "JulienDethurens",
    player.Name == "blocco",
    player.Name == "NXTBoy",
    all(
        player:IsInGroup(127081),
        player:IsFriendsWith(game.CreatorId)
    ),
    game:GetService('BadgeService'):UserHasBadge(player.userId, 1032571),
    game.CreatorId == player.userId
)
11:36, 26 February 2012 (UTC)
Well, yes I am against spaces for alignment. Tabs are meant to be used for indenting, while spaces are meant to be used to separate words. Besides, the ROBLOX script editor, which 99% of ROBLOX scripters use, has no feature to make the use of spaces to indent easier. And, anyways, I have seen lots of scripts that are not indented in free models and lots of scripts that are indented with tabs, but I have never seen a single script on ROBLOX that was indented with spaces. As for indenting the ors, well.. the thing is, I believe word wrapping should be done by the browser when displaying and by the text editor when in a text editor. We can't know how big the screen of the readers is, but the browser can. Therefore, I believe it should be handled by the browser.
26 February 2012
I'm not sure I agree with your "let the viewer line wrap" mantra. You can get much more clarity by line wrapping manually than by letting the viewer do it in rendering. The only sensible way of making that conditional statement readable was to line wrap it with spaces. That's where I think spaces can belong - had I used tabs, the text would misalign were the width changed. I don't think any IDEs will virtual-wrap (i.e. in the rendering) lines to align on column. The best they can do is type the spaces for you.
At any rate, we shouldn't make code more complex just because you don't want to wrap lines!
22:28, 26 February 2012 (UTC)
As for what you suggested, well, perhaps we could do that, but I'd prefer keeping the article simple. I mentioned in it that there would be lots of other ways to do it. Adding two more functions and stuff would just make it more complicated, and the point here is to describe all of the code. If we edit the code, we'll also have to edit the text, because I really don't want this article to become like some other articles that just give the code without explaining it. I've posted a thread on SH to get feedback about this article and most of them say they like how I described it in depths instead of just giving away code.
26 February 2012
That was just an interesting way of writing it. It's more readable than the table approach, which seems a little odd, but agreeably more complex. Just line wrap the darn thing and use ors!
22:28, 26 February 2012 (UTC)
Then, I believe we could add another section (heading) to the article in which we talk about other ways to do it. The thing is, how can you wrap it in a way that you can be sure it will look the same way with a monospace font than with a non-monospace font?
26 February 2012

... You're kidding me. Roblox still ships with a proportional font by default? This would work:

local allow = (
	player.Name == "MrDoomBringer" or
	player.Name == "JulienDethurens" or
	player.Name == "blocco" or
	player.Name == "NXTBoy" or
	player:IsInGroup(127081) and player:IsFriendsWith(game.CreatorId) or
	game:GetService('BadgeService'):UserHasBadge(player.userId, 1032571) or
	game.CreatorId == player.userId
)
22:37, 26 February 2012 (UTC)
Ah, that looks much better. And it makes sense, as we're indenting because it is actually in a parenthesis... Hm...
26 February 2012

Complex debouncing

Another thing I noticed - There's no debouncing in here - you can end up with one handler opening the door while another tries to close it.

However, you'll want to be a bit clever with the debouncing. If a stream of VIP players are walking through the door, you want the door to close only after the last goes through. That is, you want this:

0.0s - player 1 hits, door opens
3.0s - player 2 hits, door stays open
4.5s - player 3 hits, door stays open
7.5s - door closes

Rather than

0.0s - player 1 hits, door opens
3.0s - player 2 hits, door is still open
4.0s - door starts closing
4.5s - player 3 hits door while it is closing
5.0s - door finishes closes
5.0s - player 3 angrily hits door again, it opens
8.0s - door closes
09:38, 26 February 2012 (UTC)
This article is meant to explain how to script a restricted door, not to give away the best code to do it. It is probable that some users will be able to improve the door. However, perhaps we should improve it. However, one thing I thought of is to use the TouchEnded event to know when there is no player at all touching the door and to close it at that moment. Actually, what I really thought of at first is to open the door when a VIP player touches it, to close it immediately when a non-VIP player touches it, and to close it when a VIP player stops touching it. I believe that would be better than closing it after an arbitrary ammount of seconds. What do you think?
26 February 2012
That makes sense. You need to refine "a VIP player stops touching it" to "all VIP players stop touching it". Is TouchEnded guaranteed to always fire after Touched?
22:30, 26 February 2012 (UTC)

Implementation

touchCount = 0
door.Touched(function(p)
    if isVip(p) then
        --open the door if we're the first thing to start touching it
        touchCount = touchCount + 1
        if touchCount == 1 then
            open()
        end

        wait(4)

        --close the door if we're the last thing to stop touching it
        touchCount = touchCount - 1
        if touchCount == 0 then
            close()
        end
    end
end)
22:35, 26 February 2012 (UTC)

And if a non-vip touches it, we instantly close it. Also, there are some errors in your script. Anyways, coding that is not all. We also have to explain it.. Anyways..

local touch_count = 0

door.Touched:connect(function(part)
	if not part.Parent then return end
	local player = game:GetService('Players'):GetPlayerFromCharacter(part.Parent) or game:GetService('Players'):GetPlayerFromCharacter(part.Parent.Parent)
	if not player then return end
	if is_allowed(player) then
		touch_count = touch_count + 1
		if touch_count == 1 then
			-- If that player is the first to touch the door, open it.
			open()
		end
	end
end)

door.TouchEnded:connect(function(part)
	if not part.Parent then return end
	local player = game:GetService('Players'):GetPlayerFromCharacter(part.Parent) or game:GetService('Players'):GetPlayerFromCharacter(part.Parent.Parent)
	if not player then return end
	if is_allowed(player) then
		touch_count = touch_count - 1
		if touch_count == 0 then
			-- If that player is the last to stop touching the door, close it.
			close()
		end
	end
end)
26 February 2012
What were the errors? Also, TouchEnded strikes me as dangerous. Is every Touched event guaranteed to be followed by a corresponding TouchEnded? What if the part is Destroy()ed?
22:54, 26 February 2012 (UTC)
Everytime the Touched event fires, it should be guaranteed that the TouchEnded will eventually fire. If not, then the TouchEnded event is the most useless thing ever.
26 February 2012
Oh, and I suggest we forget the idea of closing it immediately if a non-vip touches it. Because the door is supposed to close progressively, that'd ruin the point.
26 February 2012
I suggest we just forget that, as, really, it'd become too complicated. It's supposed to be simple and the reader is supposed to write the code himself anyways.
26 February 2012

This isn't the best way to do it

Technically, it's better to have the door either let players in, or teleport them a bit away, otherwise they can tag behind a VIP player. Just my opinion. I prefer not using VIP doors at all. - Quenty (talk • February 26)

I know. But I explained at some place in the article that they should try to avoid using such doors if they can use something more professional. The thing is, all these players only have one thing in their mind, and that thing is what they've seen everywhere else on ROBLOX: VIP rooms.
26 February 2012