-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexperience.html
248 lines (248 loc) · 22.5 KB
/
experience.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Work Experience</title>
<link rel="stylesheet" href="styles.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lato&display=swap" rel="stylesheet">
<script src="script.js" defer></script>
<script src="https://use.fontawesome.com/9df4536e0c.js"></script>
</head>
<body>
<section class="text-doc">
<nav>
<!-- <a href="index.html"><img src="images/logo.png"></a> -->
<!-- <a href="index.html"><img src="images/HelpButton.png"></a> -->
<div class="nav-links" id="navLinks">
<i class="fa fa-times" onclick="hideMenu()"></i>
<ul>
<li><a href="index.html">HOME</a></li>
<li><a href="projects.html">PROJECTS</a></li>
<li><a href="experience.html">EXPERIENCE</a></li>
<li><a href="about.html">ABOUT</a></li>
</ul>
</div>
<i id="menu-icon" class="fa fa-bars" onclick="showMenu()"></i>
</nav>
<div class="page-title">
<h1>Work Experience</h1>
</div>
<div class="project-box" id="tatsu">
<div class="experience-header">
<div class="job-left">
<li><a href="https://www.tatsu.works/">Tatsu Works</a></li>
<div class="job-tag tag-app"><b>Node.js</b></div>
<div class="job-tag tag-personal"><b>Agile</b></div>
<div class="job-tag tag-backend"><b>Backend</b></div>
<div class="job-tag tag-game-design"><b>Game Design</b></div>
<div class="job-tag tag-game-econ"><b>Game Economy</b></div>
</div>
<div class="job-duration"><b>May 2020 - Dec 2020</b></div>
</div>
<div class="experience-role">Backend API Developer</div>
<div class="experience-body">
<p>
<a href="https://www.tatsu.works/">Tatsu Works</a> is the creator of the widely used <span id="terms">Discord</span> bot <a href="https://top.gg/bot/172002275412279296">Tatsu</a>.
<br><br>
It is used in more than <span id="emphasis">1,400,000</span> Discord servers and helps online Discord communities engage their community members by providing them with games and utilities.
The main selling point of Tatsu is the <span id="terms">Tatsugotchi</span> game, based on the popular <span id="terms">Tamagotchi</span> fad where users can collect pets, customize their own houses with more than a 1000 different pieces of furniture.
<br><br>
Tatsu also provides comprehensive utilities such as moderation features for server moderators and rewards members for activity in the Discord servers.
They are currently developing an <span id="terms">idle MMORPG</span> within Discord, <a href="https://tatsumeeko.com/">Tatsumeeko</a>, whose initial concept design I had also been involved in during my time there.
<br><br>
My main responsibility as a Backend API Developer during my internship was the implementation of <span id="emphasis">API endpoints</span> for Tatsu, using <span id="terms">Node.js</span>.
In addition, I was also involved in the game design and implementation for multiple events,
namely <a href="https://medium.com/tatsuworks/our-very-first-player-event-21091cc959f6">Tatsu's Launch Event</a> and the <a href="https://medium.com/tatsuworks/starlight-festival-2020-player-mail-basic-auto-mod-845a22d11524">Starlight Festival 2020</a>.
</p>
<div class="experience-imgs">
<div class="img-row">
<img src="images/tatsugotchi.png" class="experience-img" id="img-tatsugotchi">
<img src="images/house_customization.png" class="experience-img" id="img-house-custom">
</div>
<img src="images/tatsumeeko.png" class="experience-img">
</div>
</div>
<div class="experience-body">
<div class="experience-imgs">
<img src="images/daily_spinner.gif" class="experience-img" style="margin: 0 0 7px 0;">
<div style="position: relative;">
<img src="images/starlight_festival.gif" class="experience-img">
<p class="text-overlay">Starlight Festival 2020 Banner</p>
</div>
</div>
<p id="p-right">For both the <span id="terms">Launch Event</span> and the <span id="terms">Starlight Festival</span>, there were a bunch of limited-time mini-games added to Tatsu, along with limited pets and cosmetics.
The design of the mini-games were decided after team brainstorming sessions that I was a part of, before each of them were delegated to different developers.
<br><br>
I was in charge of implementing the <span id="terms">Daily Spinner</span> and <span id="terms">Greench</span> <em>(wordplay on the fictional character, the Grinch)</em> mini-games. I also designed the arrangement of the Bingo Board, balancing each line to make sure that task difficulties were spread out evenly.
<br><br>
I was also given the task of <span id="emphasis">game economy balancing</span>. There was a limited-time event shop during the Launch Event, with limited pets and cosmetics on sale that players would buy with the event currency (earned through the mini-games).
I had to balance the <span id="terms">currency gain</span> from the mini-games with the prices of items in the shop - the <span id="terms">currency sink</span>.
<br><br>
The goal was to ensure players of <u>different</u> participation levels would ALL have something they could afford in the shop and have fun choosing what they want and spending their currency.
The event turned out to be a resounding success, with <span id="emphasis">more than 110,000 users</span> involved in the <span id="terms">Treetsu</span> mini-game!
</p>
</div>
<div class="experience-body">
<p>Along with these events, new features were added to Tatsu. One of them was the <span id="terms">Mail system</span>.
I was tasked <span id="emphasis">alone</span> with this project, to design the <span id="emphasis">entire</span> system - both on the database side and the backend.
The implementation on the database would be done by a colleague, but the backend implementation would be done by me.
I designed how the database would store all the required information, down to the data types and <span id="terms">procedures</span> each call would do, along with the <span id="terms">backend functionality</span>.
<br><br>
Other than a slight hiccup with the database implementation, the design worked well! The system could handle sending mail to <span id="emphasis">ALL</span> users (with <span id="emphasis">hundreds of thousands</span> of users, this was non-trivial and needed to be handled) and mail to specific users.
I handled that concern by having a separate "Global Mail" and a "Personal Mail" where announcements would be stored in the Global Mail, which was stored in 1 location that all users would access.
This meant that there was no duplication of data and global mail would be have <span id="terms">O(1) space and time complexity</span>.
When individual users handled the Global Mail, for example by deleting, reading or marking as unread, a separate flag would be set for each user (with defaults).
<br><br>
Another sizeable feature I worked on was the <span id="emphasis">Moderation features</span>, namely the infract, warn, prohibit and exception commands.
It was added to make Tatsu a more comprehensive Discord bot, so that servers would not need to get a separate bot to deal with moderation unless they needed very specific features.
When enabled, Tatsu could screen members' messages and delete the message and warn or even remove them from the server if they contained any offensive words.
This required me to work with a <span id="terms">NoSQL</span> database, <span id="terms">Redis</span> that Tatsu Works used, a different one compared to the SQL database, <span id="terms">PostgreSQL</span> that I worked with in the Mail system.
At the time of writing, these moderation commands are <u>still</u> the ones used by Tatsu now!
</p>
<div class="experience-imgs">
<img src="images/delete_mail.gif" class="experience-img">
</div>
</div>
<div class="experience-body">
<div class="experience-imgs">
<div style="position: relative;">
<img src="images/machinations_diag.png" class="experience-img" style="margin: 0 0 7px 0;">
<p class="text-overlay">Machinations Diagram</p>
</div>
<img src="images/fish_catch_rates.png" class="experience-img">
</div>
<p id="p-right" style="padding-bottom: 20px;">One other project that I was initially assigned was the <span id="emphasis">re-design</span> of the <span id="terms">basic text-based fishing game</span> they had in Tatsu.
As with the other games, we did some brainstorming as the game design team and came up with an initial set of features that the revamp should include. I was put in charge of the game mechanics design
and introduced to <a href="https://machinations.io/">Machinations</a>, a <span id="terms">game economy & systems design tool</span>.
<br><br>
It's a tool that simulates systems such as players' currency gain, damage calculation that involves a significant amount of math and historically, messy Excel spreadsheets with complicated formulas.
I picked it up and used it for <span id="emphasis">preliminary design</span> on how the revamped fishing game's numbers would be calculated.
<br><br>Check out my initial drafts on fishing catch rates on the <u>left/above</u>!
I was experimenting with different scalings for the rates <span id="terms">(linear + Pokemon-based)</span> on Machinations. Sample results are shown on the graph!
<br><br>
One of the <span id="terms">co-founders</span> of Machinations, Mihai, also took an interest <em>(from one of my queries while working on it)</em> and <span id="emphasis">featured</span> my catch rate diagram on the website!
Even though the revamp was postponed to a future update because of the urgent requirements in developing the events above and bot features instead, I accrued invaluable insights from
discussing and planning the system that I'm sure will come to be useful in future projects.
<br><br>
Tatsu Works uses the <span id="terms">Agile methodology</span> and we had regular sprints where we designated tasks and allocated task priorities before assigning them to the respective developer.
We used <span id="terms">Trello</span> to keep track of tasks. It was my first experience with the Agile framework and I found it very useful in viewing our progress and checking what tasks we had left.
<br><br>
My time at Tatsu Works was very busy but also fun and very fulfilling! I learnt loads from the colleagues I worked with, about <span id="terms">different technologies</span> and how a team collaborates and works together.
I also got the opportunity to work on many projects where my work was released to <span id="emphasis">production</span> and entertained many users! Different areas were exposed to me, designing games, balancing game economies and systems,
working with different databases, backend development and more!
<br><br>
I was approached to extend my internship into a <span id="emphasis">full or part-time</span> role but I wanted to prioritize my studies and
so declined the offer. Even now, I'm sure it would have also been a great role, but I feel that the time wasn't right to accept it!
</p>
</div>
</div>
<div class="project-box" id="nparks">
<div class="experience-header">
<div class="job-left">
<li><a href="https://www.nparks.gov.sg/">National Parks Board</a></li>
<div class="job-tag tag-app"><b>HTML</b></div>
<div class="job-tag tag-app"><b>Javascript</b></div>
<div class="job-tag tag-app"><b>Visual Basic</b></div>
<div class="job-tag tag-backend"><b>Databases</b></div>
</div>
<div class="job-duration"><b>May 2019 - Aug 2019</b></div>
</div>
<div class="experience-role">Computer Science Intern</div>
<div class="experience-body">
<p><a href="https://www.nparks.gov.sg/">National Parks Board</a>, or <span id="terms">NParks</span> for short, is one of the statutory boards of the government of Singapore.
They are the lead agency for greenery, biodiversity conservation, and wildlife and animal health, welfare and management.
<br><br>
I was posted to the <span id="terms">Plant Records Unit</span>. The unit is in charge of surveying, labelling and tracking the living collections in the <span id="terms">Singapore Botanic Gardens</span>.
With thousands of species of flora in the Gardens, this is no small task!
<br><br>
My primary task was to <span id="emphasis">migrate</span> their current ageing database to a new database.
This included the analysis of different prospective databases to come up with a recommendation on which would be the best option,
and exporting of the current data.
<br><br>
Since there are numerous accesses and updates made to the database daily <em>(with the huge number of plants in the Gardens)</em>, one major consideration is that those processes should be fast and streamlined.
I looked into the regular tasks that my colleagues did to understand the processes and workflow.
<br><br>
Also, different databases also differ in the services that they provide.
For example, the <a href="https://herbaria.plants.ox.ac.uk/bol/">BRAHMS database</a> has an <span id="terms">in-built ARCGIS feature</span> <em>(a mapping solution)</em> that make it easy to map botanical collections
if the existing collection already utilizes some ARCGIS-compatible maps.
</p>
<div class="experience-imgs-large">
<div style="position: relative;">
<img src="images/brahms_arcgis.png" class="experience-img-large">
<p class="text-overlay">BRAHMS Database's in-built ARCGIS</p>
</div>
</div>
</div>
<div class="experience-body">
<div class="experience-imgs">
<img src="images/excel_convert_form.gif" class="experience-img">
</div>
<p id="p-right">Other than the database analysis, I also joined in a number of physical surveys of the plants in the Gardens with my colleagues.
I noticed that in their regular tasks of identifying and labelling trees, they had to record and track data on paper before manually entering them into the database back in the office.
This was partly due to the remoteness of certain locations and lack of Internet connectivity, resulting in a significant overhead and loss of time.
<br><br>
Thus, I set out to create a <span id="terms">HTML form</span> that could be used offline and could automatically convert collected data into an <span id="terms">Excel file</span>.
Personnel could use the form to record data while out in the field and would not need to spend time manually transferring the data to the database.
I picked up some <span id="terms">HTML</span>, <span id="terms">CSS</span> and <span id="terms">Javascript</span> to do so and managed to create a prototype form that could accomplish this task.
<br><br>
Here is a <span id="emphasis">demo</span> of the prototype form on the <u>left/above</u>! Since this is just a prototype, it's pretty barebones and simply functional.
Further improvements such as adding the ability to view added records, editing your entries can be done too!
<br><br>
In a functional botanic garden, making sure that all the collected data is accurate is essential.
Any inaccuracies such as mistyped identification numbers can result in "ghost" specimens that exist in the database but cannot be found in the Gardens.
<br><br>
One of the other tasks I was given was to work on a <span id="emphasis">checksum algorithm</span>.
Checksum algorithms are used to detect errors that occur during transmission or storage, mostly due to human error.
This would reduce errors such as a typo in the accession number when a personnel entered new data into the database.
</p>
</div>
<div class="experience-body">
<p>I considered a few algorithms, the <span id="terms">Luhn</span>, <span id="terms">Verhoeff</span> and <span id="terms">Damm algorithms</span> and eventually selected the Luhn algorithm.
The other 2 algorithms were more complex and might take a longer time to process.
Also, since accession numbers, which is what the checksum will be used for,
contains special characters along with numbers, the <span id="terms">Luhn mod N algorithm</span> was chosen as it could handle special characters.
<br><br>
Here's my implementation of the Luhn mod N algorithm in <span id="terms">Visual Basic</span> on the <u>right/below</u>.
I used <span id="emphasis">N = 39</span> as that is the total number of possible characters that can appear in a specimen's accession number.
<br><br>
To make sure that my implementation was correct, I created some <span id="emphasis">automated tests</span> in Excel using <span id="terms">Visual Basic</span> to check for the errors that the algorithm could not detect.
Since the algorithm was relatively simple, it could not detect all errors and <span id="terms">double transposition errors</span> <em>("103" instead of "301")</em> and a few <span id="terms">twin errors</span> <em>("99" mistyped as "22")</em> would pass.
However, these errors are very unlikely and the Luhn mod N algorithm will be sufficiently strong enough to detect most human errors and improve data integrity significantly.
<br><br>
A GIF of my <span id="terms">conclusions</span> from the tests is on the <u>right/below</u>! As mentioned above, double transposition errors aren't caught. This is because Luhn's algorithm
sums up the all digits after doubling the even digits. So if a digit is accidentally swapped with another even digit, the algorithm will not detect it.
<br><br>
Being my <span id="terms">first</span> foray into the workplace, my internship at NParks was a great starting point.
Although it isn't a software-focused company, meaning that it could not teach me nor expose me to more technical knowledge for my field, I could still learn non-technical stuff!
It forced me to <span id="emphasis">self-learn</span> and research, picking up HTML, CSS and Javascript which I had not worked with before.
Hearing from my colleagues' gripes about software also taught me that it is important for software to be built with the user in mind.
Even if a program had the functionality to complete a task, if users found it hard to navigate and use the interface, it would not be a good program.
<br><br>
The <span id="terms">Botanic Gardens</span> was also a very pleasant place to work at. Being someone that enjoys nature, whenever I needed a break, I could relax and walk around the Gardens to clear my mind.
My colleagues were also <span id="emphasis">very passionate</span> people <em>(which I suppose comes from the closeness they work with flora)</em> and inspired me to put my all into my work!
</p>
<div class="experience-imgs">
<img src="images/luhn_implementation.png" class="experience-img" style="margin: 0 0 7px 0;">
<img src="images/luhn_tests.gif" class="experience-img">
</div>
</div>
</div>
</section>
<script>
var navLinks = document.getElementById("navLinks");
function showMenu() {
navLinks.style.width = "125px";
navLinks.style.right = "0";
}
// CURRENTLY CLOSE MENU TRANSITION DOESNT WORK
function hideMenu() {
// value corresponds to navLinks value in styles.css
navLinks.style.width = "0px";
navLinks.style.right = "-125px";
}
</script>
</body>
</html>