今年的 Google I/O 谜题要求玩家通过棱镜来操纵光线和颜色,以解锁游戏世界的各个区域。除了核心游戏循环之外,游戏玩法中还增加了一个全新维度,即隐藏在借助 Gemini API 生成的谜语背后的奖励关卡。本博客将回顾我们构建这种谜语的方法!
我们会在地图上动态放置隐藏图块,而 Gemini 模型则会生成独特的谜语来让玩家解决,玩家解决谜语后即可找到隐藏图块。此举的目的是激励玩家探索使用 AI 构建而成的谜题的全新维度,从而提升玩家参与度。
我们并没有手动硬编码数百个秘密图块的可能位置及相应谜语,而是使用 AI 来帮助我们扩展这些内容,打造极具挑战性的独特解谜体验。
为了充分利用 Gemini 的优势,我们设计了一个可将算法精度与 AI 驱动的创造力结合起来的解决方案。后端算法会在地图上放置隐藏图块,并根据游戏规则为 Gemini API 生成提示,该提示会使用三个简单的指令来描述位置。这可确保每个谜语在游戏框架内都有一个合乎逻辑的解决方案。我们使用 Gemini 将算法生成的答案转化为巧妙的谜语。
我们会根据游戏规则,在游戏图版上以编程方式确定“秘密位置”,然后将其用作 Gemini 的提示。这可确保每个谜语都能够得到解决,且答案始终有效。
// Finds a new hiding spot for the Gemini token and generates a clue string
getHiddenLocation() {
const geminiCluePositions = GameWorld.getCluePositions() // Returns positions that are designated as a "Clue" tile. We tag important tiles when designing a level. These are generally tiles that are not movable by the player.
// We get all the tiles positions in the level, a position is a simple XY coordinate
const secretLocations = GameWorld.getAllTilePositions()
// we remove tiles that are not adjacent to a clue position...
.filter((tileA) => geminiCluePositions.some((tileB) => GameWorld.isNextTo(tileA, tileB)))
// we remove invalid positions, such as tiles that are not empty
.filter(({gridX, gridY}) => GameWorld.isValidGeminiPosition(gridX, gridY))
// we randomly choose a hiding spot
const randomPosition = secretLocations[Math.floor(Math.random() * secretLocations.length)]
const randomTile = Gameworld.getTileByPosition(randomPosition)
// now that we have a hiding spot, we generate a clue string
const riddleClues = GameWorld.generateGeminiRiddleClues(tilePosition)
return {
position: randomPosition,
clues: riddleClues,
}
}
算法输出的是简单的文本,例如:
1. 就在墙的正下方。
2. 距离彩虹节点 2 个图块。
3. 在第一个区域中。
在为要生成的提示确定统一的结构后,我们转而使用 Gemini API 来创建谜语,以隐秘的方式来描述秘密图块的位置。通过在提示中为 Gemini 提供必要的背景和限制,我们能够创建出极具吸引力和挑战性的谜语。这些谜语的格式始终如一,由我们的前端应用向用户展示。
// Build a prompt based on the tile position. We always output 3 rules in this order:
// Clue 1. The type of one adjacent tile to the secret location
// Clue 2. The sector which contains the secret location
// Clue 3. The closest color node to the secret location, and exactly how many tiles away it is.
generateGeminiRiddleClues(tilePosition) {
const adjacentTiles = GameWorld.getAdjacentTiles(tilePosition) // Get the left, right, top and bottom neighboring tiles
const locationSector = GameWorld.getTileSector(tilePosition) // get the "sector" of the tile. Levels are divided in sectors or 'chunks' by the level designer.
const nodeTiles = GameWorld.getAllNodeTiles() // get every 'Node' tile in the level
// clue 1
const randomAdjacentTile = adjacentTiles[Math.floor(Math.random() * adjacentTiles.length)]
const direction = GameWorld.getDirection(randomAdjacentTile, tilePosition)
const randomTileType = randomAdjacentTile.type
const firstClue = `Directly ${direction} a ${randomTileType} tile` // e.g. "Directly above a wall tile"
// clue 2
const secondClue = `In sector ${locationSector}` // e.g. "In sector 3"
// clue 3
const closestNode = nodeTiles.reduce((closest, node) => {
const distance = GameWorld.getDistance(node.position, tilePosition)
if (distance < closest.distance) {
return {node, distance}
}
return closest
}, {node: null, distance: Infinity})
const thirdClue = Exactly ${distance} tiles away from a ${closestNode.node.color} node`
const clues = `1. ${firstClue}. 2. ${secondClue}. 3. ${thirdClue}.`
return clues
}
由此产生的谜语为:
我立于高墙之下,
距彩虹节点两步之遥,
我身处第一个区域之中,
解出谜语即可获得 token 奖励。
谜语本质上是隐秘而有趣的,即便有些模棱两可,倒也在预料之内。在谜语中,即便 AI 生成的输出中可能偶尔会出现逻辑谬误或其他令人意想不到的措辞,我们也能够接受。此外,谜语可以测试玩家的推理能力,鼓励他们发挥创造性思维,并运用他们对游戏规则的理解,分析游戏图版的布局,同时寻找隐藏图块。
与 AI 合作本身便存在一系列挑战。其中最重要的是 AI 有“产生幻觉”或偏离给定规则的倾向。我们以编程方式来生成提示,进而降低了这种风险。我们会在提示的系统指令中提供示例和定义的 JSON 输出:
**Important Instructions:**
- Respond **only** with the JSON object in the exact format specified.
- Do **not** include any explanations, code blocks, or additional text.
- Do **not** enclose the JSON in triple backticks or any markdown formatting.
- Ensure all strings in the JSON are properly escaped.
- Escape special characters like newlines (`\\n`), tabs (`\\t`), and quotation marks (`\\"`) within strings.
- Do not use single quotes; use double quotes for all JSON keys and string values.
- Ensure the JSON is valid and parsable.
我们还利用了人类的推理能力。玩家擅长解释和破译隐秘的线索。通过创建需要逻辑推理才能解决的谜语,我们让玩家得以克服 AI 输出中的任何潜在不一致性。归根结底,我们需要在 AI 生成的内容和人类的创造力之间找到正确的平衡。
今年,我们推出了第一个集成了 Gemini API 的 Google I/O 谜题,这可谓一个里程碑。对于我们的设计和工程团队来说,这不仅仅是集成,还是一场精心筹谋的探索,让我们得以一窥与 AI 协作进行创造的新时代。我们不仅仅是构建了一个功能,我们还开创了一种全新的互动体验方法。如果您考虑将 Gemini API 引入自己的项目,在确定方法时,请牢记以下三条经验:
AI 正在改变用户与我们的应用和游戏互动的方式,使令人兴奋的全新用户体验成为可能。
欢迎和我们一起在线参加 Google I/O 大会(5 月 20 日至 21 日),今年的发布会将在山景城的 Shoreline Amphitheatre 举办并直播,真的非常令人兴奋。我们鼓励您试用 Gemini,探索其潜力,为您的用户打造更多实用且有趣的体验。我们清楚这其中存在着无尽可能。