--- Log opened Sun Dec 06 00:00:52 2020 |
00:26 | | Kindamoody is now known as Kindamoody[zZz] |
00:27 | <&ToxicFrog> | Hmm. I think I need to rubber duck a bit about spellcast. |
00:28 | <&ToxicFrog> | The first draft of my spell execution engine is just: all spells are entered into a buffer and sorted by priority; the buffer is processed in order; spells are allowed to modify the buffer, so e.g. Counterspell can be implemented by scanning the buffer for other spells with the same target and replacing their :resolve function. |
00:29 | <&ToxicFrog> | This rapidly gets ugly, though, because take e.g. the various spells blocked by Shield |
00:29 | <&ToxicFrog> | They have different messages (e.g. a missile "shatters on" a shield but a knife "slides off" or "is deflected") |
00:30 | <&ToxicFrog> | So either Shield needs to know appropriate messages for all the spells it can block, or we need a different approach |
00:30 | <&ToxicFrog> | Say, Shield sets a flag on the target and those spells check for that flag; or it sets a flag on the spells themselves and they behave differently based on that. |
00:32 | <&ToxicFrog> | But now it's not clear who is responsible for checking -- lookahead like Counterspell or flagging + lookbehind like Missile. |
00:33 | <&ToxicFrog> | So perhaps the answer is lookbehind everywhere; Counterspell sets a "counter" flag on the target and every spell has a check for that |
00:42 | <&[R]> | Is this supposed to be similar to the MtG stack? |
00:47 | | Shirley is now known as Kizor |
00:57 | <&ToxicFrog> | Not really, no. |
00:57 | < ErikMesoy> | Yes, in that there's finicky resolution rules to be precise about, no, in that this came out before MtG and also it has too much simultaneous resolution and not enough generality to be compared to a stack. |
00:59 | | Kizor is now known as Shirley |
01:00 | <&ToxicFrog> | Anyways. Lookbehind has the advantage that each spell doesn't need to know exactly how all of its interactees react, it just sets the flag and it's up to the later spells to interpret that as they see fit. |
01:00 | <&ToxicFrog> | But then we get into spell-spell interactions that aren't tied to player flags. |
01:02 | <&ToxicFrog> | Some of this is cosmetic -- e.g. if multiple missiles are cast at the same target it should produce a different message than just one. |
01:02 | | Misty is now known as Vornicus |
01:03 | | Shirley is now known as Kizor |
01:03 | <&ToxicFrog> | But some is mechanical -- multiple fire storms don't stack, fire and ice cancel out, storms subsume elementals, dispel magic counters everything on the battlefield, etc |
01:04 | <&ToxicFrog> | It almost feels like multimethods are the way to handle this, define MMs dispatched on [spell, spell] pairs for any such interactions and just have the engine run through all possible interactions after `configure-spells` |
01:04 | <&ToxicFrog> | That's O(n²) but it's a small n. |
01:05 | <&ToxicFrog> | But then things get complicated with: how are the results actually produced? |
01:05 | < ErikMesoy> | Small enough that you can write O(400) which is basically O(1) with a constant, right? ;-) |
01:06 | | Joe is now known as Reiver |
01:06 | <&ToxicFrog> | Hmm. |
01:07 | <~Vornicus> | yeah O(n^2) ain't much if you're working with less than, like, thousands |
01:08 | <&ToxicFrog> | Vornicus: yeah, I just often am working with Large Numbers at work so I have a reflexive aversion to anything with an exponent in it~ |
01:09 | <&ToxicFrog> | Maybe something like: the multimethod is expected to return a seqable of spells. The first one is the current spell and get passed to the next multimethod. The rest get appended to the "holding" spell buffer. |
01:09 | <&ToxicFrog> | When you're done, you have one spell that's been checked for interactions against the entire buffer, and the rest of the buffer; you append the former to the "ready" buffer, then sort the holding buffer, take the next spell from it, and check it against the rest, creating a new holding buffer in the process. |
01:15 | <&ToxicFrog> | So something like [shield, fireball] is identity, [icestorm, fireball] replaces the fireball with a "spells cancel out" message and rethrns [icestorm, cancellation-message], [missile, missile] coalesces them into a single missile with n=2 and returns [missile2] |
01:15 | <&ToxicFrog> | Perhaps this will actually work |
01:15 | <&ToxicFrog> | Some care will be needed not to overwrite earlier effects, e.g. if you have counterspell & 2 missiles on the same target, the output should be something like: |
01:16 | <&ToxicFrog> | - Foo casts Counterspell on Target |
01:16 | <&ToxicFrog> | - Bar casts Magic Missile on Target (x2) |
01:16 | <&ToxicFrog> | - The light of a counterspell flares around Target! |
01:16 | <&ToxicFrog> | - The missiles are erased by the counterspell! |
01:17 | | Vornicus [Vorn@ServerAdministrator.Nightstar.Net] has quit [Connection closed] |
01:21 | <&ToxicFrog> | So, the [missile, missile] interaction that stacks the missiles needs to not overwrite the change that makes it countered. |
01:21 | <&ToxicFrog> | But I think this approach may have promise. |
01:28 | <&ToxicFrog> | Some care will still be needed -- in particular interactions like [counterspell, missile] will need to DTRT whichever one comes first, and if they're processed in priority order that requires knowing what the spell priorities are when writing the multimethods. |
01:28 | <&ToxicFrog> | Possibly the answer is: dispatch arguments need to be in alpha order, dispatch function ensures that at call time, defspell macro ensures that at declaration time. |
01:32 | | Degi_ [Degi@Nightstar-gge8km.dyn.telefonica.de] has joined #code |
01:32 | | Degi [Degi@Nightstar-k6d7bp.pool.telefonica.de] has quit [Operation timed out] |
01:32 | | Degi_ is now known as Degi |
01:36 | <&ToxicFrog> | This of course means I now need to rethink how spell execution works. |
01:37 | <&ToxicFrog> | select-spells and configure-spells remain the same. |
01:37 | <&ToxicFrog> | then I think execute-spells gets split into two phases: |
01:38 | <&ToxicFrog> | - invoke-spells prints the "X casts Y (with the H hand) at Z" messages and does the interaction checks; this doesn't have to happen in any particular order as long as the interaction checks themselves are commutative |
01:38 | <&ToxicFrog> | the output is then a collection of spell resolution effects, which probably does not map 1:1 to actual spells cast |
01:39 | <&ToxicFrog> | - resolve-spells then sorts these effects (I think with this design they'll be correct regardless, but I don't want things like "the missile shatters on your shield" printing before "a magical shield forms around you") |
01:40 | <&ToxicFrog> | and then executes them in the sorted order. |
01:42 | <&ToxicFrog> | Stuff like monster and elemental attacks are implemented as "pseudo-spells"; each entity (and status effect! this is how stuff like poison and circle of protection will be implemented) can attach handlers to different game phases, so probably at the end of select-spells, e.g., each summoned monster inserts a pseudo-spell into the queue with a targeting option that will be picked up by |
01:42 | <&ToxicFrog> | configure-spells |
01:42 | <&ToxicFrog> | And these can then define their own interaction multimethods for things like shields, elemental/storm interactions |
01:43 | <&ToxicFrog> | This does mean that I will have to handle both ["summon elemental", "ice storm"] and ["elemental attack pseudospell", "ice storm"], for example |
01:43 | <&ToxicFrog> | but I think that's not a serious problem |
02:58 | <&ToxicFrog> | Leaving some notes on how zarfcast does it here, in case that's an approach I want to borrow from: each player has, in effect, a map indexed by spell ID (the zaplist). After spell selection and configuration, there's some special-case handling of metamagic (counterspell, dispel magic, magic mirror, etc). |
02:59 | <&ToxicFrog> | After that, it basically goes through most of the spells and increments the map values |
02:59 | <&ToxicFrog> | Then once all that is done, foreach player, it looks through the zaplist |
02:59 | <&ToxicFrog> | Any entry in the zaplist that's >=1 gets spell execution, checking other zaplist values for interactions like shielding, fire/ice, etc |
03:01 | <&ToxicFrog> | So the zaplist is basically "what spells actually landed on this target after metamagic is taken into account", and then each spell is responsible for checking the other zaplist entries to see if there are interactions it needs to care about. |
03:03 | <&ToxicFrog> | Looks like storm/elemental cancelling is also checked for outside the normal spell implementation functions. |
03:20 | | catalyst [catalyst@Nightstar-gfecpo.dab.02.net] has joined #code |
03:23 | | catalyst_ [catalyst@Nightstar-lfm95l.dab.02.net] has quit [Ping timeout: 121 seconds] |
03:24 | | VirusJTG_ [VirusJTG@Nightstar-42s.jso.104.208.IP] has joined #code |
03:25 | | VirusJTG_ [VirusJTG@Nightstar-42s.jso.104.208.IP] has quit [Connection closed] |
03:25 | | VirusJTG_ [VirusJTG@Nightstar-42s.jso.104.208.IP] has joined #code |
03:27 | | VirusJTG [VirusJTG@Nightstar-42s.jso.104.208.IP] has quit [Ping timeout: 121 seconds] |
03:27 | | VirusJTG_ [VirusJTG@Nightstar-42s.jso.104.208.IP] has quit [[NS] Quit: Leaving] |
03:28 | | VirusJTG [VirusJTG@Nightstar-42s.jso.104.208.IP] has joined #code |
03:28 | | mode/#code [+ao VirusJTG VirusJTG] by ChanServ |
04:19 | | KiMo|autorejoin [Kindamoody@Nightstar-eubaqc.tbcn.telia.com] has joined #code |
04:19 | | mode/#code [+o KiMo|autorejoin] by ChanServ |
04:21 | | Kindamoody[zZz] [Kindamoody@Nightstar-eubaqc.tbcn.telia.com] has quit [Ping timeout: 121 seconds] |
04:55 | | VirusJTG [VirusJTG@Nightstar-42s.jso.104.208.IP] has quit [Connection closed] |
04:56 | | VirusJTG [VirusJTG@Nightstar-42s.jso.104.208.IP] has joined #code |
04:56 | | mode/#code [+ao VirusJTG VirusJTG] by ChanServ |
05:03 | | Vorntastic [uid293981@Nightstar-h2b233.irccloud.com] has joined #code |
05:03 | | mode/#code [+qo Vorntastic Vorntastic] by ChanServ |
05:31 | | VirusJTG [VirusJTG@Nightstar-42s.jso.104.208.IP] has quit [Connection reset by peer] |
05:32 | | VirusJTG [VirusJTG@Nightstar-42s.jso.104.208.IP] has joined #code |
05:32 | | mode/#code [+ao VirusJTG VirusJTG] by ChanServ |
05:32 | | VirusJTG [VirusJTG@Nightstar-42s.jso.104.208.IP] has quit [Connection closed] |
05:33 | | VirusJTG [VirusJTG@Nightstar-42s.jso.104.208.IP] has joined #code |
05:33 | | mode/#code [+ao VirusJTG VirusJTG] by ChanServ |
08:16 | | celticminstrel [celticminst@Nightstar-26ueug.dsl.bell.ca] has quit [[NS] Quit: And lo! The computer falls into a deep sleep, to awake again some other day!] |
09:50 | | catalyst_ [catalyst@Nightstar-gl6vts.dab.02.net] has joined #code |
09:52 | | catalyst [catalyst@Nightstar-gfecpo.dab.02.net] has quit [Ping timeout: 121 seconds] |
09:58 | | KiMo|autorejoin is now known as Kindamoody |
10:10 | | Kindamoody is now known as Kindamoody|afk |
10:53 | | FLHerne [flh@Nightstar-6tv.748.10.86.IP] has joined #code |
11:12 | | Emmy [Emmy@Nightstar-l49opt.fixed.kpn.net] has joined #code |
12:21 | | FLHerne [flh@Nightstar-6tv.748.10.86.IP] has quit [[NS] Quit: There's a real world out here!] |
13:33 | | M-E [Emmy@Nightstar-l49opt.fixed.kpn.net] has joined #code |
13:36 | | Emmy [Emmy@Nightstar-l49opt.fixed.kpn.net] has quit [Ping timeout: 121 seconds] |
13:38 | | catalyst_ is now known as catalyst |
13:42 | | Kindamoody|afk is now known as Kindamoody |
14:05 | <@abudhabi> | Hmmmm. |
14:06 | <@abudhabi> | What do you call a sort of cumulative average? |
14:07 | <@abudhabi> | I mean, "at day x, the average change of f(x) from day 0 was y". |
14:08 | <@abudhabi> | That's some kind of derivative, right? |
14:08 | <@abudhabi> | Because for each x the value you get is (f(x)-f(0))/x. |
14:31 | < ErikMesoy> | Average rate? |
14:46 | <~Vorntastic> | Annualized might be the thing you're looking for |
14:46 | | Vornicus [Vorn@ServerAdministrator.Nightstar.Net] has joined #code |
14:46 | | mode/#code [+qo Vornicus Vornicus] by ChanServ |
16:20 | | catalyst_ [catalyst@Nightstar-eji0dr.dab.02.net] has joined #code |
16:23 | | catalyst [catalyst@Nightstar-gl6vts.dab.02.net] has quit [Ping timeout: 121 seconds] |
16:52 | | Vorntastic [uid293981@Nightstar-h2b233.irccloud.com] has quit [[NS] Quit: Connection closed for inactivity] |
19:38 | | celticminstrel [celticminst@Nightstar-26ueug.dsl.bell.ca] has joined #code |
19:38 | | mode/#code [+o celticminstrel] by ChanServ |
20:51 | | himi [sjjf@Nightstar-v37cpe.internode.on.net] has quit [Ping timeout: 121 seconds] |
22:54 | | catalyst_ [catalyst@Nightstar-eji0dr.dab.02.net] has quit [Ping timeout: 121 seconds] |
22:55 | | catalyst [catalyst@Nightstar-1m8o7n.dab.02.net] has joined #code |
23:18 | | himi [sjjf@Nightstar-1drtbs.anu.edu.au] has joined #code |
23:18 | | mode/#code [+o himi] by ChanServ |
23:22 | | M-E [Emmy@Nightstar-l49opt.fixed.kpn.net] has quit [Ping timeout: 121 seconds] |
23:37 | | Kindamoody is now known as Kindamoody[zZz] |
--- Log closed Mon Dec 07 00:00:53 2020 |