Design choices

After using Reeborg's World for a while or reading the world creation API documentation, you might be puzzled as to some design choices I have made. In this appendix, I attempt to explain the reasoning behind some choices I made.

Visual design

My work on early prototypes of Reeborg's World started before the "flat css style" became popular. As a designer once told me, the site looks a bit "dated" with the styling choices I have made. I do recognize this, but I not consider making any kind of style changes a high priority.

The site has not been designed as a "responsive" one. To be able to use the site effectively, I believe that users need a screen size larger than that available on some small devices.

I have decided to adopt a single color scheme for code styling. To distinguish between code that can be edited, and code that cannot be edited, the background of the latter is striped; I did not receive much feedback as to whether the visual effect was useful in helping students identify what could could be edited.

Striped background: read only
Image 9.11.1 - Striped background: read only
Solid background: can be edited
Image 9.11.2 - Solid background: can be edited

Mobile devices are not supported

Other than some minor css adjustments I have made to support some tablets, I have no plans to support mobile devices. In my opinion, there is a minimum screen size required to be able to effectively use Reeborg's World. The User Interface would have to be completely redesigned in order to accommodate "small" devices, and it is not something I am interested in doing as it would limit my freedom to make changes to the UI (something I frequently do, in small increments).

Anyone who wants to change the UI to support mobile devices is most welcome to fork the code repository, create their own version and host it on their own site.

Silencing some errors

One of my frustrations when writing JavaScript code is that often, especially if using third-party libraries, errors/exceptions being raised are silenced and/or their cause is nearly impossible to track down. One of my most frustrating experiences occurred when, in an earlier version, I use a function argument named watch as part of the "watch variables" capability. Shortly after introducing this, a user contacted me to tell me that the site was not working with Firefox. Finding out why was not exactly obvious...

When it comes to dealing with errors/exceptions, usually, I much prefer the norm in Python where errors/exceptions have to be dealt with explicitly by the user. However, from my own experience in working with the API for creating worlds, I found that dealing with certain types of errors normally generated by the API brings very little clarity and much frustration. Inspired by the Zen of Python:

...
Errors should never pass silently.
Unless explicitly silenced.
...

I have decided that, for worlds created using the API, some errors should be always silenced, while others should be silenced depending on context; however, in all cases, this should be done in a way that would be consistent with the user's expectations. The errors that are silenced are based on the following scenario:

  • A user creates a world with some code in the Onload editor to add artefacts in the world, and saves this world (either in the browser's local storage or on a file).
  • At a later time, the user selects this world without being in world editing mode, planning to use this world as a basis for creating a new one. At this stage, code in the Onload editor is being executed and artefacts are added.
  • The user edits the world and saves it. This world now contains artefacts already created and code to create artefacts. Some artefacts (walls for example) cannot be added if they are already present; attempting to do so will result in an error being raised.
  • Much puzzlement when this world is later selected and an error is raised since the code in the Onload editor appears to be completely consistent with the world's content as visually displayed.

I explain below how I treat each category of artefact when such a "problem" is encountered.

Bridges

Attempting to add a bridge where one already exists (even if it is the same type) will raise an error except if this is done from the Onload editor, in which case a message will simply be logged in the browser's console.

Decorative objects

Decorative objects are of no consequence for the behaviour of a program. If one tries to add a second decorative object of a given type (for example, a tulip) at a given location, the request will be silently ignored, whether this is done from code in the Onload editor or elsewhere. Note that this could result in an error later if one attempts to remove a given type of decorative object twice at the same location.

Objects

By "objects", I mean those that Reeborg can take() and put(). Depending on whether or not the optional argument attribute options.replace has been set to true, adding an object via

RUR.add_object('name', x, y, options)

will normally result in either adding to the total number of objects present (if replace==True) or in having the existing number of objects being replaced by the specified value of options.number (with a default of 1). For code in the Onload editor, it is assumed that replaced==True by default (it makes no sense to repeatedly add objects in the Onload editor since no individual frame is recorded and only the final result is shown to the student as the initial world).

Obstacles

Multiple obstacles can exist at a given location. However, attempting to add a named obstacle where one already exists with the same name will raise an error except if this is done from the Onload editor, in which case a message will simply be logged in the browser's console.

Overlays

raise NotImplementedError

Overlays do not exist yet. When they do, they should be handled somewhat similarly to decorative objects.

Pushables

Pushables are dealt with in a similar way to Bridges.

Walls

Walls are dealt with in a similar way to Bridges.

Background tiles

No error needs to be silenced for Background tiles when a new one is added. However, for the sake of completeness, I add a few details about their behaviour.

There can only be one background tile per location. Rather than requiring to first remove an existing background tile, and then add a new one, when a new one is to be added using

RUR.add_background_tile("name", x, y)

it simply replaces any pre-existing tile at that location. To help prevent typos, if "name" is not recognized as a valid artefact, an error is raised. However, one can also create uniformly colored tiles to used as a background tile: any color notation recognized by JS/HTML is available for this. This is done using

RUR.add_colored_tile("color", x, y)

Again, this replaces any pre-existing tile; however, this time "color" must not be a known artefact otherwise an error will be raised.

To fill the entire background tiles with a single type we use

RUR.fill_background("type", x, y)

where "type" can be either a known artefact or a color: no check is performed.

Note: if the "color" is not recognized as valid by JS/HTML, it will be painted black.

Editor content cannot be changed when using Blockly

To be explained

Why have both obstacles and background tiles?

While both obstacles and background tiles can be "fatal", having both enables a world creator to combine images and make the world more visually appealing. For example, we can have fire or fences as obstacles on an otherwise harmless grass background. The alternative would be, for example, to combine fire and grass, or various fences and grass into a single image to be used as a fatal element. Such an approach could lead to an exponentially growing number of images having to be created.

results matching ""

    No results matching ""