SMOLNET PORTAL home about changes
Teeworlds utilities
2023-07-26
Last edit: 2023-07-26
---------------------
This idea came to me when I was looking for a Teeworlds skin renderer.
The ones that existed didn't suit me, as they didn't really respect the in-game rendering. Either the feet were too far out or the colors were wrong.
So I decided to make my own toolbox to manipulate Teeworlds assets, which we use on
(URL) teedata.net (https://teedata.net)
and for the Teedata Discord bot.
Indirectly, other people use it, for example, to render skins in a Discord channel that displays messages in real time (fokkonaut's Discord server) or in other projects like
(URL) TeeAssembler 2.0 (https://teeassembler.developer.li)
that used some part of the Teeworlds utilities code.
## Use case examples
### Teeworlds skin rendering
Render a Teeworlds 4K skin with default and custom colors.
```typescript
import {
Skin,
ColorCode,
ColorRGB
} from 'teeworlds-utilities';
const renderTest = async () => {
const skin = new Skin();
await skin.load('https://api.skins.tw/database/skins/96AATxN3DEzcGww4QhmduFCsPzaxhZO7Tq6Lh9OI.png');
skin
.render()
.saveRenderAs('default.png', true)
.colorTee(
new ColorCode(6619008),
new ColorRGB(136, 113, 255),
)
.render()
.saveRenderAs('color.png', true);
}
try {
renderTest();
} catch (err) {
console.error(err);
}
```
### Result (4K)
### Scene
A custom scene including a rendered skin.
```typescript
import { Scene } from 'teeworlds-utilities';
const sceneTest = async () => {
const scene = new Scene(
'data/scenes/schemes/example.json'
).preprocess();
await scene.renderScene();
scene.saveScene('scene.png')
}
sceneTest();
```
### Result
### Merge asset parts
Here we are going to merge specific parts from a skin (right) to another (left).
Any Teeworlds asset should works.
```typescript
import {
Skin,
SkinPart
} from 'teeworlds-utilities';
const mergeTest = async () => {
const teedata = new Skin();
await teedata.load('https://teedata.net/databasev2/skins/teedata/teedata.png');
const sunny = new Skin();
await sunny.load('https://teedata.net/databasev2/skins/irradiated%20sunny/irradiated%20sunny.png');
teedata
.copyParts(
sunny,
SkinPart.FOOT,
SkinPart.FOOT_SHADOW,
SkinPart.DEFAULT_EYE,
SkinPart.ANGRY_EYE,
SkinPart.BLINK_EYE,
SkinPart.CROSS_EYE,
SkinPart.HAPPY_EYE,
SkinPart.SCARY_EYE,
SkinPart.HAND_SHADOW,
SkinPart.HAND,
)
.setEyeAssetPart(SkinPart.ANGRY_EYE)
.render()
.saveAs('skin.png')
.saveRenderAs('rendered_skin.png', true)
}
try {
mergeTest();
} catch (err) {
console.error(err);
}
```
### Result
### More skin configuration
Here we are using the `SkinFull` object to render some in-game feature like the weapon, hands and emote.
```typescript
import {
Skin,
Gameskin,
ColorRGB,
Emoticon,
SkinFull,
GameskinPart,
EmoticonPart
} from 'teeworlds-utilities';
const fullSkinRenderConfiguration = async () => {
const teedataSunny = new Skin();
await teedataSunny.load('skin.png');
const napolitano = new Gameskin();
await napolitano.load('https://teedata.net/databasev2/gameskins/napolitano/napolitano.png');
const emoticon = new Emoticon();
await emoticon.load('https://teedata.net/databasev2/emoticons/default/default.png');
teedataSunny
.colorTee(
new ColorRGB(255, 255, 255),
new ColorRGB(255, 255, 255),
)
.setOrientation(345);
new SkinFull()
.setSkin(teedataSunny)
.setGameskin(napolitano, GameskinPart.HAMMER)
.setEmoticon(emoticon, EmoticonPart.PART_1_2)
.process()
.saveAs('skin_with_weapon_and_emote.png', true);
}
try {
fullSkinRenderConfiguration();
} catch (err) {
console.error(err);
}
```
### Result
### Other possible result
## Links
(URL) https://github.com/teeworlds-utilities/teeworlds-utilities (https://github.com)
Response: application/gopher-menu
Original URLgopher://tilde.pink/1/~nagi/teeworlds-utilities.gph
Content-Typeapplication/gopher-menu; charset=utf-8