Allows you to get types from a module without requiring it. Does not work with
exported types.
To get around exporting, types can be smuggled through the returned table.
localexport={}-- Innocent module stuff.functionexport.new()end-- Some types. Must require-- the module in order to get.exporttypeFoo=string|numberexporttypeBar=()->boolean-- Smuggle them through-- the returned table.export._Foo=(nil::any)::Fooexport._Bar=(nil::any)::Barreturnexport
This is incredibly useful for smuggling types from a server module in a client
module so the data the client is going to receive from the server via a remote
can be fully typed.
So nothing breaks on the client even though the modules containing the server
types aren’t replicated, because types don’t matter at runtime. Interesting
approach.
I haven’t deliberately optimized anything, but it’s not the worst. I might be
comfortable with one query that updates every frame, for example. It’s a mess,
but you can play with it here.
hey wait a minute, arent you not a fan of observing any kind of behavior on
instances that enter the data model?
That’s right. Which is why Rx is great, because it simplifies a bunch of
boilerplate that would otherwise be need to ensure that an observation is
correct.
Metatables: I use metatables to signal the separation of data and behavior.
Data goes in the table, behavior goes in the metatable. Great for debugging; the
debugger isn’t cluttered with a bunch of methods.
Encapsulation: I don’t actually want true encapsulation, because it’s harder
to debug. Unlike local variables, private fields can be tapped into, and I don’t
have to hunt them down in the debugger. Also makes writing tests easier.
Overloading: I agree in principal, but in practice, sometimes the
convenience is too much to pass up. To reconcile this, I always accompany a
non-obvious metamethod behavior with an equivalent method.
But it’s worth noting that metamethods are harder to debug, because they don’t
allow yielding, so you can’t set breakpoints in them. That’s why it’s good to
have a regular method-based equivalent.
preprocessor syntax: In older versions of studio, having a $ at the start
of a script would highlight the first line in red. Later, when custom highlight
colors were added, this was referenced with the Preprocessor Color
property, even though it was unused.
self-returning modules leak: If a module returns a value that contains a
reference to the module (return script, return {script}, etc), then it will
never be GC’d.
How poorly do metrics have to be misinterpreted to reach the conclusion that a
developer is creating an entire new game from scratch every single time they
open the baseplate?
-- Regular method.ifmaid:Alive()thenmaid.heartbeat=RunService.Heartbeat:Connect(function(dt)print("delta time",dt)end)end-- Method if your name is Max.maid.heartbeat=ifmaid:Alive()thenRunService.Heartbeat:Connect(function(dt)print("delta time",dt)end)elsenil-- Connect method.maid:Connect("heartbeat",RunService.Heartbeat,function(dt)print("delta time",dt)end)
If you maintain a popular project, and you’re going on hiatus, are too busy, or
just don’t feel like maintaining it right now/anymore, please let your users
know.
Fingerprint scanning is literally leaving your password, which you can never
change, on everything you have ever touched, or will ever touch. And don’t
forget about all those pictures that incidentally contain your fingers in
immaculate detail.
Playing with foliage. Here we have the same texture, triangle count, and
triangle size, but different scaling of the base shape, which is a sphere in
this case. Unfortunately, it’s hard to get something that looks good without
fine-tuning each of these parameters.
… Go has some performance hurdles that make it unsuitable for many real-time
or time-critical applications, for example having a garbage collector. I would
definitely not want to use Go for something like audiovisual processing or
DSP.
Not at RDC, but I thought I’d gamejam anyway. Didn’t finish, but I still had
fun. Here’s what would have been the thumbnail:
If you’re going to solojam, try to use existing assets as much as possible. I
modeled the car, sun, and skybox from scratch, which was fun to do, but sunk way
too much time.
If you have tooling that makes use of Studio’s cookies, Roblox recently changed
how they work in Windows. Cookies are no longer stored in the registry, and are
instead stored as Credentials:
Studio stores the https://www.roblox.com:RobloxStudioAuthCookies credential.
Its value is a ; separated list of cookie names (rather, each name has a ;
appended, note the trailing ;).
The value of each cookie is stored as a credential named
https://www.roblox.com:RobloxStudioAuth + the cookie name.
Tooling will still be able to access these cookies just fine. There’s a winapi
for it, so most languages will likely have a library for it. I listed some in
another tweet.
I use passive voice for references for a formal and well-defined feeling, and
active voice for guides/tutorials to feel more loose and relaxed. Strikes a good
balance.