RFC: Language for spawning objects

Hey, I’d like to provide a more complex system for item spawning. The idea is a domain-specific language which can be specified in JSON, as the current one is, but with more clear semantics. I hope to code this over thanksgiving, but I want to make sure it’s useful before I start, so feedback would be great.

Spawn would still be specified by lists of item+number pairs in JSON, with each list being identified as either a Collection or a Distribution. In a Collection each line item is an independent event–you get back a list of items, each item with a probability equal to the number associated. In a Distribution, it’s a weighted list like the current system–you always get a single item, with higher numbers more likely. Importantly, you can nest them within each other or recurse by replacing items w/ groups and the @ sign (so we can keep groups straight from items).

For example, a dead scientist loot tables might look like this:
{
“id”: “dead_scientist_loot”,
“type”: “collection”,
“items”: [
["@shirt", 100],
["@pants", 100],
[“lab_coat”, 80],
["@bag_of_science", 10"],
[“id_science”, 50"],
["@eyewear", 20],
["@drugs", 20],
[“pda”, 25],
[“watch”, 10],
}, {
“id”: “bag_of_science”
“type”: “collection”,
“items”: [
[“backpack”, 100],
["@science_gear", 100],
["@science_gear", 66],
["@science_gear", 50],
]}, {
“id”: “science_gear”,
“type”: “distribution”,
“items”: [
[“chemistry_kit”, 2],
[“canister_goo”, 1],
["@textbooks", 4],
… long list of potential drops

That table creates a scientist that’s always dressed, has a labcoat 80% of the time, an ID card 50% of the time, etc, and 10% of the item will have a backstuff stuffed full of cool science loot. This is hopefully easier to reason about, but doesn’t make it hard to add new science loot–if it’s a new piece of loot added to science_gear everything will shift around, if it’s added to dead_scientist_loot then every corpse will get it (with some probability).

Ideally I can also get to a full language you can use when specifying a line item, instead of just specifying an item, collection, or distribution, which would let you make specify collections or distributions in a terse way that’s fairly self-explanatory. This would be the order of operations:

returns some quantity of a line item, possibly variable., ("@textbooks#1-3" returns one, two, or three books with equal probability, where each book rolled separately).

  • specifies damage to an item, possibly variable, with values between 0 for reinforced and 5 for tattered/shattered/broken ("tshirt3-4" would give a shredded or tattered shirt, equal chance. @clothes1#5-10 would make a discount rack of ripped clothes)
    ^ upgrades or loads an item (“usp^9mm#15” would return a 9mm gun loaded with 15 9mm rounds. “@rifle^rifle_scope” gives some kind of scoped rifle)
  • returns multiple items (“holster+@handgun” returns a holster plus whatever @handgun returned)
    | selects one item from the list, equal probability ("@shirt+@pants|blouse+skirt|@dress" gives an equal chance of the three outfits)

The operators don’t do much that couldn’t be done with lots and lots of lists, but they should make it easier. For instance, @bag_of_science above can just become a single line item: “backpack+@science_gear#1-3”. Is this approach easy to understand? Are there better symbols to choose for operations, or operations that are necessary but missing? I’m intentionally avoiding parenthesis or custom functions in the first go, though it would be nice to eventually be able to vary the operator order with () or have some terse ways to do common things like fully load something by saying $loaded after the item.

This…looks very promising and the proposal itself’s easy to understand. As a learn-by-reading-code coder, I appreciate both.

Heartily support.

Looks very practical and powerful. I definitely approve.

Looks pretty legible and clear, I like it. Is there a way to define objects for monsters to spawn? I’m thinking of chickens and birds spawning eggs, or maybe kamikaze robots that dash up to you and drop lighted explosives.

Practical and Powerful. I approve.

Inadequate–You can already code monsters to spawn objects, I don’t see a DSL helping much there since it’s straightforward what the generated items will be. The goal here is to try and bring clarity/functionality to really complex spawn results.

Additional notes…

Defaults: Quantity (#) defaults to the stack size or 1. Quality (*) defaults to undamaged. Continue doing what we’re doing now with containers and batteries.

Error Handling: Should just drop things that aren’t recognizable or don’t make sense. “bow^9mm” should just return a bow.

Bootstrapping: There’s a huge amount of existing content, this proposal would leave the current spawning code intact and migrate the individual call points 1-by-1 rather than trying to upheave all spawning at once. The current item_group type is basically a distribution and you can invoke it as such, so the current big lists of items can power both new and old spawn code.

[quote=“Brian Lefler, post:6, topic:4232”]Inadequate–You can already code monsters to spawn objects, I don’t see a DSL helping much there since it’s straightforward what the generated items will be. The goal here is to try and bring clarity/functionality to really complex spawn results.

Additional notes…

Defaults: Quantity (#) defaults to the stack size or 1. Quality (*) defaults to undamaged. Continue doing what we’re doing now with containers and batteries.

Error Handling: Should just drop things that aren’t recognizable or don’t make sense. “bow^9mm” should just return a bow.

Bootstrapping: There’s a huge amount of existing content, this proposal would leave the current spawning code intact and migrate the individual call points 1-by-1 rather than trying to upheave all spawning at once. The current item_group type is basically a distribution and you can invoke it as such, so the current big lists of items can power both new and old spawn code.[/quote]

Backwards compatibility too. Superlative; that was the only major sticking point, aside from your time and effort. I trust it’ll be compatible with the item-spawn slider?

Looking forward to this.

I haven’t looked at how the item-spawn slider is programmed. It’s a value between 0 and 1? I can do the straightforward thing and only keeping items with a probability equal to that setting, so a value of 0.5 would result in half as many useful items and half of the zombies you meet missing their pants? Is that how it currently works?

The slider would only apply to items spawned on the ground.

I can see something like this making generic loot more logical, ie, this zombie ended up with the hobo loot option, it gets only pants and whiskey, this zombie was a biker, it gets all leather clothes, this house was a professors house, it gets lots of skill books and no weaponry, etc.

I like it. Are item IDs guaranteed not to include the control characters though?

in broad strokes I think we need something like this, I’ve been avoiding it, but I don’t think there is going to be a simpler way to get the flexibility and control we want.
My only objection is nesting a custom DSL in the entries. It’s much simpler (if a bit more verbose) to explicitly tag the entries with optional json tags.

Item IDs are lowercase_text_and_num3ra1s only, so far as I know. Just checked and item_groups.json lacks any occurrence of @, #, ^, *, +, or |, so I think control-char conflicts shouldn’t be an issue.

bump

Anyone working on something like this?

Not that I know of, but it sounds really useful.