Logo with title ".Blog"

Briefs

Low-effort content for certain microblogging platforms.

Arrow emoji

Can we make ARROW POINTING UPWARD THEN CURVING LEFTWARD a meme so that the Unicode Consortium will add it as an emoji?

.nojekyll

If you don’t use Jekyll for GitHub Pages, be sure to disable it by adding a .nojekyll file to the root of the deployed branch. Doing this cut my build time in half.

Contrast ratios

Minimally compliant contrast ratios. Good for preventing afterimages.

Ratio: 4.56 (AA)
BG: #000000
FG: #757575
Ratio: 7.01 (AAA)
BG: #000000
FG: #959595
Ratio: 3.04 (AA)
BG: #000000
FG: #5A5A5A
Ratio: 4.56 (AAA)
BG: #000000
FG: #757575
Ratio: 7.01 (AAA+)
BG: #000000
FG: #959595
Ratio: 7.00 (AAA)
BG: #595959
FG: #FFFFFF
Ratio: 7.00 (AAA+)
BG: #595959
FG: #FFFFFF
Ratio: 4.54 (AA)
BG: #767676
FG: #FFFFFF
Ratio: 4.54 (AAA)
BG: #767676
FG: #FFFFFF
Ratio: 3.03 (AA)
BG: #949494
FG: #FFFFFF
Ratio: 3.04 (AA)
BG: #5A5A5A
FG: #000000
Ratio: 4.56 (AA)
BG: #757575
FG: #000000
Ratio: 4.56 (AAA)
BG: #757575
FG: #000000
Ratio: 7.01 (AAA)
BG: #959595
FG: #000000
Ratio: 7.01 (AAA+)
BG: #959595
FG: #000000
Ratio: 7.00 (AAA)
BG: #FFFFFF
FG: #595959
Ratio: 7.00 (AAA+)
BG: #FFFFFF
FG: #595959
Ratio: 4.54 (AA)
BG: #FFFFFF
FG: #767676
Ratio: 4.54 (AAA)
BG: #FFFFFF
FG: #767676
Ratio: 3.03 (AA)
BG: #FFFFFF
FG: #949494

Slice swap

Swapping two parts of a slice in-place.

                          // ABCDE|FGH
slices.Reverse(slice[:i]) // EDCBA|FGH
slices.Reverse(slice[i:]) // EDCBA|HGF
slices.Reverse(slice)     // FGH|ABCDE

Here’s a method for producing proportional bitmap fonts. The red component defines the drawable area for each glyph. Green defines the actual appearance. Blue defines the origin and spacing. Blank glyphs are skipped.

Layers are used to define groups of characters, allowing any part of the unicode codespace to be specified. A layer name with a single code point defines a sequential group. Ligatures are possible by defining a layer name with more than one code point.

Text is rendered by placing the left-most blue pixel of a glyph over the right-most blue pixel of the previous glyph. Using a baseline instead of boundaries for glyph placement allows glyphs to be spaced arbitrarily, and even drawn over each other.

Futuristic

There was a time when “The year is 2025” would have felt futuristic.

The year is 2025. There is still no benchmark for displaying differences in Terms of Service. Users everywhere are still expected to memorize the whole thing and then comb through looking for changes.

Same length

Today I am thankful that

  • absolute
  • argument
  • constant
  • relative
  • register, and
  • variable

all have the same number of letters.

The changes shown in this image hint at how parameters are named internally in Roblox’s engine. It’s clear that someone missed a separator when adding the “plugin” parameter.

Premature ads

You absolutely should not run ads for a game that is first-day-public. You need to publicly softlaunch for at least 10 (maybe 14?) days first or you’re going to run afoul of the security system.

@MrChickenRocket, 3:04 AM · Apr 25, 2024

Where would I learn this information that isn’t an impromptu tweet from someone I happen to follow replying to someone else I happen to follow that I happen to see incidentally?

Newly “first time public” places are subject to a bunch of security and filtering because of exploiters. The exact details are not published by roblox for .. reasons? I guess, but I’ve watched multiple game launches step on that garden rake of not being able to have people join.

@MrChickenRocket, 5:13 AM · Apr 25, 2024

Query engine

Implemented a query engine that can search for API items through just about any aspect. As expected, it’s quite fast.

For now, the plan is to use only the fuzzy matcher. After I replace the old website, I can work on writing a parser than can utilize the entire engine.

The query syntax is made up. Here’s the current plan:

Expressions

	foo bar     : expressions foo and bar
	foo && bar  : foo and bar
	foo, bar    : foo or bar
	foo || bar  : foo or bar
	!foo        : negation of foo
	(foo)       : expression grouping

Simple

	foo      : fuzzy match name to foo
	"foo"    : name exactly equal to foo
	/foo/    : match name to regexp foo
	*        : always match

Compound

	foo.     : match primary name to foo (e.g. class name)
	.bar     : match secondary name to bar (e.g. property name)
	foo.bar  : match primary name to foo and secondary name to bar

Fields

	is:foo              : of type "foo" (class, function, etc)
	tag:foo             : has tag "foo"
	has:foo             : has field "foo"
	removed:yes         : is removed
	superclasses:N      : number of superclasses (class)
	subclasses:N        : number of subclasses (class)
	members:N           : number of members (class)
	superclass:foo      : superclass foo (class)
	subclass:foo        : superclass foo (class)
	memcat:foo          : MemoryCategory foo (class)
	threadsafety:foo    : ThreadSafety foo (member)
	security:foo        : Security foo (member)
	cansave:yes         : CanSave (property)
	canload:yes         : CanLoad (property)
	readsecurity:foo    : ReadSecurity foo (property)
	writesecurity:foo   : WriteSecurity foo (property)
	valuetypecat:foo    : ValueType.Category foo (property)
	valuetypename:foo   : ValueType.Name foo (property)
	category:foo        : Category foo (property)
	default:foo         : Default foo (property)
	returns:N           : number of returns (function)
	parameters:N        : number of parameters (function)
	returntypecat:foo   : return.Type.Category foo (function)
	returntypename:foo  : return.Type.Name foo (function)
	returntypeopt:yes   : return.Type.Optional (function)
	paramtypecat:foo    : parameter.Type.Category foo (function)
	paramtypename:foo   : parameter.Type.Name foo (function)
	paramtypeopt:yes    : parameter.Type.Optional (function)
	paramname:foo       : parameter.Name foo (function)
	paramdefault:foo    : parameter.Default foo (function)
	enumitems:N         : number of enum items (enum)
	itemvalue:foo       : enum item value foo (enumitem)
	legacynames:N       : number of legacy names (enumitem)
	legacyname:foo      : legacy name foo (enumitem)
	typecat:foo         : type category foo (type)

String

	security:foo    : fuzzy match
	security:"foo"  : exact match
	security:/foo/  : regex match
	security:*      : always match

Numeric

	members:N    : field equal to N
	!members:N   : field not equal to N
	members:<N   : field less than N
	members:<=N  : field less than or equal to N
	members:>N   : field greater than N
	members:>=N  : field greater than or equal to N

Boolean

	removed:no     : match false
	removed:n      : match false
	removed:0      : match false
	removed:false  : match false
	removed:f      : match false
	removed:yes    : match true
	removed:y      : match true
	removed:1      : match true
	removed:true   : match true
	removed:t      : match true

Meta

	$types           : list entity types
	$tags            : list entity tags
	$securities      : list security field values
	$threadsafeties  : list threadsafety field values
	$typecats        : list type categories

Results

	limit:50     : set result limit to 50 (default)
	limit:0      : set no result limit
	order:foo    : sort ascending by field foo
	order:<foo   : sort ascending
	order:>foo   : sort descending
	order:score  : sort descending by score (default)
	order:name   : sort ascending by name
	go:docs      : Redirect to CreatorHub page of 1st result
	go:git       : Redirect to creator-docs repo page of 1st result

Working out how to do searches on a static website. This hinges on the assumption that testing 21k+ entries is surprisingly fast.

Fun fact: The size of this table is 3490.2x500505 pixels.

I’ve been working on a complete rewrite of the Roblox API Reference, which is why it hasn’t been updating. Until it’s finished, the new website can be previewed here, for now:

https://robloxapi.github.io/ref-temp/

Features a simpler architecture, use of full API dumps, creator-docs integration. Focusing on feature parity with the current site for now, though.