code logs -> 2018 -> Tue, 20 Nov 2018< code.20181119.log - code.20181121.log >
--- 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
code logs -> 2018 -> Tue, 20 Nov 2018< code.20181119.log - code.20181121.log >

[ Latest log file ]