Community

SCI Programming => SCI Community How To's & Tutorials => Topic started by: Cloudee1 on June 02, 2015, 10:54:41 PM

Title: SCI1.1: The joy of Polygons
Post by: Cloudee1 on June 02, 2015, 10:54:41 PM
So I have started playing with the template a bit and I have found that out of the box, white control lines do not block the ego. Instead, polygon areas must be generated. Now I admit that I have only just begun playing with this, so this first example is going to be be very rudimentary. I will add more examples as I have played with it some more, but this should at least get you started.

To begin, we need to use the polygon script. So up towards the top of the script where the other use statements are made, add in:
Code: [Select]
(use "Polygon")

Also for my first successful attempts at using it, I gave my polygon definitions some names. So I created some local variables to represent the polygon areas. Just after the uses, I define my local polygon names.
Code: [Select]
(local
    walkwayTopBoundary
    walkwayBottomBoundary
)

So far so good, the only thing left to do is actually define and init the polygon areas. In the init method of the public room instance I actually defined my polygons. The syntax is really pretty simple.
Code: [Select]
= walkwayBottomBoundary
                        (send (Polygon:new()):
                                              type(2)             // not sure exactly how many types there are
                                              init(
                                                0 157      // x y point of polygon
                                                319 157
                                                319 189
                                                0 189
                                              )
                                              yourself()
                       )           
                      (self:addObstacle(walkwayBottomBoundary))

Basicly the above bit creates a large rectangular area the whole width of the screen and from 157 to the bottom of the screen high. The next bit, creates a second rectangular area of the same width from the top of the screen down to 133.
Code: [Select]
                      = walkwayTopBoundary
                        (send (Polygon:new()):
                          type(2)
                          init(0 0 319 0 319 133 0 133)
                          yourself()
                        )
                      (self:addObstacle(walkwayTopBoundary))

With both of those polygons set up and added, it creates a simple allowable walkway from one edge of the screen to the other.
Title: Re: SCI1.1: The joy of Polygons
Post by: troflip on June 03, 2015, 12:40:28 AM
Cool, nice work. Note that you don't need to use variables for the polygons, you can just add them directly.

I've found that white control lines do block by default though (and they should, the Actor class has illegalBits set to $8000). However, the ego seems to get very easily stuck on control lines, and in general it doesn't look like SCI 1.1 used control lines to control where actors could move. So polygons are what should be used.

Looks like the interpreter has knowledge of the polygons, and I'm assuming the interpreter is responsible for pathfinding with them. In ScummVM, there are these values:

Code: [Select]
POLY_TOTAL_ACCESS = 0,
POLY_NEAREST_ACCESS = 1,
POLY_BARRED_ACCESS = 2,
POLY_CONTAINED_ACCESS = 3

So that should give you an idea of what they do. In one of the polygon writer debug scripts we saw, the following values were used:

Code: [Select]
PNearestAccess
PBarredAccess
PTotalAccess

So I'll go ahead and add those to the sci.sh header file.
Title: Re: SCI1.1: The joy of Polygons
Post by: lskovlun on June 03, 2015, 01:26:29 AM
This page is part of a report that Walter van Niftrik wrote on the polygon system in SCI:
http://wiki.scummvm.org/index.php/SCI/FreeSCI/Pathfinding/Semantics (http://wiki.scummvm.org/index.php/SCI/FreeSCI/Pathfinding/Semantics)
I thought I had the PDF somewhere, but I can't seem to find it.
Title: Re: SCI1.1: The joy of Polygons
Post by: OmerMor on June 03, 2015, 04:18:35 AM
Here is the full report:
https://web.archive.org/web/20110928143142/http://freesci.linuxgames.com/docs/pathfinding-final.pdf
Title: Re: SCI1.1: The joy of Polygons
Post by: waltervn on June 03, 2015, 08:36:38 AM
Here's a quick overview of the four different polygon types. For convenience, I'll describe them in terms of a user moving Ego around with the mouse.

Barred access An area that Ego cannot enter. If the player clicks inside such an area, Ego will move as close as possible to where the user clicked, without entering this barred area. Special care is taken with polygons on screen borders to make sure that Ego won't accidentally leave the room.

Contained access An area that Ego cannot leave. If the player clicks outside of this area, Ego will move as close as possible to where the user clicked, without leaving this contained area.

Total access An area that Ego can freely enter, but should only do so when the user specifically clicks inside it. One example here would be a room with a hole in the ground. As you move Ego around the room, you don't want Ego to accidentally fall down into the hole because the pathfinder's computed path happened to cross it, but you do want Ego to fall down into it when the user actually clicks on the hole.

Nearest access Like total access, with the added restriction that Ego should approach his destination from the nearest border. For example, imagine a room with a pool of water in the middle. Ego can enter this water but when he does, he moves a lot slower. If you're on one side of the pool and click in the water near the other end of the pool, you want Ego to walk to the other end first before entering the water, rather than slowly wade across the whole pool of water starting from this side. If Ego starts his path inside such a polygon, he'll first walk to the nearest border to leave the polygon. This happens even if his destination is also inside that same polygon. This can lead to some strange behavior (you can see this in action in the water of the starting room of KQ5 floppy).
Title: Re: SCI1.1: The joy of Polygons
Post by: troflip on June 03, 2015, 11:40:47 AM
Awesome, that summarizes things very nicely!
Title: Re: SCI1.1: The joy of Polygons
Post by: MusicallyInspired on June 15, 2015, 05:01:54 PM
I'm sorry, troflip, but I cannot get Ego to stop at a Control line even if I fill the space beyond it with the same Control colour. Your template game, for instance, WD-40 just walks over it like it's not even there. This polygon system seems to be much more versatile, but it doesn't seem very intuitive to have to type in coordinates manually for all the areas Ego is allowed and not allow to be in. What are Control lines even used for in SCI1.1 anyway if not to block Ego?
Title: Re: SCI1.1: The joy of Polygons
Post by: troflip on June 15, 2015, 06:01:18 PM
I'm sorry, troflip, but I cannot get Ego to stop at a Control line even if I fill the space beyond it with the same Control colour. Your template game, for instance, WD-40 just walks over it like it's not even there. This polygon system seems to be much more versatile, but it doesn't seem very intuitive to have to type in coordinates manually for all the areas Ego is allowed and not allow to be in. What are Control lines even used for in SCI1.1 anyway if not to block Ego?

SetUpEgo in main sets the illegal bits to 0, and the current version of the template game calls that (the first version didn't, at least on the first screen). So that would explain why it can walk through white control lines without issue.

The control screen is definitely less useful in SCI1.1, but it is still used to have clickable Features (you can associate a Feature with a control color, and clicks on that color will be routed to that Feature). You can also use them for trigger points (e.g. ego walks into a certain area, you can check if he's on a control color and do something).

I'm still trying to figure out the best way to handle creating polygons and pushing them back to the scripts. Any suggestions welcome!

Title: Re: SCI1.1: The joy of Polygons
Post by: Cloudee1 on June 15, 2015, 08:05:47 PM
I have a door, which isn't really a door, and a control line across the front of it. When it closes, I throw in an observeControl and the ego does. When it is open again, I throw in an ignoreControl and the ego does. I had mentioned before that ego ignores the white control lines initially which I am assuming is the same behavior that you are seeing with the WD40 ego. If you throw in the observeControl(ctlWHITE) into the ego init, then ego does ignore the white control lines. However, they are not taken into account for the polygon path finding from what I have seen.

I have had some issues with some polygons not quite reacting the way that I would expect them to, but that has been some pretty complex polygons. My plan was to break them down into simpler ones (less points) and having them overlap to see if that didn't solve my issues.

As for creating polygons, It would almost seem like a fake fourth screen would be needed. Something that you could trace the polygons over... or rather place the point of the polygons. Maybe save those to a picnumber.poly text file. and then... maybe a build for release button that would then take that text file and inject the addObstacle statement into the scripts... nevermind, that is already soundinlg like too much work How about the fourth screen for generating a polygon by placing the points and then in one of the panes on the side, something that could be copy and pasted into the scripts.
Title: Re: SCI1.1: The joy of Polygons
Post by: troflip on June 15, 2015, 08:15:32 PM
I liked Lars' low-tech suggestion of being able to paste lists of numbers into the pic editor (in order to copy polygons from code into the pic editor). And of course from the pic editor you'd be able to generate the code snippet that you could paste back into the script.

Another possibility that is maybe easier for the user is to have sidecar files like I do for messages. These files would contain the polygons for a pic, and you could edit them and they would persist. The pic viewer could contain a list of these polygons, and you could select and modify them or create new ones. The sidecar files would take the form of local variable definitions, which could then be included in script files. That way there is "transport" from code to pic editor and back (with me  having to scan the entire script code looking for things that look like polygons). Basically it would work in a very similar way to message nouns and conditions.

What do you think?

[edit: cloudee posted something similar while I was writing this up, lol]
Title: Re: SCI1.1: The joy of Polygons
Post by: troflip on June 15, 2015, 08:25:43 PM
To expand on my post above, you might have 100.shp, which looks like:

Code: [Select]
// Polygon editor - generated by SCI Companion, do not edit
(local
    RoomBoundary[10] = (152 32 135 117 167 118 158 72 205 26 )
)

And then (you'd need to write this, or the pic editor would be able to put this on the clipboard for you):
Code: [Select]
    (send gRoom:addObstacle
        ((Polygon:new()):
            type(PBarredAccess)
            points(@RoomBoundary)
            yourself()
        )
    )

Take the above syntax with a grain of salt... it's a bit of a mix of the different polygon coding styles I've seen (e.g. QFG2 vs SQ5).
That makes it easy to modify the points of the polygon without needing to edit the script (and I suspect that will be a common thing to want to do).
Title: Re: SCI1.1: The joy of Polygons
Post by: MusicallyInspired on June 16, 2015, 12:36:16 AM
That sounds good. I'm confused about polygon implementation, though. Was this really considered easier? Especially with SCI1.1 backgrounds having more complex walking areas than SCI0 games do. It just seems like so much tedious work to go through to get something working right. Did Sierra maybe have their own Polygon tool? I just don't understand why it's all done in scripts. Seems like backwards thinking.
Title: Re: SCI1.1: The joy of Polygons
Post by: troflip on June 16, 2015, 01:33:27 AM
My guess is that they wanted to implement advanced path-finding algorithms (e.g. that truly avoid obstacles, unlike the SCI0 "avoider"), and these require clearly defined mathematical regions to reason over, not the per-pixel stuff in the pic resources.

I suppose they could have modified the pic resource to support another screen or something (or limited the control screen to just lines?). I don't know if they tried to work this into the pic resources but decided a separate polygon concept was easier.

And yes, clearly they had their own polygon tool. In fact, it's still in most of the games' "debug" scripts. The fact that they maintained and updated it through several iterations of SCI suggests that this was their main tool for generating polygons.
Title: Re: SCI1.1: The joy of Polygons
Post by: troflip on June 17, 2015, 07:02:45 PM
So my plan for implementing polygon editing should make it mostly transparent for the common case.

Just like messages, I'll have a "poly" folder that has matching picnum.shp files for each pic resource.

By default, creating a new room (say room 100) will add this at the top of the script:
Code: [Select]
(include "100.shp")

Also added will be a call to SetUpPolys in the room's init.

The shp file will look something like this:

Code: [Select]
// 110.shp -- Produced by SCI Companion
// This file should only be edited with the SCI Companion polygon editor

(procedure (SetUpPolys)
    (send gRoom:addObstacle(
(Polygon:new()
type(PContainedAccess)
init(93 149 134 120 189 145 148 172 73 174 32 166)
yourself()
)
)
    )
    // more polys here...
)

Having a simple external "read-only" file let's me parse the contents easily, and extract them for editing in the pic editor, and be able to save them back. So all you'll need to do is edit polygons in the pic editor (it will show a list), and save. Then re-compile the corresponding script (this could be made automatic), and you're good to go!

Of course, if you are using the same pic for several different scripts, then this gets a bit more complicated. You'd need to manually include the other header files (which makes me think I should include the resource number in the function name, e.g. "SetUpPolys100", so there aren't conflicts?).

And there may be scenarios where you want to add/remove polygons dynamically from code. I suppose for these you could give them names, and we'd exclude them from SetUpPolysN - instead they'd be instances.
Title: Re: SCI1.1: The joy of Polygons
Post by: MusicallyInspired on June 19, 2015, 03:56:15 PM
I've run into a problem. After painstakingly writing in polygon draw paths from referencing a temporary control line drawing coordinates in the pic editor, I've mapped out a polygon that I want Ego to be contained inside. I gave it the proper type but every time I click outside of it the game locks up. I can still hear sound effects and the mouse moves around but Ego freezes instantly in place and no keyboard or mouse events do anything. The iconbar doesn't even come up. Here's my code:

Code: [Select]
    (method (init)
        (super:init())
        (self:setScript(RoomScript))
        SetUpEgo()
        = walkwayPoly (send (Polygon:new()):
        type(PContainedAccess)
        init(
        /*0 122  //moatFallPoly top
        24 20
        37 118
        70 120
        93 123
        124 122
        129 120
        158 119
        168 120
        199 120
        204 122
        221 123
        251 123
        259 120
        288 120
        299 122
        319 122 */ //moatFallPoly top
        319 98
        254 98
        257 102
        244 102
        221 82
        193 82
        191 78
        187 78
        187 63
        130 63
        130 78
        121 78
        120 81
        97 81
        72 102
        58 102
        63 97
        0 97 //bottom of screen
        0 122
        0 189
        319 98
)
yourself()
)
        = moatFallPoly (send (Polygon:new()):
        type(PTotalAccess)
        init(
        0 121
        24 19
        37 117
        70 119
        93 122
        124 121
        129 119
        158 118
        168 119
        199 119
        204 121
        221 122
        251 122
        259 119
        288 119
        299 121
        319 121
        319 189
        0 189
        0 121
        )
        yourself()
)
(self:addObstacle(walkwayPoly))
(self:addObstacle(moatFallPoly))
        (switch (gPreviousRoomNumber)
        (case west
        (self:
        style(dpOPEN_SCROLL_RIGHT)
)
        (send gEgo:
        posn(10 (send gEgo:y))
        loop(0)
)
)
(case east
(self:
style(dpOPEN_SCROLL_LEFT)
)
(send gEgo:
        posn(310 (send gEgo:y))
        loop(1)
)
)
            (default
            (self:
            style(dpOPEN_PIXELATION)
)
                (send gEgo:
                setScale(Scaler 100 85 75 63) //  theFrontSize theBackSize theFrontY theBackY
                    posn(159 63)
                    loop(2)
                    get(0)
                )
                (gate:
                posn(160 7)
                setStep(2 3)
                setScript(gateScript)
                )
                (gateScript:changeState(1))
            )
        )
        (send gEgo:init())
        (gate:init())
        (brookSound:play())
    )

I'm recreating the KQ1 opening area at the front castle gate. I'm assuming I can have polygons overlapping eachother, right? Either way, that's not the problem. It's when I click on an outside area (above y 63) where there are no polygons that it seizes up.

EDIT: Ok, scratch that. It's not just when I click outside of a polygon. It seems to seize up randomly. Any idea what's causing this?

Ok, maybe the problem WAS the overlapping polygons. I just got rid of the lower one and now it doesn't seize up anymore.

EDIT 2: Bah. Now I'm getting crazy bugs where Ego can randomly walk outside of the polygon area. Maybe my coords aren't matching up. I'll just wait for the polygon editor.
Title: Re: SCI1.1: The joy of Polygons
Post by: troflip on June 19, 2015, 04:05:18 PM
This should get a lot easier when I have the polygon editor working (keep getting distracted).
Title: Re: SCI1.1: The joy of Polygons
Post by: MusicallyInspired on June 19, 2015, 04:12:34 PM
Yeah, Ego is somehow escaping the polygon barriers I've created now so I'll just wait to do them until after. Hard working blind. :)
Title: Re: SCI1.1: The joy of Polygons
Post by: Cloudee1 on June 24, 2015, 11:37:02 PM
So I have come to the conclusion that polygons really aren't as smart as I had anticipated them being.  I have had to resort to also including control lines and instructing ego to observe them in order to truly control the boundaries. I try to place the control lines just inside the polygon areas to let them do their thing if they are going to, but I am finding that they really don't. At least not to the extent that I thought they would.

I need to run a test with one of Sierra's rooms using their points and background and play the original and the template side by side to see if it is just my expectations that are too high.
Title: Re: SCI1.1: The joy of Polygons
Post by: troflip on June 25, 2015, 12:02:26 AM
What are your expectations? What type of polygons are you using, and what do they look like?
Title: Re: SCI1.1: The joy of Polygons
Post by: troflip on June 25, 2015, 12:14:21 AM
Here are the polygons from a couple of rooms from LSL6.

I'd guess the top image has a single contained access polygon, while the lower one (lobby) has three barred access polygons.

What's clear from this is that I need to make it easy to extend polygons to the pic edges.

Also, it looks like only the ego's hot spot is checked against polygon boundaries, not the entire bounds rect like with control lines. So the ego's feet can easily extend into a barred access polygon, for instance.
Title: Re: SCI1.1: The joy of Polygons
Post by: troflip on June 26, 2015, 05:08:12 PM
I'm trying to figure out how I can avoid having to embed the pic number in the method for setting up the default room polygons and create new named polygons. Since I want to also support including multiple polygon header files in one room, and without embedding the pic number in the procedures, there would be name conflicts.

Here's an alternative proposal:

SetUpPolygons and CreateNewPolygon become global functions in main. Instead of taking a define that identifies the polygon, they take the address of a local variable from the script. The local variable would be an array of values that consist of: the number of polygons associated with that variable, followed by the following for each polygon: type, number of points, x/y for each point.

So the *.shp file might look like:

Code: [Select]
(local
    P_110[???] =  (2 PBarredAccess 3 212 68 45 67 47 88 PBarredAccess 5 12 68 269 68 286 85 267 101 225 101)
                  )
    P_SomeName[8] = (1 PBarredAccess 3 212 68 45 67 47 88)
)

Then in the room's init, you'd have:

Code: [Select]
AddPolysToRoom(@P_110)

and to create polygons dynamically (for path motions, or to add around new features that appear after room init:

Code: [Select]
(send gRoom:addObstacle(CreateNewPolygon(@P_SomeName)))

I'm trying to make this as easy as possible to code against, while still being flexible enough to accomplish any task.

Thoughts?
Title: Re: SCI1.1: The joy of Polygons
Post by: Kawa on July 02, 2015, 12:51:42 PM
Okay I gotta be misunderstanding something here.

I got my sample room that I've been working on. It has a Contained polygon outlining the floor and extending a bit into the doorway, and two Barred polygons surrounding the table and lamp. I also have control lines in the doorway like SCI Studio's version has, and white control lines surrounding the floor like the first polygon does. There is, as per default, an AddPolygonsToRoom(@P_Default110) statement, and Ego starts in the middle of the room.

I can't walk through the table or lamp. If I click the wall, Ego walks up to it and stops at the edge. But if I click near (not even in) the doorway, Ego walks over the wall to the nearest point inside the doorway.
Title: Re: SCI1.1: The joy of Polygons
Post by: troflip on July 02, 2015, 01:07:38 PM
Aha! Played around with this. Polygon winding order *does* matter. (I thought I read in the freessci intern polygon spec that it didn't). At least it matters for contained access polygons. Try drawing your contained access polygon with the points going counter clockwise and see if that works for you.

And it looks like barred-access polygons need to go in clockwise order.
Title: Re: SCI1.1: The joy of Polygons
Post by: Kawa on July 02, 2015, 01:33:48 PM
Aha! Played around with this. Polygon winding order *does* matter. (I thought I read in the freessci intern polygon spec that it didn't). At least it matters for contained access polygons. Try drawing your contained access polygon with the points going counter clockwise and see if that works for you.

And it looks like barred-access polygons need to go in clockwise order.
That solved it handily, yeah. Well, I guess you can have your sample room shortly then...