--- Log opened Tue Nov 20 00:00:22 2018 |
00:31 | | Derakon[AFK] is now known as Derakon |
00:39 | | * ToxicFrog gnaws on this project |
00:40 | <&ToxicFrog> | So, an entity is a miserable pile of components. |
00:41 | <&ToxicFrog> | A component is a state value and a bunch of functions. |
00:41 | <&ToxicFrog> | The issue I'm running into is that there's a bunch of ways you can classify these functions. |
00:41 | <&McMartin> | if (talk.isEnough()) { self.haveAt(thee); } |
00:42 | <&ToxicFrog> | First of all there's the purity level -- functions that are pure (Obstacle/blocks?), functions that modify the component state (Render/set-face!), and functions that modify the game state more broadly (Mobile/move!) |
00:43 | <&ToxicFrog> | And then there's a difference between functions called on a specific component, and messages received by all components on an entity. |
00:43 | <&ToxicFrog> | The latter of which may have to return a value, which is a whole can of worms I've barely even opened. |
00:45 | <&ToxicFrog> | In the lua prototype the approach was just to pass {} to the message handlers and let them mutate it if desired; I guess in clojure I could do the equivalent (each message handler returns a value and that's passed to the next handler) |
00:50 | <&ToxicFrog> | (these messages are used by, e.g., the verbs system, where every component in an entity can contribute different verbs) |
00:52 | <&ToxicFrog> | Hmm. I guess (defmessagehandler) could also define a reducing function. |
00:52 | <&ToxicFrog> | Although then what happens if different components define different reducing functions? Erk. |
00:56 | <&ToxicFrog> | I guess that's not, functionally, much different from the lua version where message handlers could do whatever they wanted to the input. |
00:57 | <&McMartin> | I think I would rethink the idea that it is the caller who gets to decide whether a method goes to one component or the entire object. |
00:57 | <&McMartin> | The traditional solution for this in a non-gaming context would be event handler chains in a gui |
00:58 | <&McMartin> | In other news, woo, new pageview record set for Bumbershoot Software yesterday |
00:58 | <&McMartin> | By a lot |
00:58 | <&McMartin> | But apparently due to One Dude In Italy archive binging |
00:58 | | celmin|away is now known as celticminstrel |
00:59 | <&ToxicFrog> | McMartin: so, component functions are already namespaced by the name of the component, e.g. it's (Obstacle/blocks? ent :sight) rather than just (blocks? ent :sight) |
00:59 | <&ToxicFrog> | This implies a different API for messages, e.g. (send-message ent :verbs) |
01:00 | <&ToxicFrog> | The caller doesn't really choose; the components do and the caller uses the appropriate API. |
01:08 | <&ToxicFrog> | Thinking about it I think from the caller's perspective, we have three distinct categories: |
01:08 | <&ToxicFrog> | - methods tied to a specific component, which may or may not modify the game state |
01:08 | <&ToxicFrog> | - event messages that may be handled by multiple components and will probably modify the game state and return nothing |
01:09 | <&ToxicFrog> | - query messages that may be handled by multiple components, do not modify the game state but are expected to return data from multiple components |
01:14 | | Degi- [Degi@Nightstar-u7h08o.dyn.telefonica.de] has quit [Ping timeout: 121 seconds] |
01:38 | <&McMartin> | Hm |
01:38 | <&McMartin> | I have nothing to say about the first, particularly - presumably you have something like "getComponent" that an entity can reject if it lacks that component |
01:39 | <&McMartin> | Events seem like they should be broadcast to all entities "in range", which again has obvious parallels to UI processing |
01:39 | <&McMartin> | And queries seem like they should be managed by the overall entity itself |
01:40 | <&ToxicFrog> | Attempting to call a component method on an entity lacking that component throws. If you need to conditionally call such a method, every component automatically defines (Foo/? ent) which returns true iff ent contains component Foo. |
01:41 | <&ToxicFrog> | Events are more things like "it is possible that some component(s) in this entity will want to react to this but I don't have a priori knowledge of which ones" |
01:42 | <&McMartin> | Right, for an RTS that would be something like "a unit just moved to this location" and this guard needs to check if that means it can see/hear it |
01:42 | <&ToxicFrog> | E.g. stepping on a tile fires :stepped-on on the player (so that autopickup and effect-on-movement buffs can fire) and then :stepped-on-by on anything remaining the tile (so that traps and teleporters can fire) |
01:43 | <&McMartin> | (For a UI, a mouse just clicked in your drawing area and you need to see if it was on *you* or if it needs to be bubbled down to your children) |
01:43 | <&ToxicFrog> | I'm not sure if area-broadcast events need to be a thing in this but if they do, that would just be querying the map to get every entity in the given area and firing the event on all of them. |
01:45 | <&McMartin> | Right |
01:46 | <&ToxicFrog> | The UI analogy isn't quite the same here because one event can legitimately be handled by multiple components at once, e.g. a :damage-taken event will both reduce HP and potentially activate any when-hit buffs, which are handled by a separate component. |
01:47 | <&McMartin> | This is also true for UIs but I do concede that in this case it is never acceptable to swallow a result as part of a responder chain. |
01:48 | <&McMartin> | You would need some kind of interception system to handle this for something like, say, stealth blocking messages from being sent in the first place |
01:48 | <&McMartin> | Meanwhile, I have an abstraction problem of my own |
01:48 | <&McMartin> | I am writing up an entire (small) GUI application, and I'm working on the sequencing |
01:48 | <&ToxicFrog> | Mechanically, I'm not sure that will ever arise, but yes. |
01:49 | <&McMartin> | I'm starting "bottom up", with the model, and then the widget that displays the data within the model |
01:49 | <&McMartin> | I could keep going "up", to the meta-widget that organizes that widget with some sibling control widgets, and then rising through several glue layers until the top-level event loop is hit |
01:50 | <&McMartin> | But I feel like it might make sense to instead flip over to the "top", set up the event loop and then drill down from there, so that the glue logic is done last. |
01:52 | <&ToxicFrog> | Is this a how-does-the-event-handler-work question or a what-order-do-I-write-these-bits-in question? |
01:52 | <&McMartin> | The latter. |
01:52 | <&McMartin> | The program itself is written; I am now attempting to walk a hypothetical reader through it as a worked example of a technique. |
01:52 | <&ToxicFrog> | Aah. |
01:53 | <&McMartin> | And while I feel like the conventional answer is "start at one end - it doesn't really matter which one, but UNIX guys will generally pick the bottom and Mac guys the top, and work to the other" |
01:53 | <&McMartin> | That means at some point you're setting up a bunch of glue with no obvious referent |
01:54 | <&McMartin> | Which is also reminding me of the adages about Mac guys making applications that are very shiny but functionally a complete shambles |
01:54 | <&McMartin> | And about how Unix guys have a tendency to design a pile of bricks instead of a house |
02:07 | | Kindamoody is now known as Kindamoody[zZz] |
03:30 | | celticminstrel [celticminst@Nightstar-l19e78.dsl.bell.ca] has quit [Ping timeout: 121 seconds] |
04:16 | | celticminstrel [celticminst@Nightstar-l19e78.dsl.bell.ca] has joined #code |
04:16 | | mode/#code [+o celticminstrel] by ChanServ |
04:27 | | macdjord|wurk is now known as macdjord |
04:46 | | himi [sjjf@Nightstar-1kl.41m.141.110.IP] has joined #code |
04:46 | | mode/#code [+o himi] by ChanServ |
04:55 | | celticminstrel is now known as celmin|sleep |
05:22 | | Derakon is now known as Derakon[AFK] |
05:32 | | Emmy [Emmy@Nightstar-9p7hb1.direct-adsl.nl] has joined #code |
08:45 | | Vornicus [Vorn@ServerAdministrator.Nightstar.Net] has joined #code |
08:45 | | mode/#code [+qo Vornicus Vornicus] by ChanServ |
09:21 | | Degi [Degi@Nightstar-s3bc72.dyn.telefonica.de] has joined #code |
09:34 | | Emmy [Emmy@Nightstar-9p7hb1.direct-adsl.nl] has quit [Ping timeout: 121 seconds] |
10:29 | | Degi [Degi@Nightstar-s3bc72.dyn.telefonica.de] has quit [Ping timeout: 121 seconds] |
10:41 | | Kindamoody[zZz] is now known as Kindamoody |
10:42 | | Emmy [Emmy@Nightstar-9p7hb1.direct-adsl.nl] has joined #code |
13:01 | | gnolam_ [lenin@Nightstar-ego6cb.cust.bahnhof.se] has joined #code |
13:01 | | tripflag [ed@Nightstar-7pe1df.clients.your-server.de] has quit [[NS] Quit: ZNC - http://znc.in] |
13:02 | | Tamber [tamber@furryhelix.co.uk] has quit [The TLS connection was non-properly terminated.] |
13:02 | | Tamber [tamber@furryhelix.co.uk] has joined #code |
13:02 | | mode/#code [+o Tamber] by ChanServ |
13:04 | | Kizor [moryok@Nightstar-e0a4sm.utu.fi] has quit [Ping timeout: 121 seconds] |
13:04 | | abudhabi [abudhabi@Nightstar-7nkq9k.de] has quit [Ping timeout: 121 seconds] |
13:05 | | gnolam [lenin@Nightstar-ego6cb.cust.bahnhof.se] has quit [Ping timeout: 121 seconds] |
13:05 | | Kizor [moryok@Nightstar-e0a4sm.utu.fi] has joined #code |
13:06 | | tripflag [ed@Nightstar-7pe1df.clients.your-server.de] has joined #code |
13:08 | | Vorntastic [uid293981@Nightstar-6br85t.irccloud.com] has quit [[NS] Quit: Connection closed for inactivity] |
13:10 | | abudhabi [abudhabi@Nightstar-7nkq9k.de] has joined #code |
13:10 | | mode/#code [+o abudhabi] by ChanServ |
13:56 | | gnolam_ is now known as gnolam |
13:56 | | mode/#code [+o gnolam] by ChanServ |
13:58 | | gnolam [lenin@Nightstar-ego6cb.cust.bahnhof.se] has quit [[NS] Quit: Update] |
14:27 | | gnolam [lenin@Nightstar-ego6cb.cust.bahnhof.se] has joined #code |
14:27 | | mode/#code [+o gnolam] by ChanServ |
16:58 | | Emmy [Emmy@Nightstar-9p7hb1.direct-adsl.nl] has quit [Connection reset by peer] |
16:58 | | Emmy [Emmy@Nightstar-9p7hb1.direct-adsl.nl] has joined #code |
20:28 | | Degi [Degi@Nightstar-s3bc72.dyn.telefonica.de] has joined #code |
21:26 | | Derakon[AFK] is now known as Derakon |
22:15 | | Degi [Degi@Nightstar-s3bc72.dyn.telefonica.de] has quit [Connection closed] |
22:15 | | Degi [Degi@Nightstar-s3bc72.dyn.telefonica.de] has joined #code |
23:16 | | Emmy [Emmy@Nightstar-9p7hb1.direct-adsl.nl] has quit [Connection closed] |
23:31 | | Vornicus [Vorn@ServerAdministrator.Nightstar.Net] has quit [Operation timed out] |
23:32 | | Degi [Degi@Nightstar-s3bc72.dyn.telefonica.de] has quit [Connection closed] |
--- Log closed Wed Nov 21 00:00:24 2018 |