CSS sanity checks

What do you want to see in Armagetron soon? Any new feature ideas? Let's ponder these ground breaking ideas...
User avatar
Z-Man
God & Project Admin
Posts: 11589
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

CSS sanity checks

Post by Z-Man »

Split from http://forums.armagetronad.net/viewtopic.php?t=18248:

Just to make it clear, I'm not opposed to using full CSS and libcroco, I just want to make sure it's the right choice.

First, units are nice, but does it support custom units? For maps and other game data, the real world units don't really work for us,
because we support map scaling.

Ok, one use case:

Ed wants to make a maze map where the player only sees the portion of the maze he currently is in. Therefore, he defines all of his walls as "opaque" and disables the HUD map on the clients by giving the map the "nomap" property.

Will that be possible with CSS, WITHOUT giving the user a way to circumvent it by, say, giving the used wall class a different height or a partially transparent texture in his user.css file? Provided we add checksums to resources, of course, so the user can't just edit the downloaded map file :) Perhaps by putting the properties directly into the map file, which would kind of defeat the purpose of CSS?

Another concern is whether the simple property -> value mapping CSS provides is enough for most our customizations. It doesn't have to be enough for all of them, the value can always be a reference to something more complicated, but if that is required for every second property that will actually be used, that's one level of indirection more that necessary.

Last concern: Is user customization on that level really something that will be useful in the long term? Right now, for example, wall texture coordinates are autogenerated and walls are always simple, upright rectangles. So you can effectively change the look of a wall by only switching the texture. That is likely to change, however. Artistic mappers will soon demand to be able to select texture coordinates themselves (giving us a nasty problem with map scaling as well), and to give the walls more interesting geometry (slanting them, giving the upper edge a slope, attaching decorative geometry objects like alcoves). And don't get me started about the can of worms of gameplay on arbitrary 3d shapes :) Will we still be able to let the user customize all of that, and if yes, will the users actually be able to handle it? AFAIK, no other game of sufficient visual complexity (that excludes tile based games like freeciv) lets the user control the appearance of a map independently of the map itself, apart from the detail level, the mapper is in full control of the visuals and the gameplay. Don't get me wrong there: if we really pull it off to keep looks and gameplay separate, that would be awesome. If we could have N maps and M "moviepacks" and get N x M combinations of them that all look good, I'd be happy. But to get there, we need to define RIGHT NOW which map properties are visual only and which aren't (or apologize later for breaking a subset of the moviepacks), and these decisions matter. For example, if we say that wall height is visual only, then that excludes jumping as a future gameplay element, because you should be able to jump over a low wall, but not a tall one. And we need to have a way that the user can't accidentally override gameplay relevant map features.
User avatar
wrtlprnft
Reverse Outside Corner Grinder
Posts: 1679
Joined: Wed Jan 04, 2006 4:42 am
Location: 0x08048000
Contact:

Re: CSS sanity checks

Post by wrtlprnft »

Z-Man wrote:First, units are nice, but does it support custom units? For maps and other game data, the real world units don't really work for us,
because we support map scaling.
As i said in the other thread (before noticing this one), it's not possible without changing libcroco. If we just limit ourselves to percentages and ems and stuff like that I'd say we're going to be fine. It actually has support for frequencies and times (sound engine!), so most things should be covered. If we're going to bundle our own version we can change it, I doubt it would be all that difficult as libcroco doesn't do any actual logic with the units.
Ok, one use case:

Ed wants to make a maze map where the player only sees the portion of the maze he currently is in. Therefore, he defines all of his walls as "opaque" and disables the HUD map on the clients by giving the map the "nomap" property.

Will that be possible with CSS, WITHOUT giving the user a way to circumvent it by, say, giving the used wall class a different height or a partially transparent texture in his user.css file? Provided we add checksums to resources, of course, so the user can't just edit the downloaded map file :) Perhaps by putting the properties directly into the map file, which would kind of defeat the purpose of CSS?
Maybe a special FORBID_EX_IMPORTANT to forbid the use of !important in user CSS files (we could accomplish that by parsing the CSS file first and removing all !important flags in memory)? That way the server would have a way to have the final word about some property.
Another concern is whether the simple property -> value mapping CSS provides is enough for most our customizations. It doesn't have to be enough for all of them, the value can always be a reference to something more complicated, but if that is required for every second property that will actually be used, that's one level of indirection more that necessary.
Well, we have the function syntax, which can do a lot, albeit it might not always be the most beatiful thing. There's also the @font-face syntax (dunno if libcroco supports that), which we could extend for that.
Last concern: …
If something starts to have an effect of physics we'd have to add that to the map, anyways, where it would override any CSS rule.

For user configurability I simply suggest we have a default UA stylesheet (=moviepack) that uses textures from one single dir, for simple customisation they could then just replace those textures. Anything more compilcated always required editing text files.
There's no place like ::1
User avatar
Lucifer
Project Developer
Posts: 8645
Joined: Sun Aug 15, 2004 3:32 pm
Location: Republic of Texas
Contact:

Post by Lucifer »

Um, css isn't quite "simple name=>value pairing". Consider this:

Code: Select all

Wall {
   height: 8em;
   border: 1px neon-blue solid;
}

.zone {
   height: infinite;
   line-style: solid;  /* not the dashed zones we have now */
}

.zone Wall {
   border: 1px neon-red solid;
   height: 20em;
}
So first I defined a wall, and you see there's three values for border there. Then I defined a zone. Then I defined a Wall that appears inside a zone.

Between classes, identities, and elements, css files are extremely flexible. I've attached a css file I'm working on for my accounting program so you can see more. That css file is for qt4.3.

As for designing the map specification, I agree with you that we need to do it, I disagree with the urgency and priority I'm getting from your post. HTML started without css and got quite far, and the transition to CSS was largely smooth (except for the browsers still now supporting the whole standard). Qt' CSS is really nice, and they more or less plunged right in themselves. It debuted in Qt4.1 and has been through some interesting revisions. At the end of the day, you can skin the entire application of arbitrary complexity with css. So I'm not *that* worried about us screwing up and putting display elements in the resource xml files and then having to fix it later, that's just growing pains. ;)

Edit: I went ahead and attached a much larger xml file that contains a much more complex definition. This one's actually uglier than the first. If you want to see these, you have to run my accountant program.
Attachments
widgets2.css.not.zip
(4.25 KiB) Downloaded 357 times
widgets.css.not.zip
(1.29 KiB) Downloaded 535 times
Image

Be the devil's own, Lucifer's my name.
- Iron Maiden
User avatar
Z-Man
God & Project Admin
Posts: 11589
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Post by Z-Man »

Lucifer wrote:Um, css isn't quite "simple name=>value pairing".
Well, yeah, but that's only how the CSS library fetches the value :) To us, in the end, we'll still just have the array of names and values for every map element, and my main concern was that the values themselves are too limiting. But with the function syntax, we should be able to go a long way for complicated cases.

About the units: well, it's already in some comments in the source that the basic length unit in the game is the meter. We could go with that, and for maps, simply say that you give the map dimensions at size level 0. Maybe we should define one pixel as one meter at any map size level.

For textures and walls, we need the different units: we need walls that scale up with the level (in case somebody wants to make a cube that is always a cube no matter at what size) and textures that scale up (for things like the flower power sumo moviepack, which would also need to scale up with the map.

About both your "we can fix things later" attitude: well, it is certainly true that we can always change things later, but what we end up with may be that there are no purely visual attributes left. Think about 3d shooters. Have you seen one where you can simply skin the walls? I haven't, and the reason is that the map, its geometry and textures form a unit that cannot be easily altered. Take glTron, which now supports maps imported from 3d design programs with arbitrary geometry and lets you drive on the flat bits (at height 0, I think). Result: because the textures would scale awkwardly, maps there now have a fixed size. What I'm getting at here is that if our maps get sufficiently complex in structure, there will be nothing left for CSS to customize, and the whole system would get meaningless. So it only makes sense to even start to think about CSS for maps (for cockpits, that's a different thing) after we decided that there always will be enough visual style to separate from the functionality of the map.

That's not a problem, really ;) It's a decision I'm willing to make in favor for the separation. The simple reason being that we need the dedicated server to stay as undemanding as possible, and for that, the game logic needs to work with basic data, and not the 10k poly mesh of some graphics thing somebody slapped onto the map. As far as I'm concerned, gameplay should always consist of 2d elements on a surface (not necessarily flat), and how they are represented in 3d above or below should not matter.

So yeah, you destroyed my concerns. I'm still not sure about whether the particular library choice is the right one, but if we use C++-friendly wrappers anyway, we may as well give it a shot.
User avatar
dlh
Formerly That OS X Guy
Posts: 2035
Joined: Fri Jan 02, 2004 12:05 am
Contact:

Post by dlh »

Another option would be to use Lua (and drop ruby), and create a small binding to the libxml2 xpath functions, so we'd be able to do something like:

Code: Select all

resource:find("//Wall"):style({
    height = 8,
    border = border(1, "neon-blue", "solid")
})

resource:find("//[@class='zone']"):style({
   height = math.huge,
   line-style = "solid"
})

resource:find("//Wall[@class='zone']"):style({
    border = border(1, "neon-red", "solid"),
    height = 20
})
Currently boost is a dependency on trunk, so we could use luabind to create the wrappers. We could also use swig so release sources wouldn't have another dependency.
User avatar
Lucifer
Project Developer
Posts: 8645
Joined: Sun Aug 15, 2004 3:32 pm
Location: Republic of Texas
Contact:

Post by Lucifer »

I forgot to address the texture positioning thing.

That problem is partly solved already in web pages. The units em, %, and there's another one that starts with e that I've forgotten, can all be used as screen coordinates too. So you can place an image precisely, yet relatively. % doesn't really work well as a coordinate, but em and en are units of length relative to the current font. So 1em of NY Times 12pt is a different length than 1em of Times New Roman. Theoretically. In practice, I think web browsers implement some standard length of unit for em that is still somewhat font dependent.

Then in background images, you're given several other options. x-repeat, y-repeat, no-repeat, etc.

So, what we need then is some unit that is derived from the current map size factor. Then we need to be able to rescale textures accordingly, or something like that. I realize there are optimal texture sizes to consider here. It may make more sense when scaling down to instead scale everything else up and do some camera tricks. :) I don't know, but my point is if we ignore optimal texture sizes, we can have the user specify texture sizes relative to the current map size factor, positions relative to those, and then we take the actual texture and scale it. Then apply as normal.

I'm sure there are many other issues there, I'm just trying to make the easy connection between how this same problem is solved in the 2d web page and extend it to 3d. There are no doubt more problems that come with scaling.

Apparently I've been reading too much Republican news, now I'm full of faith and belief, in particular that we can successfully separate the game logic and the game presentation. :)

Edit: Oh yeah, I'm not trying to have a "we can fix things later" attitude. :) I'm just certain we'll not find all the issues too early. What I think we need is to get it out to people to find all the issues for us. You know, size it up.

Edit2: Grr, why doesn't it show the thread in a frame when you hit edit, but it does when you hit reply?

Anyway, I'm perfectly ok if we have problems really scaling the maps and css in maps. In the end, we can consider solutions like "If size_factor < 1 use <this.css> else use <thisother.css>". The UI, the cockpit, the sound engine, all will benefit from having css available. Also, if we ever manage to make scriptable widgets, having css will help to tell the client how to render them. Same with server-controlled widgets (particularly server-controlled widgets from scripts).

And I totally share your concerns about libcroco. Maybe we ought to use libcroco for a quick and dirty implementation we can put in 0.3.1, make sure to mark it as highly experimental and tell people we will break css compatibility in 0.3.2, but we need their feedback on how the system should look. So we toss out the lowest hanging fruit in 0.3.1, get our active modding community to mod the hell out of it and tell us in detail every place we screwed up. Then we have a pretty good handle on the size of the problem and can talk real design. Of course, we'll want our active modding community to help hammer out the design. :) Then we make the call on whether to continue with libcroco, or plug in our own css parser.
Image

Be the devil's own, Lucifer's my name.
- Iron Maiden
User avatar
Z-Man
God & Project Admin
Posts: 11589
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Post by Z-Man »

Oh, sorry, I forgot to agree to the plan of first building something with croco to see what we can do with the general concept, then exploring our other possibilities.

I've had a look at luabind. It's nice and easy to use (as far as I can tell) and seems well though out. The code size overhead however lies around 10 kilobytes per wrapped function signature, which is quite hefty, and it does not support templates directly, you have to bind them instance by instance. It does give us the override of C++ virtual functions in Lua, and Lua is one of the most widely used scripting languages for games, so it can't be totally shitty. We should keep it in our list of choices, but /me is off finishing clio :)
User avatar
Z-Man
God & Project Admin
Posts: 11589
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Post by Z-Man »

Hey, why haven't we done this yet? :) The libcroco stuff, I mean. Luke has this generic property storage thing implemented, and we could store the properties from libcroco there, too, so the code actually using them doesn't need to care whether they come from the xml file or the css style.
Luke-Jr
Dr Z Level
Posts: 2246
Joined: Sun Mar 20, 2005 4:03 pm
Location: IM: luke@dashjr.org

Post by Luke-Jr »

Earlier, I was pondering making a real Pac-Man style game with Armagetron. I realised that it would need some method of defining the "dash" zone behaviour once and creating a lot of clones. This could be done with CSS, provided CSS controls physics and game logic too. But that doesn't stretch to name=>value stuff. :/

Any ideas? :)
User avatar
Z-Man
God & Project Admin
Posts: 11589
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Post by Z-Man »

A template system would be the perfect fit for this:

Code: Select all

<template name="dash">
  (define stuff normally here, centered at 0,0. Arbitrary geometry allowed)
</template>
And later

Code: Select all

<inserttemplate name="dash" x="10" y="10" />
<inserttemplate name="dash" x="30" y="10" />
<inserttemplate name="dash" x="50" y="10" />
...
This would also simplify symmetric maps if rotation is supported (which should be easy).

Also, I no longer see a reason to be anal in our code about the game logic/visuals stuff :) There are cases where it makes sense to override physics in the server controlled CSS file (you really like a map, but would like all zones to be double their usual size) and cases where it would be cruel to force all visuals into CSS (a patchwork map where every wall looks different).
User avatar
wrtlprnft
Reverse Outside Corner Grinder
Posts: 1679
Joined: Wed Jan 04, 2006 4:42 am
Location: 0x08048000
Contact:

Post by wrtlprnft »

We could do it like SVG, where you can define (almost) everything in both plain attributes and CSS.

By the way, a template system not unlike the one z-man described is already in place in the cockpit.
There's no place like ::1
Luke-Jr
Dr Z Level
Posts: 2246
Joined: Sun Mar 20, 2005 4:03 pm
Location: IM: luke@dashjr.org

Post by Luke-Jr »

wrtlprnft wrote:By the way, a template system not unlike the one z-man described is already in place in the cockpit.
Is it cockpit-specific, or can we easily extend it to resources in general?
User avatar
wrtlprnft
Reverse Outside Corner Grinder
Posts: 1679
Joined: Wed Jan 04, 2006 4:42 am
Location: 0x08048000
Contact:

Post by wrtlprnft »

It's pretty specific to the cockpit system, but it's not really rocket science. All it really does is act as if the contents of the <WidgetTemplate> tag were inside the widget itself.
There's no place like ::1
Luke-Jr
Dr Z Level
Posts: 2246
Joined: Sun Mar 20, 2005 4:03 pm
Location: IM: luke@dashjr.org

Post by Luke-Jr »

Something tells me we should use gParserState for the "modifiers"-- but not sure how that will work with autodetecting attribute types. Any suggestions?
User avatar
Z-Man
God & Project Admin
Posts: 11589
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Post by Z-Man »

Yeah, that was what I was thinking :) How does it detect the storage types now?
Post Reply