diff --git a/scripts/dev.js b/scripts/dev.js index 5fbc306..562fdb7 100644 --- a/scripts/dev.js +++ b/scripts/dev.js @@ -11,7 +11,16 @@ app.locals.basedir = app.get('views'); app.get(/\/.*$/, (req, res) => { const pugpath = req.path.slice(1) || 'index' const ENV = 'dev' - res.render(pugpath, {require, ENV, PATH: req.path}) + const locals = {require, ENV, PATH: req.path} + const renderFunc = (err, html) => { + if (err) { + console.error(err.message) + console.error(err.stack) + return res.status(500).send(`
${err.message} ${err.stack}
`) + } + res.send(html) + } + res.render(pugpath, locals, renderFunc) }) app.listen(PORT, () => { diff --git a/src/pug/_common.pug b/src/pug/_common.pug index 6841b29..f284152 100644 --- a/src/pug/_common.pug +++ b/src/pug/_common.pug @@ -28,12 +28,17 @@ ctrl_app: 'https://ctrl.inputlabs.io', } + const findLatestBlogPost = () => { + const index = FS.readFileSync('src/pug/blog/_blog.pug', 'utf8') + return index.match(/wikilink\('(.+?)'\)/)[1] // Top wikilink post. + } + const redirect = { db: '/mixed-input/db', contribute: '/contribute/open_source', devices: '/alpakka', alpakkaManual: '/alpakka/manual/ctrl_app', - blog: '/blog/alpakka_2_crowdfunding_fail', + blog: '/blog/' + findLatestBlogPost(), } const loadMathJax = [ @@ -96,9 +101,9 @@ mixin figure(id, caption, src, cls, style) div.figure(class=cls) img(src=src style=style) if id - div.caption(style=style) Figure #{id}: #{caption} + div.caption(style=style) Figure #{id}: !{caption} else - div.caption(style=style) #{caption} + div.caption(style=style) !{caption} div.caption block diff --git a/src/pug/blog/_blog.pug b/src/pug/blog/_blog.pug index 369977e..fc0028a 100644 --- a/src/pug/blog/_blog.pug +++ b/src/pug/blog/_blog.pug @@ -23,22 +23,22 @@ block page div.box.index h2 Blog - h3 News + h3 Latest news div + +wikilink('report_31') Progress report 31 + //- +wikilink('gamesir_collab') GameSir collaboration +wikilink('alpakka_2_crowdfunding_fail') Alpakka 2 crowdfunding fail +wikilink('future_developments') Future developments +wikilink('report_30') Progress report 30 +wikilink('report_29') Progress report 29 +wikilink('kapybara_development') Kapybara development +wikilink('report_28') Progress report 28 - //- Keep only last 3 reports. - +wikilink('reports_all') Old progress reports - +wikilink('recap_year_2') Year 2 recap - +wikilink('alpakka_v1') Alpakka 1.0 announcement + +wikilink('report_27') Progress report 27 + +wikilink('all_posts') Older posts + + h3 Pinned news + div +wikilink('patents') Patents, a necessary evil - +wikilink('recap_year_1') Year 1 recap - +wikilink('half_anniversary') Half anniversary - +wikilink('shop_opening') Shop opening +wikilink('live') We are live h3 Research diff --git a/src/pug/blog/reports_all.pug b/src/pug/blog/all_posts.pug similarity index 69% rename from src/pug/blog/reports_all.pug rename to src/pug/blog/all_posts.pug index c809f76..df28868 100644 --- a/src/pug/blog/reports_all.pug +++ b/src/pug/blog/all_posts.pug @@ -1,17 +1,30 @@ extends _blog.pug block append subtitle - | All progress reports + | All blog news block content - h2 All progress reports + h2 All blog news hr + h3 2026 ul + li: +a('report_31') Progress report 31 + li: +a('alpakka_2_crowdfunding_fail') Alpakka 2 crowdfunding fail + + h3 2025 + ul + li: +a('future_developments') Future developments li: +a('report_30') Progress report 30 li: +a('report_29') Progress report 29 + li: +a('kapybara_development') Kapybara development li: +a('report_28') Progress report 28 + + h3 2024 + ul li: +a('report_27') Progress report 27 + li: +a('recap_year_2') Year 2 recap + li: +a('alpakka_v1') Alpakka 1.0 announcement li: +a('report_26') Progress report 26 li: +a('report_25') Progress report 25 li: +a('report_24') Progress report 24 @@ -19,20 +32,30 @@ block content li: +a('report_22') Progress report 22 li: +a('report_21') Progress report 21 li: +a('report_20') Progress report 20 + li: +a('patents') Patents, a necessary evil + + h3 2023 + ul li: +a('report_19') Progress report 19 + li: +a('recap_year_1') Year 1 recap li: +a('report_18') Progress report 18 li: +a('report_17') Progress report 17 li: +a('report_16') Progress report 16 li: +a('report_15') Progress report 15 li: +a('report_14') Progress report 14 + li: +a('half_anniversary') Half anniversary li: +a('report_13') Progress report 13 li: +a('report_12') Progress report 12 li: +a('report_11') Progress report 11 li: +a('report_10') Progress report 10 li: +a('report_9') Progress report 9 + li: +a('shop_opening') Shop opening li: +a('report_8') Progress report 8 li: +a('report_7') Progress report 7 li: +a('report_6') Progress report 6 + + h3 2022 + ul li: +a('report_5') Progress report 5 li: +a('report_4') Progress report 4 li: +a('report_3') Progress report 3 diff --git a/src/pug/blog/alpakka_2_crowdfunding_fail.pug b/src/pug/blog/alpakka_2_crowdfunding_fail.pug index e570aa2..ebadffc 100644 --- a/src/pug/blog/alpakka_2_crowdfunding_fail.pug +++ b/src/pug/blog/alpakka_2_crowdfunding_fail.pug @@ -5,7 +5,7 @@ block append subtitle block content h2 Alpakka 2 crowdfunding fail - +news_header('2 March 2026', 'future_developments', '') + +news_header('2 March 2026', 'future_developments', 'report_31') h3 Results of the campaign p From the 2nd of February to the 2nd of March #[em we ran a Indiegogo campaign to fund the Alpakka 2], unfortunately the campaign was #[em not funded], as it did not reach the target we set. diff --git a/src/pug/blog/report_31.pug b/src/pug/blog/report_31.pug new file mode 100644 index 0000000..23106ae --- /dev/null +++ b/src/pug/blog/report_31.pug @@ -0,0 +1,109 @@ +extends _blog.pug + +block append subtitle + | Progress report #31 + +block content + h2 Progress report #31 + +news_header('29 July 2026', 'alpakka_2_crowdfunding_fail', '') + + h3 Shipping to the United States of America again + + p On July 30th 2025, the U.S. administration announced the end of the #[em de-minimis exemption], therefore making orders of less than $800 subject to tariffs and import taxes. As it turned out, this change caused all #[em european postal services to stop shipping] anything to the United States "temporarily". + + p As we were hoping that this would last only a few days, or perhaps weeks, we contacted affected customers, explaining the situation and offering refunds. Weeks turned into months, and none of the postal services available in Finland resumed their services. + + p By the end of 2025 some european postal services (Sweden and Spain) were able to ship to the U.S. again, so we tried to use these countries as a proxy #[em Finland->Sweden->US], or #[em Finland->Spain->US]. + + p We were able to ship a controller to a real customer via #[em Correos] (Spanish postal service), but with an additional 15% tariff that we (Input Labs) had to pre-pay, and also with the obligation of providing customers' social security number (SSN) 🤯. We decided that the complex logistics and SSN disclosure #[em were unreasonable requirements], and abandoned this approach. + + p In June 2026 we signed a contract with #[em DHL] (Deutsche Post), which enables us to ship to the U.S. again. Unfortunately the cost of shipping with DHL is significantly higher than the postal service we use for the rest of the world, and comes with additional requirements: + ul + li The service is "Delivered At Place" (DAP), #[em requiring the customer to pay] U.S. tariffs and service fees, before final delivery. + li Customs and Border Protection (CBP) requires DHL to collect the recipient's #[em Employer Identification Number] (EIN). However, it seems that deliveries still go through even if not provided. + + p So far we have been able to successfully ship about a dozen orders to our U.S. customers. Based on their experience, the total to be paid by the customer for a complete Alpakka kit is #[em $46] in shipping costs + #[em ~$30] in tariffs and additional fees. + + p While we understand these prices are insane, there are no other alternatives until international trade goes back to normal. + + //--------------------------------------------------------------------------- + hr + h3 Firmware and Ctrl app 1.2.0 + p Codenamed #[em The Thumbstick update], includes a lot of new features related to thumbstick input, and a few more extras. Also we made this fancy video: + + br + +axc('https://www.youtube.com/watch?v=mpyJ-rRGbj4') + img.wm(src='/static/blog/fw-120-video.jpg') + + h4 Thumbstick features + ul + li New thumbstick rotation mode (including #[em Flickstick] support) + li #[em Push auto-toggle] (emulate console-like sprint push behavior). + li Vertical sensitivity ratio. + li Configurable inner/outer bind threshold. + li #[em Acceleration] curves (with app curve previews). + + h4 Extra features and quality of life + ul + li #[em Gyro per-axis sensitivity] (so it allows for custom vertical sens). + li Reworked app update notification. + li More consistent window resize, better support for small screens (e.g. Steam Deck). + li Keybind dialog #[em quick-open] (double-click) and quick close. + + - let fwRelease = 'https://github.com/inputlabs/alpakka_firmware/releases/tag/1.2.0' + - let appRelease = 'https://github.com/inputlabs/ctrl-app/releases/tag/1.2.0' + p Check full release notes for the #[+ax(fwRelease) Firmware 1.2.0] and #[+ax(appRelease) Ctrl app 1.2.0]. + + //--------------------------------------------------------------------------- + hr + h3 Kapybara functional prototype in the works + p We are making another push for the #[em Kapybara DIY controller], with the expectation of having a fully #[em functional prototype] by the end of the push (hopefully by the end of summer). + p This involves a parallel development of the #[em Printed Circuit Board] and #[em 3D-printed case], selecting and testing electronic components, designing the mechanical integration of buttons and triggers, how the external case clamps into itself, bolts and nuts placement, and many other tricky details. + + +figure( + '', + 'Kapybara with real triggers, internal spaces,
and case-locking mechanism', + '/static/blog/kapybara-r31-a.jpg', + 'medium inline nobottommargin', + ) + +figure( + '', + 'Kapybara assembly in Blender
(work in progress)', + '/static/blog/kapybara-r31-b.jpg', + 'medium inline nobottommargin', + ) + +figure( + '', + 'Kapybara PCB
(work in progress)', + '/static/blog/kapybara-r31-c.jpg', + 'medium inline nobottommargin', + ) + +figure( + '', + '2x 950 mAh batteries
14430 form factor (smaller than AA)', + '/static/blog/kapybara-r31-d.jpg', + 'medium inline nobottommargin', + ) + + //--------------------------------------------------------------------------- + hr + h3 Mixed Input DB + p We repurposed the game database on our website as a database for #[em mixed input] compatibility, simply called #[+a('/mixed-input/db') Mixed Input DB]. The goal is to have a solution similar to #[em ProtonDB] or #[em WineHQ], since this aspect of input is poorly documented on #[em PCGamingWiki]. + p Initially launching with #[em 107] entries, it reached #[em 156] games only a few weeks later, thanks to #[em community contributions]. We hope that the simplicity of the format encourages the gyro community to submit even more games. + + +figure( + '', + 'Mixed Input DB example search', + '/static/blog/mixed-input-db.png', + 'medium inline nobottommargin', + ) + +figure( + '', + 'Tier explanations', + '/static/blog/mixed-input-db-tiers.png', + 'medium inline nobottommargin', + ) + + //--------------------------------------------------------------------------- + hr + p Thanks for the support! 🤍
- Michael and Marcos diff --git a/src/static/blog/fw-120-video.jpg b/src/static/blog/fw-120-video.jpg new file mode 100644 index 0000000..fe91a47 Binary files /dev/null and b/src/static/blog/fw-120-video.jpg differ diff --git a/src/static/blog/kapybara-r31-a.jpg b/src/static/blog/kapybara-r31-a.jpg new file mode 100644 index 0000000..5578660 Binary files /dev/null and b/src/static/blog/kapybara-r31-a.jpg differ diff --git a/src/static/blog/kapybara-r31-b.jpg b/src/static/blog/kapybara-r31-b.jpg new file mode 100644 index 0000000..6319e90 Binary files /dev/null and b/src/static/blog/kapybara-r31-b.jpg differ diff --git a/src/static/blog/kapybara-r31-c.jpg b/src/static/blog/kapybara-r31-c.jpg new file mode 100644 index 0000000..9bc41b8 Binary files /dev/null and b/src/static/blog/kapybara-r31-c.jpg differ diff --git a/src/static/blog/kapybara-r31-d.jpg b/src/static/blog/kapybara-r31-d.jpg new file mode 100644 index 0000000..3b6839f Binary files /dev/null and b/src/static/blog/kapybara-r31-d.jpg differ diff --git a/src/static/blog/mixed-input-db-tiers.png b/src/static/blog/mixed-input-db-tiers.png new file mode 100644 index 0000000..5718a66 Binary files /dev/null and b/src/static/blog/mixed-input-db-tiers.png differ diff --git a/src/static/blog/mixed-input-db.png b/src/static/blog/mixed-input-db.png new file mode 100644 index 0000000..1d93d77 Binary files /dev/null and b/src/static/blog/mixed-input-db.png differ diff --git a/src/static/style.css b/src/static/style.css index d7ac828..a81a818 100644 --- a/src/static/style.css +++ b/src/static/style.css @@ -582,6 +582,9 @@ main .boxes.center { display: inline-block; margin-right: 20px; } +.wiki .figure.nobottommargin { + margin-bottom: 0; +} .wiki .math { width: 420px; }