Just a warning that this is a very, very, very large tutorial. In fact it's turned in to a 6,300 word, 17 paged monstrosity. It's designed to teach you Bedrock from the ground up and there are tons of things to cover. I highly recommend you do the first few spoilers. Some of the latter ones are things that not everyone needs to know or you might not need to know right now. Once you've got the basic idea you can simple pick the ones you want to read. I wouldn't skim read the first sections, they contain a lot of information about how Bedrock works, which is vital to understanding how to make your programs.
I haven't quite covered everything yet, I haven't be able to write some really advanced topics (custom objects, custom windows, scroll views, etc) due to time constraints. But I will add them soon. Some of the spoilers didn't want to do what they were supposed to either, so some formatting is a little off.
Getting Started
Before you start coding there are a few things you should do.First, make sure that HTTP is enabled on whatever emulator/version you are using. You can install it by copying and pasting the file off GitHub, but this method is far easier.
Second, ensure that you are happy with your editor. While using the built in edit will suffice, I recommend you use an external editor such as Sublime Text. If you must code in-game use a program such as LuaIDE. It will save you a lot of pain.
Finally, if you run in to any issues. Double check you haven't just made a silly mistake. Check in the common errors spoiler and see if your problem is one of those. If you are pretty sure it's a bit more complicated then create an Ask a Pro topic, do not PM me. I say this for two reasons, one, it'll probably consume a lot of my time if I'm getting 10 PMs a day asking for help, two, if it's publicly accessible others might be able to find the solution to their problem without having to ask anyone. Just a note on this: I will try to answer most of these, but if you see one and you think you know the answer please do reply, even if it might be wrong.
Let's get going!
The first thing you'll want to do it start a fresh computer and make a file for your program, I recommend calling it startup to save having to type it in a hundred times, but it doesn't matter.
You'll now want to enter this code:
local bedrockPath='/' if OneOS then OneOS.LoadAPI('/System/API/Bedrock.lua', false)elseif fs.exists(bedrockPath..'/Bedrock')then os.loadAPI(bedrockPath..'/Bedrock')else if http then print('Downloading Bedrock...')local h=http.get('http://pastebin.com/raw.php?i=0MgKNqpN')if h then local f=fs.open(bedrockPath..'/Bedrock','w')f.write(h.readAll())f.close()h.close()os.loadAPI(bedrockPath..'/Bedrock')else error('Failed to download Bedrock. Is your internet working?') end else error('This program needs to download Bedrock to work. Please enable HTTP.') end end if Bedrock then Bedrock.BasePath = bedrockPath Bedrock.ProgramPath = shell.getRunningProgram() end
local program = Bedrock:Initialise()
program:Run(function()
end)
Every time you make a Bedrock program all you essentially need to do is paste this code and run it. If it's not already installed it will download Bedrock, so you don't need to worry about that.
Let's look at next line. When you start your program you assign a variable, which can be called anything, but I personally call it ‘program', to the return value of Bedrock:Initialise() This loads all the APIs and makes a copy for your program. You only ever need to call this once at the top of your program. Lots of Bedrock functions use a colon ( : ) rather than a fullstop. The colon gives the function the thing that called it as well as the other arguments. See the below example for an example.
--high five the person
person:HighFive('left')
--this calls
function HighFive(receiver, hand)
--high five receiver with your left/right hand
end
If you run in to a problem when calling a function, especially if you get an ‘attempt to index' error, chances are you forgot to use a colon.
Now, the next line starts the program. In a normal program you have a while true do loop, that loop is within that function. As a result any code after program:Run will never be called, remember that! But what happens if you want to do something after the program starts, such as set a label's text? Well, fortunately there's quite a simple solution. Simple pass a function as an argument (which can either be written somewhere else and passed as a variable or as I have above. The code in the function will be called once all the buttons, etc. are on-screen and ready to be played with.
Note: You can not access any objects (buttons, labels, etc) before calling program:Run, so all code that changes them at startup must be called within the function given to program:Run
So, there you have it. A basic Bedrock program. If you try and run it chances are you'll get an error saying it can't find a view, but we'll get to that in the next section.
Views (Basics)
Views, simply put, are like screens or windows. Each view has it's own objects on it. You can have as many or as little views as you like. However, you must have, at the very least, one. If you think about the iPhone's (and many other's) Settings app there are a number of views. The first view you see is the list of the various categories. When you click on the category button you are brought in to another view with a separate collection of objects on it. Once you get your head around what a view is, using them will be a lot easier.Bedrock has a special file system that programs need to use. You now need to make a folder called ‘Views'. Note: For many ComputerCraft installations this is case sensitive, so make sure you use a capital V.
In the future I hope to make a program which allows you do make views using a drop and drop interface, similar to Xcode's Interface Builder. However, if you're reading this then chances are I haven't.
By default, if it exists, Bedrock will load a view called ‘main', so to keep things simple create a new file called ‘main.view' in the Views folder and open it. View files use the textutils.serialize format which is pretty much the same format as making a table in Lua, so there aren't any fancy things you need to do really.
If you've done everything correctly your computers files should look like this:
Here is a basic view file, copy this in for now.
{
Children={
{
X=2,
Y=2,
Name="HelloLabel",
Type="Label",
Text="Hello! I'm a Label!"
},
{
X=2,
Y=4,
Name="HelloButton",
Type="Button",
Text="Hello! I'm a Button!"
}
},
BackgroundColour='white'
}
If you don't understand how Lua tables work I recommend you look for a quick explanation elsewhere, but they're fairly easy to pick up.
You'll see that the entire file is a table. In the one above there are two values of the main table, the BackgroundColour and the Children (or the objects in the view). The BackgroundColour is, obviously, the background colour of the view, not really any explanation needed. However, do note that the value (in this case, red) can either be the name of the colour (so basically just remove the ‘colours.' e.g. colours.lightBlue would be lightBlue, these are case sensitive) or the colours number (what you get when typing in colours.*** in the Lua prompt). When getting the BackgroundColour from an object (which we'll do later) it will always return the number, not a string if you gave it one.
Note: As I live in a place where ‘colour' is the correct spelling I use it over ‘color'. However, due to some metatable wizardry I've managed to make it so you can use either colour or color, so it's entirely up to you. Essentially, what it does is when ever you get or set a value with ‘Color' in the key name it will replace ‘Color' with ‘Colour'. So, technically there is only one value, but it acts as if there are two separate (yet always equal) values.
I'll also point out that when using Bedrock you can also use colours/colors.transparent, the label we have is transparent by default. This means that if we change the background colour of the view, or anything behind it, it will take that colour. The numerical value for transparent is 0.
Let's try running our program now. If you've done everything correctly you should now see something like this:
Buttons, Labels and Other Basics
All objects (which, as stated before, are things on the screen such as buttons. I'll always call the objects.) have default values. For example, the default text colour for a button is light grey. So you don't have to set every value. If you want to know what properties a certain object has, the best way is to either visit the Wiki (if I've made it the link will be at the top of the post) or look at the object's code on GitHub, so for example, https://github.com/o...ects/Button.luaNote: It's not a good idea to try and look at the code that is downloaded as the API. That file has all the files squished in to one and is minified. In other words, it's really hard to read. Just visit the GitHub repo, it'll save you a lot of pain. Do be aware, however, that the file that all objects are based off (their parent class) is actually in the API folder (Object.lua)
The type of an object is set using the Type value, to view the different types of objects you can use see the Objects folder in the GitHub repo.
Let's try changing the background and text colour of our button, pick and colours you like, just don't make them the same colour. See if you can figure it out on your own, but if you're having issues I've put the solution in the spoiler below.
Spoiler
Open main.view and add the following two lines under ‘Text="Hello! I'm a Button!"':
BackgroundColour='blue',
TextColour='white',
Make sure you have commas after each value.
Run your program and your button should have changed colours!
Extra
Note: I'll put extras in from time to time that have things that, while not vital, may be useful to know.
Spoiler
If you click a button you'll notice that by default it will change colour momentarily. These colours are ActiveBackgroundColour and ActiveTextColour.You can also make a button toggle. Like an on/off switch. The on off buttons on the OneOS Settings program use this.
To do this add the follow to your button:
Toggle=false,
The boolean is the starting value. Every time someone clicks the button this will toggle.To set the on/off colours simple set Background/TextColour for the off state and ActiveBackground/TextColour for the on state.
You'll notice that we didn't actually set the width or height of the label or button, yet it's sized correctly. In terms of height, 1 is the default for all views. But buttons and labels have a value called AutoWidth. What it does is when ever it's text changes it will automatically resize the object to the required size. However, if you want to choose the size of your button/label on your own you simple need to add the following values to your object.
Width=10,
Now, in the case of labels something interesting happens if you make the width smaller than it's content. So to see this, add Width = 10 to the label (you may want to set the button's Y value to 6 or higher).
If you did it correctly you should now see that the label's text wraps. Pretty cool, eh?
Another thing you can do with both buttons and labels is make the text align to the left, center or right. Now, with AutoWidth on you won't actually see it do anything, but lets look at another very thing you can do with Bedrock so we can.
In the past when you've tried to make something the width/height of the screen you've probably used term.getSize and set the width through that. It's clunky, needs code, and, too be frank, gets annoying. Fortunately Bedrock provides a snazzy way to do this, and if you've used CSS before you'll fell right at home.
In the case of making our Label the width of the screen we simple do:
Width="100%",
Remember that when doing this you need to put it as a string, not just a number.Ta da! It's the width of the screen. You can also use this for the X & Y position, and naturally the Height, on any object that supports custom sizing (most do). This means that you can do something like:
X="10%",
Width="80%",
This will give the text a 10% margin either side.
But what if, rather than a percentage margin you wanted a fixed width margin. Well, you can.
X=5,
Width="100%,-10",
By simply adding a comma you can put a number, positive or negative, to alter the result. So, this would result in the label with a 5 pixel margin either side.I use these frequently throughout OneOS, a good example of their use would be the First Setup program. https://github.com/o...p.program/Views
Now, back to our label centring. Once we've set the width to "100%" we can align the text using: (yes I know I'm using the American spelling)
Align="Center",
You can also use "Left" and "Right". By default Labels use Left and Buttons use Center. If you've done it correctly you should see something like this:
Getting and Setting Values With Code
It's all good being able to set values statically using view files, but sometimes you just want to be able to get/set them using code.Before we do this, take a quick look at your view file. You'll notice that each object actually has a name value. In the case of the Button it's Name="HelloButton". The name is used to get the button in code, rather than using a variable. You'll see it used very soon, it makes your code a lot easier read and write.
Note: In terms of naming, you can call your objects anything. You should always set a name though, even if you don't access it in code. You should try to make the name descriptive though, that way in your code you know what object your using. I personally have a few words describing it and then the object type, so for example, ComputerNameTextBox. But really, it's up to you.
Open up your main code file (the one the program:Run). At the moment the function given to program:Run should be empty. But lets add some code to it now. We want to set the label's text to something else.
program:Run(function()
program:GetObject('HelloLabel').Text = 'That was easy!'
end)
Remember to make sure the code is within (or called at some point by) the program:Run function, it won't work anywhere else.Notice the use of the colon ( : ) here, were making the instance of Bedrock that is our program get the object with the name ‘HelloLabel'. If you were using variables to do this previously then this would basically be the same as your variable. You can now get and set values for your object. In this case we set the text, but you can set anything. Try changing the background colour. Hint: it's very similar to what we did earlier with the button.
If you're having trouble look in the spoiler.
Spoiler
program:Run(function()
program:GetObject('HelloLabel').Text = 'That was easy!'
program:GetObject('HelloLabel').BackgroundColour = colours.lightBlue
end)
You may be asking yourself, "What if there are two or more objects with the same name?". Well, you should only do that in certain circumstances. The main one being when you have a number of almost identical objects that you want to be able to access all easily. For example, in the OneOS Settings program the colour buttons all have the same name. If I had separate names it'd require me to have special code for each button. However, if there is more than one object with the same name it will only return the first one it finds. It won't change all of them. For information about how to do this see the extra below.
Extra
Spoiler
It's not very complicated really. There's a function called GetObjects which returns a table of all the objects with that name. Here's an example.
for i, v in ipairs(program:GetObjects('HelloLabel')) do
--v is the same as program:GetObject('HelloLabel')
v.Text = 'That was easy!'
end
Getting a value is very easy too. In this case we're setting text of the label to the text of the button.
program:Run(function()
program:GetObject('HelloLabel').Text = program:GetObject('HelloButton').Text
end)
Object Events (Clicking Buttons)
At the moment we have a button, but it's not actually doing anything when we click it yet.Objects have a number of different events such as being clicked, loaded, having a key press, etc. However, most of them are handled internally so there are only two you'll have to deal with really. OnClick and OnChange. OnChange is only used by TextBoxes, so really there's only one you'll use often. There's also OnDrag and OnScroll, but you probably won't need to use them.
If you've used LÖVE2D before it's a fairly similar way of handling events.
First we get our button using GetObject, we then set OnClick to a function which will get fired each time it's clicked. If you want to can define this function else where and use the function name instead.
program:Run(function()
program:GetObject('HelloButton').OnClick = function(self, event, side, x, y)
end
end)
You'll notice that the function has a few different arguments given to it. The first, self, is the button. It basically saves you having to do GetObject again. It also means you can use the same function for multiple buttons and know what button to change. The remaining values are values from the event. As I'm sure you're familiar with, doing os.pullEvent() will return the event and a few values. In all functions in Bedrock that give something from a pullEvent the arrangement will be the same; self, event, arg1, etc. In our function side is which mouse button you used (1 for left, 2 for right, 3 for middle). The x and y values are the position where the mouse was clicked. However, these values are relative to the button. In other words, if you clicked the top left of your button, no matter where it is, x and y will both be 0. An example of this being used in OneOS is the bar at the top of the screen with the program names. Each program is just a single button. There is not ‘x' button, when the program is active I add a ‘x ‘ to the text. When you click on the button and the x value is 2 (where the ‘x') is it closes the program.So, let's make our button do something. Within the function lets set our label's text to something. See if you can do it yourself. If you can't take a look in the spoiler below.
Spoiler
program:Run(function()
program:GetObject('HelloButton').OnClick = function(self, event, side, x, y)
program:GetObject('HelloLabel').Text = 'That was easy!'
end
end)
And that's about it for buttons. See how easy Bedrock is? Previously you would've had to spend ages writing your own APIs and messing around with hit detection then telling it and the label to draw, now you only need a single function for a button.
I previously mentioned that there are OnDrag and OnScroll events. I'm not going to write anything more about them really, but their use it very similar. If you want to use them just play around for a bit. I will point out that for scrolling there are dedicated Scroll, List and CollectionViews if your wanting for things like the Files icon scrolling, but they're a more advanced topic (there's probably a spoiler about them below).
Alert Windows
One common task that you might want to do is make an alert windows. These are the windows that tell or ask your something, for example, a window like this:Previously due to the reasonable difficulty of such a task you may have either been unable to do such a think or spent hours, even days, trying to get something like this working. Yet again, Bedrock makes this very easy. In this example we'll be opening it when the user clicks a button, but you could do it any time after program:Run has been called.
program:Run(function()
program:GetObject('HelloButton').OnClick = function(self, event, side, x, y)
program:DisplayAlertWindow(title, text, buttons, callback)
end
end)
These are the arguments you pass to the function, the title is show on the grey bar at the top of the window and the text is the message shown above the buttons. If the title is too long it will be cut off, so it should only be a few words. The text is wrapped automatically and should be more descriptive, but avoid making it too long, it will start to look a bit messy. The next argument, buttons is a table of the buttons shown. You can actually leave this blank, if you do a red close button will appear next to the title. The final argument is a function callback which passes the text of the button clicked. Here's an example:
program:Run(function()
program:GetObject('HelloButton').OnClick = function(self, event, side, x, y)
program:DisplayAlertWindow('Are you sure?', 'Are you sure you want to destroy everything?', {'Yes', 'No'}, function(value)
if value == 'Yes' then
--destroy everything
end
end)
end
end)
There is no set limit on the amount of buttons, but avoid having more than three. They might become cut off or make the window confusing.
Note: In all Bedrock views and windows the content is clipped, as it does in real OSs. This means that if, for example, your window is say 10 pixels wide but you have a button in the window that is 15 pixels wide you'll only be able to see 10 pixels of it.
So yea, that's about it. The buttons in the table are kinda backwards in terms of their order, but it's fairly straightforward.
Extra
Spoiler
If you try to click outside of a window the window will flash and nothing will happen. If you want to close the window for some reason in code (for example, a timeout) you can do something like this: (this uses a function which will be covered next)
program:Run(function()
program:GetObject('HelloButton').OnClick = function(self, event, side, x, y)
program:DisplayAlertWindow('Are you sure?', 'Are you sure you want to destroy everything?', {'Yes', 'No'}, function(value)
if value == 'Yes' then
--destroy everything
end
end)
--this code runs just after the window is shown, it does not wait for the window to close
program:StartTimer(function()
if program.Window then --program.Window is the current window, you should also use an if because the user might have closed the window
program.Window:Close()
end
end, 1) -- the 1 is the length of the time in seconds
end
end)
Timers
In the past if you've ever wanted a delay before something happens or want something to happen every X seconds you've either needed to use sleeps, which cause your entire interface to freeze, or a painful if statement. Bedrock puts an end to this with two (well kinda three) easy functions.The first will run the function given after the time given. If you've used JavaScript before this is almost identical to the setTimeout function.
program:StartTimer(function()end, 1)
The first argument is the function to be run, you can either do it inline like above or give it the name of another function. The second argument is the time in seconds until it should be run. That's it!The second function will do a function every X seconds. This is very similar to JavaScript's setInterval function.
program:StartRepeatingTimer(function()end, 1)
The arguments are the same as above, except this time it will happen again and again.Extra
Spoiler
The repeating function can actually take the time value as a function, this is useful if you want to modify the interval at some point. Simple give it a function that returns a number. Do note that the new interval will only take effect once the timer starts again.Custom Event Handling
Spoiler
Some times you need to do something when an event, such as the peripheral attaching event, happens.There is a simple function for this. This works by adding a function to a list of functions to be called when a certain event is fired. This means that you can register the same event more than once, although I don't really know why you would, but it does mean you can get raw key and click events that haven't been tampered with.
program:RegisterEvent('peripheral', function(self, event, side)end)
You can actually do this before program:Run as long as it's after Bedrock:Initialise.As mentioned before, most Bedrock event functions also include self. In this case self is the same as ‘program'. For more information about these see the Object Events section.
An example of this being used is in Files, when you attach/disconnect a peripheral it will refresh the peripherals list.
Add and Removing Objects (Using Code)
Spoiler
By this stage you're able to have objects in your program using view files, but what if you wanted to add or remove an object part way through your program?There are two easy functions to do such things.
To remove you simple use the code below.
program:RemoveObject(‘HelloButton')
The function takes one argument, the name of the button.Extra
Spoiler
If you have multiple objects with the same name there is a function which will remove every object with that name.
program:RemoveObjects(‘HelloButton')
It's virtually identical but has an 's' on the end.Now, adding objects is a little more complicated.
program:AddObject({
Y=8,
X=2,
Name="GoodbyeButton",
Type="Button",
Text="Goodbye"
})
As you see, there is only one argument, a table. You could copy and paste the table from a view and they would work in either. You can basically do anything you would do in a view file. Remember to set a name! If you don't it will default to the type, so if I left out the name in the example above the name would be ‘Button'Menus
Spoiler
I'm sure you've wanted to add a menu to your program at some point. Unfortunately they can be a really b*tch to get working and looking decent. Bedrock allows you to easily display a menu with, yet again, a single function. They behave identical to the OneOS menus (well, OneOS uses Bedrock menus, that's why), once open if you click anywhere else it will close the menu but not trigger anything else.Unfortunately, menus are a little harder to do than most other things, although it's still exponentially easier than most doing it on your own.
There are two main ways to load what shows on the menu I recommend you use the first method as it's cleaner and uses less code, but pick whatever suits you.
First Way
This method involves making another view file, so create a new file in your Views folder. I call my menu views something like ‘optionsmenu' but it doesn't really matter, just make it clear. Also make sure the view file has the .view extension.
The easiest way to show a menu is to attach it to a button click, as I have below.
program:GetObject('HelloButton').OnClick = function(self, event, side, x, y)
if self:ToggleMenu('optionsmenu', x, y) then
end
end
You'll notice that the button is actually calling ToggleMenu. What happens is, when you click the button if you haven't already got another menu open it will open it, otherwise it will close the old one. You'll also notice that there is an if statement. The function returns true if the menu was opened, which means that your menu buttons are showing, but at this stage won't do anything. There are also x and y coordinates given, while not needed the menu will appear where you clicked, as apposed to just next to the button.
First though lets create the file which says what the menu has on it. If you haven't already, create a file called ‘optionsmenu.view' (or whatever you want to call it) in your Views folder (place it next to main.view).
You're then going to want to put this text in to it:
{
Type="Menu",
Children={
{
Name="ViewModeMenuItem",
Type="Button",
Text="List View"
},
{
Name="HiddenFilesMenuItem",
Type="Button",
Text="Show Hidden"
}
}
}
This format should by now look fairly familiar. It's the same format you use for views, child objects and the AddObject function. However, Type must always be ‘Menu'. You also need a table called Children which will have the menu items in it. You do not and should not set the size or position of any menu child, however, you should set Name, Type and Text. I've just copied this example from the options menu in Files, so the menu items aren't really anything specific. In terms of naming convention, yet again it's up to you, but I personally have a few descriptive words and ‘MenuItem' at the end.Let's look at the code to make these menu items do something. Within the if statement we wrote before you'll want to add a few lines such as the ones below which set the OnClick value of each menu button.
program:GetObject('HelloButton').OnClick = function(self, event, side, x, y)
if self:ToggleMenu('optionsmenu', x, y) then
if listMode then
program:GetObject('ViewModeMenuItem').Text = 'Icon View'
end
program:GetObject('ViewModeMenuItem').OnClick = function()
--Do the related stuff
end
program:GetObject('HiddenFilesMenuItem').OnClick = function()
--Do the related stuff
end
end
end
Note: Notice that I am still using program:GetObject, not self or any menu value. If you want to you can use program.Menu instead, but it's not necessary. However, this is why having unique names are so important, if you have something else called ‘ViewMode' then you'll end up with quite a nasty bug.
Now, the reason I'm using this example is because the menu items' text actually changes based on the settings (I have removed the if statement for the other menu item purely to keep the code shorter for the example).
You may have seen in OneOS that the menus also have separators (grey horizontal lines) between some items. It's very easy to add a separator, simply paste this between two menu items and it should work.
{
["Type"]="Separator"
},
Second Way
I previously said that there are two ways to load menu content. This way is pretty much identical to the first way except rather than loading the menu items from a file you simply copy and paste the table from the file (or just use the same format) and replace the menu name with the table. For example:
if self:ToggleMenu({
Type="Menu",
Children={
{
Name="ViewModeMenuItem",
Type="Button",
Text="List View"
},
{
["Type"]="Separator"
},
{
Name="HiddenFilesMenuItem",
Type="Button",
Text="Show Hidden"
}
},
}, x, y) then
This way can get quite messy. However, the biggest advantage is that you can easily change the menu content dynamically. As a bonus you can also include the OnClick function as a table value.
Text Boxes
Text boxes are an essential part of many programs. However, due to the difficulty to code them people often use read(), which isn't ideal. With Bedrock you can easily make text boxes that the user can interact with as they would with a text box on their real computer.You'll want to add a text box to your view or use AddObject. See if you can do it yourself as it is something you'll need to do a lot. I have put an example in the spoiler below, however.
Spoiler
{
X=2,
Y=2,
Width=15,
Type="TextBox",
Name="SearchTextBox",
Placeholder="Search...",
Active=true
}
You will also notice that I've got Active set to true. This automatically selects the text box so the user doesn't have to click on it first.
To get text from a text box use the same way we used with labels and buttons previously.
If you want do so something each time the user presses a key, such as instantly update the search you can use the OnChange event. Similar to OnClick this will fire each time a key is clicked.
program:GetObject('SearchTextBox').OnChange = function(self, event, keychar)
--update the search
search(self.Text) --you'd obviously have to define search() elsewhere
end
The event may either by key or char, so key char will either be a number or string. In most cases you won't need to know what thi" chara…" is so you can just use self.Text.Image View
Spoiler
Image views allow you to easily display an image in your program. It is important to note that the images must be NFT format, which can be created using Sketch or NPaintPro. Files made in paint will not work (although I might look in to adding support for paint files).There are three values you need to set in the objects table. The width, height and path of the image. If you do not set the size of the image it will only be 1 x 1 pixel. The path the image should just be a string, such as "/Images/myimage". I create a folder called ‘Images' to put my images in, but it's up to personal preference.
Thanks for trying out Bedrock. It might take a bit of getting used to, but I think you'll find it very useful. As mentioned at the top, I haven't quite finished, but those tutorials will come soon.
At this stage Bedrock is in beta. I'll try to avoid future updates that break things, but I don't really see myself changing much really. Bedrock is a culmination of PearOS, OneOS 1-1.1 and my work in Cocoa. It's pretty much my ultimate GUI API.
Anyway, please give any feedback about Bedrock itself on the topic in APIs & Utilities. This topic is strictly for tutorials/documentation.
A final reminder. I ask that if you have any issues you just can't solve you either post here, or if it's a large problem create an Ask a Pro topic. It's probably also a good idea to PM me with a link to the topic, as I don't really look in Ask a Pro very much and mightn't see it. It just makes the answers public and easy to find.
Enjoy!