April 25, 2018

Setting a data dump non-breakpoint in JS debugging



This works for Firefox, Chrome and probably other browsers with integrated developer tools.

If you have programmed on other platforms or debugged with other tools, you may be missing a very handy feature: the ability to set a breakpoint that really dones't break but dumps the value of some variable or expression when it's hit.

The truth is that there is no such explicit feature. But you have it implicitly. Let me explain myself:

The trick is simple: use a conditional breakpoint instead, with a condition such as console.log(yourVariable).


When the relevant line is hit, since that expression will evaluate to false, there will be no break, but, given the expression is evaluated indeed, console.log (or any other of its family) will be called, effectively dumping your value to the console.

March 20, 2018

Sketchfab integrates with Godot

This is cross-posted from the official Godot blog. I'm putting it here since I was the one that took the job from Sketchfab.




Sketchfab is a well-known site where you can browse a big library of 3D models and download them for use in your own projects. Many of them are free, covered by open licenses.


They have just announced their download API (announcement), which allows third-parties to integrate with it, giving any application access to hundreds of thousands of models in glTF, a standard format that many tools, Godot included, understand.

They have integrations for other famous game engines, like Unity and Unreal and have decided to provide an official plugin for Godot! It's also available on the Godot Asset Library. You can watch the video to get a better idea:


So it seems that more and more companies are taking Godot very seriously and it's becoming a big player in the game engine landscape.

In order to run the Sketchfab plugin, you'll need to wait until the upcoming Godot 3.0.3 is released since it contains some needed bugfixes, that were done after the last official version. If you are a Windows (x64) user and can't wait, you can get a build snapshot from the plugin repository, under which it will work.

December 09, 2017

Let people touch Godot!

This is cross-posted from the official Godot blog. I'm putting it here since I was the one that took the job from AdPodnet. By the way, very nice people!


Maybe you have already seen an AdPod around. They are three-sided giant multitouch-capable screens. The company behind them customizes them for very important customers for promotion campaings for things like movies (Disney, Universal).

They "skin" the device cosmetically for the targeted product and develop interactive apps that run on them. People walking by can interact with them, something which creates great product awareness and also entertains.

Now they have decided to use Godot for such development work! The switch from a well-known non-free engine they were using formerly has been a wise decision.

They were pretty confident about Godot's features and solvency, but they needed multitouch support on Linux. That's why they decided to hire someone to add it. However, as they feel so grateful for the Godot community for providing such a nice tool, they kindly decided to donate the code to the project!

What is more, they wanted to be sure that multitouch support is more widely available so the job was extended to ensuring it worked well on Windows too (it was already done, but needed some improvement) and creating well-commented examples in GDScript and VisualScript. Finally, they asked for all this to work on both Godot 2.1 and the upcoming 3.0.

We thank them for their contribution and for having become new Godot believers. They won't regret!

Next time you see an AdPod, you'll know Godot is ruling it. :)

For more information about them and what they do, you can visit their website: https://www.adpodnet.com/

November 26, 2017

Introducing onion skinning for the Godot game engine

You may already know about the great open source Godot game engine. I've been contributing to it since two years ago or so. Today I'm writing here to announce a feature I developed for the upcoming 3.0 version, and of which I'm pretty proud of: onion skinning.

So what's onion skinning?

It's a technique used in animation from its early days consisting in the ability to draw frames of animation on a semitransparent paper (onion paper) so you can see the previous frame through it. That provides the artist with a good reference to base his new drawing in.

Of course, this concept once brought to computers gets much more flexible: arbitrary number of see-through layers, ability to see the past and/or the future, etc. Every decent software package with an animation editor features it nowadays. And some people was requesting it for Godot.

This picture from the Adobe Animate CC documentation [CC-NC-SA] is fairly telling about the concept:

How it looks like in Godot?

This images are from the pull request I made and based on the main character from the 3D platformer example. (By the way, this works for both 2D & 3D.)

With the default past/present colors (that you can change in the editor settings), seeing one frame to the past and to the future.

August 21, 2017

Scroll to item-of-interest in Angular

Imagine you have a list of elements of some kind (by means of *ngFor). You'd like to make that Component aware of the fragment in the URL so it can scroll to the element identified by it.

For instance, you let the user create a new element in a form in one page and you want that on return, the list scrolls automatically to the item just added. You are using Angular routing facilities.

For more background, you can check the discussion on the issue on the Angular project.

There, some users have provided their approaches. On the basis of some solutions suggested there, I've built my own and it seems to work fine:

[...]

private fragment: string;

constructor(private route: ActivatedRoute { }

ngOnInit() {
this.route.fragment.subscribe(fragment => { this.fragment = fragment; });
}

ngAfterViewChecked(): void {
try {
document.querySelector('#' + this.fragment).scrollIntoView();
} catch (e) { }
}

[...]

I think this adds very little bloat and it handles these situations:

  • No fragment present in the route.
  • Fragment present but invalid (querySelector() throws).
  • Fragment present and valid, but the element is not present.

Actually, the try block is masking these situations rather than handling them. Nevertheless, usually you won't find yourself needing to do anything about them.

July 11, 2017

Fail: LinkedIn internationalization

Let's let LinkedIn open my public collection of technologic fails!

It looks as they had missed the translation to Spanish of a string during an update and what we are seeing is its key.

By the way, a few minutes later it rendered properly:

A 'shooting' fail. Maybe I should make a wish…

July 07, 2017

Self-containment challenge in Angular

I didn't plan on writing too much about web development here, but for the past months I've been learning modern web frameworks/techonologies and I've found something worthy writing about regarding Angular.

In Angular, as in other well designed framework you are expected to separate concerns as much as possible. For instance, Components should be as reusable as possible. One feature for such reusability is self-containment. That is, while sometimes you need their host component to interact with them beyond their APIs (Inputs, Outputs, etc.), you need to move in a slightly lower layer for things like adding/removing CSS classes. But you can take measures so everything is under control.

Nonetheless, you can see yourself in trouble with the markup. Due to the rigidity of HTML, certain elements must be direct children of their 'semantic ancestors' if you don't want the browser to make a mess out of your markup. For instance, a <tr> must be a direct child of a <table>, or at least of a <thead>, <tbody> or <tfoot> —among a few others that don't alleviate the issue—. The same holds for lists; for instance an <ul> must contain <li>s.

Let's look at the problem with a concrete example.