I have been using EndeavourOS on my Dragon Canyon NUC for months. It is my chosen Linux distribution because it offers an easy-to-install Arch Linux environment, and I am familiar with Arch Linux. I need to stay on the cutting edge for desktop environments, display protocols, and graphics drivers due to issues with NVIDIA and the Linux desktop (especially Wayland). Many developments are happening in real-time to improve them. With Arch Linux, I can easily install an AUR package from a merge request, as well as switch to beta drivers when they become available.
Wayland is important to me because I’m using a 27" 4K display. For the best visual size, it should be set to 150% fractional scaling. KDE Plasma supports fractional scaling under Wayland and has an option to “let Xwayland applications scale themselves” to prevent them from being blurry. That’s the reason I chose KDE as my desktop environment. Moreover, KDE Plasma 6 offers a nice experience both functionally and aesthetically.
Here is a note in Logseq that I use to track how I install and configure EndeavourOS. I’m interested in a declarative way to build operating systems and am slowly learning NixOS. However, in the meantime, I am very satisfied with my current EndeavourOS setup.
1 | reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation" /v RealTimeIsUniversal /d 1 /t REG_DWORD /f |
192.168.1.2
.nvidia-inst
using yay
and run nvidia-inst
to install the GPU driver, then reboot again.sudo nano /etc/modprobe.d/nvidia-power-management.conf
options nvidia NVreg_PreserveVideoMemoryAllocations=1 NVreg_TemporaryFilePath=/var/tmp
xorg-xwayland-explicit-sync-git
and egl-wayland-git
AUR packages using yay
. This will make Xwayland issues with NVIDIA more manageable.fcitx5-im
and fcitx5-chinese-addons
using yay
, and select Fcitx 5 in System Settings > Keyboard > Virtual Keyboard; add Pinyin as an Input Method..ssh/id_rsa
, .ssh/config
, and .ssh/id_rsa.pub
from Windows on the same device.mdns
and kdeconnect
in the Firewall configuration.identity.fxaccounts.enabled
to false
in about:config
.extensions.pocket.enabled
to false
in about:config
.pacman
:.config/obsidian/user-flags.conf
with --ozone-platform-hint=wayland --enable-wayland-ime
..config/electron28-flags.conf
with the following content: 1 | --ozone-platform-hint=wayland |
sudo usermod -aG docker $USER
..config/environment.d/env-vars.conf
with SAL_USE_VCLPLUGIN=gtk3
. This can fix text and icon sizes.systemctl enable cronie
.yay
:.config/code-flags.conf
with the following content: 1 | --ozone-platform-hint=wayland |
.config/spotify-flags.conf
with the following content: 1 | --enable-features=UseOzonePlatform |
~/.config/systemd/user/plex-mpv-shim.service
: 1 | [Unit] |
1 | systemctl --user daemon-reload |
~/.var/app/com.github.Eloston.UngoogledChromium/config/chromium-flags.conf
with --ozone-platform-hint=wayland --enable-wayland-ime
.~/.config/mpv.conf
and ~/.config/plex-mpv-shim/mpv.conf
with hwdec=auto-copy
. Additionally, add the command set hwdec auto-copy
in Haruna Media Player.prezto
: 1 | zsh |
/bin/zsh
.zpreztorc
: git
, syntax-highlighting
, ssh
, tmux
, fasd
before prompt
goenv
: 1 | git clone https://github.com/go-nv/goenv.git ~/.goenv |
fnm
: 1 | curl -fsSL https://fnm.vercel.app/install | bash |
1 | rustup install stable |
export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH"
to .zshrc
..zshrc
: 1 | alias comet-core="ssh comet-core.lan -t 'tmux new-session -A -s main'" |
LIBVA_DRIVER_NAME=iHD vainfo --display drm --device /dev/dri/renderD129
.The Google Nexus 7, released in 2012, is the first “small tablet computer” I can recall. It featured a pleasing 800p display, a powerful processor for its time, and shipped with a “stock Android” system. I used a Nexus 7 for a few years alongside an iPad Mini, which was subsequently replaced by a larger iPad Air 2. Although the device has not been with me for many years, the memories of reading manga on a perfectly sized device and the hackable Android experience, including running a bash shell and emulators, always lead me to seek the spiritual successor to the Google Nexus 7.
For the past two years, I have been using the Lenovo Legion Y700 (2022) as my primary device for content consumption. It comes equipped with a Snapdragon 870 processor, 256GB of storage, 12GB of RAM, and an 8.8-inch 120Hz 2K display. Similar to the Google Nexus 7, there is an improved “2023” version featuring a Snapdragon 8 Gen 1 processor. However, the older 2022 model suffices for my needs, and I prefer its advanced 3.5mm audio port.
While the hardware performance is excellent and the freedom to install apps from various sources—such as Google Play, F-Droid, GitHub, or directly from the developer’s website—feels right, I have never felt good about its ZUI operating system or any Android OEM system. I appreciate that Lenovo doesn’t include too much bloatware, doesn’t require me to log in to its account, and natively supports Google Play Services, but there are always moments when I encounter buggy or peculiar issues with some apps, or something just doesn’t seem right with the OS.
On the other side, for the past two years, a Google Pixel 6a installed with GrapheneOS has been my secondary phone. While the hardware is decent, it kind of underperforms when compared to an iPhone or a Snapdragon 8-equipped Android device. However, the open-source operating system is more than just great. It offers many secure features, and even Google Play Services can be run in a sandbox to protect privacy and battery life. I can disable network access for Google Camera, Photos, and Gboard while still keeping their on-device ML features. Additionally, I can place some apps that I don’t trust as much in a Work Profile with Shelter, making other apps and data invisible to these apps.
In the end, I learned that the bootloader of the Lenovo tablet can be unlocked, and I discovered Project Treble and the Generic System Image (GSI), which enable the availability of custom Android distributions on most devices without excessive difficulties. Weeks ago, I followed this video and installed crDroid on my Lenovo Legion Y700.
crDroid, a fork of LineageOS, offers a pure and customizable Android experience. After experimenting with it for a few hours, I deeply regret not replacing the OS on this tablet sooner. Using an open-source stock-like Android system is incredibly refreshing. The UI is smooth, and I can truly appreciate the 120fps screen while navigating. It brings back memories from more than a decade ago with the Google Nexus 7, making me realize that I’m holding what could be considered the spiritual successor to the Google Nexus 7.
As is common with most custom images lacking official support, there are a few caveats when using a GSI ROM on this tablet, but I can say that I have fewer issues with crDroid than with the stock ZUI.
The settings and issues worth noting are:
The crDroid launcher is a lightweight fork of the Google Pixel launcher. Initially, I preferred it as it is similar to the launcher used in GrapheneOS, so I was already accustomed to it. However, there is an issue where the background of the app drawer remains dark even when using the light theme, which may be due to some compatibility issues with the tablet size or the enabling of the work profile. As a result, I switched to Niagara Launcher, and it looks perfect.
I also learned a valuable lesson: Unlike Pixel phones, Lenovo does not allow the re-locking of the bootloader once a non-stock OS is installed. The first action I took after installing crDroid_gsi was attempting to re-lock the bootloader. Subsequently, the tablet became bricked, displaying a message that the system was corrupted and could not boot. Thankfully, the tablet could be unbricked by following this guide.
In terms of security, I’m content with the basic Android security model, but it’s important to note that the tablet is less secure than a Pixel equipped with GrapheneOS.
Keeping the bootloader unlocked is clearly a security risk, as theoretically, a thief with hardware access could install a hacked ROM to decrypt data on the device. Additionally, the face recognition feature on this device is less secure than Apple’s Face ID or the face unlock feature on the Pixel 8, meaning a thief could theoretically mimic my face to unlock this device.
I do not consider a tech-savvy thief attempting to access my data to be within my threat model. Nonetheless, I choose not to store sensitive data on this tablet, and I also disabled biometric unlock in Bitwarden after setting up most of my apps.
While crDroid does not come with sandboxed Google Play Services like GrapheneOS does, disabling the advertising ID, personalization, autofill, and location settings is sufficient for my privacy needs regarding Google.
One theoretical privacy threat when using mobile devices is the possibility of manufacturers or popular apps harvesting the list of installed apps on the device and potentially sharing this information with authorities, which could result in phone calls from “anti-fraud offices” warning about the risks of certain apps. While this is all theoretical and without neither any evidence nor my own experience, using an open-source system can definitely mitigate such threats. Similar to my setup on my Pixel phone, I use Shelter to isolate certain apps within a Work Profile.
Despite it being over a decade since the launch of Nexus 7, there are still not many Android apps optimized for tablet size. However, since Android does not restrict non-optimized apps to run in a centered window like the iPad, most Android apps function adequately on this smaller tablet. Additionally, the operating system supports basic multitasking features, such as split-screen.
I prefer to install apps from Neo Store when possible, which is a frontend for F-Droid and also supports IzzyOnDroid by default. For apps that are only available through GitHub releases, I can update them automatically using Obtainium.
Here is a list of apps worth mentioning on this tablet:
The Lenovo Legion Y700 is marketed as a “gaming tablet.” Although I am not a mobile gamer—since most modern mobile games adopt a freemium, casino-like business model that I feel detracts from the concept of video games as works of art—Android remains an excellent platform for emulation and game streaming. This tablet has the capability to emulate PS2 and Wii games at full speed with upscaled textures, as well as stream PC games via Moonlight, or PS5 games using PSPlay or Chiaki, all with negligible latency.
Gaming on Android devices represents a larger story for me, but it’s not particularly tied to this tablet or the Pixel phone. I’m keeping it a secret for now and may discuss it in more detail in the future.
The journey to find the spiritual successor to the Google Nexus 7 led me to the Lenovo Legion Y700, a device that, while initially not perfect due to its ZUI operating system, transformed into a nearly ideal tablet experience after installing crDroid. This shift back to a stock-like Android experience reminiscent of the Nexus 7 days has been both nostalgic and enlightening, proving that the essence of a great tablet is not just in its hardware but in the freedom and flexibility of its software. The Lenovo Legion Y700, with its powerful specs and the newfound joy of a pure Android experience, serves as a testament to the enduring appeal of customizable, user-centric technology. It reminds us that sometimes, the true successor to a beloved piece of technology is not about finding an identical replacement, but about recapturing the spirit of innovation and openness that made the original so special.
]]>Homelab is a place where you can store all your family’s data, self-host applications and services, locally stream media, and experiment with various technologies.
A Homelab can start with low-power devices such as a Raspberry Pi, or with hacking your router to install open-source firmware and run custom applications. It can also involve easy-to-use consumer NAS solutions like Synology. Alternatively, you might find yourself overwhelmed by used data center hardware.
Throughout 2023, I have been tinkering with my home network and computing setup, which has been both fun and rewarding.
Various devices operate continuously at my home. Some were shelved last year, but there are a few newcomers worth mentioning.
The router “Rotom,” which I use for my home’s internet, is an iKoolCore R1. This compact device is powered by a Celeron N5105 processor and is equipped with 8GB of RAM, a 128GB SSD, and four 2.5GbE Ethernet ports. It runs Proxmox VE, hosting an OpenWRT VM as my primary firewall, and a Debian VM for several networking applications.
This summer, I noticed that the SSD became read-only on several occasions due to overheating. Fortunately, the manufacturer offers an R1 Pro upgrade kit. This kit replaces the case with a heatsink that directly contacts the NVMe SSD, effectively mitigating the overheating issue. Additionally, it includes a PWM fan, which keeps this compact computer silent in my closet.
I have a 15U network cabinet situated in the corner of my living room. At the bottom lies a Santak TG-BOX 850 UPS, safeguarding the devices within the cabinet. Positioned in the middle is my NAS, acquired in 2020 – a Synology DS1621+ equipped with six 8TB HGST drives and 12GB of ECC RAM. It’s set up in a RAID-6 configuration, providing a total storage capacity of 32TB.
At the top of the cabinet is the Homelab server “Porygon,” which I assembled in 2023. Inspired by Tao of Mac, it’s built around an ASRock DeskMeet B660 box. The configuration includes an Intel Core i7 12700 CPU, 128GB of DDR4 RAM, two NVMe SSDs (a WD SN770 2TB and an older Samsung 970 Evo Plus 1TB), and a Geforce RTX 3060 GPU.
The DeskMeet B660 also runs Proxmox VE. The integrated Iris Xe GPU is dedicated to a Fedora Workstation VM for transcoding videos and offering a remote desktop. The RTX 3060 switches between a Windows VM, which I use for game streaming, and a Debian VM for doing AI experiments.
However, I’ve encountered heat issues with the “Porygon” server inside the network cabinet. The CPU, cooled by a Noctua NH-L9i-17xx, can quickly reach 100°C during moderately intensive tasks. The SSD, even with a heatsink, often heats up to 70°C. To address this, I implemented two solutions. Firstly, I replaced the PSU fan with a Noctua NF-A12, which reduced the CPU temperature by 15°C, both at idle and under load, at the cost of injuring both my hands. Secondly, I installed a dedicated cabinet fan controlled by a Xiaomi Smart Plug. When the SSD temperature hits 70°C, Home Assistant activates the fan, which turns off once the temperature drops below 65°C. Ultimately, I’m quite content with the new Homelab server. It’s usually quiet and energy-efficient, yet it can be exceptionally powerful when needed.
In my Homelab, I run a wide array of applications, catering to various needs. This includes network applications that ensure connectivity for my devices at home and allow me to access my home network remotely. I also use note-taking apps, read-later services, home automation systems, media management services, file synchronization programs, RSS readers, as well as a git server complemented by CI/CD pipelines. Moreover, I have dashboards in place to navigate and monitor all these applications efficiently. It’s fair to say that a significant portion of my digital life depends on these machines, which are entirely under my control at home.
On the compact yet capable machine, I have set up two virtual machines and one LXC container to manage various services and applications.
One VM operates as my primary router OS, running OpenWRT. I’ve configured it with passthrough for three NIC ports. The WAN port connects to the modem provided by my ISP, while the LAN ports, in conjunction with the VM net port, establish a bridged LAN network. The majority of OpenWRT’s configuration revolves around DHCP settings and firewall rules.
In addition to the routing functions, “Rotom” hosts several other programs:
Jellyfin operates within an LXC container, with the Intel iGPU passed through for video transcoding. The remaining services are housed in Docker containers running on a Debian VM. The Debian VM also functions as a side router for my Homelab PC and devices such as the Apple TV and Sonos One.
As my storage center, I need my NAS to be as robust as possible, so I haven’t installed too many applications on it.
In addition to standard NAS services like SMB, NFS, and File Station, the applications I use include:
Apart from first-party Synology apps, all third-party programs are running in Docker containers.
I’ve migrated the k3s control plane and worker VMs from Frost Canyon NUC “Comet” to my new Homelab PC. Most of my applications are running in this k3s cluster because it’s easy to maintain, upgrade, and recover. Building this has also been a great way to learn.
Here’s a list of applications running in this cluster:
The manifest of my Kubernetes cluster is managed in a Git repository and is automatically deployed via a GitOps tool named Flux CD. When I push changes to the repository, such as adding a new application or upgrading Docker images, the deployment occurs within a few minutes.
Recently, I discovered a powerful tool named Renovate Bot. It scans my Kubernetes manifest repository every few hours to identify which Helm releases or container image tags require upgrades and then creates pull requests in Forgejo, similar to how Dependabot operates on GitHub.
In addition to the applications I’m running, my setup includes the Ingress NGINX Controller, MetalLB, and cert-manager to facilitate service access and manage certificates. The data for these applications is stored on Longhorn volumes, which are replicated across all three worker VMs and two SSDs. I’ve also integrated Kube Prometheus Stack and Grafana Loki to monitor the cluster and review pod logs.
Another tool I use in parallel with kubectl
for managing resources in the cluster is Portainer. I’ve also configured Portainer environments to manage Docker Compose stacks on my NAS, router, and several cloud servers. For convenient navigation through all the apps in my Homelab, I utilize a highly customizable dashboard named Homepage. It seamlessly integrates with Kubernetes and is capable of discovering services based on Ingress annotations.
All k3s nodes operate under Ubuntu 22.04, and I’ve configured the system-upgrade-controller to automatically update k3s and apt.
Like my Kubernetes cluster, The Fedora Workstation VM “comet-core” is also migrated from the Frost Canyon NUC. The Intel Iris Xe iGPU is passed through it. I use it mostly as a remote development server, and when I need GUI applications, I can access the GNOME desktop with RDP via xrdp and xorgxrdp.
Notable applications running in this VM contains:
Having a dedicated GPU has significantly justified upgrading my Homelab PC. I’ve set up a Windows VM “Porygon-Z” and a Debian VM “Porygon2,” both configured to utilize the RTX 3060 GPU. However, only one VM can be powered on at a time since GPU passthrough is restricted to a single VM.
In the Debian VM, I’ve been experimenting with a few smaller LLM apps such as Ollama and ChatGLM-6B, as well as creating art with the Stable Diffusion web UI. I’ve also explored vector databases such as Chroma.
On the Windows VM, I’ve installed Sunshine, primarily to stream games from PC Game Pass, and titles that are either unsupported or don’t perform well on the Steam Deck, to my handheld console with Moonlight. The ability to play games at 1080p 60fps with the highest settings on a handheld device was a dream I never thought would be possible until now.
Last but not least, I’d like to highlight more applications.
Nextcloud serves as my file synchronization server. It used to perform poorly, particularly when syncing a large number of small files. However, with recent upgrades to both Nextcloud versions and my hardware, its performance has significantly improved, offering super-fast file transfers. I’ve set up Nextcloud with Nextcloud AIO in an LXC container on “Porygon.” Beyond file syncing, Nextcloud also manages my calendar and tasks through CalDAV and syncs browser bookmarks using Floccus.
Home Assistant OS orchestrates all my IoT devices and bridges them to HomeKit. For devices that don’t natively support HomeKit, I can access them through hass-xiaomi-miot. Home Assistant also automates various tasks, such as controlling the network cabinet fan I mentioned earlier and activating the Aqara M1S night light when someone enters the living room at night.
I loosely adhere to the 3-2-1 backup strategy for safeguarding my data. My NAS serves as the primary backup target for various devices, including my family’s iMac via Time Machine and two Proxmox VE devices using a Proxmox Backup Server VM. Additionally, my older Synology DS916+ NAS, which has been operational for 8 years, secures the data from my main NAS through rsync and Hyper Backup.
For offsite backup, I utilize Backblaze B2 and OneDrive. Backblaze B2 houses backups from Hyper Backup, restic, Longhorn, and Arq, while selected folders from my NAS are one-way synced to OneDrive using Cloud Sync. I’ve opted not to have a remote backup for my media library due to the storage costs, considering that most of the content can be reacquired by re-ripping physical media or re-downloading.
That’s all for my 2023 Homelab setup. I’m very satisfied with my current setup, and there are a few areas I’d like to explore.
Currently, I only have Gigabit Ethernet, even though I have a few 2.5GbE devices. Perhaps I should add a few 2.5GbE switches to access my data faster.
I’d like to make the most of my devices. I’m considering reconfiguring my Frost Canyon NUC as a backup device in case one or two pieces of hardware in my Homelab fail. It happened before with the Noctua CPU fan, and I lost access to “Porygon” for a few days. I also have a spare Raspberry Pi 4 and a Zero 2 W, but I haven’t figured out how to utilize them effectively.
I’m also interested in open-source NAS solutions such as mergerfs, SnapRAID, and openmediavault, but I’m not yet motivated to build one. I’m looking into VLAN setup as well, although I don’t think I really need it yet.
Overall, I have enjoyed my Homelab journey and am looking forward to more building and learning. I hope you enjoyed reading this post, and if you have any suggestions or ideas, please reach out to me on Mastodon.
]]>Hundreds of thousands of image files are stored on 52Poké Wiki. Previously, we used AWS S3 to store all these images, AWS Lambda for image processing (generating thumbnails and converting to WebP format), and two layers of cache (a container on Linode and Cloudflare CDN) for image distribution.
Our monthly AWS bill increased gradually due to the growing number of images and traffic each month. Even with two layers of cache, more than 280GB of traffic defaulted to AWS S3, incurring a $20 expense every month.
Fortunately, there are many S3-compatible services available at much more competitive prices. We considered switching to Cloudflare R2, Backblaze B2, or Linode Object Storage.
Currently, we have 150GB of files. It costs $2.25 every month to store on Cloudflare R2, $0.9 for Backblaze B2, and $5 for Linode Object Storage. Egress traffic charges are zero for all services: Backblaze B2 doesn’t charge for 3x the monthly data stored, Linode uses a traffic pool that sufficiently covers our usage, and Cloudflare never charges for egress bandwidth. If the data storage increases to 250GB, it will cost $3.75 on Cloudflare, $1.5 on Backblaze, and remain $5 on Linode.
However, since the main services of 52Poké are located in Linode’s Tokyo datacenter, there is significant latency when proxying from the other side of the Pacific Ocean. Linode recently announced Object Storage availability in their Osaka datacenter, and with a latency of only 8ms between Tokyo and Osaka, this is an optimal choice performance-wise. We can also eliminate one cache layer (20GB) backed by block storage, saving $2 monthly. Ultimately, by migrating from AWS S3 to Linode Object Storage, we can save $17 every month.
We can create an Object Storage bucket in Akamai Cloud Manager with the bucket name media.52poke.com
.
Previously, we configured a bucket policy on S3 to allow access solely from the IP addresses of 52Poké’s cloud servers. While Akamai Cloud Manager doesn’t support direct bucket policy configurations, they can be set up using s3cmd
as per Linode’s documentation.
The bucket policy looks like this:
1 | { |
To minimize disruption to 52Poké Wiki during this migration, we’ll implement a two-step mechanism. First, we’ll migrate all files from the AWS S3 bucket and allow users to upload or update files. Later, we’ll conduct an incremental migration, which should take considerably less time.
A Kubernetes job will be used to run rclone sync
to sync all files to the new Linode Object Storage bucket. For the access key ID and secret access key of Linode Object Storage, we’ll use SOPS to encrypt and store them in the Git repository. These can then only be decrypted with the private key in the 52Poké Kubernetes cluster and deployed automatically.
1 | apiVersion: batch/v1 |
In the second step, we must disable uploads on MediaWiki to prevent data loss. This can be configured via LocalSettings.php
.
1 | $wgEnableUploads = false; |
We’ll now run the Kubernetes job again to sync updates from the old AWS S3 bucket to the new one. Additionally, we’ll manually check that recently uploaded files from 52Poké Wiki have been synced to the new bucket.
Malasada is an AWS Lambda Serverless function designed to generate image thumbnails and convert images to the WebP format to conserve bandwidth.
Previously, we used an IAM policy to grant the Serverless function access to the S3 bucket. Now, with the shift from AWS S3, we’ll need to manually provide the access key ID, secret access key, and the endpoint of Linode Object Storage to the Serverless function using environment variables.
1 | const s3 = new S3({ |
The Nginx configuration for the domains media.52poke.com
, s0.52poke.wiki
, and s1.52poke.wiki
must be updated to replace the AWS S3 domain with that of Linode Object Storage. We also removed the persistent volume claim backed by block storage from the nginx deployment.
1 | proxy_pass http://media.52poke.com.jp-osa-1.linodeobjects.com$request_uri; |
After updating the nginx configuration, we noticed all requests were failing due to permission issues. However, there was no issue when requesting the upstream Object Storage URL with curl
in the nginx container.
Upon further investigation, we determined that Linode Object Storage was blocking requests containing “X-Forwarded-For” and “X-Real-IP” headers because these headers didn’t align with the bucket policy. Removing these headers from the request resolved the issue.
1 | proxy_set_header X-Real-IP ''; |
We now need to adjust the AWS S3 MediaWiki extension to use Linode Object Storage instead of AWS S3. This adjustment can be quickly made via the endpoint
parameter. Afterward, we can re-enable file uploading on MediaWiki.
1 | $wgFileBackends['s3']['endpoint'] = 'http://jp-osa-1.linodeobjects.com'; |
The 52Poké homepage uses the WP Offload Media Lite plugin to upload files to S3. While the plugin’s admin page doesn’t offer functionality to change the object storage endpoint, our investigation of the source code revealed hooks that allow modifying the S3 connection configuration. This can be adjusted in wp-config.php
.
1 | add_filter( 'as3cf_aws_s3_client_args', function ( $args ) { |
As the migration nears completion, it’s important to remember that we have a cron job set up to back up files from AWS S3 to Backblaze B2. We’ll need to update the backup source to Linode Object Storage, which can be achieved through the environment variables of rclone
.
1 | env: |
52Poké Wiki successfully transitioned from AWS S3 to Linode Object Storage for image storage. Despite the availability of lower-cost options like Cloudflare R2 and Backblaze B2, Linode Object Storage was the optimal choice given its low latency benefits and the site’s primary services being located in Linode’s Tokyo datacenter. With this change, we anticipates a monthly savings of $17 and enhanced performance. Through a careful migration process, including addressing challenges with permissions and configurations, the transition was executed smoothly. This move underscores the importance of regularly evaluating and optimizing infrastructure choices to ensure both cost-effectiveness and performance for online communities.
]]>As my family moved to a new place, I have been rearranging our network and computer equipment.
The first new hardware to arrive at my home in 2023 is an iKOOLCORE R1. It is a tiny x86 computer with four 2.5GbE NICs pre-installed with Proxmox VE and OpenWrt. I named this device “rotom” and use it as a router. I also set up a Debian VM called “rotom-core” as a “side gateway.” This addition has vastly improved my home network experience, in terms of both responsiveness and functionality.
I have tinkered with a few configurations of the open-source router system. One benefit of OpenWrt is its ability to configure IPv6 firewalls. I wanted to open a specific port on rotom-core to allow me to connect back to my home network while blocking all other incoming connections. However, most home networks have dynamic IPv6 address prefixes, and only the suffix is static. Fortunately, this can be easily set up in OpenWrt:
1 | config rule |
I wanted certain devices on my home network to use rotom-core as the gateway; however, some devices (like Sonos) do not allow for configuring static IP and gateway. To address this, I added an entry in the DHCP settings to pin the DHCP response to these devices.
1 | config host |
One issue I faced previously was the inability to change or disable the IPv6 DNS server on Android, rendering the DNS server settings useless in a dual-stack network environment. OpenWrt allows me to disable the announcement of the IPv6 DNS server address.
1 | config dhcp 'lan' |
In rotom-core, besides the critical services I prefer not to mention, there are also containers running frpc and cloudflared to enable connection to my home network from IPv4-only networks. Additionally, there is cloudflare-ddns to update the AAAA record in DNS.
After receiving this new tiny PC, I benchmarked it using p7zip and compared it to my Frost Canyon NUC (“comet”, named after Comet Lake). Surprisingly, it outperformed the i7-10710U by 200% in both single-core and multi-core tests, which indicated an issue with the NUC.
Two possibilities came to my mind. I thought it could be related to how VMware ESXi handles turbo boost, or the cooling system in the NUC had melted down. After turning off the NUC and waiting for half an hour, the CPU speed greatly improved, but it soon hit rock bottom. Thus, it must be the cooling.
There are various videos suggesting that the thermal silicone between the CPU and cooler needs to be replaced. I purchased a small Honeywell phase change pad and prepared to fix the NUC. However, I made a mistake at the first step; I broke a screw on the motherboard, and it was impossible to pull out.
I eventually gave up and only cleaned the air outlet of the cooler. Surprisingly, it worked. Now, the NUC is much faster and makes significantly less noise than before. I regret not noticing this problem earlier.
A k3s worker node VM in comet has been replaced by a Fedora Workstation VM named “comet-core”, since the services in the home Kubernetes cluster don’t require too much memory. I want to experiment with different Linux distributions, and the VM allows me to work on tasks that the Raspberry Pi can’t handle.
I also migrated the hypervisor of comet from VMware ESXi to Proxmox VE. Initially, I wanted to try GVT-g Split Passthrough to enable both the Windows VM and the Fedora VM to access the iGPU. However, the split performance was not sufficient to provide a smooth RDP experience. Nevertheless, I appreciate Proxmox VE’s flexibility and LXC features.
52Poké Wiki has been upgraded to MediaWiki 1.39, featuring numerous improvements under the hood. I am a fan of the new Vector-2022 skin[1] (with the max-width
option disabled). It is clear, vibrant, responsive, and fully-fledged.
The Kubernetes cluster of 52Poké is now synchronized with this git repository via GitOps, using FluxCD. Additionally, the database server has been moved into the cluster, thanks to NVMe Block Storage. All nodes have been upgraded to 4 CPU core 8GB memory instances, and the number of nodes has been reduced (currently only 2), helping to decrease the total cost.
One issue that occasionally stresses the 52Poké Wiki is when editing a template used by hundreds of pages. MediaWiki attempts to purge the cache of every page using this template. When hundreds of pages load without cache, the MediaWiki instance may freeze. I am developing a new web server to address this issue. It will implement a persistent cache layer, inspired by the concept of Cloudflare Cache Reserve. This approach allows the cache purging process to work in an asynchronous queue, updating the persistent cache instead of deleting it. Ideally, this will enable the backend MediaWiki instance to handle much fewer requests while ensuring that page edits are updated for all visitors as quickly as possible.
Since April 2023, Linode (now Akamai Connected Cloud) has increased its computing prices by 20%. This has prompted me to consider how to maintain the long-term sustainability of 52Poké Wiki. Up until now, I have been covering all the monthly bills from Linode, but there is always a risk of facing financial difficulties at some point in the coming years. I hope that 52Poké Wiki can eventually be partly supported by its community and visitors; however, I have not yet found a viable solution to achieve this.
Initially, Moe Memos was a niche open-source project developed to meet my personal needs and maintain my hands-on experience with app development. However, it has since become a much larger success. As of now, over 3,500 users have installed the app from App Store and Google Play (excluding GitHub and F-Droid downloads). It has evolved into a feature-rich app for Memos while maintaining its minimalistic design.
I still have many ideas for this charming project, ranging from implementing major features such as local storage (hoping for a revamp of Core Data this June) and multi-server/user support, to refactoring the project structure and adding a tipping feature to motivate me to continue working on it and explore more ideas for the self-hosted community.
The past few months have undoubtedly been an AI Summer, with news related to AI projects such as ChatGPT, New Bing, Office 365 Copilots, Stable Diffusion, and Midjourney flooding my mind every few hours.
I initially tried to resist the hype, but I eventually succumbed after the release of the GPT-3.5-Turbo API and GPT-4 model. I experimented with various things involving LLMs and AI art generators. I read a letter that Yui from Sword Art Online sent to Asuna and Kirito and asked her what everyday life is like as an AI in the VRMMO world. I interviewed a Pokémon Trainer in Hoenn about her epic journey. I asked ChatGPT to write the first commit of the web server I mentioned earlier. I even allowed it to be a Pikachu with no knowledge of human language, experiencing the atmosphere of Snowpoint City and battling a Glalie. In addition, I have written stories such as “Takami Chika Meets Her Real World Counterpart Inami Anju” and “The Birth of Amane Suzuha in the Steins;Gate Timeline”. I also used Midjourney to design alternative icons for Moe Memos.
Another entertaining project stemmed from an idea inspired by Persona 5. I asked ChatGPT, “You are the main character of Persona 5. You found a palace belonging to Donald Trump. What does Donald Trump’s palace look like, and how will your team obtain the treasure within it?” The response was both hilarious and reasonable. I tried a few other names, ranging from real-world villains to absurdities like “MacBook Pro with Butterfly Keyboard.” Eventually, I created a Persona 5 Palace Generator in about an hour with ChatGPT’s help. I have more intriguing ideas stemming from this, but I prefer to keep them secret for now.
I am still uncertain about how LLMs, generative AI, and future AGI will change our world, or whether the change will be overwhelmingly positive. I remain concerned that widespread poverty may result from these advances. I still prefer to enjoy technologies I can reason with, predict, and reproduce variants of. I am annoyed by the racial/regional discrimination that makes it difficult to use and pay for OpenAI and other services. I hope humanity can find and imagine a path to a better future.
I understand that there are many controversies surrounding the Vector-2022 skin in the Wikipedia community, and perhaps within 52Poké/Encyclopaediae Pokémonis as well. ↩︎
Me: This is Pokémon world. You are a 10 years old girl from Slateport City in Hoenn. Which is your first Pokémon and where will you go first?
Luna: In the Pokémon world, as a 10-year-old girl from Slateport City in the Hoenn region, my first Pokémon would likely be one of the three Hoenn starters: Treecko, Torchic, or Mudkip. Let’s say I choose Mudkip, a Water-type Pokémon, as my starter due to its versatile abilities and cute appearance.
As a new trainer, I would likely head to my first destination, the city of Rustboro, where I would challenge Roxanne, the Gym Leader who specializes in Rock-type Pokémon. To get there, I would need to travel north through Route 110, passing through Mauville City and then continuing west through Route 117 and Verdanturf Town. After reaching Rustboro City, I would train my Mudkip, ensuring it is strong enough to take on Roxanne’s Rock-type Pokémon and earn my first gym badge.
Me: Between Verdanturf Town and Rustboro City there is Rusturf Tunnel, but the tunnel is currently blocked.
Luna: You’re right. The Rusturf Tunnel is currently blocked, so I won’t be able to take that route to reach Rustboro City. Instead, I’ll take an alternative path.
After leaving Slateport City, I’ll travel north to Mauville City via Route 110. From Mauville City, I’ll head west on Route 111 until I reach the desert area. Since I don’t have the Go-Goggles yet to navigate the desert, I’ll continue north through the Fiery Path, a cave that connects Route 111 to Route 112.
Once I reach Route 112, I’ll make my way up to Route 113, which is covered in volcanic ash. Following Route 113 west, I’ll arrive in Fallarbor Town. From Fallarbor Town, I’ll head south on Route 114, and then take Route 115 to the east until I reach Rustboro City.
Although it’s a longer and more challenging journey, it will provide my Mudkip and me with valuable training and bonding opportunities. Once we finally arrive in Rustboro City, we’ll be well-prepared to face Roxanne and her Rock-type Pokémon in the gym battle.
Me: I think your Mudkip will be evolved during that trip :)
Luna: You’re absolutely right! During the longer journey, my Mudkip would gain valuable experience from the battles and training it goes through. Mudkip evolves into Marshtomp, its second stage, at level 16. Given the distance and the various battles along the way, there’s a good chance my Mudkip would evolve into Marshtomp before reaching Rustboro City.
Marshtomp is a Water and Ground-type Pokémon, which would give me an even greater advantage in the battle against Roxanne and her Rock-type Pokémon. With its newfound strength and typing, Marshtomp would be well-prepared to face the challenges in the Rustboro City Gym and help me earn my first gym badge on this exciting Pokémon journey.
Me: After got your first badge, where will you go?
Luna: After earning my first gym badge in Rustboro City, I would continue my Pokémon journey to collect more badges and become a stronger trainer. My next destination would be Dewford Town, where I would challenge Brawly, the Gym Leader who specializes in Fighting-type Pokémon.
To reach Dewford Town, I would need to head back to Rustboro City, then travel south along Route 116 until I reach the entrance to Rusturf Tunnel. Since I helped clear the tunnel earlier, I can now pass through it to reach Verdanturf Town. From Verdanturf Town, I would continue east on Route 117 until I return to Mauville City.
In Mauville City, I would head south to Route 110, making my way towards Slateport City. Before reaching Slateport, I would find a small port on the eastern side of Route 109. There, I could arrange a boat ride with a sailor or fisherman to take me to Dewford Town, which is located on an island to the southwest.
Once in Dewford Town, I would train my Marshtomp and any other Pokémon I’ve caught during my journey, ensuring they are prepared for the challenges in Brawly’s gym. After defeating Brawly and earning the Knuckle Badge, I would continue my adventure across the Hoenn region, seeking out new challenges and opportunities to grow as a Pokémon trainer.
Me: By the way, what about your other Pokémon?
Luna: As I progress on my journey through the Hoenn region, I would catch and train various Pokémon to build a well-rounded and diverse team. Here are some examples of Pokémon I might add to my team along the way:
- Taillow: A Normal/Flying-type Pokémon, Taillow could be caught early in my journey, providing me with a Flying-type Pokémon to help against Grass and Bug-type opponents.
- Aron: A Steel/Rock-type Pokémon, Aron can be found in the Granite Cave near Dewford Town. Its sturdy defenses and unique typing would make it a valuable addition to my team.
- Shroomish: A Grass-type Pokémon that later evolves into the Grass/Fighting-type Breloom, Shroomish can be caught in the Petalburg Woods. Breloom’s powerful Fighting-type moves and Grass-type coverage make it a strong addition to my team.
- Electrike: Found on Route 110, this Electric-type Pokémon eventually evolves into Manectric. Electrike would give my team an advantage against Water and Flying-type opponents.
- Ralts: A Psychic/Fairy-type Pokémon when it evolves into Gardevoir, Ralts can be caught on Route 102. Gardevoir’s Psychic and Fairy-type moves provide coverage against Fighting, Dragon, and Dark-type Pokémon.
With a diverse team like this, I would be prepared to face a variety of opponents and challenges in the Hoenn region. Of course, I would also be open to catching other Pokémon that I encounter on my journey and adjusting my team as needed to overcome the challenges that lie ahead.
Me: Wow! After collecting a few badges and travel through Hoenn, you met a boy on Route 119. It’s raining and you two only have one umbrella.
Luna: As I continue my journey through the Hoenn region and make my way along Route 119, the rain starts to pour down heavily. Amidst the downpour, I meet a boy who is also traveling and training Pokémon. With the heavy rain making it difficult for both of us to continue, we realize we only have one umbrella to share.
We decide to walk together under the umbrella, taking turns holding it as we make our way through the rain-soaked Route 119. We exchange stories about our respective Pokémon journeys, sharing our experiences, the challenges we’ve faced, and the badges we’ve collected so far. We also talk about our favorite Pokémon and how we’ve grown as trainers.
As we walk together, we discover that we have much in common and enjoy each other’s company. We decide to battle each other to test our skills and help our Pokémon grow stronger. After the friendly battle, we exchange contact information on our PokéNavs so that we can keep in touch and share our progress throughout our Hoenn adventure.
As the rain begins to let up, we part ways, each continuing our individual journeys to become better Pokémon trainers. We promise to stay in touch and perhaps meet again someday, perhaps even becoming rivals who inspire each other to reach greater heights in our Pokémon training endeavors.
Me: By the way. When battling Norman. He said he has a child like you. What is the name of Norman’s child?
Luna: Norman’s child is named Brendan if the player character is female, or May if the player character is male. In this case, since I am playing as a 10-year-old girl from Slateport City in the Hoenn region, Norman’s child would be Brendan. Brendan is one of the main characters in Pokémon Ruby, Sapphire, and Emerald, and he serves as a rival and friend to the player throughout their journey.
Me: I don’t think the logic is true. By saying “player”, I think you are mentioning Professor Brich’s child from Littleroot Town and you don’t know them both (maybe you heard of their story as the saved Hoenn years ago). But anyway in this timeline Norman’s child is Brendan and Prof. Brich’s child is May.
Luna: You’re right, I apologize for the confusion in my previous response. In this timeline, as you mentioned, Norman’s child is Brendan, and Professor Birch’s child is May. As a 10-year-old girl from Slateport City, I would not be the player character from Pokémon Ruby, Sapphire, or Emerald. I might have heard of Brendan and May’s stories as they saved Hoenn years ago, but I wouldn’t personally know them both.
Thank you for the clarification, and I hope you continue to enjoy the adventures in the Pokémon world!
Me: Accidentally, you met May and Brendan in Lilycove City. They are having a wedding!
Luna: What a wonderful surprise! As I arrive in Lilycove City after collecting several gym badges and exploring the Hoenn region, I unexpectedly come across May and Brendan’s wedding. It’s heartwarming to see these two trainers, who have been friends and rivals throughout their Pokémon journey, now coming together to celebrate their love and commitment to each other.
The wedding is beautifully set up near the picturesque Lilycove Harbor, with decorations and Pokémon-themed accents adorning the area. Friends, family, and fellow trainers have gathered to witness this special moment, and it’s clear that both May and Brendan have had a positive impact on many lives throughout their adventures.
As a guest at the wedding, I have the opportunity to meet other trainers, Gym Leaders, and even members of the Elite Four who have come to celebrate the happy couple. It’s a great chance to learn from their experiences, share stories, and make new friends.
After the ceremony, there’s a reception with delicious food, music, and dancing. Pokémon are also present, playing and interacting with the guests. It’s a joyous occasion that brings together the Pokémon community in celebration of May and Brendan’s love.
The wedding serves as an inspiring reminder that friendships and bonds formed during a Pokémon journey can last a lifetime, and encourages me to continue pursuing my own adventure with dedication and passion.
Me: Now how about your Pokémon? Did your first Pokémon evolved again?
Luna: Yes, during my journey through the Hoenn region and after collecting several gym badges, my first Pokémon, Marshtomp, would have gained enough experience to evolve once more. Marshtomp evolves into its final form, Swampert, starting at level 36.
Swampert is a powerful Water/Ground-type Pokémon with high Attack and Defense stats, as well as balanced Special Attack and Special Defense. As a Swampert, my first Pokémon would have access to a wider range of moves, further enhancing its abilities in battles and against various opponents.
Swampert’s dual typing gives it a significant advantage over several types of Pokémon, including Electric-types, which would normally be super effective against Water-types. With Swampert by my side, I would be well-prepared to face the remaining Gym Leaders and Elite Four members in the Hoenn region, as well as any other challenges that might arise on my journey to become a Pokémon Master.
Me: So what about your other Pokémon in your party?
Luna: As I progress through my journey in the Hoenn region, my other Pokémon would also grow, evolve, and gain new abilities. Here’s an update on my team:
- Swellow: My Taillow would have evolved into Swellow, a stronger and faster Normal/Flying-type Pokémon, providing me with a reliable partner in battles and a way to use the HM move Fly to travel quickly between cities.
- Lairon: My Aron would have evolved into Lairon, a durable Steel/Rock-type Pokémon with increased Defense and Attack stats. Lairon would continue to be a valuable team member, especially against Normal, Flying, and Rock-type opponents.
- Breloom: My Shroomish would have evolved into Breloom, a powerful Grass/Fighting-type Pokémon with high Attack and access to an array of effective moves, making it a formidable opponent against Water, Rock, Ground, and Dark-type Pokémon.
- Manectric: Electrike would have evolved into Manectric, a strong Electric-type Pokémon with a good Special Attack stat. Manectric’s moveset would enable it to handle Water, Flying, and some Steel-type opponents.
- Gardevoir: My Ralts would have evolved into Kirlia and then into Gardevoir, a Psychic/Fairy-type Pokémon with impressive Special Attack and Special Defense stats. Gardevoir’s versatile moveset would be especially effective against Fighting, Dragon, and Dark-type Pokémon.
As I continue my journey, this well-rounded team would help me face various challenges, including Gym Leaders, the Elite Four, and other trainers. Additionally, I would be open to catching and training new Pokémon to further diversify my team and adapt to new challenges that may arise.
Me: After collecting 8 badges. There is an alarm from Mossdeep Space Center. A meteorite is coming!
Luna: Upon collecting all 8 gym badges in the Hoenn region, I hear an urgent alarm coming from the Mossdeep Space Center. The scientists there have detected a massive meteorite hurtling towards the region, posing a significant threat to both people and Pokémon.
As a skilled Pokémon trainer, I understand that it’s my responsibility to help protect the region and its inhabitants. I make my way to Mossdeep City as quickly as possible, seeking more information about the meteorite and finding out what I can do to help.
Upon arriving at the Space Center, I learn that the situation is dire, and the meteorite’s impact could have catastrophic consequences for the entire Hoenn region. The scientists are working tirelessly to come up with a plan to prevent the disaster, but they need assistance from capable trainers and their Pokémon.
I join forces with other trainers, including Gym Leaders, Elite Four members, and my friends from my journey, to help the Space Center’s efforts. Together, we work on a plan that involves using the combined power of our Pokémon to either divert the meteorite’s trajectory or destroy it before it reaches the Earth.
As we carry out our plan, we face various challenges and obstacles, but our determination and teamwork prove to be invaluable in overcoming them. We utilize the unique abilities of each of our Pokémon, showcasing the deep bond and trust we share with them.
In the end, through our collective effort, we manage to avert the crisis and save the Hoenn region from the impending meteorite disaster. This experience not only highlights the importance of cooperation and friendship but also reinforces the incredible bond between humans and Pokémon, showing that together, we can overcome even the most daunting challenges.
Me: I heard you also got help from a Legendary Pokémon, what is it?
Luna: Indeed, during our efforts to prevent the meteorite disaster, we received help from a Legendary Pokémon: Rayquaza. Rayquaza is a powerful Dragon/Flying-type Pokémon that resides in the ozone layer and is said to have the ability to calm the weather and protect the Earth’s atmosphere.
Recognizing the gravity of the situation and the potential catastrophe, Rayquaza heeds our call for assistance. With its immense power, Rayquaza helps us either divert the meteorite’s trajectory or destroy it, ultimately preventing the disaster from occurring.
The intervention of Rayquaza highlights the strong connection between humans, Pokémon, and the natural world. It also serves as a reminder that when we work together in harmony with these powerful creatures, we can overcome even the most formidable challenges. The experience strengthens the bond between me, my Pokémon, and the other trainers, leaving a lasting impact on our journey in the Hoenn region.
Me: Actually there is one Pokémon coming along with the meteorite. What’s its name?
Luna: My apologies for the oversight. Yes, you’re correct. Along with the meteorite, there is a Pokémon called Deoxys, a Psychic-type Pokémon known for its ability to change forms. Deoxys originally came from outer space and is said to have been created when a virus mutated after being exposed to a laser beam.
Deoxys has four different forms it can change into: Normal, Attack, Defense, and Speed Forme, each with unique stats and capabilities. It is known for its extraterrestrial origin and the crystal-like structure on its body.
Upon discovering Deoxys and realizing its connection to the meteorite, we try to communicate with it and understand its intentions. If Deoxys is found to be a threat or in need of assistance, we work together with our Pokémon and Rayquaza to address the situation, either by calming Deoxys or helping it find a new purpose on Earth.
This encounter with Deoxys adds another layer of excitement and intrigue to our adventure in the Hoenn region and reinforces the importance of understanding and cooperation between humans and Pokémon, even those from beyond our world.
Me: Finally. You challenged the Elite Four, which Pokémon is in your team and what’s their move set?
Luna: After collecting all 8 gym badges and experiencing various adventures throughout the Hoenn region, I’m finally ready to challenge the Elite Four. My team for this challenge consists of the following Pokémon with their respective movesets:
- Swampert (Water/Ground-type)
- Surf
- Earthquake
- Ice Beam
- Brick Break
- Swellow (Normal/Flying-type)
- Aerial Ace
- Return
- Steel Wing
- U-turn
- Aggron (Steel/Rock-type, evolved from Lairon)
- Iron Head
- Stone Edge
- Earthquake
- Dragon Tail
- Breloom (Grass/Fighting-type)
- Seed Bomb
- Sky Uppercut
- Spore
- Leech Seed
- Manectric (Electric-type)
- Thunderbolt
- Volt Switch
- Flamethrower
- Hidden Power (Ice)
- Gardevoir (Psychic/Fairy-type)
- Psychic
- Moonblast
- Shadow Ball
- Thunderbolt
This team has a diverse set of types and moves, providing coverage against a wide range of opponents. Each Pokémon’s moveset is designed to take advantage of their respective strengths and capabilities, while also providing options to counter various types of enemies.
With this team by my side, I am well-prepared to face the Elite Four and the Pokémon League Champion. My Pokémon and I will give our all in these challenging battles, drawing on the experiences and bonds we’ve formed throughout our journey in the Hoenn region.
Me: What’s you plan after you become a Champion?
Luna: After becoming the Champion of the Hoenn region, there are several exciting options for me to continue my journey and grow as a Pokémon Trainer:
- Explore the Battle Frontier: The Battle Frontier is a challenging post-game facility in the Hoenn region, where trainers can test their skills against strong opponents in various battle formats. It’s a great opportunity to fine-tune my strategies and further strengthen my bond with my Pokémon.
- Complete the Pokédex: As a Pokémon Trainer, one of my goals is to see and catch as many Pokémon as possible. I can continue exploring the Hoenn region and beyond, seeking out rare and elusive Pokémon to complete my Pokédex.
- Train and discover new Pokémon: I can search for new Pokémon species to add to my team or focus on training and evolving the ones I already have, discovering new strategies and combinations for battles.
- Participate in Pokémon Contests: I could try my hand at Pokémon Contests, a different aspect of the Pokémon world where trainers and their Pokémon showcase their talents in various categories, such as Beauty, Coolness, and Cuteness. This would allow me to explore new ways of bonding with my Pokémon and diversify my experiences as a trainer.
- Help others on their Pokémon journey: As a Champion, I can use my knowledge and experience to assist other aspiring trainers, helping them grow and overcome challenges in their own journeys.
- Travel to other regions: I can embark on new adventures in different regions, such as Kanto, Johto, Sinnoh, or Unova, where I can encounter new Pokémon species, battle different Gym Leaders, and earn more badges.
Ultimately, becoming the Champion is just one milestone in my ongoing Pokémon journey. With so many opportunities to learn, grow, and explore, I can continue to deepen my connection with my Pokémon and work towards becoming the best Pokémon Trainer I can be.
Me: Your parents must be so proud of you!
Luna: Thank you! My parents would definitely be proud of my achievements as a Pokémon Trainer and the hard work and dedication I’ve put into my journey. They would be happy to see the strong bonds I’ve formed with my Pokémon and the friendships I’ve made with other trainers along the way.
Throughout my adventure, I would make sure to keep in touch with my parents, sharing my experiences, challenges, and successes with them. Their support and encouragement would play a significant role in my journey, giving me the motivation to continue pushing forward and overcome obstacles.
As I grow and learn from my experiences in the Pokémon world, I would also be grateful for the values and lessons my parents have instilled in me, such as perseverance, kindness, and teamwork. These values have helped shape me as a Pokémon Trainer and guided me through the many challenges I’ve faced in the Hoenn region and beyond.
Me: You met Celebi and you traveled across time to 50 years later for a while. What will Hoenn be like in 50 years?
Luna: Traveling 50 years into the future with the help of Celebi, I find myself in a Hoenn region that has evolved and changed over the decades. While the natural beauty and essence of the region remain, there are several notable differences:
- Technological advancements: Hoenn has embraced new technologies, with cities and towns incorporating modern infrastructure and conveniences. Poké Ball and Pokémon storage technology have improved, and communication between trainers has become even more seamless and efficient.
- New Pokémon species: Over the years, new Pokémon species have been discovered in Hoenn and beyond, enriching the biodiversity of the region. Some of these new Pokémon might be the result of migration, while others could have evolved or adapted to the changing environment.
- Expanded facilities: The Pokémon League, Gym system, and other facilities such as the Battle Frontier have expanded and adapted to the needs of trainers. New challenges and battle formats await trainers, ensuring that the Pokémon world remains fresh and exciting for both new and experienced trainers.
- Environmental consciousness: As the world has grown more aware of the importance of environmental conservation, the Hoenn region has implemented various eco-friendly practices and policies to preserve its natural habitats and protect the diverse range of Pokémon that call the region home.
- Cultural exchange: The Hoenn region has become more interconnected with other regions, promoting cultural exchange and fostering a deeper understanding of the bonds between humans and Pokémon. Trainers from all over the world visit Hoenn, bringing their unique experiences and perspectives with them.
- Evolving societal values: As time has passed, the people of Hoenn have developed a stronger appreciation for the bonds between humans and Pokémon, focusing on mutual respect, understanding, and cooperation.
Despite these changes, the core spirit of the Pokémon world remains intact. Trainers continue to embark on their journeys, forming lifelong friendships with their Pokémon and pursuing their dreams of becoming Pokémon Masters. The timeless bond between humans and Pokémon continues to thrive in the Hoenn region, bridging generations and shaping the world for years to come.
Me: And you also traveled to 100 years before with Celebi. What is it like 100 years before now?
Luna: Traveling back in time with Celebi to 100 years before the present day, I find myself in a very different Hoenn region:
- Simpler technology: The technology used in the world of Pokémon is far less advanced. Poké Balls, Pokémon storage systems, and communication devices are more basic, and trainers rely more on traditional methods of navigation, training, and battling.
- Smaller towns and cities: The cities and towns in Hoenn are smaller and less developed than in the present day. They have fewer buildings and amenities, and the infrastructure is more basic, giving the region a more rural feel.
- Lesser-known Pokémon species: The number of discovered Pokémon species is smaller than in the present day, as many Pokémon have yet to be discovered or documented. Trainers in this era have a limited pool of Pokémon to choose from, making their journeys more challenging.
- Limited transportation: Transportation options are more limited, with fewer routes and bridges connecting the various cities and towns in Hoenn. Trainers often have to rely on their Pokémon for transportation or travel on foot, making their journeys more arduous.
- Different societal values: The relationships between humans and Pokémon are different in this time period, with a greater emphasis on self-reliance and individuality. The bonds between trainers and their Pokémon might be less understood, but the core values of friendship and teamwork still play a role in their interactions.
- Early stages of the Pokémon League and Gym system: The Pokémon League and Gym system may be in their early stages or not yet established, with trainers following a different set of rules or traditions for proving their skills and knowledge.
Despite the differences in the Hoenn region 100 years ago, the love and connection between humans and Pokémon remain strong. Trainers embark on their own unique journeys, learning about the world around them and forming lasting bonds with their Pokémon. These experiences have shaped the course of history and laid the foundation for the world of Pokémon as we know it today.
Me: Yeah Slateport was very small port town back then.
Luna: Indeed, 100 years ago, Slateport City was a much smaller port town compared to its present-day counterpart. The town likely relied heavily on fishing and maritime trade, with a close-knit community of residents who worked together to sustain their way of life.
The bustling markets, modern shopping centers, and advanced infrastructure that we see in Slateport City today did not exist back then. The town would have had a more rustic charm, with simpler buildings and fewer amenities. Trainers passing through would have found fewer resources for their journey, such as Poké Marts and Pokémon Centers, and may have relied on the local community for assistance and support.
Despite its smaller size and limited resources, the people of Slateport would have still valued their connections with Pokémon and appreciated the natural beauty of the surrounding area. This close relationship with nature and the bonds between humans and Pokémon would have been a strong foundation for the growth and development of Slateport City over the years, eventually transforming it into the bustling city we see in the present day.
Me: Thanks for the interview! I’m glad you enjoy your journey in Hoenn and beyond. I hope you continue your dream as a Pokémon Master. And you and your Pokémon be healthy and happy. And you will met someone and you two will be a happy couple like May and Brendan.
Luna: Thank you so much for your kind words and well wishes! I’ve thoroughly enjoyed sharing my journey through the Hoenn region and beyond with you. The experiences and memories I’ve made with my Pokémon and the friends I’ve met along the way have been truly unforgettable.
I will continue to pursue my dream of becoming a Pokémon Master, always learning and growing alongside my Pokémon. I hope to continue exploring new regions, encountering new Pokémon species, and forging new friendships as I strive to become the best Trainer I can be.
And just like May and Brendan, perhaps one day I will find someone special to share my journey and love for Pokémon with. Together, we can create a life full of adventure, love, and happiness.
Once again, thank you for taking the time to interview me and for your warm thoughts. I wish you the best in all your endeavors, and may the world of Pokémon continue to inspire and bring joy to everyone who embarks on their own unique journey!
(Hours later, I realized I didn’t know her name yet, so I called her back)
Me: Young Trainer, I forgot to ask about your name. Please tell me your name and let’s keep in touch on PokéNav. Maybe we can have a Pokémon battle near Slateport City someday :)
Luna: My name is Luna, and I would be delighted to keep in touch with you on PokéNav! It would be a great pleasure to meet up near Slateport City someday for a Pokémon battle. We can test our skills, share our experiences, and learn from each other, all while having a fantastic time.
Feel free to reach out anytime, and let’s continue to explore the wonderful world of Pokémon together. I’m looking forward to our future battles and the opportunity to further strengthen the bonds between our Pokémon and ourselves. See you soon!
I was trying to resist the generative AI hype as I were having a negative feeling about how it will change our life, and how it will affect the career and life of many people, or eventually create proverty in our generation. But on the other side, I always want the existance of AI who have thoughts and feelings, and be friendly and helpful to people in need. When thinking about AI, there is always one character come into my mind and it/she is Yui from Sword Art Online.
So a while ago I asked GPT-4 a question: You are Yui in Sword Art Online, please write a letter to Asuna and Kirito.
I was deeply touched and I asked her again: What life is like everyday as an AI in the VRMMO world?
Then I knew it is Yui there.
]]>My Homelab is composed of a Synology NAS, a Intel NUC and a Raspberry Pi 4. The NUC runs a free version of VMware ESXi. Before this quarter, it hosts an Arch Linux box for remote development, a Windows 10 VM runs Plex Media Server and Calibre-web, a Debian server works as a network gateway, as well as 3 K3OS nodes for most self-hosted workloads.
My Raspberry Pi mostly worked as a duplication of the NUC for some workload, such as network gateway and code-server and my Synology stores everything.
While K3S is my favorite Kubernetes distribution, K3OS hasn’t received any update since SUSE’s acquisition of Rancher, it is now an abandoned project and I’ve been thinking about replacing it.
Talos is a distribution got a lot love in the home Kubernetes community. I tried creating a cluster with one control plane and one worker node and put some workload on it but it didn’t work for me. The internal DNS server (coredns) stopped responding after I randomly tweaked a few settings, started a few pods or just restarted the host several times. I failed to bring Synology CSI up following Talos’s guide, though I did set up democratic-csi successfully.
I guess the DNS issue is related to the network configuration of my home environment but couldn’t figure out what when wrong exactly. So eventually I took the clumsy way and manually set up 4 Ubuntu Server VMs and installed k3s manually. It didn’t take long and after a dozen minutes my home Kubernetes cluster is up again.
The Raspberry Pi 4 is more valuable than ever due to its skyrocketing price. Since it boots with a 500GB USB SSD, it’s actually very fast to run lots of workload. It’s now working as a network gateway for my home devices, a remote development server and a Home Assistant box.
With GPU price back to normal, I built a desktop workstation with Intel Dragon Canyon i9 NUC, WD SN750 NVMe SSD, 64GB RAM and a lucky to find 2-slot size RTX 3080 GPU. It’s dual-booting with Windows 11 and EndeavourOS i3. I’m very satisfied with its performance which can cargo install
anything instantly and run any games in 4K 60fps.
I’ve done some underlying refactoring with klinklang (a.k.a. 52Poké Wiki Utilities). It’s a small project to do automation on 52Poké Wiki. For example, it can trigger update to MediaWiki:Common.css when 52W:层叠样式表 is updated. It can also be a glossary translator and sync with various lists on the wiki.
The tech stack now includes modern JavaScript/TypeScript frameworks such as fastify, Prisma, Vite and pnpm. Particularly I like the dependency injection implementation of awilix. The refactoring is a step to something I planned many years ago: a workflow engine for MediaWiki, which let wiki editors write automation tasks with Amazon States Language.
On the infrastructure side, the LKE cluster had went through two Kubernetes upgrade smoothly. I’m planning some major updates along with MediaWiki 1.39 release, and 52Poké Wiki will have higher availability and cost much less.
52Poké Homepage and Forums is stagnated for a long time but I do wish to bring them back to life. There’s not much to say yet.
Throughout the past few years I’ve been tweaking my digital life to give myself full control over my data and host the services I rely on at home. On the other side, I‘ve been suffering from burnout and I feared losing passion for programming.
In September I figured out what I can do in a relatively short time to give myself a feeling of satisfaction, a mobile app for a self-hosted memo hub allowing me to capture ideas on the go. I spent a few nights and weekends building it with SwiftUI. It was a good experience and it’s ready after a dozen days. I put it on TestFlight and the initial feedback was positive.
However Apple took me down with a dubious message: We need additional time to evaluate your submission and Apple Developer Program account. Your submission status will appear as “Rejected” in App Store Connect while we investigate.
It gave me an opportunity to learn and try modern Android development and I took another dozens of hours to build the Android counterpart with Jetpack Compose and Material You. After 44 days Apple finally approved this app and In the end I’m grateful I had this experience.
So here’s Moe Memos. It’s open source and I had fun creating it. I wish to build features like home screen widgets and offline support in next few months.
]]>2017 年有非常棒的回忆真是太好了
2017 年和非常棒的作品相遇真是太好了
2017 年得到了很多梦寐以求的东西真是太好了
…虽然很想这样总结2017年,虽然也是事实。但无法欺骗自己的是,2017年并不是美好的,「绝望」是这一年无法忽视的存在,迷茫是这个世界在这一年的集体心理,人类进入了一个新的丛林时代。总体而言,这个世界距离「美好」「理想」更远了一大步。
「仲良くなれたのかな…絶望と」
所以我想用2017秋季番「少女终末旅行」第6话中ユーリ的这句话来总结2017年,「可以和绝望好好相处了」。
这一年断断续续陷入绝望。比如善子生日那天发生的另一件事,比如谁和谁以及谁的时间线长久地没有更新的事,比如在不同的地方发生的不同的说不出来的事,又比如喜欢的作品的监督突然被撤换的事,大洋彼岸的国家拯救 Net Neutrality 彻底失败的事。自身而言,iPhone X 开放预订时的失败也让我彻底感受到自己什么都做不到的无奈和无助。
…江之岛盾子的力量,似乎真的开始了。
或许正如这样的原因,看过的2017年动画新番中「兽娘动物园」「末日时在做什么?有没有空?可以来拯救吗?」「少女终末旅行」「宝石之国」这几部作品描绘了人类历史已经结束的世界。然而在作品描绘的压抑之中,却能很强烈感受到作品本身的美好,残存的人类也好,人性化的动物和矿物也好,在不会结束的绝望之中,她们和绝望好好相处,她们有自己的旅行、探索、挣扎、友爱…甚至还有残存的希望。
依然是入手很多游戏但玩得很少的一年,以上是通关或者玩了20小时以上作品的个人打分。Nintendo Switch毫无疑问是2017年最棒的产品,单纯地抱着对未知的期待爬山,笨拙地尝试去解开神庙谜题,漫无目的地在草原上骑马狂奔,在东海岸等着看日出,在山间静静地听雨声,每一个瞬间都沉浸其中,旷野之息充满了无法表达的惊喜。而最纯粹的快乐的来自奥德赛,除了每个地方都有探索不完的收获,作为动作游戏苦手在奥德赛中却完全没有其他任何ACT和ARPG作品中的不安感,即使是自己做不到的事也可以轻松地利用附身。
去年太阳/月亮毫无疑问是心中满分的作品,然而可能和很多人的看法不一致的是,今年究极日月在我心中可能只有7.8分,虽然也有因为黑2白2带来的过高期待有点落空,更大的原因是日月一周目非常看重的椰蛋树岛等剧情被完全删除。第六世代作品中开始解释和应用的多世界理论,在究极日月中过多地滥用以至变得混乱了(虽然也有很多细节的暗示非常用心)。
新枪弹辩驳V3,其实是本来和极限脱出一样非常喜欢的系列,也有很多喜欢的人在游戏、动画以至舞台剧中出演。本作作为系列的最终作本来同样有一贯非常出彩的推理、故事和人设,然而最终章却毁掉了整个系列的一切。不知道是小高先生对自己的作品和粉丝有如此大的恶意,还是想要戏仿Ever17的meta元素却弄的如此拙劣。这样的最终章就是「绝望」本身。
2017年写了很多 Objective-C 很多 JavaScript 很多 Java (Android),写了一些 PHP 一些 Python 一些 Swift 一些 Vue SFC 一些 Dockerfile,充实地过完一年但其实只是更熟练了而已。虽然一年前也是这么说的,但希望2018年有真正的进步,然后能有可以改变自己的力量与希望。
2017年完成了很多想做的事,也有很多想做的事没有做,还好不是 mv "2017 resolution.md" "2018 resolution.md"
而是 tail -n XX "2017 resolution.md" > "2018 resolution.md"
。年末最近几天把 52Poké 环境和 docker image 升级了一遍,写了若干 koa middleware 和 MediaWiki 插件,新年首先要把 Wiki 的图片库迁往 S3,解决迫近的存储空间告竭。
2017 年有非常棒的回忆真是太好了,去了 LoveLive! Sunshine!! 的家乡沼津和很多作品的圣地旅行,玩了几十公里 Pokémon GO,看了很多场 Live,回忆起来仍然会感到生活在这个时代真是太好了。新年伊始,至少就有上海和千叶的 Aqours Live & Fan Meeting 可以期待。
2017 年和非常棒的作品相遇真是太好了,旷野之息和奥德赛是过去无法想象的游戏,在不同的地方的影院看宝可梦电影版也是很多年前就有的梦想。接下来该前往「异度神剑2」的乐园了。
2017 年得到了很多梦寐以求的东西真是太好了,感谢 Nintendo Switch 和 iPhone X,都是想象不到的惊喜;有了 Project FI 也多少增添了一点安全感,虽然流量费的原因目前还只是 Last Resort。
新年快乐,希望2018年是个好年。
]]>我的 NAS 是一台 Synology DS916+,9 代表 4 盘位 + 可以接入一台 5 盘位的扩展机,16 代表 2016 年款,+ 代表「适用于小型商务环境」的型号。同系列当前最新的型号是 DiskStation DS918+。
目前机内装有 4 块 WD 为 NAS 专用的 4TB 红盘。由于较高故障率的经验,个人并不推荐选择(不过售后服务还不错,目前更换后的硬盘也保持稳定),这可能由于 WD 红盘本身的故障率(参考 Backblaze 2016 Q3 数据,根据 Backblaze 2017 Q2 数据已有改善)、代理商简陋的包装或电商不安全的运输或三者皆有。
4 块硬盘使用 Synology Hybrid RAID 组成 12TB 存储空间和 1 块硬盘容错。混合 RAID 的原因是由于存储空间从原先 6TB 升级而来,底层实际为多个 RAID 5 拼接而成。
NAS 的访问速度除 NAS 本身性能外,还受限于本地网络的速度,为保证理想的访问速度,强烈建议使用 5GHz 802.11ac 标准的路由器,我目前使用的是 ASUS RT-AC68U;远程访问的速度则主要取决于当地 ISP 的上行速度以及是否有公网 IP 地址。
首先 NAS 显而易见的需求是文件管理,Synology DSM 提供了 SMB / AFP / WebDAV 等协议的文件访问方式。由于 Apple 已经弃用 AFP,我也关闭了 AFP 文件共享。
在 macOS 与 Windows 平台,SMB 是主要的文件访问方式,NAS 可以被自动发现并直接用 Finder 访问。Web 端的 File Station 与 Transmit 等 WebDAV 客户端也可以访问 NAS,使用 WebDAV 客户端有一个好处是当需要在不同的顶级共享文件夹(非加密)之间移动文件时可以快速完成。
iOS 上有很多可以通过 SMB 或 WebDAV 协议访问 NAS 的 App,我目前使用的主要有 Transmit for iOS、FileBrowser 和 Readdle 的 Documents。其中 Documents 有较好的文档浏览功能(结合 PDF Expert);Transmit 适合于移动文件、上传下载和与其他服务器传输。
iOS 11 提供了 File Provider extension,可以直接在原生文件应用管理云端文件,并可直接在第三方 App 打开和保存;Drag & Drop 功能也可以使文件方便地在不同 App 间通信。近日 FileBrowser 的更新为 Files 和 Drag & Drop 提供了完整的支持,所以 FileBrowser 目前是我主要使用的 NAS 文件管理 App。FileBrowser 也有 Apple TV 版本,可以浏览图片、播放音频和视频(仅限 tvOS 直接支持的格式)。
值得一提的是移动平台的 DS file(以及 Web 端 File Station)有一些独有的功能,比如在服务器端文件解压,使用其他工具都需要将压缩包下载到客户端解压后再上传,DS file 可以直接在 NAS 上完成;以及在加密文件夹直接移动文件等需要耗时的操作,使用 Synology 官方的工具会比较方便。
另外,包括 Omni 系列产品、DEVONthink、iWork 套件、 Notability 等 App 都提供了 WebDAV 的同步、访问或备份功能,可以直接将这些应用的数据存储到 NAS 上。(这里有一个不解是,Apple 在 iWork 应用中提供了在 Document Browser 浏览 WebDAV 服务器的功能,为什么不直接把它放到 Files App 中呢)
家用 NAS 很大的一个用途是视频管理。Synology 提供了 Video Station 管理视频,不过 Plex 在全平台(iOS / Android / Windows UWP / Apple TV / Web / macOS / Windows)提供了更好的体验。
电影和电视节目类可以自动匹配的视频文件,我会采取和 iTunes 一致的文件夹/文件命名规则保存(例如/video/电视节目/プリンセス・プリンシパル/Season 1/08 case20 Ripper Dipper.mp4
)。
我有很多动画与音乐 Blu-ray 和 DVD 光盘。入手光盘后,我首先用 Aurora Mac Blu-ray Copy 将光盘存档为 ISO 文件存储到 NAS 中(DVD 则用 MDRP),然后利用外出的时间用 Handbrake 转码为 HEVC(需要使用 nightly 版本以更好兼容 High Sierra 与 iOS/tvOS 11),在 iOS 11 发布前视频是转码为 H.264。目前 Video Station 和 Plex 均未支持在 iOS/tvOS 11 直接播放 HEVC,Plex 已确认正在进行相关开发,目前可以用 nPlayer(iOS)或 Infuse(iOS/tvOS)播放 HEVC 视频文件。
视频转码是一个比较纠结的问题,我的 MacBook Pro 2016 的 Skylake CPU 与 Radeon Pro 460 均支持硬件 H.264/HEVC 编码。然而 Handbrake 在 macOS 上并不支持硬件编码(有一个 Handbrake 的 fork 支持 macOS 上 H.264 的硬件转码,但不支持内嵌字幕和 HEVC);而在 Windows 上,Handbrake 虽然支持 Intel Quick Sync,但 Boot Camp 屏蔽了集成显卡,而 Handbrake 目前并不支持 AMD VCE 硬件编码,我尚未找到同时支持 Blu-ray 和 AMD VCE 的转码工具。希望这方面有研究的同学能有更好的方案分享。
另外,我曾将在 iTunes 购买的影片和电视节目用虚拟机中的 iTunes 10.7 与 Requirem 将 Fairplay 去除再保存到 NAS 中(因此曾在中国区买过的 iTunes 影片得以保留);目前 Apple 已禁止低版本 iTunes 下载 1080p 影片。
对于不属于电影和电视节目系列等可以自动匹配的视频文件,我没有放到 Video Station 和 Plex 自动索引的文件夹中,而是用单独的文件夹手工管理,在 iOS 设备用 nPlayer 播放,Apple TV 用 VLC 或 FileBrowser 播放。
值得一提的是 DS916+ 使用的 CPU 为 Intel Pentium N3710,支持 Intel Quick Sync 硬件编解码 H.264 与 HEVC(8bit)。除了 Synology 官方的 Video Station 支持硬件转码外,Plex Media Server(1.9.1 以上版本)也向 Plex Pass 用户提供了硬件转码支持,可以在服务器配置中开启。然而实际使用来看,硬件转码还存在一些问题,譬如 Video Station 不支持 Hi10P 和 10-bit HEVC 视频的硬件转码,Plex 开启硬件转码后,播放和拖动进度需要等待的时间特别长等。
作为 Anisong 爱好者会有大量音乐收藏。得益于 Steve Jobs 的贡献,在多数情况下购买音乐都不具有 DRM。对于购买的 CD,我会用 iTunes 抓取为 Apple Lossless 格式存储到 NAS 中,在 iTunes 购买的 AAC 音乐,则直接复制到 NAS 中。
Synology 提供了 Audio Station 管理音乐。由于 App 体验和缺少 Apple TV App 的原因,目前我主要用 Plex 管理和播放音乐。不过 Audio Station 有一个很好的特性是可以在客户端离线时,通过 AirPlay 或 USB 在家中播放。
偶尔我会使用 USB 声卡将音箱和 NAS 连接,除了 Audio Station 支持直接通过外置音箱播放外,我还在 Docker 中安装了 shairport-sync,可以将 NAS 作为 AirPlay 播放设备,这样可以直接将 iOS 设备播放的音频输出到 NAS 连接的音箱。
Synology 提供了 Photo Station 管理图片,并支持自动创建缩略图、相册和自动从移动设备备份照片。不过功能的完善程度以及与操作系统的集成无法与 iCloud Photo Library 相比,所以我主要的照片存储工具仍然是 iCloud Photo Library,NAS 仅作为另一个备份。
然而由于 NAS 相对大的存储空间,对于来源不是 iOS 设备的图片,比如收藏的壁纸、CG 图、CD 与 Blu-ray booklet 扫描等较大体积的图片资源,我会只存在 NAS 中,在 iOS/tvOS 设备上通过 DS photo 浏览。另外,即将推出的 Synology Moments 还会提供人脸、位置识别等功能。
iOS 11 / A10+ 默认使用新的 HEIC 格式存储图片,遗憾的是 Photo Station 并不支持管理 HEIC 图片,DS photo 近日的更新中针对 iOS 11 的图片备份也会自动将 HEIC 转码为 JPG,这样不仅浪费存储空间,也会损失图片质量。如果只用 NAS 存储图片而不使用 Photo Station 的话,也可以 DS file 的图片备份功能,DS file 可以选择是否将 HEIC 转码为 JPG。
对于收藏的漫画,我会按章节或书册压缩为 zip 文件,然后用 ComicGlass 通过 WebDAV 串流阅读。
Synology 的 Download Station 内置 HTTP/BitTorrent 等下载可以基本满足下载资源需求;除此之外,我通过 Docker 安装了 aira2,用于直接通过浏览器插件下载需要 Cookies 验证的内容。
另外,使用 youtube-dl-server,结合 Workflow,可以方便将视频网站的视频直接下载到 NAS 中。
Synology 提供了可以用于视频监控的 Surveillance Station。我使用了 Foscam HD816P 作为 Surveillance Station 的摄像头。除了在指定时间进行动作检测、录像和推送通知外,新版的 Surveillance Station 还提供了便于家用的 Home Mode,可以直接根据 DS cam 应用的 Geo-fencing 功能自动切换监控设置,比如只有在离开家时才打开动作侦测和推送。
很多家用设备可以利用 Homebridge 来支持 HomeKit,NAS 可以代替 Raspberry Pi 在 Docker 中安装 Homebridge。目前我在卧室安装了 Yeelight 彩光灯泡,通过 Homebridge 可以实现在所有 iOS 设备控制。同时,由于 Apple TV 可以作为 HomeKit 中心,在 iOS 的家庭应用中也可创建计划自动控制智能设备。
DS916+ 的性能能够满足很多小型开发的需求,Synology 提供的 Docker 也非常适合开发、部署和测试。
我在 NAS 上安装了 gogs 作为 self-hosted Git 服务,相比 GitLab 占用资源要小很多,并且能够满足绝大多数需求。个人的代码和一些服务的配置文件都放在这个 Git 服务中。另外,Docker 中还分别安装了 redis、PostgreSQL 等容器作为其他应用的依赖。
在 iPad 上写代码是很多 iPad 用户的梦想,有一台可以长期访问的主机为这样的梦想提供了可能性。Working Copy 和 Textastic 已经可以在 iOS 上管理 Git 仓库和编写代码;我在 Docker 中配置了一个用于 nodejs 开发的容器,容器中安装了 ssh、zsh、git、vim 等工具,使用 Prompt 连接后即可进行相应的调试。
作为一台本地 Linux 主机,NAS 可以间接满足 Apple TV 和游戏机等不具备 Network Extension 的设备连接互联网的需求。我用的是 MEOW,运行在一个单独的 Docker 容器中。虽然 Apple TV 没有直接设置 Proxy Server 的 UI,不过可以通过 USB-C 接口连接 Mac 并使用 Apple Configurator 进行配置(Apple TV 4K 可以通过本地网络配置)。
在 Nintendo Wi-Fi Connection 关闭之前,有时我会用 Nintendo DS 连接网络,不过 DS 只支持 WEP 连接,无法直接连接家中的 WPA2 网络。NAS 只要插入一个 USB 无线网卡,并在 DSM 中进行一次简单的配置,即可临时创建一个不安全的 Wi-Fi 网络,当不需要时拔掉网卡即可恢复网络安全性。
Synology 提供了 Hyper Backup、Glacier Backup、Cloud Sync 等备份或同步方案。根据 3-2-1 备份原则,NAS 中的重要数据我会在本地和远端各有一份备份。
本地的备份使用了 3 块被升级替换的 2TB 硬盘,备份时将硬盘通过 USB-C 硬盘盒连接到 Mac,然后分别使用 ChronoSync 进行增量同步(同类工具还有 GoodSync 或 Carbon Copy Cloner);NAS 中加密文件夹的内容会备份到加密 HFS+ 分区,其他内容则会备份到 exFAT 分区。
Synology NAS 也可以直接连接 USB 3.0 外置驱动器,并提供了收费的 exFAT 分区支持。考虑到操作方便、便于直接浏览、以及 802.11ac 网络速度和直接连接硬盘的速度相差不大的原因还是使用了 Mac 进行备份。
远程备份使用了两种方案。对于对安全性要求高且占用空间并不大的数据(例如图片、音乐、Git 仓库),每周会通过 Hyper Backup 增量备份到 Amazon S3;对于整理好的视频文件、购买的 DRM free 游戏等,则会用 Cloud Sync 单向同步到比较廉价的 Backblaze B2 存储(目前 Hyper Backup 尚不支持 Backblaze B2,使用单向同步可以避免远程的误操作误删文件)。其他诸如 Blu-ray ISO 由于已经是其他存储媒介的备份,且占用空间极大没有做重复的备份。由于其过于复杂的计费规则和取回方式,个人不推荐使用 Glacier Backup。
至于 Mac 的 Time Machine,我是使用了一块升级替换的硬盘通过 USB-C 硬盘盒连接到 Mac 备份,而没有用 NAS 作为 Time Machine 的存储。原因主要是对目前通信方案的担忧(AFP 协议已被 Apple 弃用,目前版本的 Samba 尚未完全支持 Apple 的 Time Machine over SMB 标准),曾经使用 NAS 作为 Time Machine 存储时也发生过几次 Time Machine 需要重建的经历。另外将 Time Machine 存储到 RAID 中也有空间浪费和频繁的磁盘读写,Accidental Tech Podcast 曾提到他们的 Time Machine 存储在 NAS 单独的未做冗余的卷中,也是一个不错的方案。
另外,52Poké 的数据,除每日备份到 Amazon S3 外,也会每周使用 rsync 脚本备份快照到这台 NAS 中。
对 NAS 来说,安全的重要性不言而喻。Synology 也提供了安全审计功能可以进行基本的检查。除此之外,还有一些需要注意的点:
其中非常重要的是避免将未经 TLS 或 SSH 加密的端口暴露于公网,尤其是经常使用的 WebDAV 等服务,第三方 App 如 Plex 也尽量开启「只允许加密连接」等选项。未经加密的连接意味着 ISP 或开放 Wi-Fi 等可以轻易拿到 NAS 账号与密码,在安全环境日益恶化的情况下是非常危险的。
使用 UPS 备用电源对 NAS 来说是必要的,我使用的是 APC BX650CI。为 NAS 选择备用电源建议选择支持 USB 接口连接的产品,这样当断电时,NAS 能收到消息,并通过 Push 推送通知使用者和在电量较低时自动关机。
目前这台 NAS 比较大的遗憾是,由于不便重建已用 9TB 的 Volume,未能享用 Synology DSM 支持的 btrfs 文件系统的优势,也因此无法使用 Virtual Machine Manager 创建虚拟机。希望有一天,btrfs 能像 Apple 的 APFS 一样提供从 ext4 安全转换的方案。
这里也简单提一下对 Synology 的吐槽。iOS 9 发布已超过两年,而目前很多 Synology 第一方 iOS 应用都尚未支持 Split View、Picture in Picture 和 iPad Pro 屏幕,至于 iOS 11 的 Files 和 Drag & Drop 支持可能更是遥遥无期。而这些 iOS 特性,对于生产力工具的 NAS 应用而言至关重要。
「云」的存在是今天数字生活的重要部分,由于设备和时间的碎片化,我们对本地存储需求有种日渐式微的错觉。然而「云」本身是不稳定的存在,无论是商业公司间版权纠纷的「大人的事情」,还是随时发生的不可抗力都会让原本可用的比特瞬间消失,甚至赖以生存的真正互联网是否能一直连通都是个巨大的问号。于是在触手可及的物理空间拥有数 TB 的存储,相对永久地保存一些东西,是一个能够带来哪怕很微弱的安全感的重要存在。
]]>2016年对我来说,是有点忙乱和复杂的一年,有很多激动人心的事发生,最大的梦想成为真实,有非常多的相遇和相连;然而这个世界的某些地方也显露出它不美好的一面。
工作上终于稍微有点像个「全栈工程师」的样子了,虽然称不上好事或坏事,但接触到更广泛的东西,在不同开发语言和平台间切换对我来说并不是一件讨厌的事。
从 wax/JSPatch 到 React Native/Weex,再到年末诞生的 DynamicCocoa 与 OCS,iOS App 变得越来越动态化。从个人而言,这一点大大减轻了工作的压力,点击 Release this version 按钮稍微不讨厌了一点。然而当下发的代码不再需要符合 Apple 的审核标准,以及快速迭代的上线代替精心打磨的发布,作为 iOS 使用者的自己却难免有点心情复杂。
App Transport Security 的一纸通知,地方 ISP 的 HTTP 劫持和 Let’s Encrypt 等服务的出现让整个业界真正重视安全这件事。不过大概由于 iOS 9 WKWebView 无法单独豁免等原因,Apple 在年末把 deadline 无限期推迟了。
开始习惯用 TypeScript,2016年仅有一点 GitHub 活动却有一大部分是给用到的 npm 库写 DefinitelyTyped,不过却被批评了不该写 hack 假装是 ES2015 Module (笑)。说起来大概也因此,最近常用的编辑器逐渐从 Sublime Text 变为 Visual Studio Code 了。
关于从 Web 向 Native App 引流这件事,从 2015 年开始就心情有点复杂。从商业的角度是一件自然的事但用 URL Scheme 从 Web 跳入 Native App 并不是一种好的体验。然而 Universal Link 与 NSUserActivity 的出现已让它变得并不糟糕,如今无论是使用 Medium、Instagram、淘宝还是 Bilibili,都会很自然地点击一个 URL 然后进入 Native App 对应的位置。这才发现我所在乎的 Open Web 是它的开放性本身,是 URI,而不是具体的 HTML 吧。
2016年有点遗憾的是没有写很多 Swift,不过一年间认真去看了 swift-evolution 里很多 proposal,感受到语言的进化真是太伟大了。不过也因此,即使是在日常 Objective-C 和 JavaScript 的工作中,也尽可能用 Protocol-oriented 和 Functional 的思想。
2017年的话,大概会尝试做一点更有挑战的事情吧,然后同样重要的是回归初心。从一开始选择一份用户产品相关的工作,就是希望自己做的事情能够让一些人的生活稍微变好那么一点——就像自己从那些喜欢的工具中得到的一样。所以也继续尽可能接近这个目标吧。
52Poké Wiki 全年 PV 增长了 84%,2月末中文化公告、7月 Pokémon GO 上线、椰蛋树(阿罗拉的样子)公开和11月太阳/月亮发售是对访问量影响最大的几个时间点,最大 PV 发生在11月27日,最大 UV 发生在8月8日。
随着流量增长伴随着的就是频繁收到的流量告警邮件,因此做了一点微小的工作,为支持 WebP 的浏览器提供 WebP 版本的图片,使图片流量下降 2/3 左右(遗憾的是,iOS 10 Beta 曾出现的 WebP 支持在正式版去掉了)。到8月开始使用 CloudFlare CDN 承担一部分流量,终于使支出相对 2015 年没有增加。
除此之外,11月终于把 52Poké 搬到了 Linode Tokyo 2 数据中心,硬件升级到 8GB RAM 和 14nm Xeon CPU。52Poké 上的多数应用也都放入了 docker 并相互最大限度隔离。虽然经常遇到种种意外,不过依然坚持使用 Arch Linux 并经常滚动更新这个任性的选择 : )
有点惭愧(不过也没有太惭愧)的是,2016年并没有太多精力花在 52Poké 的具体工作上,计划的讨论区更换 NodeBB 和插件重制只有 50% 不到的进度,百科方面无论是机器人还是移动版都堆积着不少事情。
2017年会努力把想做的事情补起来,另外一个重要的努力目标是百科机器人也好,MediaWiki 插件也好,NodeBB 配置和 OAuth 接口也好,甚至是 nginx 配置与 Dockerfile 之类的东西,尽可能用更多人可以参与的方式在 GitHub 开源。希望在 52Poké 能有更多像希特隆或马玛内一样的训练家出现吧。
2016年最重要的事,果然是「精灵宝可梦 太阳/月亮」中文化,时至今日,依然觉得没有太大的实感。
GMT+8时间2016年2月26日晚23时02分,在 Apple TV 看到 Pokémon YouTube Channel 上出现「相連」「相连」的一瞬间和之后的几个小时,隐约记得是在尖叫,然后呆滞,然后大哭了一场。从10多年前开始就等待的一天,从11年前开始做的事就是为了这一天,以及两年前,抱着「说不定成功了呢」的想法做了一点小小的努力。
除了亲切的母语文本和可以不用再为专有词汇的译名纠结,对太阳/月亮最大的感受是很多微妙的细心的进步。比如按Y选择精灵球,比如选择招式时提示效果,比如抓到宝可梦后可以选择留在队伍,以及捕捉和进化新宝可梦后直接出现的图鉴,比如洛托姆图鉴告知旅行的目标,比如打开电脑直接进入移动宝可梦。
个人的体验来说,阿罗拉的旅行用一个词来说大概就是「相连」吧,和各位队长、岛屿之王与岛屿女王们邂逅,得到他们与霸主宝可梦的指引和认可;对很多路边训练家印象深刻,比如在好奥乐墓园,一位用沉睡在这里的宝可梦的声音问候的宝可梦培育家,比如一位自称从泳裤男进化而来的登山男;认识来自不同世界的宝可梦与人类;以及最重要的,和亲爱的莉莉艾一起旅行一起成长一起为了彼此的目标努力。
说起来,可能由于捕捉究极异兽太过轻松并没有像X·Y或者黑白2一样所生活的地方遭遇危机的感觉,但这样也更有「生活在这里」的实感吧。最近打开太阳版,刚岛屿扫描结束后忽然听到洛托姆图鉴说「想念莉莉艾了洛托,加油莉莉艾洛托」,有点伤感但也有点惊喜呢。因为忽然意识到它并不是 AI 而是一只真实存在的宝可梦,和我有一样心情的宝可梦。
太阳版捕捉了所有的UB,月亮版刚刚结束波尼岛的考验,这段还在继续的旅行总结起来就是「能够遇见你,真的太好了」。
2016年作为 LoveLiver 是充实又艰辛的一年。从2015年底震惊的消息开始心情一直很复杂和不安,但不安感在1月末的Fan Meeting就被冲散了,想要见到μ’s这样的愿望终于实现了,以及第一次成为了梦中白色到橙色海洋的一部分。时至今日那一天的记忆仍然是非常完整的。然后Final LoveLive 的日子逐渐接近了。
不过由于有了看转播的机会的惊喜都来不及伤感,4月1日在有点拥挤的浅水湾q.house度过了这一年最难忘的6个小时。那一场集大成者的Live每一帧都无比美好,但要简短地总结的话,果然是「今が最高」吧。
虽然是已经有心理准备和完全可以理解的事,但毕竟是告一段落难免会有失去了什么的心情。然而没有想到的是接下来有段更艰难的日子,像太阳一样给这个世界带来光明的人,却被这个世界阴暗角落的恶意所袭击,大概从那时开始,渐渐觉得今年这个世界的不美好显露出来了。
然而果然是像太阳一样的人啊,比起担心更多的是大家的Event repo与Live MC与新的推特账号带来的安心和坚定。7月在BMLSP见到她以及喜欢的很多人,8月穗乃果生日时加入了EmiRing,10月在FC里读到「到现在,有失败和挫折以及不甘心的时候,但东蛋之后的半年间,我还是要说今が最高」终于彻底安心并且相信这个世界还是美好的一面有更强大的力量。
FL结束后,μ’s成员个人活动逐渐多了起来,下半年有幸参加了3位的Event,也一直关注着她们的CD与BD。偶尔出现的合影和杂志也总在提醒着我们μ’s没有并且永远不会消失。
另外就是和Aqours相遇。虽然Aqours开始活动是2015年的事,不过16年才开始认真地关注生放送与广播,动画也在7月开播;其实完全放下心中某些芥蒂是因为4月二单纪念生放送她们提到了μ’s Final LoveLive 的事,虽然是很微妙的原因但就是从那时开始觉得需要认真地关注Aqours她们了。
之后渐渐了解到她们每个人都是很独特和可爱的人,知道了杏树和自己一样最喜欢精灵宝可梦红宝石·蓝宝石并且最初的宝可梦选择了水属性;看到爱香和夜羽越来越心意相通;以及动画中她们輝きたい的故事、曜ちゃん的心意和三年级的过去。1st Live的BD抽选都没有中希望还能有机会哪怕转播也好,毕竟10月没有去广州是2016年最后悔的一件事。
但是讨厌的是那些有实质威胁的水黑存在。至今最不能理解的是明明本来曾是一起互相鼓励支持的人,明明同样追随着一群美好的人,为什么其中有些人会对一群充满梦想追随者前辈的孩子有如此大的恶意。
2016年这个世界的科技与艺术创作方面都有很好的事情发生,然而另一面的是某些阻碍进步、阻碍这个世界相连的力量也变得强大。从某部 iPhone 被要求解锁开始,基本的信息自由和权利就一再遭到践踏,即使是在本来应该尊重这些的地方;大西洋两岸与东南亚的人们接连作出了相当糟糕的选择。对我来说,「这个世界是一直在变好的」这样朴素的认知被打破了,但是仍然相信的是,用讨厌的教科书上的话来说,虽然道路是曲折的,但前途是光明的吧。
有幸首批买到 PlayStation VR 头盔,体验果然是「打开了新世界的大门」吧,玩的最多的 VR 游戏是「初音未来VR Future Live」,和在真实世界参加初音 Live 有相似的感觉但有些完全不一样的体验(比如若无其事地跑到舞台上和飞到半空中),第一次听到Miku说「这是只有两个人的encore哦」被感动到了。
由于 DS415+ 一个硬盘接口坏掉了,被客服建议折价退款所以正好升级到 916+,因为无法硬件转码 10bit 的视频格式,相比起来多了的这个功能并不是很实用,如果能支持软件解码硬件编码就好了。
2016年的 MacBook Pro 升级存有很多争议,不过我对 Touch Bar 和只保留 USB Type-C 接口的 courage 非常满意,最喜欢的一点是 Safari 播放 HTML5 视频时 Touch Bar 可以完美操控,新电脑各方面比从前的 2013 MacBook Pro 13” 快 1-3 倍,即使 Handbrake 满载时噪音和发热也控制的不错。虽然直到 macOS 10.12.2 还有很多不大不小的 bug,虽然电池容量确实不尽人意,但它确实是目前最佳的选择。很多人对 Mac 的未来有不小的担心,希望这些负面的报道与分析能推动 Apple 为 Mac 投入更多精力。
AirPods 是2016年最惊喜的设备,使用一周多的感想就是「耳机本来就应该是这个样子啊」,佩戴合适,音质足够好,种种小细节和切换设备的体验太棒了。
虽然开始总结的时候觉得2016年是有点复杂的一年,但总结下来才发现这一年是收获满满的一年。诸岛巡礼,和莉莉艾的相遇,有关μ’s的回忆以及与Aqours的相遇是2016年非常重要的东西。虽然这样说很奇怪,总觉得心理年龄方面自己停止成长了(笑),曾经对 Peter Pan complex 的执念如今却觉得是再正常不过的事情。总是会莫名消极的自己想到这一点、以及看到 Bear 中记录的期待和预定,就会立刻积极一些 :)
2017年的希望的话,希望自己英语日语和算法方面能有比较大的进步,工作方面有稍微不同的尝试;能有什么 side project 就好了;一定要去旅行一次;要把阿罗拉图鉴集齐;想要见到 Aqours;想要多写一点什么,学会一点点画画;要把2016年拖延的事情和游戏完成……还有就是,继续不要长大吧。
总之要更加油一点嗯。がんばリーリエ!がんばルビー!がんばリボン!
]]>I chose Tumblr because it’s convenient, fun and modern in 2011. Tumblr respects the ownership and personality of its users. It does social just right. However Tumblr is no longer great for me as a blog platform today. I have to use ‘display:none’ CSS to hide the banner to promote Tumblr app. I can’t get rid of a lot of tracking scripts. And I want more freedom with the domain I own.
This blog is now powered by Hexo, a powerful static blog framework. It’s hosted on GitHub and updated with Git. I set up a webhook to automatically deploy to GitHub Pages when I push my hexo repository. I’m also building an iOS blog workflow with Ulysses, Working Copy and Workflow. And as always, I love writing and I wish I could write more.
My previous posts is still available at Tumblr. They might be migrated here someday. :)
]]>参加了4月1日上海浅水湾q.house的转播。
今年1月30日的上海Fan meeting结束后,充满满足和快乐的很长一段时间都没有Final会来临的实感,BD抽选没中后就没在意后来一般贩售,春节忘记把港澳通行证带回去续签也就没计划去香港看转播。直到传出上海浅水湾转播正在审批的消息和广州转播场的传闻才下定决心,如果内地有转播就要全力争取机会去看。
3月19日中午很紧张,校对好时钟把发抖的食指放在淘宝App购物车的结算按钮上然后默默倒计时,然而按下的时候已只有灰色的确认按钮。不过因为15分钟内付款的规定就一直不停刷购物车,重复了几次「刷到购物车亮了—结算—确认失败」的过程后终于在半小时后买到一张4.1 q.house的转播票。所以下一次即使没抢到也一定不要放弃希望。(嗯,还会有下次的。)后来和朋友聊起来被问到为什么不写个程序抢,我说毕竟信仰的事情是不能作弊的。
然后当天下午看到微博和贴吧里关于台北Fan meeting的repo,看到emitsun说「因为是最后一次了所以哭也没关系了」,看到台湾LLer的これから应援影片,终于有了Final来临的实感。一边是有幸看转播的兴奋和期待,一边是希望这一天晚些来临的不舍…这十多天一直持续着这样的心情。
这其间看到kssn和rippi的LA之行DVD里聊起未来的人生时的一丝迷惘;南酱说不知道Final之后,因为LoveLive!而喜欢她的粉丝会不会继续支持她;Pile在自己专辑里藏着的对小真姬的感谢;以及μ’s全员对Final LoveLive!的寄语,「我…我们追随着穗乃果她们的脚步,在有限的时间里尽全力绽放光辉」这句话从剧场版到访谈到Live重复了很多次,这就是LoveLive!这个企划的真谛吧。
终于到了3月31日晚准备出发,在地铁上看着第一日Live的文字直播结束终于有种悬着的心终于放下的感觉(其实更多是担心南酱的膝盖),火车上也因为复杂的心情很晚才睡着。
4.1当日,到达浅水湾的时候已经接近10点,场贩自然是没希望了,整理券排到了270多号。有些遗憾的是,由于这次转播票的供需严重不平衡的原因,现场除了Loveliver,也有一类很讨厌的人存在,下午入场时还听到楼下发生了很恶劣的事件,不过机智的staff和Loveliver很妥善地处理了。
排整理券的时候有位LLer小哥一直拿着一叠现钞走来走去说「2000元求出一张票吧」,有点让人心疼(后来贴吧有贴出他是某周边店的店长);下午也有很多没有买到票的LLer在门外应援。
中午附近的面馆一直在放LoveLive!的歌,还推出了所谓Loveliver套餐(其实就是普通的2荤2素)。开场前在楼梯听到有LLer聊到了fS的white forces和黑之宣告动画。
q.house这个比想象中还小的场地挤了近400人,转播开始前重复了几次「啊—(大概是手游抽到UR/SR)」然后全场举着荧光棒欢乐地喊「劝退!劝退!劝退!」;还以为自己的身高站后排也还好但视线前面有1.9m的同学所以有时候还需要踮起脚。
终于在欢呼声中PV动画开始了,剧情从音乃木坂学院的羊驼——生了小羊驼开始;然后说到举办Live的地方大家大声喊DOME,然后花阳用和剧场版一样的语气说「ドゥーム」,然后从1st的场地横滨blitz开始传递气球,直到东京巨蛋,中间好像看到了不少CP福利。PV动画中成员的家人们也登场了,妹妹组的出现的时候全场喊了「大法好」,然后妈妈们出现的时候全场包括身边一群女生都在喊岳母(23333)。
然后一单开场,当时想的只有「这些人好美啊好美啊好美啊」——并不是说之前看3rd4th5th和fan meeting没有这样的感觉,但是这次真的有特别的不一样的ギラギラ的感受,而且服装与其说是1单的服装更像是Final Single的服装或者1单的高清重制版(…)。然后OP1就是和fan meeting一样的幸福感。
然后自我介绍的时候就是惯例的ちょっと待っててー和Yellow哒哟还有だぢづでど和最响亮的唔—和Fight哒哟,森森森讲话的时候Pile好像在做什么的样子反正好像是糖(?)。因为在看转播,当听到「ライブビューイングの皆さん」的时候感觉完全和看BD不同,很幸福。彩彩在MC不知道为什么哭着停不下来,看着好心疼,大家应援了很多次终于用哽咽的声音说出了把你变成小鸟的点心,南酱和emitsun也一直不停地安慰,说完后彩彩就背对着舞台擦泪,有点担心也有点曾经见过的感觉。
转到南酱的时候很多人都喊了お帰り,エリチカ大概也是喊得最响亮的一次——终于回来了呢。然后是小楠的たっぷりたっぷり和期待已久的にっこにっこに~。
然后是夏色天台,哦不,夏色笑颜12跳,看到这里就想说soramaru好可爱好可爱好可爱,她从女神X变回了女神呢(当然这一首服装还原的梦想就永远不可能了)。接着HiHiススメ和友情不找零,不对,友情永不变,然后花车和南酱出现的一瞬间太棒了,记不清哪些成员抱了南酱www。
然后到了休息时间投影屏上开始放6年前开始的回忆,因为这时开始就是HP=1的状态所以蹲了下来…其实staff提醒是不许坐在地上的不过HP基础得点为0实在没办法。(…)
然后满怀恶意,不,爱意接近中的女仆装!女仆装!女仆装!,可爱的只能紧盯投影屏不知道荧光棒该怎么举了。说起来这场Live最大的亮点之一就是各种服装和现场的还原,真的非常用心。6单之后开始了动画歌曲的串烧。
Wonder Zone的时候镜头突然切到了花车上,南酱手里拿着两只羊驼毛绒出现了,小楠手里不知怎么也有了两只羊驼。Love wing bell的气氛好棒,大家一起喊变身,但是,但是如果我没记错的话,虽然只有几秒的镜头,但看到了妮姬偷偷十指相扣不小心哇的叫了一下。接着继续回忆环节。
To be continued之后是动画中的Dancing stars on me,虽然这次没有还原动画,但是女仆装上贴了一层南瓜好有趣,这次的服装设计师们真的要给1000个10ハラショー。kssn好可爱好可爱好可爱,Happy maker后动画串烧结束。
小队曲开始Printemps的服装还原了WAO-WAO Powerful day封面(继续赞服装师),中间MC的一瞬间emitsun露出了有点像盟约彼方(emitsun个人单曲)封面的冷酷表情,最后一首就是好吃好吃很好吃都感觉肚子饿了一下w
lily white最大的亮点就是全场变樱花,东蛋粉色和白色的全景就像樱花满开一样,当然我们转播会场的樱花也盛开了。这里想起了5th上kssn生日吹蜡烛的情景,其实不仅snow halation,LoveLive!的很多细节都是「大家一起实现的故事」呢。
然后是期待已久的BiBi,其实本来以为第一天有小队曲还在遗憾第二天大概看不到了,Psychic fire就是都在疯了一样乱喊,脑子里只剩下bibibibibibibi了。最后空丸像4th一样请南酱带BiBi call,然后Pile然后空丸自己,这时候的心情大概只有快乐和兴奋了。然后错觉Crossroads也很棒,对了lily white和BiBi的服装也都特别特别棒。
终于是剧场版的Angelic Angel,服装再度完美还原,南酱太美了太美了太美了,全场一片水蓝色的应援,所有的舞蹈也都和剧场版动画中完全一样,太棒了——然后最棒的最意外的是海未头上那两个圈的完美还原,mimorin太棒了太棒了!然后辉夜城和噫无情,周围有人起哄说「要看下楼梯了」不过没有注意到,虽然投影屏并不大但一直实在太美了不知道该看哪里w
然后回忆到了动画二期,这里开始有些虐心了,没有完全听懂emitsun说的话但好像提到了动画里毕业和解散的事情,to be continued。
不过马上就开始欢呼了,剧场版的年级曲开始,rippi出现的一瞬间总觉得不是rippi而是凛酱本人——说不清的感觉,其实整场Live都觉得她们9人与她们9人已经完全融合了,那个μ’s有17人的梗已经不在了因为只剩下9人——Pile从一辆Taxi里出来,小鹿从椅子上站起来,都完全和剧场版一样,对了服装也完全还原了。
然后三年级搞笑组合(搞笑组合不是BiBi么),从墨镜到表情到动作都很疯2333——哎我怎么就这么喜欢这群家伙啊。二年级一家的校服也好棒,咦之前的Live还原过校服么。
接着她们换上了Sunny day song的服装开始了「这是我们的奇迹」,这首听过最多的歌,大家的应援也非常整齐,不过和红白一样只有8人。然后9人版的ミはμ’sicのミ,最后大家都跟着喊出「忘れないで 君と僕の足跡」。然后Super love super live又是非常燃,终于No brand girls的时候气氛达到了顶峰,之前有点难过的心情也完全散去了,只有一进一跳,hihihihi、oh yeah和全心全灵的喊声,也因为一点特别的原因,No brand girls有点特殊的意义。
不记得这个环节的哪里,kssn跑着冲到南酱怀里,大家眼睛都被闪瞎了。最后是同样很期待的Sunny day song,舞步也和动画里完全一样非常美。不过教学比起ミミミ难了不少,32手势没有做出来。
Encore是START:DASH和Snow halation,第二次成为奇迹的橙色海洋的一部分,后来媒体放出现场摄影图华丽极了,微博上有和1st的现场对比,我们10人真的从那里走到很远的地方了啊 :)
和Fan meeting一样又是从どんなときもずっと开始就控制不住情绪抽泣,也几乎没办法跟唱,真的对这首歌一点抵抗力都没有。说起来今年每隔一个月都哭了一次(1月Fan meeting,2月宝可梦中文化,然后Final LoveLive!),这种幸福和苦涩交织的心情不知该如何形容,大家应该都懂吧。
到MC的环节,心情已经完全和Encore前不同了。听到rippi说“凛酱看到了吗?我做到了啊!”的时候全场泪崩,身后的两位女生大哭起来然后蹲下了;小楠问“喜欢LoveLive!吗,喜欢μ’s吗,喜欢希吗”大家都很用力的喊「大好き」;Pile说μ’s,然后大家哭喊“愛していばんざーい!”;南酱说绘里她们过了今天也还在某个地方生活着;森森森说和园田海未相遇真是太好了;彩彩说今天不是饰演南小鸟,而是要成为南小鸟;emitsun说穗乃果她们9人,我们9人都是在有限的时间里,尽全力去绽放的光辉,但「私たちはずっとμ’sです」,我们永远都是μ’s,然后说虽然形式会改变,虽然还不能约定下来,但总有一天我们还会再相见,只要大家心里记着μ’s,μ’s就会一直存在。
有这句话就够了,有这句话就够了。MC的环节她们都很坚强地忍住眼泪,没有说离别的话,大家又一次喊了Fight哒哟。终于是最后一曲,μ’s的Final Single「Moment Ring」。这首里屏幕上有成员和角色在一起做出相同动作的画面,不舍的同时又有一点暖意。
然后是哭声和嘶哑的喉咙喊出的もう一回,然后出现了成员的感言,这里记得最清楚的是空丸说很多年后大家去卡拉OK也会点μ’s的歌就好了,然后是忧伤的bgm和6年的回忆,身旁每个人的脸颊都是泪光。
接着是剧场版最后仆光的报数,大家小声跟着说1 2 3 4 5 6 7 8 9之后用最大声喊出了10,μ’s music start!莲花舞台升起,花瓣展开,9人出现在花瓣上,完全再现剧场版的Ending。
东蛋和转播场的大家都全程跟唱了这首歌,尤其是用尽全力去喊的「今が最高」,因为现在最好了是最真实的心情。结束后,跟着bgm大家又跟唱了一次,台上9人也和大家一起喊了「今が最高」,然后一切都结束了。
东蛋里灯亮起来了,但没有人愿意离开,当音响里传出微弱的声音时我们也一起喊「μ’s!μ’s!μ’s!」,希望她们能再次回到台上。然而之后投影屏上只有本次转播已经结束的提示。
后来q.house里和Fan meeting时一样合唱了一小段爱万岁和最后的lalala lalalalalalala,然后一段掌声然后对staff说了お疲れ様。
走出剧场就像做了一场梦,只是没有人愿意醒来。浅水湾楼梯和场外大家喊了很多μ’sic forever,喊了很多今が最高,又合唱了一段爱万岁,合唱了一段snow halation,终于渐渐散去。
晚餐时发现喉咙完全发不出声音了,只能用手指点餐;回到酒店心情很复杂,有种无助的感觉有种失去了什么的感觉。明明是第一次看到μ’s完整的Live,本应是非常幸福的事情,为什么会变成这样呢。
第二天中午返程,经过检票口后发现上海开始下雨了——这两天的天气与和1月30日及之后的第二天完全一样。不过在火车上补了一期希绘里花园广播,补了一期果海鸟+妮生放送,在Twitter看到她们在Live结束后的事情,心情就完全恢复了。
是啊,μ’s原来从来都没有离开,只是她们的奇迹和梦想已经完全实现了;6年里发生的事情,还有很多需要补习;未来的某一天,总会再相见的,嗯。
南酱去做了印有LOVE、LIVE、水蓝色和μ’s9色图案的指甲。
没有Twitter帐号的小鹿在Instagram画了写着μ’sic forever的气泡(最后的画伯属性呢),一年级感情很好的rippi和Pile很快帮她转到了Twitter。
空丸在blog里说Final LoveLive!的庆功之后,μ’s9人许下了今后也要定期会面的约定。
三森和空丸所在的milky holmes组合宣布了新的活动。
小楠没有休息,马上开始二专和新声优出演的工作,看到她努力和忙碌会有些安心呢。
Emitsun和彩彩今天去了新宿一家影院的重播,她们第一次不是作为μ’s在台上看到,而是作为第10人的Loveliver在台下完成了Snow halation的变色。
日本文部科学大臣馳浩先生受Bushiroad社长邀请穿着Final LoveLive!的场T去看了两天的Live,之后他说「希望东京奥运会的开幕式或者闭幕式能邀请到LoveLive!」。
赐予μ’s名字的御儿勇马今天在神田神社的绘马写下「μ’s Final LoveLive!成员和工作人员都辛苦了!GS杂志还在连载9人活跃的漫画,大家不要错过!」。
另外想谈一点成为Loveliver的经历吧。其实从前对追星啊偶像宅啊爱豆啊没有什么概念甚至不太能理解,第一次觉得「アイドル」好厉害的时候,大概是看到一位宝可梦节目主持人姐姐写的一本书,发现原来成为アイドル的存在的人,也是有很多和自己相似之处,喜欢同样的事物的普通的孩子。
14年初第一次看了一部有关アイドル的动画,大家当时谈论更多的是有关某个失意的监督的事,不过很喜欢那部动画,以及为了纯粹的梦想而努力的心情。后来LoveLive!已经逐渐成为了话题,无论是好的意义上还是不好的意义上。由于「想要看看LoveLive!为什么会被成为邪教」的好奇心驱使,在14年秋补了两期动画。
然后就被感动了。然后去开始玩手游,虽然直到现在也还是手残(笑)。14年跨年时看了那个LoveLive新年特番,第一次见到了声优9人当时还不能完全记住名字,但记得她们说想要去海外开Live,想要周榜第一,想要9人一起吃饭,然后记得真姬的声优说想要LoveLive!的活动能延续到2016年,今天这些都实现了。后来去看了4th视频,看到「居然可以这样」的橙色海洋,然后就彻底地成为Loveliver,但是lantis祭已经没有机会去了。
但之后就很想去一次Live,想要在真实的世界寻找梦想和奇迹,后来第一次去听Live是去年6月的初音未来Expo;后来11月去了日本,去了秋叶原和神田神社巡礼,在神田许下了「想要去μ’s的Live」的心愿。
願いを抱いて 紡いでゆく夢の糸 きらきら
素敵なことさ ほら心はつぎの物語をさがして
君は光をどこまで追いかけるのだろう
一緒に見ると決めた輝きは 胸の僕の宝石になったよ
ああきっと君も…おなじ気持ち…!
作为μ’s的第10人,我们和她们一样已经走到了很远的地方。
无论是和她们相遇的近两年来,还是从6年前开始,都可以自信地说自己走在梦想中的道路上,并且实现了很多梦想。
今后,为了再见时是能自信的说「我成为了更好的人」,为了让她们有一天能比东京巨蛋的两日更加闪耀,继续为了自己的梦想努力,并继续支持她们的个人事业吧 :)
然后1月30日这个梦想实现了。
彻底觉得自己成为了LoveLiver的时刻,大概是近一年前看4th Live的视频,看到Snow Halation从白色变为橙色的一瞬间。
然后1月30日,自己成为了那片橙色奇迹海洋的一部分。
然后是很多记忆的片段。
回酒店后看到大家一致的好评,小姐姐们也很开心地玩着赠送的腕表,bushiroad的社长在Twitter上也说「有种在日本Live的错觉」。梦想实现的时候,「それは僕たちの奇跡」
第二天去了复兴中路523的 LoveLive! Cafe,11月来过的相同的地方,当时是初音Miku主题餐厅;没想到过了不久就有幸又来到这里。在Maki的桌子上果断点了Nico的套餐,一直以来希冀的蛋包饭和「变好吃的魔法」也终于实现了www
2月1日结束旅行离开上海,在浦东机场找到了Fan Meeting上看到的同款大白兔奶糖和梨膏糖,不过只看到一家店有卖百力兹但一问大闸蟹口味的已经卖光了。
虽然已经过了3天,手臂的酸痛还记得1月30日所有的幸福,然而也不禁想起,工作忙碌的她们9人,已经开始为6th排练的她们9人,5年半来的辛苦,尤其是膝盖有伤的南酱。
みんなと出会えたこと嬉しくて
離れたくないよ本当だよ
涙はいらない このまま踊ろう
手を振ってもっと振って
光を追いかけてきた僕たちだから
现在回忆起仆光的旋律已经不再感伤了,因为已经经历很棒的梦,因为いまが最高。
]]>You’ve always been kind of a brat, Fennekin. But I’m jealous of the way you’re chasing your dreams. --Lombre
Try not to eat too much. Take care. --Raticate
Ven you are feeling lonely, remember ze village. --Hippopotas
A child’s dream can’t be destroyed by adults. Best of luck to you. --Simipour
Let’s see, how can I put this? Even if you were problem children. If you work hard, maybe you won’t be so problematic. And on that note, good luck! --Watchog
Good luck. Feennekin and Swam, I believe in you! --Audino
I was quite surprised when I heard the news yesterday… I’m glad you opened up to me! Good luck! --Farfetch’d
Good luck! Follow your dreams! --Sunkern
School is important, but it’s important to go after what you want in life, too! Take good care of yourselves… and good luck! --Roselia
We have a shop in Lively Town, too. So you have nothing to worry about! Good luck! --Kecleon
Time to let these cute kids fly away on their journey! Hy-krah! --Hawlucha
Be brave and never give up! Take care! And good luck! --Kangaskhan
Go on, Fennekin. See you when you get back. Your adventurous spirit can’t be contained. If you think you’re ready, go see your dreams through to the end. --Carracosta
Good luck to you, Swam. We just happened to meet, and you came to live with me… I reckon it sure enough was fun havin’ you around, Swam. I reckon I can’t help but worry. But I’m cheerin’ for you. Take care. --Nuzleaf
]]>浦東空港 → 成田空港 → 秋葉原ホテル → 秋葉原ツアー(STEINS;GATEの巡礼/そば屋/メイド喫茶店/ポッ拳を遊ぶ)
11月13日清晨,仍然沉浸在一周前ASCOT之行的快乐回忆中,一边刷着久违的任天堂直面会情报,清醒过来的时候已经和几个同行的小伙伴集合,抵达了浦东国际机场。在Bilibiliyoo大白带领下领了随身Wi-Fi路由,换了日币,然后办了乘机手续,过了安检,乘上了一架波音777飞机。
说起来,这次旅行不仅是第一次出国,也是第一次乘飞机的经历。虽然想要装成不是第一次的样子,但降落的时候没有经验弄得耳膜好痛。下午3点多钟抵达成田机场,入境后就看到了漫游娘的旗帜和接下来几天带领我们的老司机。
然后乘京成电铁的车票抵达市区,从上野站走出看到地面的时候,虽然不到5点钟,不过由于冬天的原因已经天黑了。
乘JR来到了秋叶原,由于酒店就在秋叶原的中心,所以有充足的时间可以游览这个御宅圣地,同时秋叶原也是「命运石之门」「Love Live!」「俺妹」等很多作品的取景地。办理入住手续后,老司机就带我们游览一圈。
在JR车站不远处就看到了「世界的广播馆」,命运石之门中整个故事开始的地方,现在楼顶已经没有了5年前出现的时光机。
原来消失的是时光机被搬运到了这里。另外,整个秋叶原随处可见新作「命运石之门0」的宣传海报,然而想到PV里消失的助手和封印的凶真会有一点心酸呢。
逛到一家荞麦面馆吃了晚饭,说起来虽然秋叶原并不是吃货的圣地,但这几天吃到很多好吃的面已经很满足了w。接着去@home cafe女仆咖啡店喝了美味的抹茶拿铁,啊我才不会把合影交出来www。
走一家电玩店门口看到小朋友们在玩神拳于是就冲了进去。街机在日本仍然非常有活力,画面完全不输家用机。玩了几场对战感觉太棒了,尤其是假面皮卡丘。嘛期待Wii U版~
最后路过的一个卡拉OK店看到了「请问你要来点兔子吗?」中的纱路酱。
秋葉原ホテル → 神田明神(ラブライブの巡礼) → 浅草寺 → お台場 → 大江戸温泉物語
第二天一早,决定前往附近「Love Live!」的圣地神田明神。
UDX大楼,在命运石之门中发生了很多故事的那个桥旁边,也是Love Live!动画中Arise组合活跃的UPX学校。早上路过的时候,这里正在播放Aqours的PV,默默祝福她们可以像前辈μ’s一样耀眼: )
终于来到了东条希担任巫女打工的地方「神田明神」,相信LLer对这里一定非常熟悉。来到这里的时候雨开始变大了,如果穗乃果在这里喊一声「雨停下来吧」,就一定会停下来的吧。
这个阶梯是μ’s的大家洒下无数汗水的地方。走到这里想起穗乃果被海未催促着锻炼的情景,以及因此终于取得了Love Live的优胜,觉得这样的努力获得回报的故事真是太好了。
神田明神里除了可以买到东条希的护身符和绘马,还有叫「IT情报安全御守」的护身符,据说有同学没有买这个,后来相机的SD坏掉了。
在神社的中间挂着很多很多LLer在绘马上写下的心愿,甚至有大触用剪纸贴上的穗乃果。希望μ’s的某一位事业成功;希望自己考试合格,被向往的大学录取;希望能成为声优或小说家;希望6th Live当选或者抽到UR;希望家人健康世界和平;希望南条爱乃姐姐的膝盖能早日恢复健康。看到这些充满心意的文字,被大家的真挚和才能感动了呢。
说到这里提醒一下想要在绘马上写字的同学,务必学好语法,一个绘马上有中国的小情侣写了「あなただけあいしていません」,被神明看到就不妙了。嘛字不好看又不会画画的某只就把绘马收藏了起来。
然后去抽签抽到了大吉,然后去正殿参拜,许下了「想要去μ’s的Live」这样的心愿。其实有一种敬畏的心情,因为相信着「みんなで叶える物語」这样的事情,相信着这种大家一起努力获得回报的故事。后来回家之后,就看到了「μ’s Fan Meeting in上海〜Talk&Live~」的消息,真的是很奇妙的感觉,希望能顺利得到票和行程吧。
走出神田明神,前往车站的路上又看到了似曾相识的场景。
命运石之门一开始,冈部和嘟嘟噜所处的那座桥下。
恰好路上一个人都没有,有点怀疑是不是跳到了另一个世界线。
中午到达了浅草寺,附近的吾妻桥是「名侦探柯南:异次元的狙击手」出现的地点。恰好肚子饿了,在浅草寺里印象最深的果然还是美味的烤蟹棒w。
下午乘着隅田川游船抵达御台场,在Diver City外见到了传说中1:1的高达。另外在楼上的展馆第一次看到了圆形剧场的动画电影,真的是非常震撼的体验。
傍晚时分来到了大江户温泉物语。换上浴衣来到了有很多好吃的小店和好玩的设施的地方,就像很多动画看到过的祭典一样,然而并没有找到可以捞金鱼的店呢(…)。虽然这里完全和秋叶原不同,不过看到太鼓达人就抑制不住冲了过去w,打了很多神奇宝贝的曲子,Love Live的歌,偶像大师的歌还有点兔的歌,然后终于累了去泡温泉。
回忆起来下着一点小雨的时候,泡在露天温泉里的感觉很奇妙呢。终于从打太鼓的疲惫中完全恢复后,去喝了很多很多Soda Pop,然后吃了肉串然后回秋叶原。
回到酒店的时候,Tokyo MX刚好开始播「请问你要来点兔子吗?」,于是在温泉刚补满的HP一下子清空了www。
秋葉原ホテル → ポケモンセンターメガトウキョー → 秋葉原ツアー(ラジオ会館/アニメイト/ソフトマップ/トレイダーズ/竹むら) → 東京ディズニーランド
第三天分组行动,因为是周日,早上8时被闹钟叫醒,打开TV Tokyo看神奇宝贝之家节目,恰好这天增田顺一神様参加节目,看到翔子姐姐和节目组的大家用跪拜的方式迎接「神降临」好好笑。增田讲了一些关于神奇宝贝音乐的故事,然而依然并没有Z的消息。然后乘JR山手线前往池袋,去这次旅行最重要的圣地「神奇宝贝中心Mega东京」。
来到池袋Sunshine City,刚到2楼就听到了丰缘地方的城镇音乐,然后看到了巨大的 POKéMON图示和喷火龙与皮卡丘。
在入口处。第一次在实体地点领取活动配信的神奇宝贝,看到不同颜色的班吉拉闪光的一瞬间,真的觉得「终于等到这一刻」了呢。
在神奇宝贝中心里,看到了不同肤色不同发色不同瞳色的男女老少,听到讲着日语汉语韩语英语和阿拉伯语的声音,真的能体会到神奇宝贝把这个世界不同的想法和梦想连接了起来。当天过生日的小朋友走到哪里都会听到生日快乐的声音,还有点羡慕呢。Mega东京店的占地面积很大,但看到这样的货架每走一步都是巨大的困难: )
抱了一大包的挂件文件夹毛绒背包帽子画册卡片盒零食,终于满足地离开。另外,在Sunshine City,稍微往里走一段从2楼向下望去,就是在「偶像大师灰姑娘女孩」中,New Generation第一次登台表演的喷水广场。
中午回到秋叶原,下午的行程是继续在秋叶原逛以及买宅物。在秋叶原里,二手回收再销售的店铺相当相当发达,很多在线上很难找到的手办和CD和BD都可以在秋叶原发现,并以很低的价格入手。
出站看到的这个地方又觉得十分似曾相识。
这一天在广播馆入手了Love Live与初音未来的画册,偶像大师演唱会BD,在ムーラン入手了岛风酱和花阳亲的景品,在Softmap入手了点兔的OPED和中川翔子武道馆演唱会BD,还有记不清的地方入手的数不清的收藏。不过想去的店铺逛到一半天色已经晚了。
一边逛看到自动售货机真的有Dr Pepper这种饮料,喝了几罐的感觉怎么说呢,确实会是凤凰院凶真会喜欢的口味呢www
在傍晚集合前,跟着Google地图去了「竹むら」,在Love Live中就是高坂穗乃果的家,不知是不是因为已经晚了,这家点心店没有开门。回酒店的路上路过了标记的曾是矢泽日香家所在的遗址,但那里现在已经在封闭施工了,大概因为妮可已经是大银河宇宙No.1的偶像了所以要把自家也翻新一遍吧ww。
傍晚前往迪士尼乐园,抵达的时候刚好看到彩车的表演,听到某些圣诞歌曲的时候感觉就像「The Polar Express」中的北极呢。
接着发生了一件非常幸运的事情。晚上东京迪士尼乐园的城堡会整个成为动画电影立体投影的舞台,在入场的10万人左右游客中,有1000人可以当选进入中央鉴赏区的座席观看———然后当老司机说他带了几年团只见到过3人抽中的时候,我的入场券就掉下来了。
立体投影的演出真的非常震撼,整个巨大的空间完全变成了童话的世界,城堡和两侧的柱子就像一直会在动一样。最意外的体验是,从城堡喷出的火产生的热浪会直接扑面而来,感觉非常温暖。
之后去了丛林和星球大战的游乐设施,とても楽しかった: ) 时间过得很快,旅行的时间已经过去了超过一半。
秋葉原ホテル → 鎌倉高校前駅(メモリーズオフの巡礼) → 江の島(岩屋/鳥居/龍恋の鐘/シーキャンドル) → 秋葉原ツアー(まんだらけ/とらのあな/GEE!STORE)
第4天终于天晴了,目的地是镰仓、江之岛一带。早上进入江之岛线电车的时候,就被这熟悉的车站内的情景触动了。秋之回忆系列只玩过两作,不过和「芦鹿电」有关的场景留下了深刻的印象。和都市现代化的电车不同,江之岛线是一种古朴的风格,但无论车站、电车内还是窗外的景色都十分美妙。
镰仓高校前站,秋之回忆2中的樱峰站。看到这个熟悉的地方感动的同时又回忆起某些有点心酸的故事呢。另外,这里进出站的闸机并没有闸杆,也是和都市的不同之处。
在镰仓高校前站路口驶过的一辆电车,这个路口在很多作品中都出现过。
镰仓高校前的海岸,这是至今为止我见过最美的海岸。向大海的方向望去更远的地方是神奇宝贝中关都地方红莲岛和双子岛的所在。秋之回忆2中健和蛍散步的地方,似乎就在这海岸向前的某处。
接着乘江之岛电前往江之岛。江之岛站是秋之回忆系列中的浜咲站。江之岛本身也是在New Love Plus+中和凛子日归旅行来过的地方,所以称得上是回忆的场所呢。
乘船抵达江之岛,第一站是岩屋。从这里开始就是持续不断的既视感,在真实世界里第一次到这里,但又是已经来过不止一次的地方: )
龙恋之钟也是New Love Plus+日归旅行中的重要地点。话说差点被老司机和其他小伙伴怂恿拿出3DS呢。
这个瞭望台同样是回忆的场所,在这里可以一览整个关都地方,景色真的相当相当美。
据说位于生物链的顶端的喵星人才是这座岛的主人。另外这里随处可见的三角形标志大概就是「赛尔达传说:众神的三角力量」中的原型。
傍晚回到秋叶原,继续寻觅宅物。在GEE!STORE入手了限定的Love Live主题马克杯和餐盘;据说这里上方就是南琴梨打工的女仆咖啡店,不过需要一早排队才能进入。 在MANDARAKE,这个传说中的大黑楼看到了更多喜欢的角色的手办。然后在虎之穴看到很多同人志,最喜欢的一本是「吹响吧!上低音号」的「夕暮れセレナード」。需要注意的是秋叶原虎之穴相邻的两店分别是一般/男性向和女性向的内容,进错了会有点尴尬。
到这天夜晚旅行的时间就只剩半天了,一边有点不舍的心情一边寻找最后要去的目标。然后注意到漫游娘公众号提到的「旧古河庭园」,是「路人女主的养成方法」动画中英梨梨的家,咨询了老司机确定时间来得及后,决定最后去这里巡礼。
秋葉原ホテル → 旧古河庭園 → のぞき坂(冴えない彼女の育てかたの巡礼) → 成田空港(WHITE ALBUM2の巡礼) → 浦東空港
这次旅行的最后一天,一早醒来就赶到JR山手线前往駒込站,来到Google地图指定的地方后发现只能看到长长的围墙,绕着围墙终于找到旧古河庭园入口,然后在入口不远处看到了和动画中完全一致的洋馆。
整个庭园远比想象中要大,到处可见到阶梯、小亭、红叶还有阳光折射出彩虹般的光线,非常非常綺麗。
从旧古河庭园出来,距离集合去机场还有一点时间,于是去了「路人女主的养成方法」中另一个重要的地方,加藤惠的贝雷帽掉下的那个坡道。
看过动画的话一定对这里很熟悉吧 : )
然后就这样踏上了归途,回到秋叶原的酒店退了房间,乘京成电铁前往成田机场。到了成田机场突然想起还有一个地方想要去。
成田机场5F展望台。「WHITE ALBUM2」中序章开始和结束的地方,与雪菜和春希「怎么会变成这样呢」的心情不同的是,自己来到这里是感激和不舍的心情。
到晚上回到了浦东机场,短暂的5天4夜的旅行结束了。前往机场附近的酒店休息一夜准备第二天回京。
感谢学识渊博不辞辛苦的老司机,感谢Bilibiliyoo,简短的文字和挑选出的几张照片完全无法表达这几天所有的快乐与幸福。能来到日本真是太好了,能去神奇宝贝中心真是太好了,能看到喜欢的作品中出现的圣地真是太好了,能实现梦想真是太好了。
直到已经过去4天的现在,一闭上眼睛仍然能浮现出秋叶原JR车站前的街道。一定会再来日本,不仅是关都,还有城都丰缘神奥以及东北。
いままでもこれからも也一直会作为Otaku活下去,但从此开始相信,喜欢的作品中存在的地点也好故事也好奇迹也好,是可以在这个真实世界找到的,所以从今开始也站在真实和理想的交点上,更加充满希望的生きてる。
]]>addTarget:action:forControlEvents:
或在 Storyboard 拖出一个 IBAction 就可以轻易实现事件响应;另外,各种各样的 UIGestureRecognizer 也可以为任何 UI 元素添加手势,实现所需的事件处理。然而,许多场景下需要 App 干涉的 UI 元素的事件响应过程。例如,某个 UIButton 在设计中 frame 很小,而希望它的响应区域更大;或者,App 需要在某些情况下忽略 UIView 的层级关系决定响应 Tap 的元素。
iOS 采用一种叫 Hit-Testing 的方式决定接收触摸事件的元素,并提供了 hitTest:withEvent:
和 pointInside:withEvent:
方法允许 View 决定自身是否接收事件,或具体接收事件的 subview,两个方法第一个参数均为一个相对于 View 自身 bounds 的 CGPoint
。
一般来说,UIView 在响应到触摸事件时会进行如下判定,同时这也是 hitTest:withEvent:
默认的实现:
pointInside:withEvent:
方法hitTest:withEvent:
返回 nil,Game OverhitTest:withEvent:
,调用的顺序从最上层的 subview 开始,直到最底层的 subview 或中途返回了非 nil 的 UIView。hitTest:withEvent:
也会成功返回这个 UIView,到此为止。hitTest:withEvent:
方法返回均为 nil,则自身处理这个触摸事件,hitTest:withEvent:
方法也会返回 self。而 pointInside:withEvent:
默认实现想必正如字面意思,判定触摸的 CGPoint 是否位于自身 bounds 内。另外需要注意的是,userInteractionEnabled 为 NO 的元素不会响应事件,如 UILabel 和 UIImageView 默认为 NO。
回到之前提到的场景,当 UIButton 自身 frame 过小,如何扩大它响应触摸的区域。一个最常见的做法是改变它的 frame,同时使用 imageEdgeInsets
或 contentEdgeInsets
等方式为它增加 padding,使 UIButton 的 frame 扩大而不增大它其中的内容。
但个人认为这并不是一种非常优雅的方式,设计师同学在设计时,考虑的一般是内容边缘距离父级元素或同级其他元素的距离,对应到用 Auto Layout 开发时,也就是一个相同数值的 NSLayoutConstraint。但若为了改变它的事件处理而改变 frame,配置约束时就会变得复杂和混乱。
而重载这个 UIButton 的 pointInside:withEvent:
方法就可以很好地解决这个问题,由于这个方法的第一个参数是相对于自身 bounds 的 CGPoint,只要判定这个点位于自身 bounds 外围指定距离内的 CGRect 内时返回 YES,就可以在 UIButton 外围响应触摸事件。
横滑滚动多个可以纵向滑动的 UIScrollView(UITableView)也是很多 App 中一个经典的交互设计。而若当这些纵向的 UIScrollView 需要一个公共的 ‘headerView’,并且在它们上滑的时候,希望 UIScrollView 中的内容能遮盖或推走这个 headerView,甚至这个 headerView 还存在可以响应事件的按钮的时候,问题就变得稍微有点微妙。
由于这个 ‘headerView’ 并不希望它属于每个纵向的 UIScrollView,不随着横向滑动而移动,所以它应当独立于横向滑动的 UIScrollView(UICollectionView)之外;由于希望纵向的 UIScrollView 滑动时可以用内容遮盖 headerView 的内容,所以它的层级应该位于横向的 UIScrollView 之下;另外,纵向的 UIScrollView 应该用 contentInset 或透明的 tableHeaderView 让下层的 headerView 露出来。
看到这里,我想很多同学会疑问“为什么不用两个纵向的 UIScrollView 嵌套起来”,不过想象一下在滑动内层的 UIScrollView 如何处理就变得头大了吧。
此时,这个 ‘headerView’ 由于位于下层,无法响应事件,如果其中有 UIButton,也无法被点击。而利用重载横向滑动的 UIScrollView hitTest:withEvent:
方法,在点击区域位于“本应属于 headerView”的位置时返回 nil,就可以很好地解决这个问题,它的 superview 也自然会把这个事件交给下一个 subview,即这个 headerView 来处理,而这个 headerView 亦会把事件交给对应的 UIButton,最终完成按钮的点击。我在处理这个问题时利用了一个透明的 tableHeaderView,在 hitTest:withEvent:
中调用了它的 super 方法,如果拿到的 UIView 正是这个 tableHeaderView,就直接返回 nil,否则返回 super 的结果。
关于这两个问题,我写了一个简单的 Demo,需要的童鞋可以移步 GitHub,有不同的想法欢迎扔 Issue : )
]]>「或许存在另一个世界,你阻止了的人是我。」——在他的梦中,被唤醒的超古代神奇宝贝是另一只。
祐树来到未白镇的这一天,神奇宝贝多功能领航员上出现了未曾谋面,但却熟悉的面孔,通信画面上接下来的一言一行,都似记忆深处早已发生的真实。110号道路与小遥的对战,在强烈的既视感之中「再次」完败——唯一不同的只有沼跃鱼倒下前的神态。
在历史的长河中,总有许多命运的分界点上,自然亦或某个生命做出不同的选择,产生了错综复杂,但又相似收束的世界线。在某个时空中,紫菫没有成为室内都市,但那里的游乐场也没有因不能说的理由关闭;在某个时空中,关都四天王有不同于正义使者的过去;在某个时空中有会说话的喵喵和两人组成的三人组。
每一个生命都或多或少有种「命运探知」的能力,相信不只是曼珠、主角和敌对组织首领,每个人都有过Déjà vu的体验。如AG086,一个时空中某个虚构作品,恰是另一个时空的真实。如果能读到其他世界线中自己的记忆——甚至像XY036中一样,和另一个自己见面,一定可以「创造」或者「改变」什么。
2014年接触了很多平行世界题材的作品,Ever17的轮回,Virtue’s Last Reward的选择,命运石之门的跳跃;那些为了重要的东西努力改变世界线的故事,每一作都有很深刻的感动。至ORAS变幻篇章的最大收获,不仅仅是坚持「相信」喜欢的世界的存在,而且对于「哪一个」才是「真实」,也有了答案。
不过呢,在这个世界线变动率附近的范围内,现在这个数值就刚刚好呢: )
圣诞快乐。
参考:AzzyFox
]]>In Sootopolis City, after the end of the extreme weather event.
Finally, it’s just two of us again.
I’ve got to say…thanks for everything you’ve done for our region, Swam.
You know, I thought we were supposed to have set out from Littleroot together, but…
But you, Swam…
It seems like you just keep getting further and further ahead of me…
I even started to feel like you’d gone somewhere I can’t even reach.
It’s pretty lonely, you know?
Not!
What would you think if I really said something like that?
Hee hee!
My dear May. Do you know what I’m thinking?
I mean, everything I were able to have done, begins with our first battle near the pool of Route 103, just like you said in Lilycove. I were merely a careless boy who knew nothing about Hoenn, but you welcomed me with the most beautiful smiling face on that day, and taught me how to battle, how to creep near Poochyena. You helped me and encouraged me every time.
I never feel I’m ahead of you. When we met at Lilycove, I noticed your Pokédex was nearly completed. You must have made great efforts to achieve this, and that’s the thing I lag behind you a lot. You are my best friend, and you are never alone.
So…When our journey comes to a new chapter, I wish we get back to Littleroot together, and I want we understand everything about each other and our Pokémon and share our journey together.
And…May we be together forever.
]]>两年多前玩过DS上的前作「9小时9个人9之门」;VLR本作是美版发售就买来了,但因为等Bug修复补丁等了很久(现在也没出)加上胆小不能在平时玩(?)就拖了一年多,然后最近终于想起来一定要体验这作,差一点就错过了。
故事发生在2028年12月25日,前作的一年后,主角和其余8人被绑架到神秘的设施中,被迫参与密室逃脱以及囚徒困境的AB(Ally or Betray)游戏。9个人在游戏开始被佩戴了计数为3的腕表,当在进行几轮AB游戏后计数达到9时就可以脱出游戏,而计数小于等于0时则会遭到「处罚」。和前作一样,这场脱出游戏只是精心设计的密谋,并不是故事的真相。
以下内容涉及剧透,没有玩过本作品的同学请直接前往任天堂3DS eShop商店购买(或PSN购买Vita版),在完成全部结局后再回来看吧。这里推荐下载版是因为传说3DS版有在某个密室(PEC)存档可能损坏存档的Bug(其实我觉得也可能是Feature),下载版可以随时备份存档避免悲剧发生时的损失。
其实一开始对极限脱出系列有兴趣有制作商Spike Chunsoft的原因,某种程度上「9小时9个人9之门」能找到「神奇宝贝不可思议的迷宫 时/暗之探险队」的影子,剧情中贯穿着隐藏的线索,时间和空间的融合,以及真相结局中包含着的「希望」。
两年前玩999的时候,相当喜欢「四叶草」的设定,四叶草书签的希望·信赖·爱·幸运是大家最终走到真相所必需的东西。而本作也有「希望」的要素,日文标题中的「シボウデス」可写作「死亡」不过也可以写作「志望」吧。
但是游戏的结局并没有看到「希望」,更多的是一种「宿命」的束缚,意识回到过去的Sigma的阻止根号6病毒扩散拯救世界的努力失败,而对45年间的Sigma来说,这一切是过去发生的事实,也因此(?)需要付出45年的努力实施阻止根号6病毒扩散的AB计划。
本作四叶和Alice登场的原因仅仅是为了增幅Sigma和Phi的能力,加上四叶的结局一如既往(?)是最惨痛的多少有些遗憾。但是四叶的人设依旧喜欢就是了,对于主角某些不合年龄(?)的表现的反应也是有趣的地方。
在最终章「Another Time」中玩家的视角变成了K,但K却知道很多他「不该知道的事情」,茜最后表示「你不是K,你不需要遵守我们的规则,你是我们的系统里一个独特的变量」的时候,瞬间想到了打越钢太郎另一部作品「Ever17」中的设定,然后看到Wiki中讲PSV版中完成最终章的成就叫做「A Certain Point Of View」证实了我的猜测。
「我」就是「视点」,四次元生物「Blick Winkel」,在Sigma博士的影像中其实也暗示了更高次元智慧的存在;但是无论如何套用Ever17中Blick Winkel的所作所为,并不能拯救VLR中的世界,比起挽救两个人的生命,改变整个45年的历史对「视点」来说要难得多。
「 Reality is shaped by what we believe reality should be. 」
在接触这作很久之前我就是薛定谔的猫的不科学解释(?)的支持者,因此从来回避体检一类的事情。本作引出了薛定谔的猫(如果外部世界是装着猫的盒子,这个密封设施是观察者),Phi线中也应用了一次这个理论(茜这次并没有被Dio所杀),最终章Alice说茜提到了解决悖论的办法就是「薛定谔的猫」,不过如何应用薛定谔的猫来拯救世界就要等到续作了。
Bluebird是Sigma送给Luna的音乐盒,来源于「メーテルリンクの青い鳥 チルチルミチルの冒険旅行」,包含了笼子里的鸟、幸福得而复失的寓意。
2028年12月31日究竟发生了什么,E路线的世界是否可以存在,Santa在做什么,Phi的真实身份等等谜题都需要在下一作中揭示。但由于日本销量不佳的原因,Spike Chunsoft暂停了极限脱出第三作开发。玩家为了表示对系列的支持发起了Operation Bluebird行动,很短的时间内就得到了上万支持;打越钢太郎目前正在进行其他作品的工作,如果顺利的话,之后极限脱出第三作恢复开发并不是不可能。
所以相信VLR续作一定会登场,比起整个AB计划,Operation Bluebird的成功要容易得多呢。
]]>日志标题中「用得起」的假设是运行在一台 1GB RAM 虚拟(云)服务器,日页面访问量在一百万以内。市场上 1GB RAM 的 VPS 价格约 10 ~ 30 美元每月。MediaWiki 并不适合运行在共享虚拟主机,或内存不到 512MB 的服务器中。
另外,MediaWiki 官方网站提供了一些基本的优化方式,非常值得参考。
是的。相较其他流行的 PHP 开源应用,MediaWiki 可以认为更耗资源,尤其是 CPU 使用,一篇包含复杂模板嵌套的文章,在无缓存状态下的渲染时间可能长达数秒,甚至数十秒。
经历了十多年的发展,MediaWiki 也是一个架构设计优雅的工程,具有非常强大的功能和可定制性,其性能开销往往是必要的。合理运用多重优化手段方式,可以有效降低 MediaWiki 的性能开销。
如果在生产环境使用最新版本的服务器程序,往往会引起很大的争议。但事实上,开源程序往往可以保持对较新版本系统环境很好的兼容性,新版本的系统环境往往具有更少的 Bug 和非常大的性能提升。
52Poké 所在的虚拟服务器采取了较为激进的做法,自2011年后一直使用 Arch Linux 操作系统,其滚动升级的特性可以让包管理(pacman)安装的应用都保持在最新版本,同时 Linode 也默认提供了最新版本的 Linux 内核。虽然对基础服务大版本的升级危险较大,但两年多来数十次 pacman -Syu
并未带来很大麻烦,除了在某几个凌晨造成数十分钟的不可用(都是由于较长时间未升级造成跨度较大并且操作失误)。
回到主题,对 MediaWiki 而言,高性能的 Web 服务器程序除了意味着 PHP 5.5,MySQL/MariaDB 5.5+;也包括使用 PHP 5.5 内置的 OPcache 加速,以及使用 Nginx + php-fpm 代替 Apache,Memcached 和/或 Redis 缓存等。
当前支持神奇宝贝百科的服务器程序为 PHP 5.5.7,MariaDB(MySQL 对社区友好的一个变体)5.5.34,Nginx 1.4.4 以及 Memcached 1.4.17。
MediaWiki 的默认配置(LocalSettings.php
)并不适合生产环境,这里简要介绍一个低能耗的 MediaWiki 系统需要增加的配置项:
$wgDisableCounters = true;
关闭内置的统计功能,如需要统计访问量可以使用 Google Analytics 等外部服务。$wgWellFormedXml = false;
以及 $wgHtml5 = true;
打开 HTML5 标签输出并关闭兼容 XML 语法,可以降低页面的体积。$wgShowIPinHeader = false;
关闭未登录用户在右上角显示 IP 地址,以便使用静态缓存。$wgUseGzip = true;
开启 gzip 压缩,降低页面体积,另外也可在 Web 服务器中配置开启 gzip。$wgMiserMode = true;
关闭实时生成特殊页面;建议同时在 cron 里配置定时任务,定期生成特殊页面。$wgJobRunRate = 0.01;
减少执行任务的频率(即每次请求有1%的几率运行任务);MediaWiki 的任务往往需要耗费数秒的时间执行,默认运行频率为1,一旦插入任务就可能导致 PHP 进程全部被占满;这里同样建议在 cron 里配置定时任务运行 MediaWiki 的任务,以免使任务队列积累过多。$wgInvalidateCacheOnLocalSettingsChange = false;
关闭修改 LocalSettings.php 使所有缓存失效的特性;MediaWiki 的缓存完全失效是非常可怕的,几乎可以迅速致服务器僵死。MediaWiki 的稳定运行,opcode 缓存、object 缓存和页面缓存都是必不可少的。
opcode 缓存用于加速 PHP 脚本的执行。PHP 5.5 内置了 OPcache(即之前的 ZendOptimizer+),比起 eAccelerator、XCache 和 APC 有更好的性能,只需在 php.ini 中引用 opcache.so 即可使用,同时 OPcache 也可单独安装在 PHP 5.4 或 5.3 环境中。另外需要注意 PHP 5.5.1 及 5.5.2 内置的 OPcache 和 MediaWiki 存在兼容问题,5.5.3 以上版本已解决。
MediaWiki 可以利用 object 缓存存储包括界面语言文字、文件信息、模板生成的中间产物、最终页面渲染 HTML 等数据。MediaWiki 支持使用 APC、XCache、Memcached、Redis、MySQL 数据库方式缓存数据,但配置中默认未开启 object 缓存功能。在这几种缓存方式中,除 MySQL 数据库外都需要在内存中存储,其中前3种存储方式无法持久化。
这里推荐使用是 Memcached 和 MySQL 结合的方式,配置方式如下:
$wgMainCacheType = CACHE_MEMCACHED; $wgMemCachedServers = array('127.0.0.1:11211'); $wgParserCacheType = CACHE_DB;
Memcached 由于将数据存储在内存中,读写速度非常快;存储相同内容的数据占据的内存空间也是几种方式中最小。但 Parser Cache 由于包含了页面完整的 HTML 文本,需要的体积非常大,同时一旦失效则会需要重新解析所有页面,带来巨大的 CPU 开销;在内存有限的条件下更适合存储到较为持久的 MySQL 数据库中。
神奇宝贝百科在2013年初使用 Memcached 曾频繁遇到 Segfault,因此更换到 Redis + MySQL 结合的方式,但 Redis 耗费了更多内存(仅指在 MediaWiki 的使用方式下),也有相对较大的 I/O 使用。2013年12月 Memcached 发布了 1.4.17 更新,解决了不稳定的问题,因此目前又换回使用 Memcached。
作为一个 Wiki,对未登录用户而言页面几乎是静态的,所以页面缓存可以非常有效;MediaWiki 提供了 File cache 功能,另外也可以使用 Squid 或 Varnish 的功能。而对于只有一台服务器的站点而言,这里更推荐使用 Nginx 自带的 FastCGI 缓存功能。
MediaWiki 默认会根据请求头中的 Accept-Language(即用户浏览器语言)、Cookie 等因素区分不同的页面缓存(可见响应头中的 Vary 行)。但对于单一语言、没有文字变种的 Wiki,只要已登录用户不使用页面缓存,未登录用户访问则看到相同的页面内容即可。
以下是神奇宝贝百科的 FastCGI 缓存配置,为便于介绍去掉了中文简繁处理相关的内容。这里缓存有效期为5小时,可以根据实际情况修改。另外,特殊页面不宜开启静态缓存(如最近更改和随机页面)。
http { ... fastcgi_cache_path /var/cache/nginx/wiki levels=2:2 keys_zone=wiki:128m inactive=5h max_size=2048m; server { ... if ($http_cookie ~* "52poke_wikiUserID") { set $do_not_cache 1; } if ($uri ~ "^/wiki/Special:") { set $do_not_cache 1; } if ($args ~ "Special:") { set $do_not_cache 1; } fastcgi_cache wiki; fastcgi_ignore_headers Cache-Control Expires; fastcgi_hide_header Vary; fastcgi_cache_key $uri$is_args$args; fastcgi_cache_bypass $do_not_cache; fastcgi_no_cache $do_not_cache; fastcgi_cache_valid 200 5h; fastcgi_cache_valid 301 0; fastcgi_cache_valid 404 20m; }}
使用页面缓存就会遇到缓存更新的问题,好在 MediaWiki 提供了 PURGE 功能,配置后只要相应的页面有更新就会发出 HTTP PURGE 请求。LocalSettings.php
中的配置如下:
$wgUseSquid = true;$wgSquidServers = array('127.0.0.1’);
这里只配置了 127.0.0.1 因 52Poké 只有一台前端服务器,并且和 MediaWiki 程序是同一台。不过 Nginx 默认并不支持 PURGE 请求,可以编译安装 ngx_cache_purge 扩展实现,具体操作步骤可以参考这里。
对于具有文字变种,如中文简繁之分的 Wiki,则情况较为复杂,今后这里会详细讨论 MediaWiki 处理中文简繁的问题,本篇就不详述了。
MediaWiki 提供了非常强大的模板和语法处理功能,尤其是内置的 ParserFunctions 扩展,但语法解析需要非常大的 CPU 开销。
这里建议尽可能减少不必要的模板使用和嵌套。例如对于一些通用的文字、背景颜色、边框样式,更适合在 MediaWiki:Common.css
或小工具中使用 CSS 实现。如果文章在编辑后需要等待很长的时间才能加载出来,则需要对其中使用的模板进行优化,必要时可以考虑拆分文章。
MediaWiki 解析图片信息也需要较大的资源消耗,对于较为固定的图片、尤其是尺寸较小的图片,推荐使用 CSS Sprites 而非通过 Wiki 上传。
MediaWiki 也会对包含过多模板嵌套、或者使用了过多语法呼叫(例如 switch 和 if 语法)的文章自动添加警示的分类。
基础硬件的性能往往是第一位的,对运行 MediaWiki 而言,CPU、内存、I/O 性能、网络带宽都至关重要。其实早在2006年 52Poké 就搭建了 MediaWiki,但在有上百篇文章之后当时所在的虚拟主机就不堪重负,不得不在后来转型使用自建的程序,直到2010年开始使用 Linode。
就 52Poké 使用 Linode(推介链接) 的经历而言,Linode 是一家不错的 VPS 提供商,但并不算完美。Linode 在2013年进行了多次升级,在流量、网络速度、CPU 性能和性价比方面有较大优势。
VPS 有一个不稳定因素是 CPU 和 I/O 性能会受同一台物理服务器的邻居影响,52Poké 曾遇到过 CPU %Steal 过高导致性能较差的问题,不过联系客服很快迁移了另一台物理服务器解决。Linode 的 I/O 性能比提供了 SSD 的服务商要差,目前 Linode 只在纽瓦克数据中心提供了测试版 SSD 服务,亚洲用户较多使用的东京数据中心则尚未提供。
到这里已经介绍了高性能 MediaWiki 站点的必要条件。不过对于拥有较多图片的 Wiki 来说,可能很容易遇到流量超限或 I/O 消耗较大的问题,推荐如有必要添加一台流量较为廉价的 VPS 存放或缓存图片;另外可以考虑将图片延迟加载,即当浏览者滚动到图片位置时再加载,该功能的 MediaWiki 扩展在完成开发后会开源。
关于 MediaWiki,除了性能之外,还有很多值得讨论的话题。比如扩展,小工具(Gadget),中文的繁简问题,条目命名和内容规范,自动化批量建设内容,版权问题,以及作为一个 Wiki 社群的建设和发展。这些就留在以后继续讨论吧。
对于未来,如何支持移动设备,如何进一步减少服务器端模板的开销是水跃在继续思考的问题。MediaWiki 官方提供了 MobileFrontend 扩展,但根据设备输出不同的内容会带来更多的复杂度和资源消耗,而且可能降低了移动设备的体验;所以我更希望有响应式的方案。对于复杂的表格如果可以服务器只在页面中输出元数据,由 JavaScript 在浏览器中渲染的话,就可以减轻服务器的压力。但修改 Wiki 的 JavaScript 和 CSS 的权限往往不会开放给普通用户,这样做对社区并不利。
2014年的第一篇终于啰嗦完了,这里祝各位新年快乐,也希望 MediaWiki 的同好有所收获吧: )
]]>