266 okumalar

Sonraki İçerikD&D oyununu oynayabilir misin?

ile John Polacek10m2025/06/05
Read on Terminal Reader

Çok uzun; Okumak

Eğer hiç bir zaman bir sohbette AI ile bir oyun oturumunu yapmaya çalışmışsanız, ne kadar hızlı bir şekilde çözebileceğinizi biliyorsunuz. umarım uygun bağlam, belirli talimatlar ve yapılandırılmış veri fonksiyon çağrıları sağlarsanız, keyifli bir deneyim elde edebiliriz.
featured image - Sonraki İçerikD&D oyununu oynayabilir misin?
John Polacek HackerNoon profile picture

Bir Flash geliştiricisi olarak günlerimden beri bir multiplayer RPG web platformu oluşturmayı düşündüm. online TTRPG seçeneklerinin bolluğu var (birçoğu harika!) ama bunların hiçbiri nasıl oynamak istediğimi tam olarak hissetmiyordu.

Gördün müVideolarıDeborah Ann Woll, Jon Bernthal'in D&D'yi nasıl oynadığını gösteriyor (bu 2M görüntüleri var!)

O kadar güzeldi ki, ben de böyle bir şey yapabilseydim.

fikri

Anlatıcı yönlendirilmiş, çok oyunculu çevrimiçi rpg platformu, kurallarda hafif ama paylaşılan hikaye anlatımında yüksek, sonuçlar bir D20'nin rulo tarafından belirlenir.

her zaman sevdimD&D ModüllerAyrıntılı karşılaşmalar ve epik hikaye planları, oyuncuların karakterleri iklimli bir final için yollarını buldukları için keşfedeceklerdir.

İnsanların kendi macera modülleri oluşturma yolunu yaratabilseydim, herhangi bir RPG türü için, o zaman oyuncuların bu maceralar boyunca karakterlerini çalıştırmalarına izin verir miydim?

Landing Page for D20Adventures.com


Kim oyunları çalıştırır? Oyun ustaları bulmak zordur. Bir AI'yi bir oyun ustası olmak için eğitebilseydim ne olurdu? Gerçekten iyi yapılandırılmış bir macera planını çalıştırmak (insan tarafından tasarlanmış!) oyuncular için eğlenceli ve sadece bir sürü değilKaldı ki slop?

başlamak için

Birçok şeyi AI ile yapmaktan keyif aldım (bkz.Projeye BaşlangıçBen kullanmak için en sevdiğim stack kullanacağımD20Adventures.com HakkındaNext.js web uygulaması ile Tailwind için UI (gerekirse bile söylenmelidir?)SDK Hakkındaİkizler ve AConvex VeritabanıVercel’e yönlendirildi

Ve bunu açık bir şekilde oluşturmaya karar verdim, kodu yayınladımGitHub Hakkında.

Prototype Hakkında

Bir prototip için, kelimenin tam anlamıyla podcast'te belirtilen senaryodan başlayarak, geceleri ormanda yürüyen bir ranger, uzakta bir kırışıklık duyuyor, ki bu bir yılan ayı olduğu ortaya çıkıyor.

Amacım kısa bir tek atış macerası oluşturmak ve bir AI DM'yi bu macera için küçük bir dizi dönüş ve karşılaşma çalıştırmak için eğitebileceğimi görmek.

Gece Yarısı Summons Eski bir druid arkadaşından gizemli çağrılar Valkarr ormanının vahşetine bir reçel ranger çekiyor.

The Midnight SummonsEski bir druid arkadaşından gelen gizemli bir çağrı, Valkarr ormanının vahşi bölgelerine sığınmacıyı çeker.

Birçok deneme ve hata yaptıktan sonra, nihayet tam bir oyun yapabildim ve YouTube'a yayınladım:

nasıl çalışır

Landing Page

Ulaşım sayfası büyük bir kahraman görüntüsü (Midjourney'de “The Power of the D20” iletisi ile oluşturulmuştur). yeni CSS @starting-style kuralı kullanarak animasyonda basit bir yumuşaklık ekledim:

.fade-in {
  @apply opacity-100 transition-opacity duration-1000 ease-in-out;
  @starting-style {
    opacity: 0;
  }
}

Authentication

Hızlı Başlangıç oyunu oynamak için bir kullanıcı hesabı gerektirir.Bu, API'lerimi kullanan anonim insanlar veya botlar yüzünden çok para yatırılmaktan kaçınmak.clerkKullanıcı yönetimi eklemek çok basittir ve tüm projelerimde bunları kullanıyorum.

Ek olarak, bir token sistemi ile kullanımını kısıtlayacağım token kullanım izlemeye sahibim, burada bir demo oynamak için yeterli miktarda tokenle başlarsınız, daha sonra gittikçe daha fazla satın alabilirsiniz.

The First Turn

Kullanıcı hızlı başlangıç için macera sayfasına inerken, gerçekleşen ilk şey, sadece basit bir JSON dosyası olan demo macerası için verileri yüklemektir (Böyle böyleSistemin bir macera modülü veya planı, LLM için talimatlar ile birbirine bağlı olan bir dizi karşılaşmadan oluşur:

"encounters": [
  {
    "id": "broken-silence",
    "title": "Broken Silence",
    "intro": "Thalbern, a solitary ranger of the Valkarr woods, has always trusted the silence of the wilds more than the promises of men. Orphaned by border raiders and raised by the elves of the Valkrarr Forest, he has spent years living on the edge of Kordavos, guiding travelers, hunting for his own survival, and keeping his distance from the tangled politics of the city.\n\nYet on this night, a message delivered by a red squirrel bearing the unmistakable script of Wollandora, a trusted elven friend and druid, has drawn him from his hidden home. The note was simple and urgent: Meet me at the Old Standing Stones at midnight. The balance of the forest could depend on it.\n\nNow, as midnight approaches, Thalbern moves quietly through the dense undergrowth, guided by memory and instinct. It is dark with almost no moonlight coming through the forest canopy.\n\nSuddenly, the hush of the night is broken by a sharp crack. Something large has just stepped on a branch somewhere off in the distance.",
    "instructions": "A perception check is appropriate if Thalbern investigates (low difficulty with a plus 3 modifier). If successful, he will determine it is a large creature that is approaching quickly. With a high roll (18+), he will determine it is an Owlbear. If combat ensues and Thalbern is below 25% health, Wollandora will intervene. If Thalbern avoids or defeats the Owlbear, or if Wollandora saves him, he proceeds to the Old Standing Stones.",
    "image": "images/settings/realm-of-myr/the-midnight-summons/broken-silence-2.png",
    "transitions": [
      {
        "condition": "If Thalbern successfully uses stealth to evade and proceeds cautiously towards the Standing Stones, go to meeting-at-stones.",
        "encounter": "meeting-at-stones"
      },
      {
        "condition": "If Thalbern fails a perception check, advance to owlbear-confrontation.",
        "encounter": "owlbear-confrontation"
      },
      {
        "condition": "If Thalbern fails any dice roll (including stealth, perception, or any other check), advance to owlbear-confrontation.",
        "encounter": "owlbear-confrontation"
      },
      {
        "condition": "If Thalbern does NOT successfully use stealth to evade, go to owlbear-confrontation.",
        "encounter": "owlbear-confrontation"
      },
      {
        "condition": "If Thalbern does nothing or takes no action, go to owlbear-confrontation.",
        "encounter": "owlbear-confrontation"
      },
      {
        "condition": "If Thalbern has a healthPercent of less than 50%, go to wollandora-intervention.",
        "encounter": "wollandora-intervention"
      }
    ]
  },
  {
    "id": "owlbear-confrontation",
    "title": "Owlbear Confrontation",
    "intro": "From the direction of the sound, a little bit of eye shine glints in the shadows of the tree line. A hulking fifteen foot tall monster with the body of a giant bear and the head of an owl. As it crashes out from the undergrowth, it lets out a guttural squawk, clearly agitated and territorial.",
    "instructions": "The Owlbear will attack. If Thalbern attempts an animal handling check (high difficulty) and succeeds, he can move past the Owlbear. If Thalbern wins initiative and attempts to hide, he can move past the Owlbear if he passes a medium difficulty stealth check. If Thalbern's health drops to a critical level, Wollandora appears and drives off the Owlbear, transitioning to 'wollandora-intervention'. If Thalbern defeats the Owlbear, describe his victory and transition to 'meeting-at-stones'.",
    "image": "images/settings/realm-of-myr/the-midnight-summons/owlbear-confrontation.png",
    "npc": [
      {
        "id": "owlbear",
        "behavior": "Aggressively attacks any perceived threat. Will fight until heavily wounded or driven off.",
        "initialInitiative": 1
      }
    ],
    "transitions": [
      {
        "condition": "Thalbern defeats the Owlbear, manages to evade it, successfully uses Animal Handling to pacify and move past it, or successfully rolls any other way to move past it.",
        "encounter": "meeting-at-stones"
      },
      {
        "condition": "Thalbern is reduced to critical health by the Owlbear.",
        "encounter": "timely-rescue"
      }
    ]
  },
  ...
]

The First Reply

Demo modunda olduğumuzdan, henüz arka tarafta oluşturulan gerçek bir macera yok. Oyuncu ilk yanıt verdiğinde bu gerçekleşir. Her yanıtla, birformatNarrativeActionCevabın dilbilimsel olarak doğru olduğundan emin olmak için AI kullanan üçüncü kişilik bir fonksiyon ve edebi anlatım tarzında iyi çalışmasını sağlamak için diyalog veya başka bir proza ekler.

Formattırma uygulandıktan sonra, cevap bir sunucu eylemine gönderilir. Bu bir demo olduğu için, bu ilk yanıt alındığında veritabanında macera oluşturuyoruz.

Processing Player Responses

veprocessTurnReplyişlevi, S3'ten gelen macera verileri, Convex'ten gelen mevcut dönemi yükler ve belirli karşılaşmayı ve eylemi gerçekleştiren karakterleri tanımlar.

Bu bağlamda, daha sonra eylemin gerçekçi olup olmadığını belirlemek için AI'yi kullanır (çocuğum oyun testlerinde ranger'ın bir nükleer fırlatması vardı) ve eğer öyleyse, bir dikiş rulo mekanik olarak gerekli olup olmadığını (örneğin, bir "Attack Roll" veya bir "Stealth Check"), rulo türü ve zorluğu dahil olmak üzere.

Bunu bir işlev çağrısı ile yapabiliriz, bu durumda yapılandırılmış verilerin iade edilmesini istediğimiz AI'ya belirleyebiliriz.rollRequirementSchema:

import { z } from "zod";

export const rollRequirementSchema = z.union([
  z.object({
    rollType: z.string().describe("The type of roll required, e.g. 'Stealth Check'"),
    difficulty: z.number().describe("The difficulty class (DC) for the roll"),
    modifier: z.number().optional().describe("Bonus or penalty to the roll, e.g. +2 or -1"),
  }),
  z.null()
]);

export type RollRequirement = z.infer<typeof rollRequirementSchema>;

Sonra, ayrıntılı bir prompt ve şemayı gönderen bir fonksiyonumuz var.generateObject:

export async function getRollRequirementForAction(action: string) {
  const prompt = `
Given the following player or NPC action, determine if a dice roll is required for the character to attempt the action. If a roll is required, return a JSON object with "rollType" (choose the most appropriate from the list below) and "difficulty" (a number between 5 and 25). If no roll is required, return the JSON value null (not a string).

Possible roll types:
- Perception Check
- Investigation Check
- Insight Check
- Stealth Check
...

Examples:
Action: "Try to sneak past the guards."
Result: { "rollType": "Stealth Check", "difficulty": 15 }

Action: "Attack the goblin."
Result: { "rollType": "Attack Roll", "difficulty": 12 }

Action: "Try to determine what the sound is."
Result: { "rollType": "Perception Check", "difficulty": 10 }

Action: "Say hello."
Result: null

Now, given the following action, determine the roll requirement.

Action: "${action}"
`;
  try {
    const result = await generateObject({
      schema: rollRequirementSchema,
      prompt,
    });
    if (
      result.object &&
      typeof result.object === "object" &&
      "rollType" in result.object &&
      (result.object.rollType === "null" || result.object.rollType === "none" || result.object.rollType === "")
    ) {
      return null;
    }
    return result.object ?? null;
  } catch (error) {
    throw error;
  }
}

Turn hikayesine oyuncunun yanıtını ekledikten sonra, bir dikiş rulo gerekirse, karakterin durumunu Convex turn verilerinde, cevap verdiğini yansıtmak için güncelleriz, ancak dönüşü tamamlanmadı.Bu güncelleştirme, rulo ayrıntılarını gösteren kullanıcı arayüzüne gerçek zamanlı bir güncelleştirme neden olur ve oyuncunun bir D20 rulo yapmak için bir düğme verir.

Dice Roll needed for Thalbern the Ranger’s Perception Check. Roll a D20

Kullanıcı bir kez girdiğinde, birresolvePlayerRollResultSonuçların görsel görüntülenmesi ile anlatıyı güncelleyen ve sonuçları tarif eden prosa yazan bir sunucu eylemi.

Owlbear Confrontation Turn. The Owlbear rolled a 14 for a successful attack on Thalbern the Ranger

NPC Actions

NPC'lerin yanıt vermesi durumunda, oyuncu olarak benzer bir şablonu takip ediyoruz, ancak bu durumda AI cevap yazacak. Her karşılaşma NPC'lerin motivasyonları hakkında bilgi içerir ve şimdiye kadar macera hikayesinin bağlamıyla birleştirildiğinde, umarım AI iyi bir yanıt üretebilir, sonra kendi dikiş rulo ve sonuç güncellemesi üretebilir.

Training AI to Run RPGs

Eğer hiç bir zaman bir sohbette AI ile bir oyun oturumunu yapmaya çalışmışsanız, ne kadar hızlı bir şekilde kaybolabileceğini biliyorsunuz.

Umuyoruz ki, uygun bağlamı, belirli anahtar talimatları ve yapılandırılmış veri fonksiyon çağrıları sağlarken, keyifli bir deneyim elde edebiliriz.

Kesinlikle bir sürü deneme ve hata, konsol loglama ve prompt tweaking var. Örneğin, AI'nin test sürümlerinden birinde karşılaşma talimatlarını neden takip etmediğini sorduğumda, Cursor sohbetinin bana söylemesi gerekenler şunlardı:

Özetle, LLM, bir karakter algı denetimi başarısız olduğunda geçiş için açık talimatlarını takip etmedi, ancak bu tür bir başarısızlığın ve bu özel senaryo için bir geçiş kuralının açık kanıtı ile sağlanmasına rağmen.

Özetle, LLM, bir karakter algı denetimi başarısız olduğunda geçiş için açık talimatlarını takip etmedi, ancak bu tür bir başarısızlığın ve bu özel senaryo için bir geçiş kuralının açık kanıtı ile sağlanmasına rağmen.

Sanırım AI'nin tam olarak beklenen şeyi yapmadığı tesadüfi eğlencenin bir parçası olabilir.

İşte bir örnekOyun Seanslarından biri.

Bu proje için tam kaynak kodunu görebilirsinizgithub.com/d20adventures.com Hakkında Bilgi

Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks