Codify - Convert anything to Luau, TypeScript, Fusion, React, Vide, Rojo

I’ll look into this one, thanks! :+1:

that’s odd. I haven’t been able to reproduce that myself, but will look into it if I can.

Hey! Absolutely awesome plugin - makes my workflow much easier.
Some criticisms, though:

  • FontFace property on TextLabel objects generates the following code:
    image

  • Adornee property on BillboardGui instances (possibly others) generates the following code:
    image
    I believe a better solution would be to intentionally omit this property to generate an error, making it easier to see.

  • There should be an option for PascalCase names; I use PascalCase in my code, while this plugin generates them in camelCase. Closest option I found was Naming Scheme, but this does not control variable naming conventions.

2 Likes

Thanks so much! Always great to hear people are enjoying Codify! :smile:

Good catch! I’m on holiday now, but I’ll look into this when I can. There’s not currently a separate case for handling FontFace, but that’s easily added.

Oops. Properties that take Instances are supposed to be omitted. I’ll take a look into this one too!

Excellent suggestion, and I agree with you. While I might use camelCase in Roact, I would definitely use PascalCase with vanilla Roblox instances. I’m planning an updated look for the settings panel, so I’ll include this setting in with that

1 Like

Thanks for the quick response time! To clarify on this:

I believe the plugin should make it clear that the property was omitted, to prevent people from spending hours figuring out why their billboards aren’t rendering :sweat_smile:

1 Like

Absolutely valid point! Alerting people of that upfront definitely makes for a better DX.

The only time you should be seeing Instance-based properties being set is when you’re using the “Regular” framework, where the Parent property is set for any descendant Instances (so, all Instances with the exception of the root object that was initially selected).

The reason behind not setting Instance properties is for the sake of portability. Those Instances aren’t guaranteed to exist (or have the same pointer) in one project file as they are another, and are irrelevant in some frameworks (Roact, and possibly Fusion, but I’ve not used Fusion before to be able to comment).

3 Likes

Just a heads-up:

@IdleBrick (sorry for the delay) I’ve added your issue regarding numeric names to the project on GitHub.

@PysephDEV I’ve added all of your feedback to some new issues on the GitHub project.

@TheH0meLands I’ve added this to the to-do list.

2 Likes

Great plugin, I had developed a smaller similar version for Fusion, but this does everything I need and better.

Personally, I like my code to in a certain order, so I have to rearrage the properties when creating components (ie Name, break, AnchorPoint, Size, Position, break, Background). Somthing like a hirearchy module passed into the plugin which would determine order and add line breaks would be a nice optional addition.

The other idea I had with Fusion would be to pass in the ‘defaultProps’ module found in the Fusion code, which means that default properties don’t get generated. Having the code set the BorderSizePixel and BorderColor3 for every element is a slight pain, which I why I have a macro to fix this when building the UI by hand, so being able to omit this when generating code would be nice.

Apart from these two critiques, which are mostly down to my personal preference, it’s a really helpful plugin. Thanks

1 Like

amazing plugin, i love it!

But I have a suggestion. Would it be possible to add Roact JSX support? An example would be an option where it’s called “Roact JSX” and it’ll convert the instance to Roact JSX instead of default roact. This would greatly benefit my workflow as I mainly use roblox-ts for all my projects. And i’m sure it’ll benefit other devs too!

Version 2.2.3

What’s Changed

  • Fixed issue #22: TextLabel, TextBox and TextButton now have a FontFace property which is currently not usable in Studio, but has not been hidden by Roblox which caused it to be added to the properties for those classes. This hotfix adds the ability to filter out properties from classes internally so they are not serialised by Codify.

Full Changelog: 2.2.1…2.2.3

2 Likes

Sorry for the delay. I’ve issued a hotfix to address this issue (v2.2.3).

I’ll have a think about this. It doesn’t seem like a high-priority addition, and I’d need to explore the best way to implement it. If you’re using vscode you can use ALT+Up/Down to move lines up/down in the code editor. You can do this in the Roblox script editor too.

I’ll look into this one. Codify shouldn’t be serialising properties that are already at their default values. I don’t personally use Fusion, but I’m sure if it’s necessary to implement, I can do that.

JSX support was planned originally, back when it was Roactify. I’m still not adverse to exploring JSX at some point, but it’s not a high priority at this time. Keep your eyes peeled though.

1 Like

Version 2.2.4

Get on Itch Get on GitHub Get on Roblox

What’s Changed

Fixed

  • Issue #21: Previously, Instances whose name contained exclusively unsafe characters would cause an error. Unsafe names are now mapped to a safe character; e.g. "123" will now become "w23".
  • Issue #18: Properties which accepted an Instance as a value would cause Codify to generate their values as “some.Property = Instance.new("Thing")”. Instance-based properties are now omitted from the output. In future, I’d like Instances that are present in the tree (when using the “Regular” framework) to be referenced within the output.
  • Issue #20: As Instance properties are now omitted, a notice is now displayed on the home tab to ensure users are aware that properties, such as Adornee or PrimaryPart, will be excluded from the output.
  • Issue #23: When using the “Regular” or “Fusion” frameworks, the “Name” property of Instances would be converted to their safe name. Codify will now respect the original name of the Instance.

Changed

  • [Internal] The GetIgnoredPropertyNames method of Lib/Properties.lua will now include globally ignored properties in its resulting array.
  • [Internal] Codify now uses Sift instead of Llama for table operations, as Llama is now deprecated.

Full Changelog: 2.2.3...2.2.4

1 Like

Will there be an option for a “create” type of generation (or whatever its called)
Sometimes people use a function that works like this

create "ScreenGui" {
	create "Frame" {
		Size = UDim2.fromScale(.2,.1),
		BackgroundColor3 = Color3.new(1,.25,.25),
		create "TextLabel" {
			Size = UDim2.fromScale(.5,.5),
			Position = UDim2.fromScale(.25,.25),
			Text = "hello!",
			TextScaled = true,
		},
	},
	create "TextLabel" {
		Size = UDim2.fromScale(.5,.5),
		Position = UDim2.fromScale(.25,.25),
		Text = "hello!",
		TextScaled = true,
	},
	IgnoreGuiInset = true,
}

The frame and textlabel are parented to the ScreenGui, and the text label (not the one parented to screengui) is parented to the frame. Would really like this as sometimes I make small UI components like this and its much more readable than Instance.new

2 Likes

I’m going to look into reworking the way snippets are generated internally to make adding new frameworks easier to potentially allow for TypeScript and RbxUtil (the create method you mentioned)

no ETA on this right now, but I’ll add it to the GitHub project as a feature request

for the time being I’d suggest using Fusion to generate those snippets. you can change the creator method to “Create” in the settings, and just remove the [Fusion.Children] = { line and it’s matching closing bracket

example:

return Create "Frame" {
  BackgroundColor3 = Color3.new(),

  [Fusion.Children] = { -- remove this
    Create "TextLabel" {
      Text = "Hello, world!",
    },
  }, -- remove this
}

It would be cool if this plugin supported roblox-ts as well. Ie, converting the output of fusion to something for RBXTS.

1 Like

Heyo! Reporting some bugs:

  • Multiline strings in TextLabels (or any textholder objects) break down:
    image

  • Objects with exclusively numbers in them get renamed to x, y, w etc. You mentioned above that this is expected behavior, but it becomes an issue when relying on UIListLayout.SortOrder = Name. You can detect all ‘illegal’ characters (excluding keywords, since that’d be more than 1-line) through this if-statement:

if not string.match(String, "^[_%a][_%w]*$") then
    String = "[\"" .. String .. "\"]"
end
2 Likes

For the latter bug, here’s a more ‘complete’ solution:

local specialCharacters = {["\a"] = "\\a", ["\b"] = "\\b", ["\f"] = "\\f", ["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t", ["\v"] = "\\v", ["\0"] = "\\0"}
local keywords = { ["and"] = true, ["break"] = true, ["do"] = true, ["else"] = true, ["elseif"] = true, ["end"] = true, ["false"] = true, ["for"] = true, ["function"] = true, ["if"] = true, ["in"] = true, ["local"] = true, ["nil"] = true, ["not"] = true, ["or"] = true, ["repeat"] = true, ["return"] = true, ["then"] = true, ["true"] = true, ["until"] = true, ["while"] = true, ["continue"] = true}

local function GetSafeName(instance: Instance)
	local name = string.gsub(instance.Name, "[%c%z]", specialCharacters)
	if keywords[name] or not string.match(name, "^[_%a][_%w]*$") then
		name = string.format("[\"%s\"]", name)
	end

	return name
end

GetSafeName({Name="break"}) --> ["break"]
GetSafeName({Name="1var"}) --> ["1var"]
GetSafeName({Name="v1ar"}) --> v1ar
GetSafeName({Name="\n"}) --> ["\n"]
GetSafeName({Name="1"}) --> ["1"]
GetSafeName({Name="h"}) --> h
2 Likes

thanks for the reports (and solutions!), I’ll look into this when I can :relaxed:

Can we have support to Rojo JSON Models?

2 Likes

I don’t see why not. that looks like a good way to serialise the data before converting it to Luau, so I may switch over to that internally and give the option to expose it

I’m currently working on an update to Codify to fix a bunch of bugs, and add a few new features, so I’ll be sure to add this to the to-do list

3 Likes

Version 2.2.4-patch.1

Get on Roblox Get on Itch.io Get source code on GitHub

This is an unofficial patch. The source for this patch has not been uploaded to GitHub, but will feature in the next update to the minor version (v2.3.0), which will also address more bugs and include a few new features :eyes:. Plugin binaries are released on the plugin marketplace and Itch.io.

This is also a reminder that Codify now costs :robux_gold: 350 via the Plugin Marketplace (and is now listed in the toolbox!), but can still be obtained for free via the Itch store page (optional donation), or by building from source—The GitHub README has not yet been updated to reflect this.

Finally, thank you so much for 1,000+ installs via Roblox! Please don’t forget to give the plugin a :+1: thumbs up if you’re enjoying it.

image

What’s Changed

  • Patched number converter.

Fixed

  • [Internal] Instances which allowed inf/-inf values would serialise as “inf”. This is a minor patch to convert those values to math.huge and -math.huge, respectively.
2 Likes