Download

New Loom Feature: Stack Traces in Release Build

Howdy, Loomers!

We believe that one of the best ways to make a product better, is to use it. As such, we use Loom in personal projects as well as client work, some people call this ‘eating your own dogfood’ or other such things… we just think it’s common sense.

Today’s we introduced an improvement around stack traces. We’ve had stack traces for a long time in debug builds, but they are disabled for release builds. Unfortunately, the public builds of Loom are all built in release mode… meaning that most Loom users have never seen stack traces in their script errors!

In fact, most of the time all you see is something like this:

1
[error] Assert failed [..\..\..\loom\script\native\core\system\lmObject.cpp@154] (type): error getting type in Object._as

That’s not very helpful. Why did it happen? How did it happen? And - WHERE did it happen? There really aren’t any clues.

Let’s look at the same error as of version 1.1.2114, which is available via loom use latest --firehose (or sprint29 when we release it). Just keep scrolling, we’ll see you at the bottom…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
[error] Assert failed [../../../loom/script/native/core/system/lmObject.cpp@154] (type): error getting type in Object._as

=====================
=   RUNTIME ERROR   =
=====================

Native Assertion - see above for full error text
Stacktrace:
system.Object._as : [NATIVE] : 0
feathers.core.DisplayListWatcher.applyAllStylesForTypeFromMaps : src/feathers/core/DisplayListWatcher.ls : 382
feathers.core.DisplayListWatcher.processAllInitializers : src/feathers/core/DisplayListWatcher.ls : 344
feathers.core.DisplayListWatcher.addObject : src/feathers/core/DisplayListWatcher.ls : 410
feathers.core.DisplayListWatcher.addedHandler : src/feathers/core/DisplayListWatcher.ls : 438
system.Function._call : [NATIVE] : 0
loom2d.events.EventDispatcher.invokeEvent : src/loom2d/Events/EventDispatcher.ls : 135
loom2d.events.EventDispatcher.bubbleEvent : src/loom2d/Events/EventDispatcher.ls : 175
loom2d.events.EventDispatcher.dispatchEvent : src/loom2d/Events/EventDispatcher.ls : 100
loom2d.events.EventDispatcher.dispatchEventWith : src/loom2d/Events/EventDispatcher.ls : 191
loom2d.display.DisplayObjectContainer.addChildAt : src/loom2d/Display/DisplayObjectContainer.ls : 113
feathers.controls.supportClasses.LayoutViewPort.addChildAt : src/feathers/controls/supportClasses/LayoutViewPort.ls : 247
feathers.controls.ScrollContainer.addChildAt : src/feathers/controls/ScrollContainer.ls : 276
loom2d.display.DisplayObjectContainer.addChild : src/loom2d/Display/DisplayObjectContainer.ls : 93
com.example.app.screens.LoginScreenMediator.onInitialize : src/com/example/app/screens/LoginScreenMediator.ls : 71
system.Function._call : [NATIVE] : 0
loom2d.events.EventDispatcher.invokeEvent : src/loom2d/Events/EventDispatcher.ls : 135
loom2d.events.EventDispatcher.dispatchEvent : src/loom2d/Events/EventDispatcher.ls : 100
feathers.controls.ScrollContainer.dispatchEvent : src/feathers/controls/ScrollContainer.ls : 349
loom2d.events.EventDispatcher.dispatchEventWith : src/loom2d/Events/EventDispatcher.ls : 191
feathers.core.FeathersControl.initialize_addedToStageHandler : src/feathers/core/FeathersControl.ls : 1528
system.Function._call : [NATIVE] : 0
loom2d.events.EventDispatcher.invokeEvent : src/loom2d/Events/EventDispatcher.ls : 135
loom2d.events.EventDispatcher.dispatchEvent : src/loom2d/Events/EventDispatcher.ls : 100
feathers.controls.ScrollContainer.dispatchEvent : src/feathers/controls/ScrollContainer.ls : 349
loom2d.display.DisplayObjectContainer.broadcastEvent : src/loom2d/Display/DisplayObjectContainer.ls : 362
loom2d.display.DisplayObjectContainer.broadcastEventWith : src/loom2d/Display/DisplayObjectContainer.ls : 373
loom2d.display.DisplayObjectContainer.addChildAt : src/loom2d/Display/DisplayObjectContainer.ls : 118
loom2d.display.DisplayObjectContainer.addChild : src/loom2d/Display/DisplayObjectContainer.ls : 93
feathers.controls.ScreenNavigator.showScreen : src/feathers/controls/ScreenNavigator.ls : 344
com.example.app.init.view.MasterViewMediator.showDialog : src/com/example/app/init/view/MasterViewMediator.ls : 96
com.example.app.controller.ShowDialogCommand.execute : src/com/example/app/controller/ShowDialogCommand.ls : 19
org.puremvc.as3.core.Controller.executeCommand : src/org/puremvc/as3/core/Controller.ls : 118
system.Function._apply : [NATIVE] : 0
org.puremvc.as3.patterns.observer.Observer.notifyObserver : src/org/puremvc/as3/patterns/observer/Observer.ls : 100
org.puremvc.as3.core.View.notifyObservers : src/org/puremvc/as3/core/View.ls : 127
org.puremvc.as3.patterns.facade.Facade.notifyObservers : src/org/puremvc/as3/patterns/facade/Facade.ls : 406
org.puremvc.as3.patterns.facade.Facade.sendNotification : src/org/puremvc/as3/patterns/facade/Facade.ls : 389
org.puremvc.as3.patterns.observer.Notifier.sendNotification : src/org/puremvc/as3/patterns/observer/Notifier.ls : 49
com.example.app.init.controller.InitializeViewCommand.execute : src/com/example/app/init/controller/InitializeViewCommand.ls : 47
org.puremvc.as3.patterns.command.MacroCommand.execute : src/org/puremvc/as3/patterns/command/MacroCommand.ls : 118
com.example.app.init.controller.StartupCommand.execute : src/com/example/app/init/controller/StartupCommand.ls : 13
org.puremvc.as3.core.Controller.executeCommand : src/org/puremvc/as3/core/Controller.ls : 118
system.Function._apply : [NATIVE] : 0
org.puremvc.as3.patterns.observer.Observer.notifyObserver : src/org/puremvc/as3/patterns/observer/Observer.ls : 100
org.puremvc.as3.core.View.notifyObservers : src/org/puremvc/as3/core/View.ls : 127
org.puremvc.as3.patterns.facade.Facade.notifyObservers : src/org/puremvc/as3/patterns/facade/Facade.ls : 406
org.puremvc.as3.patterns.facade.Facade.sendNotification : src/org/puremvc/as3/patterns/facade/Facade.ls : 389
com.example.app.Main.run : src/com/example/app/Main.ls : 25
loom.Application._run : src/loom/Application.ls : 120
system.BaseDelegate.call : [NATIVE] : 0
loom.Application.tick : src/loom/Application.ls : 251

That’s a deep callstack! :) Here’s the important part, the first few lines:

1
2
3
4
Stacktrace:
system.Object._as : [NATIVE] : 0
feathers.core.DisplayListWatcher.applyAllStylesForTypeFromMaps : src/feathers/core/DisplayListWatcher.ls : 382
feathers.core.DisplayListWatcher.processAllInitializers : src/feathers/core/DisplayListWatcher.ls : 344

We can see by reading the first line or two that the applyAllStylesForTypeFromMaps method on feathers.core.DisplayListWatcher is the site of the crash (and that it’s on line 382 of DisplayListWatcher.ls). At this point we can isolate the problem and inspect it using trace()s or the debugger, or just by reading the code.

Debugging is a lot easier when you know where the problem is. We hope this improvement makes your Loom development faster and more productive!

LoomCasts and the First of Many Loom Hangouts

One of the most common suggestions we receive is to create more tutorials about developing on Loom. We hear ya! So, we’re ecstatic to announce LoomCasts (http://www.loomcasts.com), weekly screencasts about developing with the Loom Game Engine!

In celebration of kicking off LoomCasts, we’re going to have our first ever Loom Hangout.

Tomorrow (May 9th, 2013) at 12:00pm (Noon Pacific Time) the Loom Team will be streaming live via Google Hangout, and you’re invited. We will be answering your questions and talking about what we have planned for Loom.

If you can’t make the event live, don’t worry! The recording will be available shortly after the event on LoomCasts.

Submit your questions beforehand for a better chance that they’ll be answered.

We hope to see you there!

Loom Supports OUYA!

The Loom team has been polishing Ouya support this sprint, and we wanted to share a video showing our latest demo:

We’ve worked very closely with community member HanClinto to create the Platformer Example. It will be a standard part of Loom in the near future, free for you to use and extend in your own games (including the art).

We’ve fixed a ton of issues in Cocos2d-x’s tilemap rendering (which we plan on contributing back to Cocos2d-x), as well as a few crashes and bugs in Loom itself, and those fixes are already in firehose loom use latest --firehose. As usual we’ll give a full report at end of sprint.

We look forward to seeing what you build on the OUYA with Loom! Sign up for Loom now, if you haven’t already!

Our Unplanned $1,750,000 (and Counting!) Giveaway

This week, we launched Loom. The last 48 hours have been an amazing ride, and we want to share the experience with you, because you made it possible.

The timeline is fun - a cool insight into an unexpectedly successful launch. We got a ton of new users and visibility. But here’s what is really exciting: Every one of our new users got a free Loom Indie License. The total value of those licenses is hovering near $1,750,000. Of course, not every user who signed up would have paid. But we feel that giving out $1.75M in software licenses is a solid expression of how much we value Loom being in the hands of developers.

And with that - on with the tale of launch!

5:47pm PST, Feb 25 2013

The scene: our small office in Eugene, OR. We soft launched our 1.0 site update after a long day’s work. The day had included hail and sunny skies, and our tasks had included everything from website development to build system debugging to last minute bug and documentation fixes. We only accidentally queued builds on all 200 branches in our repo once…

With the site quietly launched, the team broke for dinner. Nate and Ben agreed to catch up later that night to prepare an e-mail blast for 8am the next day (Feb 26). The plan was to announce that the Loom Game Engine is free until the Game Developers Conference at the end of March in order to help us build a thriving community for our new game engine.

8:06pm PST, Feb 25 2013

However, our plans to rest up and prepare were foiled a little more than two hours later by Ben Burbank, who caught us in the act and tweeted this to the world.

8:08pm PST, Feb 25 2013

Since we’d been announced after all, Ben Garney (our Chief Engineer) caved and started talking about Loom on Facebook and Twitter.

Soon after, the whole team joins in on the fun.

9:00pm PST, Feb 25 2013

Less than an hour in, George Broussard of 3D Realms fame picked us up… as did several members of Adobe’s current and former product evangelism team (@__ted__, @renaun, @ryanstewart). That exposure was enough to get us picked up by the global Twitter cycle. At this point, the cat was thoroughly out of the bag.

12:00am PST, Feb 26 2013

We see a huge growth in our traffic. What followed exceeded everyone’s expectations. We began to see our concurrent vistor count rising. Fans of Loom posted stories to Hacker News, Reddit, SomethingAwful, and Digg, all without our involvement.

Friend of Loom, Ted Patrick (@__ted__) starts a series of tweets endorsing Loom to his 6,000 followers.

3:02am PST, Feb 26 2013

By 3am, after seven hours of excitement, Ben and Josh (while estatic about the pickup), decide they should get some sleep so they could be fresh and ready to answer questions and work with the newly growing community.

3:25am PST, Feb 26 2013

Records are set and Nate sends Ben a text waking him up because we surpassed 250 concurrent vistors on the website.

Signups are streaming in non-stop.

5:00am PST, Feb 26 2013

Nine hours in, Ben finally tears himself away and heads to bed. Nate continues to be glued to the computer, monitoring the site using New Relic and watching the Google Analytics Real-Time Dashboard as the East Coast begins to wake up and come on board.

Jeremy comes online to start answering questions after a refreshing night of sleep.

6:07am PST, Feb 26 2013

We hit our peak of 325 concurrent vistors on the website.

8:00am PST, Feb 26 2013

Twelve hours after Ben Burbank outed us, our scheduled email blast goes out to everyone who was on the mailing list.

We have our site post every time a user signs up. It plays the Zelda “you found a key” noise! As the team met for our first live chat, we had to move the box into its own room due to the sheer volume of signups. We just couldn’t hear each other as the notifications poured in.

11:00am PST, Feb 26 2013

After less than six hours of downtime, Ben comes back online and allows Nate to go get some sleep.

1:00pm PST, Feb 26 2013

The whole team is back online. It’s all answering forum posts, chatting with licensees and fixing bugs from here.

5:00pm PST, Feb 27 2013

Now, two days after launch, we’re still staying steady at 50 concurrent vistors. The dust is settling.

This is only the beginning, we’re glad you’re here!

Free Loom License Details

Hi everybody!

We noticed a little bit of confusion around the free Loom Indie licenses we have been giving out, so we thought we’d take a minute to clarify just what exactly you are getting… and why it’s such a screaming deal.

To summarize:

  1. We are giving out free Loom Indie Licenses to anyone who signs up between now and the end of GDC 2013.
  2. You get one year of free updates and forum access.
  3. You can use this license to keep making games with Loom forever, even after the free year runs out.
  4. This license includes full C++ source code, all platforms, and any number of titles.

The only reason you have to pay us is if you want to keep getting updates after the free year runs out, if you want to grow your team after the free signup goes away, or if you need to buy a Studio License (because you exceeded the $25M/yr revenue cap).

You can read all the details on our licensing page, or hit the licensing thread in the forums to discuss/ask questions. You can also view the full text of the EULA.

Thanks for reading!

Loom 1.0 Now Available!

Have you found that AIR is too heavy for mobile? That Unity adds too much weight to your budget and download footprint? That Corona and Moai encourage you to use Lua, but Lua’s strange syntax and dynamic typing are no walk in the park? That HTML5 is ideal… if you want to recreate the hits of the early 1980s with Javascript?

If you are looking for a way to build games using great workflow, powerful scripting, and live development on device, the Loom Game Engine is your answer. Built by a team of game industry veterans, Loom is the best option for quickly developing great mobile 2D games across iOS, Android, OS X, and Windows.

Don’t take our word for it, watch it in action:

Like what you see? We are giving away free Loom licenses, including full C++ source code, for the first 32 days after launch. After that, an indie Loom license for all platforms, with full source code, will cost $500. Click here to create your account, download Loom, and start developing today.

Why We Built Loom

Loom exists because we couldn’t find the game technology that we wanted to use.

We wanted a game engine that was great for building casual 2D and 3D games quickly. But the most mature and solid engines, like Unity and Unreal, are focused on high end 3D.

We wanted a game engine with a developer focused workflow, but couldn’t find one. We have become used to great developer tools like Git, Heroku, Ruby on Rails, make, and bash - that are command-line driven, extensible, self contained, and used on a daily basis.

We wanted a game engine that was lean, because download size is crucial in mobile and web games. But it’s hard to find a desirable engine that also has a small footprint. Unity clocks in around 8mb, while AIR is closer to 12mb! Loom is a svelte 2-4 megs compressed based on features YOU decide to compile in.

We wanted a game engine that would let us take off the hood and dig inside, but it is hard to find good tech that includes full C++ source code access. AIR, Unity, and Corona all expect you to ship a game without ever encountering a bug or missing feature.

We wanted a game engine that brought something innovative to the table. A lot of the current crop of mobile engines are YALEs - Yet Another Lua Engine. Engines like Moai, Corona, and LOVE take Lua, integrate some 2D rendering, sound playback, write some tutorials, and call it good. There’s nothing bad about them, but they aren’t particularly exciting - the oatmeal of game technology!

We wanted a game engine that had a powerful and familiar scripting language with a tiny footprint. We needed great profiling and debugging, and excellent bindings to C++. We wanted something more effective than Lua, so we invented LoomScript.

We wanted a game engine that wasn’t carrying over a decade of technical cruft, but a lot of the players in this space are products that were around when I started with GarageGames in 2002! Marmalade, Unreal, Source, and Torque have been around for a long time and they are set in their ways.

We wanted a game engine that leveraged genuinely useful technology. There are great libraries out there like TinyXML2, Sean Barrett’s stb_image, Cocos2DX, and the Lua virtual machine. But we saw most engines going with bigger, bloated options.

We wanted a game engine that was a good deal, especially for smaller studios (like us and our friends!). We don’t have guarantees of huge profits on our games, so even a 10% revenue share is a big deal - never mind something higher like 25%. Never mind the auditing and book-keeping that that implies! We also didn’t have tens of thousands of dollars to spend on licensing for our team. That said, we also wanted whoever we bought from to have a good business model so we wouldn’t be stuck with an orphaned product.

In the end, we decided that the only thing for it was to make it ourselves. Which we did. And we called it Loom.

Loom has an awesome workflow with live reload and great command line integration. It’s lean and small with low technical debt, so it has a small footprint (2-4mb depending on platform). It’s at an indie-friendly price. It uses good libraries but innovates when it has something worth adding. Get Loom from our website now.