前言

本文展示 MicroBlocks 与 Roblox 之间的互操作。 具体而言, 我们在 Roblox 中构建一个操场大小的像素屏(16x16), 当角色踩到这个巨型屏幕上的某个像素时, 虚拟世界里的这颗像素将随机变色, 同时现实世界的像素将做出一致变化。可以将其视为数字孪生的一个案例。

本文也展示了 AI(LLM) 作为编程助手,不仅可以让我们在不熟悉的领域快速起步, 还提升了整个学习体验。

我之前对游戏开发和 Roblox 都缺乏经验。借助 AI, 作为新手可以很快就构建出了核心功能,通过几句提示词,花了上几分钟就构建了可运行的核心功能!

与 AI 一起编程,不只消除了起步的困难(对语法和 API 不熟悉), 它本身还是绝佳的学习方式: 这是一种货真价实的项目式学习。我要求 AI 帮助实施我的项目, 然后我阅读并试运行 AI 生成的项目代码,如果出错,就跟它反复沟通。

这个学习过程要比我之前的学习有效许多(之前一般先阅读并弄懂文档,然后开始编程)。之所有有效,或许是因为我一开始就扎入核心工作里, 而不是预先学习大量细节知识。 AI 帮我搭建项目骨架,帮我处理细节问题,我则在更高层面驾驶它。在解决问题过程中,我被迫关注具体细节,此时,细节知识对我而言已经变得有趣(相比于之前学而不用的集邮式学习),因为它是构建我的想法大厦的砖块,知识一旦与学习者发生联系,就不再乏味了。

Roblox

Roblox 提供了世界上最易用的 3D 创作工具, 让任何人都能随时随地创造任何东西。

近期我们在 Roblox 里做一些与 AI (LLM)相关的探索, 被这个环境的灵活度与易用性所折服, 它在某些方面达到了个人计算期待的软件品质, 具有相当不错的 Liveness 特质。

原理说明

Roblox 提供了出色的 3D 创作工具, 让我们可以天马行空地构建想象中的世界, 在这个例子里,我们想象并制造了一个操场大小的像素屏(16x16)。

我们为这个像素屏添加了行为, 使之能够响应用户的操作: 每当有用户踩到像素上时, 像素立刻随机变色, 并且

使用 HTTP 进行通信

开始实验

为了复现这个实验, 你需要做以下工作:

  1. 安装配置 Roblox Studio

提示词

1
2
3
4
5
在 Roblox 创建脚本做以下事情:

1. 创建一个方形面板,名叫 NeoPanelBasePlate。方形面板的尺寸正好容纳其上的所有长方体
2. 方形面板上边均匀排布 16 行 16 列的 光滑黑色长方体, 这些长方体的尺寸如下, 长: 4, 宽: 4, 高:1。 这些长方体之间间隔为 4
3. 这些长方体有如下行为: 当角色碰到某个长方体时,它就随机变色, 对每个长方体做防抖处理。

我将以上提示词输入到 GPT-4,立刻得到了相当不错的脚手架代码。第一次运行就基本完成了 90% 的功能!一些细微瑕疵在我跟它反馈之后,GPT-4 很快就修复了。

以上提示词是我凭记忆重写的,可能和真实的提示词有出入,最初的对话记录找不到了,因为账号被封 :-(

OpenAI 最近 GPU 很不足, Twitter 上不少 Plus 用户抱怨被退钱封号。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
-- chatgpt: https://chat.openai.com/c/15583885-2a3f-4138-9c22-39b9b4cb8929
local HttpService = game:GetService("HttpService")


-- 计算需要的板子大小和位置
local blockSize = Vector3.new(4, 1, 4)
local blockGap = 4
local gridLength = 16
local basePlateSize = Vector3.new((blockSize.X + blockGap) * gridLength, 1, (blockSize.Z + blockGap) * gridLength)

-- 创建方形板子
local basePlate = Instance.new("Part")
basePlate.Name = "NeoPanelBasePlate"
basePlate.Size = basePlateSize
basePlate.Position = Vector3.new(basePlateSize.X / 2, 0, basePlateSize.Z / 2)
basePlate.Anchored = true
-- basePlate.BrickColor = BrickColor.new("Black")
basePlate.Parent = game.Workspace
basePlate:SetAttribute("NeoPanel_url", "http://192.168.1.9") -- "http://127.0.0.1:8000"
local NeoPanel_url = basePlate:GetAttribute("NeoPanel_url")

-- 创建16行16列的光滑黑色长方体
for i = 1, 16 do
	for j = 1, 16 do
		local block = Instance.new("Part")
		block.Size = blockSize
		block.Position = Vector3.new(i * (blockSize.X + blockGap) - blockSize.X / 2, blockSize.Y / 2, j * (blockSize.Z + blockGap) - blockSize.Z / 2)
		block.BrickColor = BrickColor.new("Black")
		block.Material = Enum.Material.SmoothPlastic
		block.Anchored = true
		block.Parent = basePlate

		-- 创建防抖动机制
		local debounce = false

		-- 添加触摸事件
		local function changeColor(otherPart)
			local humanoid = otherPart.Parent:FindFirstChildWhichIsA("Humanoid")
			-- print(humanoid.PlatformStand, humanoid:GetState())
			if not debounce and humanoid and humanoid.PlatformStand == false and humanoid:GetState() == Enum.HumanoidStateType.Running then
				debounce = true
				-- 更改颜色
				block.BrickColor = BrickColor.Random() -- Cocoa

				-- 发送 HTTP GET 请求
				-- todo rgb BrickColor.r 0.10588236153125763
				-- 0.1 to int math.floor(0.33*255)
				local r,g,b = math.floor(block.BrickColor.r*255), math.floor(block.BrickColor.g*255), math.floor(block.BrickColor.b*255)
				local url = `{NeoPanel_url}/?R={r}&G={g}&B={b}&X={i}&Y={j}`
				print('url:', url)
				local response = HttpService:GetAsync(url)

				wait(1) -- 防抖动
				debounce = false
			end
		end

		block.Touched:Connect(changeColor)
	end
end

ServerScriptService 创建 Script, 放入以上脚本

与外部系统交互的部分,我是自己实现的

MicroBlocks

NeoPanel 库

MicroBlocks 最近增加了一个新的库: NeoPanel。 由 Citilab 的 José 贡献给社区。

我在上周六的 MicroBlocks 分享会里分享了这个库。

测试

在线

在浏览器打开: http://板子的IP地址, 诸如我的板子地址是: http://192.168.1.9

程序

我使用 MicroBlocks 内置的 Browser Control Panel 作为脚手架。

这是修改后的程序 Roblox NeoPanel demo

导出 rblx

参考