May 31st 2007

Hats Stats

Clockwork and I have been monitoring the Roblox economy since hats were released yesterday. There have been 1472 sales completed since the release. Not surprisingly, the top seller is the red hat. However, the most profitable item at the moment is the viking helm. The data are a little skewed since some items, like the Fedora, were put out later than the others.

Miked, prominent Roblox tycoon83,481 RO$ have been spent so far. However, the amount of money in the economy continues to slowly increase, after a large dip yesterday. Part of this increase is due to 14,000 RO$ of debts the Roblox Team paid off yesterday to various individuals. Possibly citizens are now saving money to buy the more expensive hats, after having purchased all the cheap ones.

At the moment there are 300,904 RO$ outstanding. The Roblox tycoons on the top 20 list control 45,788 RO$, or 15.2% of the money supply. There are 630 Robloxians with over 100 RO$.

- Telamon

AddThis Social Bookmark Button

May 30th 2007

Robloxian Hat Dance!

 

Rejoice! A new release is upon us! What’s new?

Hats

There are now hats and shirts for sale in the Roblox Catalog. Hats are currently offered at prices ranging from 7 to 5000 RO$. Obviously, prices may go up or down in the future. You can see the hats that you have bought in the Change Character screen. This is also where you can choose which hat, if any, you are currently wearing.

Physics and Networking Upgrades

The networking and physics code has been improved in this release to help reduce lag. Tests in our lab have shown some very respectable performance improvements in certain levels. Your mileage may vary.

We’re testing a very experimental change in this release. When you are in a map that has a lot of exploding or moving parts, we try to slow down time while keeping character movement responsive.

New Admin

We’ve added a new member to the Roblox Team, who is interning with us over the summer. If you see clockwork in game, say hi. Over the next several months, he’ll be helping us to expand our Catalog, update the wiki, maybe make some cool levels, and probably hundreds of other things. Since he’s new, be nice and don’t message him with a deluge of tech support questions. We don’t want to scare him off.

- Telamon

AddThis Social Bookmark Button

May 23rd 2007

Sneak Peek: Hats

Straight from my debug build of Roblox to your browser…

- Telamon

AddThis Social Bookmark Button

May 21st 2007

ROBLOX ROBUX REDUX

The Top 20 Wealthiest Robloxians

 

ROBUX were released last Monday and as I write this an incredible 96,251 RO$ are in circulation. The Roblox tycoons on the top 20 list control 21,480 RO$, or 22.3% of all currency. There are 140 Robloxians who have more than 100 RO$.

It looks as though next week’s release will feature items for purchase. We will be using data like those above to calibrate our initial prices. Our intent is to offer goods for all budgets at all price points.

- Telamon

AddThis Social Bookmark Button

May 17th 2007

Cleaning Up an Old Script

One of my favorite tasks at work is to clean up old code. You know what I mean: It’s like the pleasure you get from throwing those smelly socks in the clothes hamper, putting your books back on the shelf and trashing the old apple core that’s been moldering under your bed. Well… maybe you don’t know what I mean.

Anyway, today I looked back at one of the first scripted models I created with Roblox and I realized it stunk worse than an old pair of gym socks. It’s the old Fountain model that sprays little water droplets around.

In this article I’m going to refactor the script. That means I’m going to re-write it in a better way without making substantive changes to the model and how it works. Along the way we’ll explore some new features in Roblox that can make scripts faster and more powerful. We’ll also adopt some better coding styles.

Sound like fun?  If not then stop reading. We’re going to get technical now.

First let’s look at the old code:

local r = game:service(”RunService”)

function rv()
     return 5*math.random()-2.5
end

function spawn(spawnTime)
     local droplet = Instance.new(”Part”)

     local headPos = script.Parent:findFirstChild(”Head”).Position

     droplet.Position = Vector3.new(headPos.x, headPos.y+3, headPos.z)
     droplet.Size = Vector3.new(1,1,1)
     droplet.Velocity = Vector3.new(rv(), 50, rv())
     droplet.BrickColor = BrickColor.new(102)
     droplet.Shape = 0
     droplet.BottomSurface = 0
     droplet.TopSurface = 0
     droplet.Name = “Droplet ” .. spawnTime
     droplet.Parent = script.Parent.Parent

     local delete
     function(time)
          if time > spawnTime + 5 then
               droplet.Parent = nil
               r.Stepped:disconnect(delete)
          end
     end

     delete = r.Stepped:connect(delete)
end

local nextTime = 0

while true do

     time = r.Stepped:wait()

   if time > nextTime then
          spawn(time)
          nextTime = time + 0.3
     end
end

Down near the bottom you’ll see the “while true do” loop.  This is the main loop of the script. Let’s tackle it first. Here’s a much nicer rewrite of the code:

– The main loop
while true do
     time = wait(0.3)
     spawn(time)
end

Roblox now defines a global function called “wait”.  You specify how long you want to wait for (0.3 seconds) and it does the rest. This is much nicer than listening to the RunService.Stepped event, which fires 30 times a second. Our code has gotten shorter and it is much more efficient, since it doesn’t have to check 30 times a second for elapsed time.

Now let’s turn our attention to the meat of the script. The “spawn” function. In here the script connects an anonymous function to the RunService.Stepped event and after 5 seconds it deletes the water droplet. It would be tempting to rewrite this with the global wait() function, but that won’t actually work. You see, since spawn is called directly from our main loop, calling wait() inside of spawn() would actually put our main loop asleep for 5 seconds. As it turns out, there’s a completely different and much better way to do this. A few weeks ago we quietly released a Debris service. Its job is to do exactly what we want: Delete random stuff after a set period of time. Here’s the new code:

local debris = game:service(”Debris”)
     debris:AddItem(droplet, 5)

The Debris service will delete the droplet after 5 seconds. We can “create-and-forget” the droplet. The Debris service has another nice feature – it will delete items earlier if too much debris piles up in a map. So, if you create a map with 500 fountains, the Debris service will make sure there aren’t 10,000 water droplets lagging your map down to a crawl. As a map author you can configure the maximum number of debris items. The default is 300.

Now our script is shorter, easier to read, and more efficient. From here on we’ll do a few more things to make the script stylistically more pleasing. Here is the final script:

– This script sprays water droplets for the fountain

local debris = game:service(”Debris”)
local spout = script.Parent:findFirstChild(”Head”)

– Utility function
function randomVelocity()
     local x = 5*(math.random()-0.5)
     local z = 5*(math.random()-0.5)
     return Vector3.new(x, 50, z)
end

function createDroplet()
     local droplet = Instance.new(”Part”)
     droplet.Position = spout.CFrame * Vector3.new(0,3,0)
     droplet.Size = Vector3.new(1,1,1)
     droplet.Velocity = randomVelocity()
     droplet.Elasticity = 0.2
     droplet.BrickColor = BrickColor.new(102)
     droplet.Shape = 0
     droplet.BottomSurface = 0
     droplet.TopSurface = 0
     droplet.Name = “Droplet”
     droplet.Parent = script.Parent

     — the Debris service will delete the droplet
     debris:AddItem(droplet, 5)
end

– The main loop
while true do
     wait(0.4)
     createDroplet()
end

Here’s what I did:

1)     Renamed spawn() to createDroplet() for clarity

2)     Added a few comments for clarity

3)     Assigned the simple string “Droplet” to droplet.Name rather than giving each droplet a unique name.

Re-using the same name for each droplet improves network performance.

4)     Set the droplet’s parent so that it resides inside the model, not outside of it.

This makes the explorer view look better. Also, if you delete the model, the droplets go away to)

5)     Moved the definition of the spout object outside of the createDroplet() function.

It is slightly more efficient to do this.

6)     Replaced the crypting rv() function with a randomVelocity() function

7)     Did some clever vector math to set the initial position of the droplet

The droplet’s position is now spout.CFrame * Vector3.new(0,3,0) This is nice in case the fountain tips over. The old script would put the droplet 3 units above the middle of the fountain’s shaft, even if it was resting on its side. The new approach puts the droplet at the end of the shaft. See http://wiki.roblox.com/index.php?title=Scripting#CFrame for details of CFrame operators.  I realize now that I should also rotate the initial velocity of the droplet. Ah well, maybe another day!

That’s it! We’ve refactored an old script. It is now easier to read, more efficient and works better in busy maps. As a final bit up tuning I set the sleep interval from 0.3 seconds to 0.4 seconds. It still looks pretty nice and it means the fountain requires a little less physics – which is always a good thing.

- Erik

AddThis Social Bookmark Button

Next Page »