In response to Fartmonger
I love the discussion we have going here.

Should be moved to design philosophy though :)

Edit:

If I was a lesser man I would make a joke out of:
Mob - Can I enter you?
Turf - No.
Mob - Guess I should turn around.
In response to K'ros Trikare
K'ros Trikare wrote:
I love the discussion we have going here.

I like thinking about these principals too... helps keep it fresh in me noggin'

Should be moved to design philosophy though :)

Well it did start out as a how-to question, it just got de-railed incredibly :P

Edit:

If I was a lesser man I would make a joke out of:
Mob - Can I enter you?Turf - No.Mob - Guess I should turn around.


That counts as a joke ¬_¬

PS: I edited my last post with more thoughts.
In response to Fartmonger
Fartmonger wrote:

Edit (more rambling):
On the topic of 'why should the mob try to move to the barrier and get rejected, when it can just decide not to try it'

Consider a game where there are three types of turfs. One normal type, where anyone can enter. One type where only one mob can stand at a time. And one turf where people can only enter if it contains a magic item:

Scenario #1 - Mob decides which barriers to test:

Mob looks at Turf, wondering 'Are you a normal turf?'
Turf is not a normal turf.
Mob looks at Turf, wondering, 'Oh well are you a one-person-at-a-time turf, and is there somebody standing on you?'
Turf is not a one-person-at-a-time turf.
Mob looks at Turf... (well you can see what I'm getting at.)

Scenario #2 - Mob uses the Enter() Interface so it only has to ask one question:

Mob: Can I enter you?
Turf considers its current state and decides whether Mob can enter
Turf: No.
Mob: Oh better record that I've tried you and try somewhere else.

In scenario #1, adding extra conditions that may prevent a mob from entering a turf will involve editing the mob's AI as well as adding the actual turf.

In scenario #2, adding extra conditions will just involve adding an extra turf that can answer the question 'Can I enter you?' The mob doesn't need to know why it's being blocked, just that it has not been allowed.

I may be getting out of my depth here but, I see where you're going with this.

Maybe we could agree that it depends on the design and scope of the game. Didn't we say that using such a small scale example (3 different turf types is pretty small scale, in my opinion) changes how we look at the implementation of such a system?

If we have a much wider scope, and are grouping the different types of turfs correctly, then I still think the way Kaioken and myself have been arguing would be cleaner, if not more efficient.

Which is good, I think. There should never be any universal constants when it comes to this stuff. We should be willing to take a second glance and redesign if it becomes more efficient after a change.

I'd throw in some pseudo code or an example explaining what I mean here but I don't think I have a concrete enough of an example. :)

In response to K'ros Trikare
It may not matter which way you do it in a small project. But I feel it's important to strive for exstensible code which is written once.
In response to Fartmonger
Fartmonger wrote:
Efficiency isn't really the issue here as far as I can see.
Clarity of code and coupling between the mob and turf is where I see the problem.

Not so much. Much more importantly, the 2 methods have distinctly separate results; each functions differently. It's not like the result is the same and the difference is simply where you have the code placed.

Suppose a bug develops somewhere in the NPC's AI. If there are fragments of the NPC's AI in the turf code you now have to check two places.

This ain't really that much of a problem, though. Suppose you simply have the turf/Enter() code in the same file as the AI, maybe even directly underneath the AI() proc. Then you no longer need to check 2 places. :P
In response to Kaioken
Kaioken wrote:
Not so much. Much more importantly, the 2 methods have distinctly separate results; each functions differently. It's not like the result is the same and the difference is simply where you have the code placed.

The result of calling Enter() on a turf and checking CanIEnter(Turf) (for example) are the same.


You're missing it, though, it's not only preference. The 2 results are inherently different. If you don't alter your AI logic and simply override Enter(), your AI logic will attempt to move even to restricted locations, and will think it succeeds in movement but in fact the Move() call will fail, and it will keep attempting to move because it doesn't account for the restricted area.

mob/proc/bleh(/turf/T)
if(!Move(T)) //will call Enter() on the turf *before allowing the move*
bleh(randomTurf())//move failed, try a new square
src<<"You moved to T!"


I don't understand why you think overriding Enter() will make the mob think it has moved successfully. If Move() or Enter() return 0 then you know the move was not allowed. This is the same as checking if the move was valid and then calling Move() afterwards. In fact it could be said to be more efficient since it takes one procedure call instead of two. It also takes advantage of the interface specified in the DM reference and reduces coupling.

Suppose a bug develops somewhere in the NPC's AI. If there are fragments of the NPC's AI in the turf code you now have to check two places.

This ain't really that much of a problem, though. Suppose you simply have the turf/Enter() code in the same file as the AI, maybe even directly underneath the AI() proc. Then you no longer need to check 2 places. :P

This is an example of file coupling (I think :S). And is also poor Object Oriented design. I know DM allows you to spread an object definition across multiple files, but this does not mean it is good design.

The main issue I have with your design is that the flow of control is not clear. If the mob both selects destination tiles and decides if it's allows to go into them it's doing the work of two objects. In my design:

mob - responsible for selecting a tile, and attempting to move to it. If this move fails, record the failure (recursive backtracking in a pathfinding algorithm maybe) and try a new tile.

turf - responsible for deciding if a mob is allowed to move to it or not.

Edit

I think you're misunderstanding what enter does. Enter is called before the mob is moved to the turf's contents.

If it returns 1, the mob will be moved from its old turf to a new one. If it returns 0 the mob will not be moved.

Enter provides a place for the turf to decide who gets in.

http://www.byond.com/docs/ref/info.html#/atom/proc/Enter

Furthermore, Enter() is defined at the atom level. This means that if you later design objects that allow mobs to enter them (vehicles or something maybe, I dunno) you can adapt your AI to it much easier.
Page: 1 2